0

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.

zam664
  • 757
  • 1
  • 7
  • 18
  • Can you show the code you are using for your transmission, both for TX and RX? – angelatlarge Mar 31 '13 at 05:00
  • 3
    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 Mar 31 '13 at 05:02
  • I²C can absolutely transmit 0x00. If you can't, it's an implementation issue, not a protocol flaw. – jedwards Mar 31 '13 at 05:50
  • Take a look at my question and answer: https://stackoverflow.com/questions/46028764/is-there-a-general-i2c-command-to-see-if-a-device-is-still-present-on-the-bus – Codebeat Oct 17 '17 at 02:37

2 Answers2

6

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.

angelatlarge
  • 4,086
  • 2
  • 19
  • 36
  • @jedwards: if you pass the size then yes. But without it, there is no version of `write()` that takes an array of numbers... and besides, how would it know the size of the array? Unless you want it to treat `bytes[4]` as a `long`, but I think that's inadvisable. – angelatlarge Mar 31 '13 at 06:01
0

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

DarenW
  • 16,549
  • 7
  • 63
  • 102