I2C collision detection I have put together a system that uses multiple Arduinos and a couple of 20x4 LCD displays to monitor my PV sun tracker and a weather station.  I am using I2C to link them all together.  One of the LCDs has been modified to have a different address (0x3b) so as to not conflict with the first one (0x3f).  So far, so good.   The sun tracker shows its display on the yellow one and the weather station shows its data on the blue one.

In order to connect this together I am using the Mayhew I2C&amp;Power devices, so one power source energizes the entire system.  I send 12 Volts on the wire, then at each node I use a 12v to 5v converter to provide power for the I2C&amp;Power board and the Nanos.  (The anemometer on the WX needs 12V to operate so that's a plus)

Each Arduino has a unique I2C address - there is no master in the system.

I have learned to set the screen updates to be quick (take readings and do any calculations before writing to the LCD in one swell foop), and to stagger the display update timings (the WX info updates every 65050 ms (full display update) and the PV info updates every 67050 ms (4 characters) and 605550 ms (full display refresh).  I chose these (arbitrarily random) values to make it less likely that they would try to update at the same time, because when both systems try to update their respective displays at the same time it causes some very interesting results - basically wiping out one or both displays.  It works most of the time but eventually one or the other screen will get wiped out.

Question:  Is there any way to implement collision detection on the I2C bus to prevent transmitting while other devices are communicating?  Something like CSMA/CD (Carrier Sense Multiple Access with Collision Detection) on Ethernet..
Collision detection on I2C is fully supported (See I2C Multi-Master). It works basically by attempting to transmit something and reading what is being transmitted at the same time. If what is read matches what is transmitted then the transmission worked. If it didn't match then there was a collision.

It is usually performed on a per-bit basis:


If a 0 then pull the data line LOW. If a 1 then let the resistor pull the data line HIGH.
Read the data line. If you want a 1 and get a 0 then some other device is pulling the data line low for a 0.
If the value was wrong then stop your transmission and back off by a random amount. Retry again. (note: both ends may retry, so you need good random numbers).


There is no support in the Wire library for collision detection, though, so you will have to implement it yourself. Section 22.4 of the datasheet gives you more information about how to implement it.