Raspberry PI Multiple I2C Devices

Introduction: Raspberry PI Multiple I2C Devices

Frustrated because you can not use multiples of the same I2C devices in your project. No need to use slow multiplexers. The latest raspbian kernel support the creation of multiple I2C busses using GPIO pins. This solution is super fast.

Step 1: Some Shell Comands

Connect one of your i2c devices while your raspberry pi is of, start your raspberry pi and run

sudo i2cdetect -y 1

You will see a table like in the attach figure. I have attach a BMP280 temp and barometric pressure sensor. The i2c address is 0x76 according to the table. Note this address.

Do this for all your i2c devices.

Step 2: Case One: I2c Devices Have the Same Address

This was always the problematic case. An i2c bus can handle multiple devices, but they should have different i2c addresses. Some i2c devices have jumpers to set other i2c addresses, but many don't. In this case you may use a i2c multiplexer (hardware) to rotate the i2c SDA (Data) and SCL (Clock) or you can create an additional i2c bus or more.

I will create two aditional busses, nl bus 3 and 4

Open the cli and run

cd /boot

sudo nano config.txt

Add the following line of code, preferable in the section where spi and i2c is enabled.

dtoverlay=i2c-gpio,bus=4,i2c_gpio_delay_us=1,i2c_gpio_sda=23,i2c_gpio_scl=24

This line will create an aditional i2c bus (bus 4) on GPIO 23 as SDA and GPIO 24 as SCL (GPIO 23 and 24 is defaults)

Also add the following line to create i2c bus 3

dtoverlay=i2c-gpio,bus=3,i2c_gpio_delay_us=1,i2c_gpio_sda=17,i2c_gpio_scl=27

GPIO 17 will be the SDA and GPIO 27 will be the SCL for i2c bus 4.

Tipe control X to exit.

Note on the Bus Numbering and order:

Never use bus 0 and 2, it is use for other things in the board like eprom on hats etc

For the April 2019 raspbian release:

You should always start with the highest bus (Bus 4 in this case) in your config.txt and work through to the lowest bus (bus 3).

The lowest bus must always be bus 3

If you need 5 extra busses, the busses must bi in the order of 7,6, 5, 4, 3

This issue on bus order was not there when this Instructable was originally written. It seems like changes was made to the kernel.

Shut down your PI, switch it of. Connect your i2c devices to bus 4 (SDA to GPIO 23 and SCL to GPIO 24) and the other to i2c bus 3 (SDA to GPIO 17 and SCL to GPIO 27).

Switch on the pi.

Run:

sudo i2cdetect -l (Lower Case L)

You will now see that i2c bus 3 and 4 is also listed. Also run:

sudo i2cdetect -y 3

sudo i2cdetect -y 4

Now you can use your sensor in your programming language. Remember to specify the correct i2c busses.

Attach is an example for the popular BMP280 Temperature and Pressure sensor. No multiplexer can read 2 BMP280s this fast.

An example of 2 Sensirion SDP 810 sensors is also attach. Again working much faster than the multiplexer I used in the past

I created python code to read two new BMP388s from adafruit.

I may also add other sensors in future to https://github.com/JJSlabbert/Raspberry_PI_i2C_conficts

Step 3: Case 2: Different I2c Addresses.

Simple. i2c is a bus. A bus purpouse is to communicate with multiple devices. Connect the devices parallel to the same i2c bus. You can use bus one.

Run:

sudo i2cdetect -y 1

You will see the devices listed.

