I'm using a Raspberry Pi 4B to read pressure sensors via I2C, with Python 3.7.3 and the SMBus library. I ran into the Broadcom clock-stretching bug, so I switched to software-based I2C (brief description here: https://github.com/fivdi/i2c-bus/blob/master/doc/raspberry-pi-software-i2c.md). This helped me significantly; the reads on hardware-based I2C were highly oscillatory and unreliable.
Unfortunately, it introduced a new problem: the clock speed. The sensors only support a max of 100 kHz, and the Pi is running at ~140 kHz, as measured on a scope. The problem presents as the bus getting stuck intermittently, with the clock and data lines getting pulled low and unable to bounce back to high until the sensor is physically disconnected from the Pi. I think the stuck bus is due to the clock speed being too fast (the sensors work very well with NI LabVIEW, which uses a clock speed of 100 kHz), so that's what I'm trying to address.
I don't think software I2C clock speed is controlled in the same way as hardware, but I tried several settings nonetheless. The main things I tried:
sudo modprobe i2c_bcm2708 baudrate=100000
- Creating a .conf file in /etc/modprobe.d/ with the content
options i2c_bcm2708 baudrate=100000
i2c-bcm2708 baudrate=400000 i2c-dev
None of these had any effect on the clock speed. Is there a special way to control the clock speed for software-based I2C?
In case it's helpful, I also looked at
vcgencmd measure_clock arm while the Pi is at rest, is reading sensors successfully, and has the stuck bus. These are different values than the scope readings for clock frequency, so I'm not quite sure how to interpret them, but they certainly show a difference:
- Idling: ~600,000,000
- Successfully reading: ~700,000,000-800,000,000
- Stuck bus: ~1,500,000,000
If I can't fix the clock speed, some other ideas I've had which I've briefly looked into are:
- Try using the GPCLK functionality of one of the other GPIO pins--although figuring out how to set those pins to be clocks, let alone editing their specific frequency, seems to be quite challenging
- Look into headers for converting SPI to I2C, and use SPI functionality on the Pi
- Switch from Pi to an alternative platform
I'd welcome other options to investigate as well.