last day (16 days later) » 

11:36 PM
1
Q: I2C bus fails after a few sensor reads

Rob H.I'm building a small home automation hobby project for which I try to connect 4 temperature/humidity sensors (AM2320) to an I2C bus on the Raspberry Pi. When initially connecting the sensors they work fine, but after a few calls (10 to 50) with 4s interval, the reading fails with a "OSError: [Err...

 
How are the twisted pair wires paired? I hope SDA and SCL are not paired together.
 
Unfortunately they are. (Vcc + GND one pair, and SDA + SCL another). Would that give them sufficient mutual capacitance to disrupt any communication you think? The problem also appears with a sensor where I completely untwisted the wires. (So it's just 4 dangling single wires now.)
 
Yes, it could, because now the capacitance is between SDA and SCL. So a falling edge on one wire would capacitively couple to be a falling edge on the other wire too, as it is only weakly held high by a resistor. You might also be missing supply bypass caps on sensor end of the wire.
 
So that could also be an effect if both wires are no longer twisted but separated by a few cm of air? I did not add extra components to the sensor side yet. The bypass cap would be between V+ and GND?
 
It would not effect untwisted wires much. Yes cap between supply and ground.
 
11:36 PM
@ Rob H, Welcome and nice to meet you. Just a quick reply, more replies to follow in the next couple of days.(1) The instructable you mentioned: instructables.com/Raspberry-PI-Multiple-I2c-Devices. is NOT trustworthy. Rpi4B has official instructions to do up to 5 I2C buses. I tried but found that using two I2C buses (1 and 3) is OK, but three or more is not reliable.
Some two years ago I played with AM2302 (similar to AM2320). You might like to read my old posts to see how I did I2C troubleshooting. Testing AM2302 - Rpi.org.forum raspberrypi.org/forums/…. Please feel free to ask me any related questions. Cheers.
My AM2302 is outdated. Perhaps I should try AM2320 later. kandrsmith.org/RJS/Misc/Hygrometers/calib_many.html.
You might like to read my old post on I2C frequency and multiport setting. As I said earlier, three or more I2C ports even for Rpi4B and buster is NOT reliable.What is Rpi's I2C Maximum Speed? - Rpi SE raspberrypi.stackexchange.com/questions/108896/….
And have you ever heard of the I2C Address MUX? TCA9548A 1-to-8 I2C multiplexer! learn.adafruit.com/….
One way to improve I2C performance is the up shift 3V3 logic to 5V0. You might have noticed in my I2C projects that I am using Logical Level Shifter/Converter TSX/TBX0102/4/6/8 with chip enable. This is also sort of I2C MUX that eg, with one I2C bus you can have as many as same address sensors, BUT not at the same time.Ref: TSX0108 adafruit.com/product/395
 
Thanks for the welcome and for all the suggestions guys. I'll try around some more with components I have available and update in the post. If it does not work out I'll indeed probably have to go for a level shifter, muxer, or maybe some other sensors altogether.
 
at work so can't read all this, but general advice for i2c with extended distance: (0) if you have an oscilloscope, look at the signal! (1) series resistance, ~50-100 ohm. (2) replace R pull_up with constant current pull-up. works wonders. perhaps install on both ends. find the sweet spot, excessive pull-up current just makes more noise. (3) don't put caps on signal lines (4) if >5m, cable construction can be a factor too, but prob shouldn't be i2c then
 
Hello Pete. (0) Unfortunately not available (1) So you suggest each of the lines between slave and master should have a series resistance between 50 and 100 ohm? Why exactly? (2) I can imagine that would help indeed. I don't have that readily available though. (3) I didn't and I won't. (4) <5m check.
 
"I unfortunately don't have an oscilloscope to measure the signals on the line directly." - time to get one!
 
@Rob -- (4) good (3) good (2) up to you, but it is not hard with a current mirror, which is a dual-transistor and one resistor; it adds one extra discrete package per line. (1) the resistance will form an RC filter with the bulk capacitance of the wire, and will slow down the rise/fall of the signal. Terminates too. Slowing down the dV/dt, less crosstalk between SDA/SCL. (assuming that is the problem, which is just a guess.) If on the other hand the power/ground are bouncing around, you would fix it a different way. (0) if you could observe it directly, it would be easier to diagnose the cause
to be clear, the current pull-up is a little bit unconventional, but I have found it tremendously useful for exactly your situation
 
11:36 PM
Pete is right about the 100 ohm resistors. Wires have inductance, and in fact since it is CAT5 cable the pair is a 100 ohm differential transmission line, and in fact the end pulling low is a short circuit and the other end is open, so there could be reflections. The 100 ohm series resistors would slow down falling signal edges. As the Raspberry Pi also has configurable IO pin driver strength, make it as weak as possible, or at least weaker.
 
Alright, I can try the series resistor and/or configuring the driver strength tomorrow. Specifically the second one requires me to read into it a bit. Question out of curiosity on the suggested current driver: That does seem counteractive to the suggested resistor right? Using a current driver would speed up dV/dt? So either could be a solution, but likely not both?
(btw: The Pi has been sampling bus 1 at 10s intervals for almost 5hrs now without a single hick-up. That one seems pretty solid. (Single sensor, GPIO 2 and 3, no other buses enabled, via twisted pairs Cat5 cable, standard Pi 1.8 kOhm pull-ups, sensor side bypass caps of 4.7 nF and 47 uF, no added series resistors or any other tricks) I have the feeling the issues with the other buses may instead be in the Pi / i2c_gpio?)
 
@Rob, re: constant current vs series R ... they attack the problem of crosstalk and V_DD/GND noise in different ways. The series R does 2 things: (1) reduces dv/dt, which reduces magnitude of induced voltage on adjacent line in the cable. (2) terminates reflections when the open-drain output is turned on....
... . The constant current source does other things. (3) allows lower pull-up current to be used, which can reduce noises on local GND from the dI/dt of the chip pulling low against the line's capacitance (4) despite this, "responds" faster than a resistor pull-up. The crosstalk scenario for i2c is when a negative spike (or rising GND) comes along, while SCL is supposed to be staying high. In this case the resistor doesn't start to counteract this induced spike (source current to pull back up) until some meaningful voltage has already dropped. The CC pull-up immediately sources current.
there are two caveats with the series R. Firstly, the "low" level will rise -- due to the voltage divider formed by R_series vs R_pullup. (similar effect with I_pullup). So you can't make the R_series too big. Secondly, you don't want to slow down the signal too much. But I wouldn't worry about that in practice.
Now if you had a scope, you could really see all these things vividly, and figure out just how much fooling around with the circuitry you need =)
In terms of making the thing reliable -- if you suspect intermittent/marginal signal quality relating to the length of the 2m cable, then get a 5m cable or 10m cable, and make it work for that. Then you will be really confident.
 

  last day (16 days later) »