I2C Multiple Slave Devices with Same Addresses

Hello All,

I am working on an Atmega328p host controller that manages two Atmega328p based slave devices. A requirement that seems to be challenging is:

— Each slave device must have the same address so the user does not have to worry about which host he or she plugs into. For example a user might have 10 host units and 20 sensor units. But they need to be able to swap sensors from host to host. I thought I could do this by simply only powering one sensor at a time. However if both sensors are not powered at the same time (like a bus) the I2C bus goes dead? Could this be caused by the impedance state of the powered down sensor “drowning” the SCL and SDA lines? If both are powered on at the same time it works fine. But this requires unique addresses for each sensor.

I have tried setting the pinModes of A4 and A5 to INPUTS (HIGH IMPEDANCE) after a request from the master has been fulfilled and before the sensor gets powered down.

Any clever workarounds floating around out there?

Thanks!

No, sorry. I think you want too much. The I2C bus is not plug-and-play, it was never intended for that.
The Arduino Wire library is for I2C and what you want is more like the SMBus : http://en.wikipedia.org/wiki/System_Management_Bus.

What is the total length of wires of all the Slaves to a single Master ? It can be 50cm but not a lot more.

If one Slave has no power, it pulls the SDA and SCL low, that stops the I2C bus.
An Arduino has protection diodes for every pin, so the current is going from SDA to VCC (inside the microcontroller) and that pulls SDA low.

Hi jasonparm

Maybe you could use an I2C multiplexer chip to give you two downstream I2C channels. Your slaves would all have the same address, with the master writing to the multiplexer control register to determine which slave is connected at any one time.

The code on the master would need to handle the situations of zero, one or two slaves connected at the same time.

Regards

Ray

The OP in this thread came up with what I consider a novel approach by using a CD4053 to multiplex only the SCL line to each device. I haven't tried it myself, but it does make sense.

This is considering the the I2C master is the only device generating the clock signal on the SCL line.

Thanks guys! I was not aware of the I2C multiplexer :astonished: Sounds like that is the only option to get I2C going for this specific application.

What is the total length of wires of all the Slaves to a single Master ? It can be 50cm but not a lot more.

Currently the sensors are 7ft a piece. 14ft total on the bus! I have tested it up to 35 ft with no problems!? Maybe because I’m using Cat5?

An Arduino has protection diodes for every pin, so the current is going from SDA to VCC (inside the microcontroller) and that pulls SDA low.

Thanks for that explanation, that will save some grief in the future for other projects. This means that I would probably have the same issue with SPI if I were to try it with the same requirements (turn one on and one off)? Of course in that case I could leave both on and use unique SS pins.

Since I am only dealing with 2 sensor ports I will probably take the advice of @Peter_n and search for the right communication scheme. Maybe Software Serial or SMBus.

Thanks!! ALL of you have been very helpful!

One more thing I might try. I do have an extra IO pin running to each slave device. So maybe I could:

1)Power both sensors up at the same time

2)Write the spare IO pin HIGH or LOW telling the sensor to either connect to the bus Wire.begin() or Set inputMode on A4 and A5 as INPUT (High impedance) disconnecting it from the bus? After a request for data has been fulfilled by the master the sensor would listen for the extra IO pin to go low, telling it to disconnect.

Am I wrong assuming that setting pinModes A4 and A5 to INPUTS would virtually disconnect that sensor from the bus?

Thanks!

If A4 and A5 are inputs (default at startup) they are disconnected from the I2C bus, that is correct.
But if that Slave has no power, it will still pull the SDA and SCL low, making the I2C bus useless for others.

jasonparm:
Currently the sensors are 7ft a piece. 14ft total on the bus! I have tested it up to 35 ft with no problems!? Maybe because I'm using Cat5?

Maybe because of the quality of the cable and connectors because the unshielded twisted pair build of the cable provides nothing as I2C is not differential and therefore no noise cancellation benefit.

So I mocked it up and it seems to work great. I power both sensors at the same time so the bus does not go dead. I then use the extra pin running to each (A0, A1) sensor to trigger the external interrupt 0 on the sensor. The sensor’s pinModes (SDA,SCL) are initialized to INPUTS on power up but when it catches the interrupt from the host, it calls wire.begin() and connects to the bus and stays connected until I power down the sensor. I guess that is really the same thing as multiplexing but without the extra hardware. Although now I have sensors that require an extra signal pin from the host to be useful :confused:

Thanks!!

Peter_n:
If A4 and A5 are inputs (default at startup) they are disconnected from the I2C bus, that is correct.
But if that Slave has no power, it will still pull the SDA and SCL low, making the I2C bus useless for others.

This was really useful for my project too - good post.
Thank you
D6

If your data is not highly time sensitive, then why not use SoftI2Clib. You can connect multiple I2C devices without the multiplexer! Just use simple I/O pins on Arduino just like SoftwareSerial.

Here is the link

http://playground.arduino.cc/Main/SoftwareI2CLibrary

Hope this helps!