Using I2C bus devices at same address.

Place code snippets and demo code here
Post Reply
AndyGadget
Posts: 222
Joined: Mon Feb 15, 2021 1:44 pm
Has thanked: 120 times
Been thanked: 132 times

Using I2C bus devices at same address.

Post by AndyGadget »

I'm doing a rebuild of my greenhouse monitor with AM2320 devices instead of DHT22 or BME280, both of which proved to be unreliable.
I need to take readings from two of these sensors and unfortunately there is no facility for an alternative I2C address on them so . . .

Initially I tried connecting the devices independently and had a separate I2CSETUP command for accessing each one.
This approach did not work on the board I'm using (a TTGO Display board with the display removed) for reasons I've yet to fathom. I could only get GPIO 21 and 22 to work with I2C.

So plan B was to use a common sda and scl and power on each AM2320 individually using a GPIO pin.
The GPIO pins on an ESP32 can source 40mA, and a high output is very close to the supply voltage although this would drop at as current increases. The AM2320 takes under 1mA peak, so no problem there. I've assigned one GPIO pin each to connect to the Vcc of each AM2320.
It's OK to use just one pair of I2C bus pullup resistors (4.3K to 10K) on the ESP32 side and take the common of these to the 3V3 supply.

This approach also has the advantage in an application where you're trying to minimise supply current; you're only powering on a device when you need it.

As well as the temperature and humidity readings from the AM2320 I'll be using a BMP280 for atmospheric pressure readings. I'll connect this in the same way with its own supply, although I could just twin it up with one of the other sensors as they are at different addresses.

Here's example code for what I'm doing. The AM2320 read routine is the the code I posted here some time ago.

Code: [Local Link Removed for Guests]

pause 1000

pin.mode 25, output ' GPIO25 connects to Vcc of 1st AM2320
pin.mode 26, output ' GPIO26 connects to Vcc of 2nd AM2320
pin(25) = 0
pin(26) = 0

'wlog BME280.SETUP(&h76)
iobuff.dim (1, 8)    ' Initialise io buffer to accept received data from AM2320
i2c.setup 21,22

wlog "Start"

do
  
  pin(25) = 1    ' Power on 1st device
  pin(26) = 0    ' Power off 2nd device
  wlog "Int"
  gosub read2320
  
  pin(25) = 0    ' Power off 1st device
  pin(26) = 1    ' Power on 2nd device
  wlog "Ext"
  gosub read2320
  
  'gosub readBME280
  
loop


Read2320:

pause 1500
I2C.BEGIN &h5C    ' First write wakes up AM2320
z =  i2c.end
I2C.BEGIN &h5C     ' Write to device to start measurement
I2C.WRITE &h03
I2C.WRITE &h00
I2C.WRITE &h04
if i2c.end <> 0 then wlog "Device Error"' Check for acknowledgement

pause 2200        ' Delay to allow measurement to complete

I2C.READ_IOBUFF(1), &H5C, 0, 8    ' Check for 8 bytes returned by device
if iobuff.len(1) = 8 then
  Hum = ((iobuff.read(1,2) * 256) + iobuff.read(1,3)) /10
  
  if iobuff.read(1,4) > &H7F then    ' Test for top bit of temperature byte set which indicates negative value
    Tmp =  -(((iobuff.read(1,4) and &H7F) * 256) + iobuff.read(1,5)) /10    ' Mask top bit and make negative if set.
  else
    Tmp = ((iobuff.read(1,4) * 256) + iobuff.read(1,5)) /10
  end if
  
  wlog "AM2320",Tmp, Hum
else
  wlog "Invalid device read operation"
end if

return

ReadBME280:

wlog "BME280", bme280.temp, bme280.qfe + 21

return
BeanieBots
Posts: 325
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 173 times
Been thanked: 104 times

Re: Using I2C bus devices at same address.

Post by BeanieBots »

