5

I have setup an I2C bus between 3 Arduinos (Master, Slave1 and Slave2) by connecting all 3 A4 pins together, all 3 A5 pins together and one GND pin of each Arduino to a common ground line. The 3 Arduinos are currently being powered by independent USB power supplies, but I intend to power all of them from one single power supply using their Vin pins.

The slaves use the Wire library: Slave1 is at address 0x07 and Slave2 at 0x08. The Master uses the I2C library by Wayne Truchsess, because this library has timeout functionality. Master polls Slave1 and 100 ms later, polls Slave2. If either Slave is unavailable, Master should still read the other Slave (this is why Master doesn't work with the Wire library).

However, even though Master doesn't get locked-up, it can't read one Slave if the other gets powered down but left connected. If I cut the power of Slave1, Master becomes unable to read data from Slave2 until I physically disconnect Slave1. If I disconnect Slave1, Master is immediately able to read from Slave2 again. I2C scanning suggests the whole bus becomes invalid when a Slave is powered down (SCL and/or SDA turned low?).

From what I have been reading, this is not a software issue but an electronics circuitry problem: leaking current related to Slave1 and Slave2 having some diodes, something that perhaps could be solved with some transistors or N-FETs which would act like check-valves? Please advise.

P.S.: I have very little background in electronics and English is not my first language.

2

From what I have been reading, this is not a software issue but an electronics circuitry problem: leaking current related to Slave1 and Slave2 having some diodes, something that perhaps could be solved with some transistors or N-FETs which would act like check-valves? Please advise.

A nice solution to this problem is to use I2C Bus Isolation with TI TCA4311A Hot Swappable 2-Wire Bus Buffers alt. Analog Devices ADUM1250.

Please see the EEVblog Electronics Community Forum for further details and discussion.

Cheers!

  • That was the forum where I saw the "diodes" issue. I tried to draw an schematic of how I understood things should be wired, but I don't know what to connect to the VCC of the hot swap chip. A4 and A5 are the I2C pins of arduinos and D6 would be a pin I could use to drive the hot swap. Could you take a look? schematics.com/project/test-44785 – Jolas Marginópolis Dec 5 '16 at 15:25
  • Please see fig. 11, pp. 13, for correct wiring of hot-spot; ti.com/lit/ds/symlink/tca4311a.pdf – Mikael Patel Dec 5 '16 at 16:09
  • Thank you! It makes sense. Two more questions: 1) what is BD_SEL? 2) can the VCC of the backplane simply be a 5V regulated output from the Master Arduino? – Jolas Marginópolis Dec 5 '16 at 16:35
  • Ah, another question: in the drawing, there is a branch called "Card enable/disable". That is a pin in the slave arduino which would be always set HIGH by the slave's firmware so that a failure would automatically disable that slave, right? – Jolas Marginópolis Dec 5 '16 at 16:54
  • The ADUM1250 might be easier to understand and use. Please see the Application Note; analog.com/media/en/technical-documentation/application-notes/…. This is very straight forward. – Mikael Patel Dec 5 '16 at 18:40
2

The 3 Arduinos are currently being powered by independent USB power supplies, but I intend to power all of them from one single power supply using their Vin pins.

I think your problem here is that if you power down one Arduino, it isn't really powered down, because it will get "parasitic power" from the I2C line, particularly from the pull-up resistors which should be there. The protection diodes (internal to the processor) will allow power to flow from the A4 and A5 pins to the Vcc pin of the chip, which will then power up, probably in some sort of indeterminate state.

