Skip to main content
Added language specifier
Source Link
void sendByte(byte data) {
  pinMode(DATA_PIN, OUTPUT);  // to output mode
  // Send start bit
  digitalWrite(DATA_PIN, LOW);
  delayMicroseconds(500);
  // Send data bits
  for (int i = 0; i < 8; i++) {
    digitalWrite(DATA_PIN, (data & (1 << i)) ? HIGH : LOW);  // send one bit
    delayMicroseconds(500);  // duration of one bit
  }
  digitalWrite(DATA_PIN, HIGH);  // Idle state
  pinMode(DATA_PIN, INPUT);  // back to input mode
}    

byte receiveByte() {
  byte received = 0;

  // wait for LOW (start bit)
  while (digitalRead(DATA_PIN) == HIGH); 
  delayMicroseconds(500)  
  for (int i = 0; i < 8; i++) {
    delayMicroseconds(250);  // wait for the half of bit
    if (digitalRead(DATA_PIN) == HIGH) {
      received |= (1 << i);  // read the bit
    }
    delayMicroseconds(250);  // to the end of bit
  }
  return received;
}
    void sendByte(byte data) {
      pinMode(DATA_PIN, OUTPUT);  // to output mode
      // Send start bit
      digitalWrite(DATA_PIN, LOW);
      delayMicroseconds(500);
      // Send data bits
      for (int i = 0; i < 8; i++) {
        digitalWrite(DATA_PIN, (data & (1 << i)) ? HIGH : LOW);  // send one bit
        delayMicroseconds(500);  // duration of one bit
      }
      digitalWrite(DATA_PIN, HIGH);  // Idle state
      pinMode(DATA_PIN, INPUT);  // back to input mode
    }    

    byte receiveByte() {
      byte received = 0;
    
      // wait for LOW (start bit)
      while (digitalRead(DATA_PIN) == HIGH); 
      delayMicroseconds(500)  
      for (int i = 0; i < 8; i++) {
        delayMicroseconds(250);  // wait for the half of bit
        if (digitalRead(DATA_PIN) == HIGH) {
          received |= (1 << i);  // read the bit
        }
        delayMicroseconds(250);  // to the end of bit
      }
      return received;
    }

In addition there may be some timing problems. Testing with an ATtiny1614 instead of an ATtiny13, the delayMicrosecondsdelayMicroseconds was found to give too short delays, resulting in the byte received being wrong, the reply being started too early, and the reply having wrong timing. This problems could be solved by including

#define F_CPU 16000000UL
#include <avr/delay.h>
    #define F_CPU 16000000UL
    #include <avr/delay.h>
void sendByte(byte data) {
  pinMode(DATA_PIN, OUTPUT);  // to output mode
  // Send start bit
  digitalWrite(DATA_PIN, LOW);
  delayMicroseconds(500);
  // Send data bits
  for (int i = 0; i < 8; i++) {
    digitalWrite(DATA_PIN, (data & (1 << i)) ? HIGH : LOW);  // send one bit
    delayMicroseconds(500);  // duration of one bit
  }
  digitalWrite(DATA_PIN, HIGH);  // Idle state
  pinMode(DATA_PIN, INPUT);  // back to input mode
}    

byte receiveByte() {
  byte received = 0;

  // wait for LOW (start bit)
  while (digitalRead(DATA_PIN) == HIGH); 
  delayMicroseconds(500)  
  for (int i = 0; i < 8; i++) {
    delayMicroseconds(250);  // wait for the half of bit
    if (digitalRead(DATA_PIN) == HIGH) {
      received |= (1 << i);  // read the bit
    }
    delayMicroseconds(250);  // to the end of bit
  }
  return received;
}

In addition there may be some timing problems. Testing with an ATtiny1614 instead of an ATtiny13, the delayMicroseconds was found to give too short delays, resulting in the byte received being wrong, the reply being started too early, and the reply having wrong timing. This problems could be solved by including

#define F_CPU 16000000UL
#include <avr/delay.h>
    void sendByte(byte data) {
      pinMode(DATA_PIN, OUTPUT);  // to output mode
      // Send start bit
      digitalWrite(DATA_PIN, LOW);
      delayMicroseconds(500);
      // Send data bits
      for (int i = 0; i < 8; i++) {
        digitalWrite(DATA_PIN, (data & (1 << i)) ? HIGH : LOW);  // send one bit
        delayMicroseconds(500);  // duration of one bit
      }
      digitalWrite(DATA_PIN, HIGH);  // Idle state
      pinMode(DATA_PIN, INPUT);  // back to input mode
    }    

    byte receiveByte() {
      byte received = 0;
    
      // wait for LOW (start bit)
      while (digitalRead(DATA_PIN) == HIGH); 
      delayMicroseconds(500)  
      for (int i = 0; i < 8; i++) {
        delayMicroseconds(250);  // wait for the half of bit
        if (digitalRead(DATA_PIN) == HIGH) {
          received |= (1 << i);  // read the bit
        }
        delayMicroseconds(250);  // to the end of bit
      }
      return received;
    }

In addition there may be some timing problems. Testing with an ATtiny1614 instead of an ATtiny13, the delayMicroseconds was found to give too short delays, resulting in the byte received being wrong, the reply being started too early, and the reply having wrong timing. This problems could be solved by including

    #define F_CPU 16000000UL
    #include <avr/delay.h>
Post Migrated Here from electronics.stackexchange.com (revisions)
Source Link
Terje D.
Terje D.

There are at least three problems with your code. The first is that the sender does not send the startbit that the receiver expects, and the others are that the the receiver waits for a startbit for each bit received, and that it samples that startbit instead of the following bits. Thus, the code should be more like this:

void sendByte(byte data) {
  pinMode(DATA_PIN, OUTPUT);  // to output mode
  // Send start bit
  digitalWrite(DATA_PIN, LOW);
  delayMicroseconds(500);
  // Send data bits
  for (int i = 0; i < 8; i++) {
    digitalWrite(DATA_PIN, (data & (1 << i)) ? HIGH : LOW);  // send one bit
    delayMicroseconds(500);  // duration of one bit
  }
  digitalWrite(DATA_PIN, HIGH);  // Idle state
  pinMode(DATA_PIN, INPUT);  // back to input mode
}    

byte receiveByte() {
  byte received = 0;

  // wait for LOW (start bit)
  while (digitalRead(DATA_PIN) == HIGH); 
  delayMicroseconds(500)  
  for (int i = 0; i < 8; i++) {
    delayMicroseconds(250);  // wait for the half of bit
    if (digitalRead(DATA_PIN) == HIGH) {
      received |= (1 << i);  // read the bit
    }
    delayMicroseconds(250);  // to the end of bit
  }
  return received;
}

In addition there may be some timing problems. Testing with an ATtiny1614 instead of an ATtiny13, the delayMicroseconds was found to give too short delays, resulting in the byte received being wrong, the reply being started too early, and the reply having wrong timing. This problems could be solved by including

#define F_CPU 16000000UL
#include <avr/delay.h>

at the top of the ATtiny file, setting the Attiny1614 frequency to 10 MHz(!), and replacing delayMicroseconds() with _delay_us().