Changing the I2C clock speed is the first thing to try, since it allows continuing to use the existing hardware I2C peripheral on the Raspberry Pi. It also generally does not require any changes to user code. The changes are done using a system configuration file to directly alter that I2C hardware peripheral behavior.
Editing config.txt
Changing the I2C clock speed is done by adding a new line to the config.txt
file. The location of this file has changed with time. For Raspberry Pi OS releases prior to bookworm, the file is at /boot/config.txt
. Starting with bookworm, the location is /boot/firmware/config.txt
. Update the examples below to match the location for the OS release being used.
Log in to a terminal on your Pi and open that file in Nano, or your text editor of choice:
sudo nano /boot/config.txt
Scroll down until you find a block like:
# Uncomment some of all of these to enable the optional hardware interfaces dtparam=i2c_arm=on dtparam=i2s=on dtparam=spi=on
This block might vary depending on what you've enabled in raspi-config
. Directly below it, add lines that looks like (the line starting with #
is a comment):
# Set I2C Clock Speed dtparam=i2c_arm_baudrate=REPLACE_WITH_VALUE
Replace REPLACE_WITH_VALUE
with the desired clock speed value in Hz. Picking a value is discussed in the following sections.
Next, save the file and exit (in Nano, press Ctrl-X, y for yes, and Enter).
Now reboot the Pi for the setting to take effect:
sudo reboot
Slow Down The Clock
This seems to be the most universal fix. The general idea is to slow down the clock enough that any clock stretching simply gets buried within a given clock cycle. That is - the stretching happens faster than the main clock itself, so it just gets missed and is never even seen.
The suggested starting value is 10000 Hz, so the line in /boot/config.txt
would be:
# Clock stretching by slowing down to 10KHz dtparam=i2c_arm_baudrate=10000
If you still get bad data, try slowing it down more, maybe to 5 KHz or 1 KHz rate. Reboot after each change.
Speed Up The Clock
There are a few sensors, like the BNO085, for which this seems the better fix. This is done the same way as slowing down the clock, but the value is simply larger than the 100kHz default. I2C has various defined speed "ranges", and the next one above 100kHz is 400kHz, so the line in /boot/config.txt
would be:
# Clock stretching by speeding up to 400kHz dtparam=i2c_arm_baudrate=400000
Don't forget to reboot after saving the change.
Text editor powered by tinymce.