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. 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).
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, …