Hi, I've been having trouble with Wire.available() and Wire.read() not reading from the beginning of the receive buffer.
My setup is a Teensy LC (master) and Teensy 3.2 (slave) connected via i2c pins 18/19. Both are grounded, and there are 3.3k ohm pullups to the 3.3V pin on the Teensy 3.2. Both are also connected over serial for uploading and debugging.
The master reads from serial and passes it along line by line over i2c.
// Buffer contains some text, ending with a newline
Wire.beginTransmission(SLAVE_ID);
Wire.write(buffer, buffer_len);
Wire.endTransmission(false);
The slave reads from i2c and, for debugging, just prints it back to serial.
if (Wire.available() > 0) {
Serial.print(Wire.read());
}
Here's where the issue is: in order for Wire.available() to be greater than 0, each line sent must be longer than the previous, and the slave only receives the characters that come after. For example if the master sends
The slave will print
I'm guessing this is because when the slave receives a new transmission, it writes from the beginning of the rxBuffer and sets rxBufferLength, however the rxBufferIndex is not reset. When a new transmission is received and is shorter, it will return rxBufferLength - rxBufferIndex as some negative number.
There's not really an easy fix here:
- Setting rxBufferIndex to 0 would cause previous transmissions to be lost if not consumed.
- Turning rxBuffer into a ring buffer would cause issues for code using onReceive.
- rxBufferLength is used in many places for both master and slave.
Interestingly, this happens with the Arduino Wire library as well. I found a related issue but outdated workaround in https://forum.pjrc.com/threads/35500-Teensy-3-2-Master-and-Slave-I2C-communication-problem?p=113711&viewfull=1#post113711 .
Hi, I've been having trouble with Wire.available() and Wire.read() not reading from the beginning of the receive buffer.
My setup is a Teensy LC (master) and Teensy 3.2 (slave) connected via i2c pins 18/19. Both are grounded, and there are 3.3k ohm pullups to the 3.3V pin on the Teensy 3.2. Both are also connected over serial for uploading and debugging.
The master reads from serial and passes it along line by line over i2c.
The slave reads from i2c and, for debugging, just prints it back to serial.
Here's where the issue is: in order for Wire.available() to be greater than 0, each line sent must be longer than the previous, and the slave only receives the characters that come after. For example if the master sends
The slave will print
I'm guessing this is because when the slave receives a new transmission, it writes from the beginning of the rxBuffer and sets rxBufferLength, however the rxBufferIndex is not reset. When a new transmission is received and is shorter, it will return rxBufferLength - rxBufferIndex as some negative number.
There's not really an easy fix here:
Interestingly, this happens with the Arduino Wire library as well. I found a related issue but outdated workaround in https://forum.pjrc.com/threads/35500-Teensy-3-2-Master-and-Slave-I2C-communication-problem?p=113711&viewfull=1#post113711 .