Since you are planning to power them from the same supply anyway, your problem should simply go away when you do that. Connecting a device with active inputs to a circuit (ie. a voltage present) when the device itself is not powered up, is not recommended. Exceptions would be devices that are specifically designed to handle that, for example, commercially produced printers via their USB input.

  • I am powering the slaves down to simulate failures. A slave may fail even if the rest of the system keeps working. – Jolas Marginópolis Dec 5 '16 at 14:28
  • That's not a good model of a recoverable failure, as it imposes an unrecoverable electrical fault. Holding a slave in reset, especially if you can trigger it mid-transfer might be. Or put the failure simulations in the firmware of the slaves. – Chris Stratton Dec 5 '16 at 14:29
  • Indeed, but since the slaves are sensor modules that can be hard-reset in seconds and measure data for R&D, I thought I could treat all failures as unrecoverable. If I hard-reset the sensors, they do not lose calibration, and I thought later I could add relays for automatic hard-resetting. Is that a bad idea? – Jolas Marginópolis Dec 5 '16 at 16:46
0

An I2C bus should use open drain lines or open collector drivers AND there should be only 1 (one) pull up resistor for each of the 2 I2C wires. In this way, should a slave fail, it will not effect the I2C bus.

An Arduino does not truly have an open collector driven pin. Instead people have been clever and either set the pin connected to an I2C line low pulling the I2C bus low or as an input allowing the I2C bus to float high through the pull up resistor. In this way multiple I2C devices (Arduino or not) can share the bus.

However, if you power down an Arduino, it can no longer operate in this manner. In fact it will likely appear as a load or path to ground and effect the normal operation of the I2C bus.

In the end, I2C is designed for chips (usually) on the same board so that they can talk with one another. It would follow that they are all powered off the same supply. It is an unlikely scenario for power to fail for only one device on the board.

Alternatives:

There are protocols designed to go between devices (as in separately located and separately powered). RS485 is one such protocol and has been around for years. A quick search show both sheilds made specifically for Arduinos as well as tutorials using generic RS485 interfaces.

  • Thanks for the response. As I said, I lack the necessary background so I am going to have to ask further stupid questions: "to drive an open collector configure transistor" -> what does that mean? A transistor has 3 terminals, right? What goes where? Would it be 1 transistor for every slave as an intermediate between the slave and which I2C wire? Would any transistor do the trick? – Jolas Marginópolis Dec 5 '16 at 4:49
  • I think it would be difficult to design an I2C buffer that would not inhibit the bus if it lost power. I tried to describe one in the answer. But w/o electrical experience, I think it would be difficult. Also, it is an unlikely scenario given I2C devices are expected to be co-located on the same board. So I offered up RS485 as an alternative in the answer. – st2000 Dec 5 '16 at 13:23
  • RS485 is a good tip and I found that MAX485 chip being sold in my country! "transmit on one pin and receive on another" -> so if I only have 2 slaves and a lot of unused pins in the Master, would the SoftwareSerial library be a simple solution, instead of trying to use I2C? Like, using D7 and D8 as RX and TX for Slave1 and D5/D6 for Slave2? – Jolas Marginópolis Dec 5 '16 at 14:20
  • This theory is simply wrong. It appears based on guesses that were not checked but easily could have been, and as a result it only confuses readers without helping. Please delete. – Chris Stratton Dec 5 '16 at 14:30
  • Agreed. I was adding text based on the comments left by the O.P. He appears to be happy. Although he did not vote or accept my answer. I'll edit it down to a normal stackexchange answer. – st2000 Dec 6 '16 at 2:01
0

Mikael has the correct answer above.

I had this same issue when using two Megas communicating over I2C, along with other items running on the I2C bus. I needed the system to continue running if one Mega went down due to loss of power. The other Mega should detect it and execute some abort commands for my mission.

Initially I wired the Megas up on the same I2C bus, just as I would any other device. When I unplugged one Mega, the other would freeze the next time it tried to address another device on the bus.

The solution was to use a hot-swappable I2C buffer. I used this one, and everything worked immediately without issue after wiring it up: http://www.mouser.com/search/ProductDetail.aspx?r=595-TCA4311ADR

To integrate the SOIC-8 package onto a standard DIP breadboard for Arduinos, I used an adapter from Adafruit.

Cheers and good luck

Chris

High Altitude Photography Platform 360 video from a jet-stabilized platform at the edge of space http://hialtphoto.blogspot.com

Facebook @hialtphoto

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.