Skip to content

Check for bus errors ?

Koepel edited this page Oct 11, 2021 · 9 revisions

There are three common ways to check for bus errors.

No check at all

In some cases it is no problem when there is no check at all for bus errors. For example if the sensor is soldered to the Arduino board.
The Wire.read() will return -1 when there was no sensor. If that value of -1 causes no problem in the sketch, then no checking is needed.

A single check

A single check to see if a sensor is connected is often enough.
It is possible to check just once if the sensor acknowledges to its I2C address. Some sensors have a special identifier byte, for example a WHO_AM_I identifier, that can be read.
Once the sensor is detected, the rest of the code can run without error checking.
The I2C bus should run without problems though:

  • The wires for SDA and SCL should be short and definitely not side-by-side in a flat ribbon cable.
  • There should be no voltage levels problems of SDA or SCL. A problem with 5V and 3.3V can be fixed with a I2C level shifter.
  • The bus speed should be well below the maximum. The Wire.setClock() can set the bus speed.
  • The pullup resistors should be not too high and not too low. The I2C bus is specified for a maximum pulldown current of 3 mA. Every Controller and every Target device is allowed to sink more current than 3 mA, but they should be able to sink at least 3 mA to comply with the I2C standard.

Read more about the hardware aspects on the page: How to make a reliable I2C bus.

Check everything

The Wire.endTransmission() returns an error code and the Wire.requestFrom() and Wire.available() return the number of received bytes. Those return values can be checked every time a I2C bus transaction was done.

It might seem that all this checking is a good thing, but it is trivial.
When the I2C bus is so bad that errors might happen, it is doubtful that it will work at all. The Wire library can not handle I2C bus errors very well itself.

The I2C bus is a serial "bus" after all, so every experienced software engineer might want to have a check every time the bus is used. However, since the Wire library does not handle bus errors very well, I have seen no proof yet that all this extra checking is meaningful.

My advice: For you own project at home there is no need to check everything. Keep the code small and simple. If you are a company or if you are creating an extra software layer then go ahead and check everything if you want to, but keep in mind that it won't do much good.

Exception: Some sensors do not give an acknowledge when they are busy. Sometimes the datasheet is not clear how long should be waited when the sensor is busy. When developing code to interface with such a sensor, it is very useful to always check if the I2C transaction was succesful.