Skip to content

Fix Issue of I2C on Old Raspberry Pi Models

Phenomenon

Raspberry Pi OS (bookworm) seems to have issues with I2C on older models like the Raspberry Pi 2B+. Even if I2C is enabled via raspi-config, it may not be available.

Expected GPIO pin assignments are:

  • GPIO2: SDA
  • GPIO3: SCL

In the case of Raspberry Pi 2B+, GPIO3 is set as input. (In the case of Raspberry Pi 4B, GPIO3 is set as SCL and no problem.)

1
2
3
4
5
$ pinctrl
 0: ip    -- | hi // ID_SDA/GPIO0 = input
 1: ip    -- | hi // ID_SCL/GPIO1 = input
 2: a0    -- | hi // GPIO2 = SDA1
 3: ip    -- | hi // GPIO3 = input

i2cdetect command is very slow and cannot detect the device:

$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

We can see following logs in dmesg.

1
2
3
4
5
6
7
8
[   83.209881] i2c-bcm2835 3f804000.i2c: i2c transfer timed out
[   84.249847] i2c-bcm2835 3f804000.i2c: i2c transfer timed out
[   85.289853] i2c-bcm2835 3f804000.i2c: i2c transfer timed out
[   86.329848] i2c-bcm2835 3f804000.i2c: i2c transfer timed out
[   87.369849] i2c-bcm2835 3f804000.i2c: i2c transfer timed out
[   88.409851] i2c-bcm2835 3f804000.i2c: i2c transfer timed out
[   89.449847] i2c-bcm2835 3f804000.i2c: i2c transfer timed out
[   90.489874] i2c-bcm2835 3f804000.i2c: i2c transfer timed out

I have researched the web about this issue, but I couldn't find an exact solution.

Solution

We can use software I2C which can assign any GPIO pin to SDA and SCL. This is an alternative to hardware I2C.

Let's try setting GPIO4 to SDA and GPIO14 to SCL.

1. Enable I2C via raspi-config

Run the following command to open the Raspberry Pi configuration tool:

sudo raspi-config
Navigate to Interfacing Options -> I2C and enable I2C.

2. Add software I2C setting

Add the following line to /boot/firmware/config.txt:

dtoverlay=i2c-gpio,bus=1,i2c_gpio_sda=4,i2c_gpio_scl=14

3. Reboot the Raspberry Pi

sudo reboot 0

4. Check if the I2C device address is found

After rebooting, verify that I2C is working by running i2cdetect command:

$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

Then we can use the I2C device properly.

Drawbacks of software I2C:

  • High CPU load (slower than hardware I2C)
  • Low clock accuracy (not suitable for high-speed communication)
  • Weak in real-time processing (prone to delays)