Be the First to Share

    Recommendations

    • Barbecue Speed Challenge

      Barbecue Speed Challenge
    • Explore Science Challenge

      Explore Science Challenge
    • Toys & Games Contest

      Toys & Games Contest

    21 Comments

    0
    ulfh2012
    ulfh2012

    1 year ago

    Tried this solution on raspbian buster - latest version. Just copied the code, but system refuses to boot. Have to boot from another SD-card, remount the other card via USB, and remove the lines to make it boot again. Tried a new installation. and then I can see the devices, but i2detect -y on the new devices is dead slow.
    Looks like problem persist if I also have a DS3231 HW clock. After adding the lines for implementing multiple i2c-devices system refuse to boot

    0
    astromaphilli14
    astromaphilli14

    Reply 4 weeks ago

    I have no issues with booting but my i2cdetect -y 4 is dead slow, how do you fix that specific issue?

    sudo
    raspi-gpio set 23 pu
    sudo
    raspi-gpio set 24 pu

    worked for me! SOLVED!

    0
    JJ Slabbert
    JJ Slabbert

    Reply 4 weeks ago

    Post your results of
    sudo i2cdetect -l
    sudo i2cdetect -y 4
    Does it detect the devices on bus 4

    0
    astromaphilli14
    astromaphilli14

    Reply 4 weeks ago

    setting 'pu' on each gpio fixed it, thanks!

    0
    jrbrearley
    jrbrearley

    Question 5 months ago on Step 1

    Adafruit support folks answered the question: use adafruit-extended-bus package.

    type: pip3 install adafruit-extended-bus

    In your code, add:
    from adafruit_extended_bus import ExtendedI2C as I2C
    i2c_4 = I2C(4) # custom #4 per /boot/config.txt
    ads40 = ADS.ADS1115(i2c_4, address=0x48)
    ch4_48_0 = AnalogIn(ads40, ADS.P0)

    And it works, can now read data from I2C-4 device.

    0
    jrbrearley
    jrbrearley

    Question 5 months ago on Introduction

    I was able to add i2c-4 bus in the /boot/config.txt file with:
    dtoverlay=i2c-gpio,bus=4,i2c_gpio_delay_us=1,i2c_gpio_sda=17,i2c_gpio_scl=27

    sudo i2cdetect -y 4 correctly show the attached ADS1115 at address 0x.48

    However python adafruit_ads1x15 does not like i2c bus 4

    import board, busio, time, traceback
    import adafruit_ads1x15.ads1115 as ADS
    from adafruit_ads1x15.analog_in import AnalogIn
    i2c_1 = busio.I2C(board.SCL, board.SDA) # works OK
    # i2c_4 = busio.I2C(scl=13, sda=11) # gets error
    i2c_4 = busio.I2C(board.D13, board.D11) # gets error

    Traceback (most recent call last):
    File "ads1115_read_ch.py", line 8, in <module>
    i2c_4 = busio.I2C(board.D13, board.D11)
    File "/home/pi/.local/lib/python3.7/site-packages/busio.py", line 31, in __init__
    self.init(scl, sda, frequency)
    File "/home/pi/.local/lib/python3.7/site-packages/busio.py", line 72, in init
    (scl, sda), i2cPorts
    ValueError: No Hardware I2C on (scl,sda)=(13, 11)
    Valid I2C ports: ((3, 3, 2), (1, 3, 2), (0, 1, 0))

    Any suggestions?

    0
    Marcmk
    Marcmk

    7 months ago

    Great tut.
    Next what I want to do is to publish it to my MQTT broker.
    I'm stuck at that for a view hours.

    0
    StephenD148
    StephenD148

    1 year ago

    ..also what is the performance considerations compared to hardware implementation?

    0
    JJ Slabbert
    JJ Slabbert

    Reply 1 year ago

    It was much faster than the multiplexer i used. I can not remember the exact figures.

    0
    StephenD148
    StephenD148

    Question 1 year ago on Introduction

    How can we alter the i2c bus speed for these new i2c busses?

    1
    mquinteiro
    mquinteiro

    2 years ago

    It does not work as expected for me, if I enable two buses in /boot/config.txt with:
    dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=23,i2c_gpio_scl=24

    dtoverlay=i2c-gpio,bus=4,i2c_gpio_sda=27,i2c_gpio_scl=22
    I get two buses, but with the wrong number:
    # i2cdetect -l
    i2c-3 i2c i2c@4 I2C adapter

    i2c-1 i2c bcm2835 I2C adapter I2C adapter

    i2c-4 i2c i2c@3 I2C adapter

    The buses are swapped!
    One walkaround could by to get i2c@x data when open the device programmatically (I'm using C) to now which is the real 3 and 4.
    (Note: I have found that I can check /sys/bus/i2c/devices/ but it is a bit tricky)


    0
    JJ Slabbert
    JJ Slabbert

    Reply 2 years ago

    I think changes was made on the kernel. Just add bus 4 first, then bus 3 in config.txt
    The same happened with me today after updating my OS

    0
    MureyT
    MureyT

    2 years ago

    Hello. I don't think this tutorial is working for anyone (and I don't think it's that everyone is forgetting pullup resistors). Could you try it yourself? I tried it out and it didn't work for me. I posted the details on raspberry pi stack exchange (http://bit.ly/2UVmKlo). That post has 2 upvotes so far, commenters have said they have the same issue, many commenters here say they have the same issue, and people have told me in person they had the same issue. So clearly there is a problem with the tutorial. Is there any way to make this work? I need multiple I2C busses for a project.

    0
    JJ Slabbert
    JJ Slabbert

    Reply 2 years ago

    First, make sure you are using an updated operating system.

    Check out https://lb.raspberrypi.org/forums/viewtopic.php?t...
    It is clear that there were some successes. For me it worked perfectly.

    Play around with the i2c_gpio_delay_us= setting. The current setting may be to fast or slow for your i2c device

    Also check the info on the i2c-gpio in boot/overlays/README

    0
    JJ Slabbert
    JJ Slabbert

    Reply 2 years ago

    It worked for me.

    1
    broadcasttelevision
    broadcasttelevision

    2 years ago

    I am getting the same result as enrique023, using RPi3 and stretch. Any help getting a second i2c bus would be much appreciated... even a "RPI-similar" computer. Need the I/O and speed.
    Thanks

    0
    JJ Slabbert
    JJ Slabbert

    Reply 2 years ago

    Are your sensor working on bus 1 (standard i2c bus)?
    Dit you add appropriate pull up resisters between SDA and 3.3 volt and SCL and 3.3v?
    What sensors are you using?

    1
    enrique023
    enrique023

    Question 2 years ago

    Hello, excellent tutorial, very easy to follow.

    I just have problems to find my other devices, when I write the command:

    i2cdetect -l

    in effect it shows me:

    i2c-3 i2c i2c@3 I2C adapter

    i2c-1 i2c bcm2835 I2C adapter I2C adapter

    i2c-4 i2c i2c@4 I2C adapter

    but when I write the commands:

    sudo i2cdetect -y 3 or

    sudo i2cdetect -y 4

    they run very slowly and don't detect the devices (pressure sensors with same address).

    I tried with BCM GPIO and WiringPi GPIO (23 and 24, 17 and 27) considering the possibility that I'm connecting on the wrong pins but It didn't work.

    Any comment will be helpful,

    0
    JJ Slabbert
    JJ Slabbert

    Answer 2 years ago

    Tnx for feedback,

    What pressure sensors are you using?

    If you connect them to bus 1, do they show up when running i2cdetect -y 1.? If they do, try the following, read on.

    The internal i2c bus (bus 1) has a 1.8 kohms pull up resister between 3volt pin and SDA, and also between 3volt and scl. Add those resisters between your 3volt and gpio pins used as SDA and SCL and test again.

    Please let me know if this worked.

    Also read https://www.raspberrypi.org/forums/viewtopic.php?t=64610

    I beliefe that the bmp280 that i used had the pull ups on the sensor itself. My SDP810 (flow sensors) needed extra 10 kohms sensors, even on bus one.

    7AD6477D-922A-4BA5-9591-A7B24155D33D.jpeg