This is for those who work with I2C across multiple devices: Every year,

This is for those who work with I2C across multiple devices:

Every year, when I wire up whatever amount of LED strips in my window as an Xmas display, I learn something new. Something that perhaps in years past was never an issue but now it is. This year it has to do with the I2C bus. I have all the AVRs daisychained together via I2C and that works great. However, if any one of them were to go down, the master will lock up when it tries to send data to it. It has to do with the I2C implementation within the Arduino library. When it can’t reach a node, it goes into a while() loop that does nothing, it’s effectively dead, no recovery other than a reset.

So, for the next round I will be implementing I2C Isolation with something like TI’s ISO1540 or Analog’s ADuM1250. That way, if a node, or nodes, were to go down, the master won’t lock up, and when those nodes re-awaken, they’ll just rejoin the circle.

Analog Devices has an application note on this:

I wonder if one could (easily) implement a software timeout.

There I go again: thinking of EVERYTHING as a software problem…

I2C does implement a proper timeout. Arduino’s implementation does not. So, if you’re using the Arduino Wire library, you can hack the TWI.h and TWI.c files to implement a proper timeout.

However, the difference between the software timeout versus using an isolator is the immediate return. You’d have to wait for the timeout before proceeding.

Another approach that might work for you is to use a different I2C library. The Arduino Wire library simplifies a lot of things and does a lot of no-timeout blocking on certain I2C states that can cause hangs if your bus has noise on it.

If your slaves are generic non-Arduino I2C devices, I’d recommend using a simple software I2C library. I hacked together one a few years ago:
http://todbot.com/blog/2010/09/25/softi2cmaster-add-i2c-to-any-arduino-pins/
but there are many others out there now that I think are structured better.

I’ve heard good things about the “i2cdevlib” library at:

which you can set to use either Wire or their internal “fastwire” implementation that implements timeouts and how to pop out of bad states caused by noise.

Yep, that’s another solution as well. But, you’re still waiting for a timeout. And for me, where I blast out data to the nodes in rapid succession (so they can all react within a set amount of time), having to wait for a timeout will cause other problems. The hardware solution avoids that.

I2C is great for things that require confirmation, I.E. nodes or receivers that need to be set to a single state, or confirmation of data. Or for multiple devices connected in parallel on minimal wires. However for something like LED displays which most of us are doing, the confirmation is not necessary as it will just be rewritten shortly, and not affect the overall result significantly making the error very minimal.

I had a similar issue with an Arduino locking up when using an I2C LCD Display that was also controlling a high amp linear actuator and some other high voltage electronics that introduced noise into the line. This turned out to be a bad thing when the Arduino locked up with the actuator at full output.

It seems like a serial connection or something similar with an overflow buffer would be a better alternative unless you feel you absolutely need the confirmation. Although I can understand using it as they do make I2C really easy to implement.

That’s exactly what I do @Arren_Parker , multiple nodes driving multiple strings, with one master sending data to each node. Running with just two wires between nodes.

And then there’s the $4-per-wireless-mode nRF24L01+ …

http://playground.arduino.cc/InterfacingWithHardware/Nrf24L01

@Benjamin_Greenwald d tells me that a full implementation takes six pins, and that auto-ack works, and that one device can be set up as “the primary sender”.

I seem to recall that it supports multicast as well as point-to-point packets. Not sure if any of the existing Arduino code provides an interface to that.

Yep, I have used those in the past as well. The reason I didn’t stick with them was because they eat up too many pins. :slight_smile:

Six does seem like a lot, especially on an Uno or other non-mega-pin board.

The DigiX (which is like a Due clone – plus WiFi, for the relatively low price of $59) has a plug for the nRF on board and comes with one already installed.

It’s not … but there was a brief moment in my thought’s existence where I was going smaller and additional pins became a luxury … Which is also why I don’t like to limit myself to the Attiny85 but would rather use the Attiny84 with double the pins … except I can’t get FastSPI compiled for it. So I reverted back to the 328p. :slight_smile:

Strictly power failure.

Although, the isolators I’m referring to aren’t optoisolators either. They have buffers both for input and output and isolate both SDA and SCL lines, both ways.

Yep, albeit without buffers.

uh… I know your problems. I spent 2 years working on that I2C issue… I was running I2C 60 feet and ran into this issues… I ended buying line buffers and repeaters and broke the buffer into 3 30 foot buffers. I got all 3 to work but in the end only 2 worked when it was installed. If you are not using an external pullup I highly recommend it. I used 500ohm resistors for mine. I found that I could majorly minimize the lockup by having the receiveEvent() function just set a bit saying there was information there to retrieve. Then, before any LED show() call or even in the show() function do the I2C read if that bit is set on. I eventually switched to RS485 chips and considering they only cost like $4 a piece from china recommend it as it will never lock up.

I ended up using these…

I think they are limited to 16 nodes though (16rx+16tx) because after 16 nodes, it never worked… I just split the signal out ever 10 nodes and it worked great at 5v at like 56kpbs…