0
votes

I am using the Wire class to have two Arduino Unos communicate using I2C. It seems that the Wire class ends transmission on a value of 0. So if I send bytes 0x01, 0x02, 0x00, and 0x04, the master receives: 0x01, 0x02, 0xFF, 0xFF.

It seems odd that a communication network designed for processor communication cannot send a 0x00. All the examples for I2C that I have seen use ASCII only. Inter-processor communication restricted to ASCII does not seem to make any sense. Am I missing something with I2C or is this just an implementation limitation of the Arduino Wire class?

Master

void loop() {
  Wire.requestFrom(2, 4); 

  while(Wire.available()) { 
    byte b = (byte) Wire.read(); 
    Serial.println(b); 
  }

  delay(1000);
}

Slave

void requestEvent() {
  char bytes[4] = {0x01,0x02,0x00,0x04};
  Wire.write(bytes);
}

The results are: 1 2 255 255.

When that 0x00 was 0x03 I got the expected: 1 2 3 4.

2
Can you show the code you are using for your transmission, both for TX and RX? - angelatlarge
I2C is capable of transmitting arbitrary bytes on the bus, as long as the address byte and stop/stop sequences are correctly generated. Can you post the code for both Arduinos? - In silico
I²C can absolutely transmit 0x00. If you can't, it's an implementation issue, not a protocol flaw. - jedwards
Take a look at my question and answer: stackoverflow.com/questions/46028764/… - Codebeat

2 Answers

6
votes

You are passing an array of chars to Wire.write()... This makes Wire treat the argument as a null-terminated string, and therefore the NULL byte terminates the transmission. If you want to send bytes, call the write() function once for each byte, passing it byte types.

Alternatively, you can call the write(const uint8_t *, size_t); version: you pass it a pointer to / array of bytes, but you also have to give it a size of your data array.

0
votes

Do you have Wire.begin() and Wire.beginTransmission() (with correct address) happening before calling Wire.write()?