the I2C Bus on my Raspberry Pi 4 Model B is not working altough i2cdetect does detect targets.
I tried to use the Raspberry Pi Sense HAT and the SSD1306 OLED display and the PCA9685 Servo Driver with the I2C Bus. Everything works fine. I don't know why now the I2C Bus doesn`t work. Then I was not sure if one of the devices is defect. The OLED Display sometimes shows "snow". So it could be that there was a corrupted signal.
Then I tested the Raspberry Pi without the Sense HAT. Maybe the Sense HAT could be defect. Nothing helped. Then I unplugged the OLED display without any success. And after that the PCA9685 and plugged in the OLED display. Now the OLED display shows the right result. I tested the three servos which are connected to the PCA9685 with a servo checker and luckily I found out, that they aren't defect. So I connected the PCA9685 again but I can't send a PWM signal to my servos. After that I removed the I2C hub on which the PCA9685 and the OLED display are plugged in to test the Raspberry Pi Sense HAT again. It doesn`t work. After that I tried the Sense HAT on an older Raspberry Pi 3 Model B+ and there I can use it correctly.
So my thought was that there is something wrong with the Raspberry Pi configuration for the I2C Bus. Then I go to the raspi-config and deactivated the I2C Interfacing option, rebooted the Pi and again enabled this option. Nothing helped.
I can't use the PCA9685 and the Servos, and I also can't use the Raspberry Pi Sense HAT and I can't use the OLED display. With i2cdetect I can detect adresses.
So here is what I got:
python imu.py
Traceback (most recent call last):
  File "imu.py", line 3, in <module>
    sense = SenseHat()
  File "/usr/lib/python3/dist-packages/sense_hat/sense_hat.py", line 39, in __init__
    raise OSError('Cannot detect %s device' % self.SENSE_HAT_FB_NAME)
OSError: Cannot detect RPi-Sense FB device
It could be any python test program for the Sense HAT. Two days ago. Everything worked... The programs for the servos I could run without any errors but now the servos doesn`t do anything. So they don't get the PWM signal. Now I tested the OLED display program and it works. But instead of showing the text static it is blinking. Maybe this is because the I2C Bus not working correctly.
sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- 5c -- -- 5f 
60: -- -- -- -- -- -- -- -- -- -- 6a -- -- -- -- -- 
70: 70 -- -- -- -- -- -- -- 
1c, 3c, 5c, 5f und 6a should be the Sense HAT... 40 the OLED Display and 70 the PCA9685.
dmesg | grep i2c
[    2.434699] i2c /dev entries driver
cat /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
i2c-dev
i2c-bcm2708
spi-bcm2835
spi-bcm2708
snd-bcm2835
cat /etc/modprobe.d/raspi-blacklist.conf is empty
sudo i2cdetect -y 0
Error: Could not open file `/dev/i2c-0' or `/dev/i2c/0': No such file or directory
In the /boot/config.txt both lines are enabled:
dtparam=i2c1=on
dtparam=i2c_arm=on
I can't say what causes the error and what exactly would be the error. Two days ago everything works but now not. On the PCA9685 I measured the voltage on the pins and they aren't defect.
Also the dtoverlay=rpi-sense is enabled in the /boot/config.txt.
raspi-gpio get
BANK0 (GPIO 0 to 27):
GPIO 0: level=1 fsel=0 func=INPUT pull=UP
GPIO 1: level=1 fsel=0 func=INPUT pull=UP
GPIO 2: level=1 fsel=4 alt=0 func=SDA1 pull=UP
GPIO 3: level=1 fsel=4 alt=0 func=SCL1 pull=UP
GPIO 4: level=0 fsel=0 func=INPUT pull=UP
GPIO 5: level=0 fsel=0 func=INPUT pull=UP
GPIO 6: level=1 fsel=0 func=INPUT pull=UP
GPIO 7: level=1 fsel=1 func=OUTPUT pull=UP
GPIO 8: level=1 fsel=1 func=OUTPUT pull=UP
GPIO 9: level=0 fsel=4 alt=0 func=SPI0_MISO pull=DOWN
GPIO 10: level=0 fsel=4 alt=0 func=SPI0_MOSI pull=DOWN
GPIO 11: level=0 fsel=4 alt=0 func=SPI0_SCLK pull=DOWN
GPIO 12: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 13: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 14: level=1 fsel=2 alt=5 func=TXD1 pull=NONE
GPIO 15: level=1 fsel=2 alt=5 func=RXD1 pull=UP
GPIO 16: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 17: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 18: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 19: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 20: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 21: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 22: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 23: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 24: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 25: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 26: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 27: level=0 fsel=0 func=INPUT pull=DOWN
BANK1 (GPIO 28 to 45):
GPIO 28: level=1 fsel=2 alt=5 func=RGMII_MDIO pull=UP
GPIO 29: level=0 fsel=2 alt=5 func=RGMII_MDC pull=DOWN
GPIO 30: level=0 fsel=7 alt=3 func=CTS0 pull=UP
GPIO 31: level=0 fsel=7 alt=3 func=RTS0 pull=NONE
GPIO 32: level=1 fsel=7 alt=3 func=TXD0 pull=NONE
GPIO 33: level=1 fsel=7 alt=3 func=RXD0 pull=UP
GPIO 34: level=1 fsel=7 alt=3 func=SD1_CLK pull=NONE
GPIO 35: level=1 fsel=7 alt=3 func=SD1_CMD pull=UP
GPIO 36: level=1 fsel=7 alt=3 func=SD1_DAT0 pull=UP
GPIO 37: level=1 fsel=7 alt=3 func=SD1_DAT1 pull=UP
GPIO 38: level=1 fsel=7 alt=3 func=SD1_DAT2 pull=UP
GPIO 39: level=1 fsel=7 alt=3 func=SD1_DAT3 pull=UP
GPIO 40: level=0 fsel=4 alt=0 func=PWM1_0 pull=NONE
GPIO 41: level=0 fsel=4 alt=0 func=PWM1_1 pull=NONE
GPIO 42: level=0 fsel=1 func=OUTPUT pull=UP
GPIO 43: level=1 fsel=0 func=INPUT pull=UP
GPIO 44: level=1 fsel=5 alt=1 func=SDA0 pull=UP
GPIO 45: level=1 fsel=5 alt=1 func=SCL0 pull=UP
BANK2 (GPIO 46 to 53):
GPIO 46: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 47: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 48: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 49: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 50: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 51: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 52: level=0 fsel=0 func=INPUT pull=DOWN
GPIO 53: level=0 fsel=0 func=INPUT pull=DOWN
I'm not sure where I could search the error because I the hardware works on an older Raspberry Pi. Hopefully there is a person who could help me. Thanks in advance.
Question
Short description of problem
The OP's I2C bus works, but only intermittently.
Configuration
The OP is using Rpi4B. He is testing the following I2C devices:
1. Sense HAT
2. SSD1306 OLED display and 
3. PCA9685 PWM Controller/Servo Driver, connected to up to 3 servos.
Summary of the OP's test results
In the beginning, I2C bus can detect I2C devices (one by one) without any problem.
After the I2C Hub (Note 1) has been removed and restored, errors begin to appears, all sense HAT, OLED display, PWM controller do not work, or do not work properly.
At this point, i2cdetect -y 1 still works OK.
Possible causes of problem and troubleshooting suggestions
1. The I2C bus might be overloaded.
The I2C bus has a maximum impedance limit, around 400pF. So if you put too many I2C devices on the same bus, total capacitance increases and I/O error 121 begin to appear and performance is no longer stable. I usually find I2C bus not stable when I add more and more I2C device, especially with the same I2C addresses. For example, I can add three or four different I2C devices on the same bus, find no problem, but when I try to add more and more I2C devices of the same type (MCP23017 in my experiment) the system get unstable, I/O Error become frequent. My conclusion is that even I can add the maximum of 8 MCP23017s and can still be detected, but system is very unstable, and usually two MCP23017 is the limit for stable operation.
2. The wiring might be too long
When wiring is too long, capacitance/impedance will sooner or later reach the 400pF limit. I usually start with 30cm, and by trials and errors, extends to some two meters, when problems begin to appear. A quick and dirty solution is to use a level shifter, say TBX0102, and the situation improves. I once tried to use hardware I2C extender and buffer chips but found results not impressive. I also tried to use twisted CAT5 cables, but still cannot go too long.
3. I2C speed too high
For Rpi4B, we can adjust the I2C speed, down to say 10kHz, and up to 500kHz. Lower speed lowers I2C bus impedance, and therefore smaller signal distortion and less errors.
4. PCA9685 PWM controller board too noisy
This PCB board has a space to insert a "big" capacitor, to stabilize the local power supply. I forgot if 100uF is the recommend value, but greedy me usually use 1000uF or more. And I never use the Rpi's 5V power rail to drive the servos/DC motors. I always use an external power supply (6 ~ 7.5V, 3A+). Also, always try to apply the PWM signals to the servos "out of sync", to reduce spikes and glitches which might feed back to the Rpi and causes trouble.
5. Using multiple I2C buses so not to overload on one single bus
For Rpi4B, there are 5 one board I2C buses you can use. So the OP might like to spread the load to say, three buses, especially using a single bus to entertain the possibly trouble making PCA9685 PWM/servo controller.
The penzu lab report below shows how to config Rpi for more that one I2C bus, and an example of using 3 ADXL345's for three separate bus (PCA9685 is briefly described).
Configuring and using Rpi4B's 5 I2C Buses
Appendix A - /boot/config.txt tlfong01 2020mar04
# /boot/config.txt 2020feb0801  tlfong01 
# last update 2020mar04hkt1830
# *** Display ***
disable_overscan=1
dtoverlay=vc4-fkms-v3d
max_framebuffers=2
# *** Audio ***
dtparam=audio=on
# *** UART ***
enable_uart=1
# *** I2C ***
# *** Changingspeed***
# dtparam=i2c_arm=on,i2c_arm_baudrate=50000
# dtparam=i2c_arm=on,i2c_arm_baudrate=100000
# dtparam=i2c_arm=on,i2c_arm_baudrate=400000
dtparam=i2c_arm=on,i2c_arm_baudrate=1000000
# *** Configuring two I2 buses ***
dtoverlay=i2c1,pins_2_3   (board pins  3,  5)
dtoverlay=i2c3,pins_4_5   (board pins  7, 29)
# dtoverlay=i2c4,pins_6_7   (board pins 31, 26)
# dtoverlay=i2c5,pins_12_13 (board pins 32, 33)
# dtoverlay=i2c6,pins_22_23 (board pins 15, 16)
# *** SPI ***
dtparam=spi=on
dtoverlay=spi1-3cs
# *** End of config.txt ***
/ to continue, ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With