Skip to content

Common mistakes

Koepel edited this page Oct 11, 2021 · 22 revisions

1

Mistake 1: Waiting after calling the Wire.requestFrom()

The Wire.requestFrom() is blocking. It will wait until the I2C bus transaction has finished.
That means that no waiting after the Wire.requestFrom() has been called is needed. If data was received, that data is in a buffer (inside the Wire library) and ready to be read with Wire.read().

Sometimes the waiting is done with a while loop:

Wire.requestFrom(0x28, 2);
while(Wire.available() < 2);   <--- common mistake, don't do this
x = Wire.read();
y = Wire.read();

Sometimes the waiting is done with a delay or with using millis():

Wire.requestFrom(0x28, 2);
delay(10);   <--- common mistake, don't do this
x = Wire.read();
y = Wire.read();

Is it bad ? Could be bad.
When the sensor is not connected, the Wire.available() will return zero. That while(Wire.available() < 2); code will run forever and the sketch will stop.
The Wire library can detect a few problems on the I2C bus. If such a problem is detected, the Wire.available() might also return zero, and that while(Wire.available() < 2); code will stop the sketch.

2

Mistake 2: Using Wire.endTransmission() after a Wire.requestFrom()

The Wire.requestFrom() will do a complete I2C bus transaction with: START, send address, read data, STOP.

The Wire.endTransmission() has no part in this. It should only be used when writing data and only together with Wire.beginTransmission().

Wire.requestFrom(0x40, 1);
x = Wire.read();
Wire.endTransmission();   <--- common mistake, don't do this

Is it bad ? Yes, maybe.
The Wire.endTransmission() could start an extra I2C bus transaction and then the sensor acknowledges to its address. That extra bus activity takes time. It will probably not disturb the sensor. Since there are a number of Wire compatible libraries, other libraries can do other things.

3

Mistake 3: Using Wire.beginTransmission() before a Wire.requestFrom()

The Wire.beginTransmission() should only be used when writing data. It works together with Wire.endTransmission() but not with Wire.requestFrom().

Wire.beginTransmission(0x68); <--- common mistake, don't do this
Wire.requestFrom(0x68,2);

Is it bad ? No, probably not.
The Wire.beginTransmission() clears a few variables to get ready to write to a sensor. That is no problem.
There are however some Wire compatible libraries that already put a START condition on the I2C bus. That means that the I2C bus does no longer work according to the I2C specifications.

4

Mistake 4: Clearing the buffer

After the data is written or read, sometimes the "remaining" data is read with Wire.read() to clear the buffer. That is not needed. The I2C bus uses packets of data, it is not a stream. The Wire.beginTransmission() and Wire.requestFrom() clear the buffers before starting a with a new I2C transaction.

With a Wire.requestFrom() it is even impossible to receive more data than requested. When a I2C Controller is reading data, the Controller defines how many bytes will be read. The Target can try to send less or more, but that will not change the number of bytes that the Controller will read.

Is it bad to clear the buffer? No, not at all.

5

Mistake 5: Using Wire.receive() and Wire.send()

In 2011 the Arduino IDE got to version 1.0 and one of the many changes was renaming the Wire.receive() to Wire.read() and Wire.send() to Wire.write(). Today, there is still new code written that checks if the version is below 1.0 and then uses the Wire.receive() and Wire.send().

No one uses an Arduino IDE version below 1.0 anymore. The new code or new library is probably not even compatible with that old Arduino version.