Changing the default I2C bus speed on the Raspberry Pi can help improve the performance of some projects. This is particularly important when using the I2C interface to control a display module. In the newer versions of Raspbian this change must be made using a Device Tree parameter.
The bus speed is sometimes referred to as “baudrate” although the two aren’t actually the same thing.
Step 1 – Enable the I2C Interface
Before the interface baudrate can be changed the I2C interface must be enabled. This can be done using “raspi-config” on the command line or “Raspberry Pi Configuration” on the Raspbian desktop.
For step-by-step instructions on how to do this please take a look at the Enable I2C Interface on the Raspberry Pi post.
Step 2 – Find Config.txt File
The config.txt file we need to edit could be located in one of two locations. Use the following command to find it:
find /boot -name "config.txt" | grep config.txt
If the results only show one file located in /boot/ then use this command to edit it:
sudo nano /boot/config.txt
If the results show two files located in /boot/ and /boot/firmware we want to edit the second one:
sudo nano /boot/firmware/config.txt
Step 3 – Edit Config.txt File to set I2C Bus Speed
Find the line containing “dtparam=i2c_arm=on”.
Add “,i2c_arm_baudrate=400000” where 400000 is the new speed (400 Kbit/s). Note the comma.
This should give you a line looking like :
dtparam=i2c_arm=on,i2c_arm_baudrate=400000
This enables the bus and sets the baudrate at the same time with a comma separating both parameters.
Use CTRL-X, then Y, then RETURN to save the file and exit.
Step 4 – Reboot
Finally, reboot the Pi for the new setting to take effect :
sudo reboot
I2C Baudrate Values
The BCM2835 ARM Peripherals specification (page 28) says that the Pi has a “fast-mode” (400Kb/s) driver. For this reason I would recommend using 100000 or 400000 as baudrate values. The default is usually set to 100000.
I successfully used 400000 with an OLED display module to increase the rate at which images could be updated.
Finally, for a list of I2C related articles click here.
More information about the I2C protocol can be found on Wikipedia.
4 Comments
Hi Matt, thanks for the nice tutorial.
I found that sometimes we need to reduce the i2c speed instead. For example, when implementing an I2C slave with ATtiny84, who has no hardware support for I2C.
When using software to support I2C on slave, the slave may behave slow and need “clock stretching”, which is not well supported by Raspberry Pi until now (https://www.raspberrypi.org/forums/viewtopic.php?t=13771).
In my case, I reduced the I2C to 10kbps (dtparam=i2c1_baudrate=10000) to avoid clock stretching, and it worked well.
The Raspberry Pi i2c hardware has a bug which prevents it from correctly implementing clock stretching. However this can easily be overcome by disabling the standard i2c hardware and replacing it with a device tree overlay. This will allow slave devices which require clock stretching, like the BNO055 IMU, to be used with the Raspberry Pi. For full details of the procedure please see https://gps-pie.com/pi_i2c_config.htm
wow you made my day, my i2c stream got interrupted all the time until I setup this
thank you so much
My experience is that, when you only write the line mentioned in the article into the /boot/config.txt file, the I2C speed is not exactly 400kHz. It’s less.
To get it spot on, you also have to add the following line to that same /boot/config.txt file:
core_freq=250
This is what I have in my /boot/config.txt file and it works like a charm on exactly 400kHz:
core_freq=250
dtparam=i2c_baudrate=400000
(and on another line I have dtparam=i2c_arm=on because I activated the I2C interface in the setup menu through raspi-config).
If you want 100kHz, replace 400000 with 100000 and you will have exactly 100kHz.