Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    I2C Bus Error With Multiple Devices Connected

    Scheduled Pinned Locked Moved SiPy
    10 Posts 2 Posters 55 Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • L Offline
      Lennac
      last edited by

      I have one device successfully connected via I2C (pins 4 and 5) and transmitting data. This was the TSL2591 - a digital light sensor.

      I found a helpful library that got me to set that up and have the values printing to console without any issue.

      I then wanted to print the values to an LCD, so I've been using the Grove-LCD and found another library that looked promising to use for that.

      However, after connecting the LCD (pins 9 and 10), I'm suddenly running into an error:

      "OSError: I2C bus error"

      Running i2c.scan() returns [62, 98] (not sure what to make of that honestly, but I saw some people ask about that command elsewhere).

      Traceback (most recent call last):
        File "main.py", line 27, in <module>
        File "/flash/lib/tsl2591.py", line 158, in get_full_luminosity
        File "/flash/lib/tsl2591.py", line 147, in enable
        File "/flash/lib/tsl2591.py", line 61, in write_byte_data
      

      Here's what my main.py looks like:

      th = DHT(Pin('P8', mode=Pin.OPEN_DRAIN),1) # assign th variable to P8 and initialize
      tsl = tsl2591.Tsl2591(0)  # initialize lux sensor - pin initialized in ts2591.py
      i2c = I2C(0, I2C.MASTER) # init i2c for display
      d = i2c_lcd.Display(i2c) # initialize display
      
      d.home()
      
      while(1):
          d.clear()
          time.sleep(2) # sleep for two seconds as per DHT specifications
          result = th.read() # read values from DHT
          if result.is_valid(): # check if error_code = 0
              pycom.rgbled(0x001000) # green - onboard data read confirmation
              print('Temperature: {:3.2f}'.format(result.temperature/1.0)) # print temp to console
              print('Humidity: {:3.2f}'.format(result.humidity/1.0)) # print rh to console
          full, ir = tsl.get_full_luminosity()  # read raw values (full spectrum and ir spectrum)
          lux = tsl.calculate_lux(full, ir)  # convert raw values to lux
          print('Lux: ' + str(lux) + ' Lumens')
          d.write('Testing')
          gc.collect() # memory management
      

      I can only assume the LCD has caused the issue. The LCD is initialized with i2c = I2C(0, I2C.MASTER) - line 14. I tried changing that to a specific pin declaration, as I thought maybe there was an issue with one i2c being declared master? However, that resulted in the same error, except it pointed to my lcd library.

      robert-hhR 1 Reply Last reply Reply Quote 0
      • robert-hhR Offline
        robert-hh @Lennac
        last edited by

        @Lennac You try to use the I2C bus both on pins 4,5 and 9,10. That is not possible and not required. You can use multiple devices on one bus. The best approach is to rewrite your tsl2591 lib to use the I2C bus the same way like the lcd display: create the I2C instance outside the lib and hand it over to the lib. That's the way it is usually done by MicroPython. Thenyou can use the same bus with different libs. Adafruit uses a different way to deal with it.

        L 1 Reply Last reply Reply Quote 1
        • L Offline
          Lennac
          last edited by

          This post is deleted!
          1 Reply Last reply Reply Quote 0
          • L Offline
            Lennac @robert-hh
            last edited by

            @robert-hh

            Thank you for the reply. And this may seem like a silly question, but how can I connect two separate devices to the same pins? I understand what you're saying from the coding side of things and shouldn't have a problem there, but rather the physical setup and connections.

            robert-hhR 1 Reply Last reply Reply Quote 0
            • robert-hhR Offline
              robert-hh @Lennac
              last edited by robert-hh

              @Lennac I2C has a bus layout. Just connect the respective Vcc, GND, SDA and SCL lines of all devices. Only one of the devices need pull-up resistors. But if more than one has, that's also fine, if the combined value is greater than 1 kOhm.
              Since the pull-up resistors are then connected in parallel, the combined resistance is:

              1/Rtotal = 1/R1 + 1/R2 + .... + 1/Rn
              or for two resistors:
              Rtotal = (R1 * R2)/(R1 + R2)

              L 1 Reply Last reply Reply Quote 2
              • L Offline
                Lennac @robert-hh
                last edited by Lennac

                @robert-hh Thank you.

                So, I have everything connected and I can see both my devices are powering on, but when I run my code I still get a bus error when it attempts to initialize the display: d = i2c_lcd.Display(i2c) - from main.py in my original post. Just to confirm, I tried removing the second I2C device just so I could observe the code running properly and now I get a bus error where there was none before after successfully completing the while loop for 2 iterations:

                while(1):
                    # d.clear()
                    time.sleep(2) # sleep for two seconds as per DHT specifications
                    result = th.read() # read values from DHT
                    if result.is_valid(): # check if error_code = 0
                        pycom.rgbled(0x001000) # green - onboard data read confirmation
                        print('Temperature: {:3.2f}'.format(result.temperature/1.0)) # print temp to console
                        print('Humidity: {:3.2f}'.format(result.humidity/1.0)) # print rh to console
                    full, ir = tsl.get_full_luminosity()  # read raw values (full spectrum and ir spectrum)
                    lux = tsl.calculate_lux(full, ir)  # convert raw values to lux
                    print('Lux: ' + str(lux) + ' Lumens')
                    # d.write('Testing')
                    gc.collect() # memory management
                
                Traceback (most recent call last):
                  File "main.py", line 27, in <module>
                  File "/flash/lib/tsl2591.py", line 161, in get_full_luminosity
                  File "/flash/lib/tsl2591.py", line 66, in read_word_data
                OSError: I2C bus error
                
                def get_full_luminosity(self):
                        self.enable()
                        time.sleep(0.120*self.integration_time+1)
                        full = self.bus.read_word_data(
                                    SENSOR_ADDRESS, COMMAND_BIT | REGISTER_CHAN0_LOW
                                    )
                        ir = self.bus.read_word_data(
                                    SENSOR_ADDRESS, COMMAND_BIT | REGISTER_CHAN1_LOW
                                    )
                        self.disable()
                        return full, ir
                

                SENSOR_ADDRESS = 0x29

                    def read_word_data(self, addr, cmd):
                        assert cmd < 256
                        buf = bytes([cmd])
                        self.i2c.writeto(addr, buf)
                        data = self.i2c.readfrom(addr, 4)
                        return _bytes_to_int(data)
                

                The second iteration of my while loop throws this error:

                Temperature: 21.00
                Humidity: 60.40
                Lux: 64.464 Lumens
                Temperature: 21.10
                Humidity: 54.70
                Traceback (most recent call last):
                  File "main.py", line 27, in <module>
                  File "/flash/lib/tsl2591.py", line 161, in get_full_luminosity
                  File "/flash/lib/tsl2591.py", line 66, in read_word_data
                OSError: I2C bus error
                

                To be clear, removing the LCD from my circuit entirely and rebooting my SiPy board results in my code running properly without any issue.

                robert-hhR 1 Reply Last reply Reply Quote 0
                • robert-hhR Offline
                  robert-hh @Lennac
                  last edited by robert-hh

                  @Lennac what do you get with i2c.scan()?
                  Test with each of them connected separately and together?

                  L 1 Reply Last reply Reply Quote 0
                  • L Offline
                    Lennac @robert-hh
                    last edited by

                    @robert-hh I got two separate values using i2c.scan()

                    With the LCD code running and throwing the original error: [41]

                    With the LCD code commented out and the error pointing to my tsl2591.py file: [57].

                    robert-hhR 1 Reply Last reply Reply Quote 0
                    • robert-hhR Offline
                      robert-hh @Lennac
                      last edited by robert-hh

                      @Lennac When both devices are connected, you should see a list with both numbers. If not, then there is a very basic circuit problem of a address conflict.
                      For the test you do not need your libs. Just

                      from machine import I2C
                      i2c=I2C(0, I2C.MASTER)
                      i2c.scan()

                      L 1 Reply Last reply Reply Quote 0
                      • L Offline
                        Lennac @robert-hh
                        last edited by

                        @robert-hh Okay, I will re-configure my circuit and confirm that I'm getting both devices listed in i2c.scan(). Thank you.

                        1 Reply Last reply Reply Quote 0

                        Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                        Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                        With your input, this post could be even better 💗

                        Register Login
                        • 1 / 1
                        • First post
                          Last post

                        Pycom on Twitter

                        Pycom