Hi Andy,
Have you actually tried this yet? I have some grave concerns with what you suggest.
Correct me if I'm wrong about your setup, but I understand that you going to have two devices on the same bus and only power up the device you wish to read.
If that is the case, what I believe will happen is that when either of the two I2C lines goes high, they will parasitically power the unpowered device via their sda/scl inputs and potentially damage the device. Probably not too hazardous as the only current source would be the pullup resistors, but none the less, a high on an input of an unpowered device. Failing that, the pulled-up input may not go 'high' because it will be kept low by the clamp diodes of the unpowered device.
If you have any suitable instrumentation to observe the goings on, I'd be very interested in your results.
AndyGadget
Posts: 222
Joined: Mon Feb 15, 2021 1:44 pm
Has thanked: 120 times
Been thanked: 132 times

Re: Using I2C bus devices at same address.

Post by AndyGadget »

Hi BB.
Parasitic powering of the quiescent device did occur to me, but I have tried it with the AM2320 and this does not appear to be happening. I am getting valid reads from both devices.
I'm a few days away from home at the mo but when I get back I'll put a 'scope on it and dig a bit deeper. Maybe not a clean design, but it works :D (At least for the devices I'm using.)
BeanieBots
Posts: 325
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 173 times
Been thanked: 104 times

Re: Using I2C bus devices at same address.

Post by BeanieBots »

Hi Andy,
I'm glad it works, at least for that device.
Some other thoughts on how to do it:-
1. Use an I2C expander/multiplexor. Can't think of any part numbers off hand but they do exist.
2. Connect one device 'normally' and the other via an 08M2 (PICAXE) connected via serial.
3. Use an analogue switch (eg CD4066B or CD4016B) to multiplex the I2C lines.
4. Use a lower than normal pullup (maybe 3k3) and then connect to each sda/scl via say 22k so that parasitic power is minimised and any drag down caused by the un-powerd device has minimal effect on the I2C lines.
Also, whenever powering any device via an IO, I would strongly suggest 22nF decoupling.
I'd be very interested in your 'scope readings. Please post when you get a chance.

BTW. I've just done a similar project using 2x BME280 (utilising the two addresses) with great results.
One of the BMEs has been working well for over a year, the second was added a few weeks ago and is working working well.
Are you still having issues with BMEs?
User avatar
cicciocb
Site Admin
Posts: 1900
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 407 times
Been thanked: 1271 times
Contact:

Re: Using I2C bus devices at same address.

Post by cicciocb »

For info, an I2C multiplexer exists, the TCA9548A

https://learn.adafruit.com/adafruit-tca ... r-breakout
BeanieBots
Posts: 325
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 173 times
Been thanked: 104 times

Re: Using I2C bus devices at same address.

Post by BeanieBots »

Andy, any news on logic levels?
Are they rock solid or waiting for the wind to change direction?
AndyGadget
Posts: 222
Joined: Mon Feb 15, 2021 1:44 pm
Has thanked: 120 times
Been thanked: 132 times

Re: Using I2C bus devices at same address.

Post by AndyGadget »

Clock on the top, data on the bottom. This is with a 4K7 pullup on the bus.
Those spikes appear to be glitches rather than a level not making it high as they don't span a clock rising edge.
On the whole not too bad though, although it's not possible to get an entire initiate/read cycle because of the long delays the device needs for generating a value.

171.jpg
765.jpg
You do not have the required permissions to view the files attached to this post.
BeanieBots
Posts: 325
Joined: Tue Jun 21, 2022 2:17 pm
Location: South coast UK
Has thanked: 173 times
Been thanked: 104 times

Re: Using I2C bus devices at same address.

Post by BeanieBots »

I have to admit that I'm very surprised. Those traces look really sweet logic level wise.
No need for concern at all. Now I'm wondering if any other devices will behave as nicely?
It's certainly a great way to also save on power!
Maybe they did something clever with the substrate to mitigate having no addressing?
I think the glitches are lack of decoupling (some go -ve). Both the I2C devices and the ESP.
Post Reply