OS Error: I2C bus error on wipy 3.0 with BME 680



  • Hi everyone, I want to connect two BME680 sensors with a wipy 3.0 to a raspi 3 via wifi. On the raspi is a MQTT broker so we can see the temperature etc. So I've got this code from another team, but it doesn't work. The error is coming up when I set the second I2C adapter on P9, P10 and when it comes to "sensor1 = bme680.BME680(i2c_device=i2c_dev1)". I think it is because the first sensor ist defined as the same, but I don't know what to code else. You can find the code below. I hope you can help me.

    import time
    import machine
    from machine import RTC, Pin
    import onewire
    from network import WLAN
    from mqtt import MQTTClient
    import binascii
    import ujson
    import bme680
    from machine import I2C
    from i2c import I2CAdapter
    
    
    
    
    #Fühler
    # Hier werden die onewire Fühler mit addressierung festgelegt
    # Wenn neue Wände für das Haus gebaut werden, müssen genau hier neue Adressen eingefügt werden.
    # Die BME Sensoren werden extra verarbeitet.
    # Achtung die Fühlerbezeichnung wird unten im Programm weiterhin verwendet KEINE ÄNDERUNG VORNEHMEN
    # Die Anzahl der onewire Sensoren wird durch die Art der Verdrahtung (Sterntopologie 10 Sensoren)
    # und durch die größe des Pulldown Widerstand festgelegt (bei 4,7kOhm und Sterntopologie 10 Sensoren)
    
    
    fuehler={"zone2_heizbett" : bytearray(b'(ad\x11\xbd\x86Y='),
        "zone2_peltier_zuluft" : bytearray(b'(ad\x11\xbd\x86t\xe3'),
        "zone2_peltier_abluft" :  bytearray(b'(ad\x11\xbce\x01\xaf'),
        "zone2_peltier_fortluft" : bytearray(b'(ad\x123\x9b#\xc0'),
        "zone2_peltier_außenluft" : bytearray(b'(ad\x123\x9b\xa92'),
        "zone2_globetemp" :  bytearray(b'(ad\x123\xb5\x98\xcf'),
        "zone2_schicht_unten" : bytearray(b'(ad\x123\x96Br'),
        "zone2_schicht_oben" : bytearray(b'(ad\x123\x96H\x0c'),
        "zone2_wandtemp1" : bytearray(b'(ad\x11\xbf\xc9\xb6Y'),
        "zone2_wandtemp2" : bytearray(b'(ad\x11\xbct\xaei')
            }
    
    
    
    #WLAN Verbindung herstellen
    #Das Modellhaus wird mit dem WLAN des Modellhaus verbunden
    # ssid = HBC_Modellhaus
    # Passwort HBC_Modellhaus
    
    wlan = WLAN(mode=WLAN.STA)
    
    # Die Umgebung wird nach WLAN Netzen durchsucht
    
    nets = wlan.scan()
    
    #Die Schleife legt fest, mit welchem WLAN Netz Verbindung vorgenommen werden soll.
    
    for net in nets:
        if net.ssid == 'HBC_Modellhaus':
            print('Network found!')
            wlan.connect(net.ssid, auth=(net.sec, 'Modellhaus'), timeout=5000)
            while not wlan.isconnected():
                machine.idle() # save power while waiting
            print('WLAN connection succeeded!')
            break
    
    
    def settimeout(duration):
        pass
    
    
    rtc = RTC() # real-time-clock
    #print(rtc.now())
    rtc.ntp_sync('pool.ntp.org', update_period=3600)
    #while not rtc.synced():
    #    machine.idle() # TODO: make robust: prevent form waiting for ntp
    
    #print(rtc.now())
    
    
    
    # MQTT_Server
    
    cid = binascii.hexlify(machine.unique_id())
    print(cid)
    client = MQTTClient(cid,"192.168.4.1",user="Modell", password="Modellhaus", port=1883)
    time.sleep(1)
    client.connect()
    
    
    print('conneced to mqtt server', client)
    
    #client.publish('state/ag/uniqueid', binascii.hexlify(machine.unique_id()), retain=True)
    client.publish('Zone2', binascii.hexlify(machine.unique_id()), retain=True)
    
    
    #onewire
    #Hier wird die Onewire Sensoren Datenleitung mit mit dem Microkontroller verbunden.
    #Für die Verbindung wurder der Pin 4 gewählt. Der Pin kann jedoch frei gewählt werden.
    
    ow = onewire.OneWire(Pin('P4'))
    temp = onewire.DS18X20(ow)
    
    # Die Liste legt die Reienfolge für die Bearbeitung der Sensoren fest.
    
    temps=[fuehler["zone2_heizbett"],fuehler["zone2_peltier_zuluft"],fuehler["zone2_peltier_abluft"],
    fuehler["zone2_peltier_fortluft"],fuehler["zone2_peltier_außenluft"],fuehler["zone2_globetemp"],
    fuehler["zone2_schicht_unten"],fuehler["zone2_schicht_oben"],fuehler["zone2_wandtemp1"],fuehler["zone2_wandtemp2"]]
    
    
    #bme680 mit i2c Bus
    
    i2c_dev = I2CAdapter(0, pins=('P7','P8'))
    sensor = bme680.BME680(i2c_device=i2c_dev)
    
    
    # These oversampling settings can be tweaked to
    # change the balance between accuracy and noise in
    # the data.
    sensor.set_humidity_oversample(bme680.OS_2X)
    sensor.set_pressure_oversample(bme680.OS_4X)
    sensor.set_temperature_oversample(bme680.OS_8X)
    sensor.set_filter(bme680.FILTER_SIZE_3)
    
    
    
    i2c_dev1 = I2CAdapter(1, pins=('P9','P10'))
    sensor1 = bme680.BME680(i2c_device=i2c_dev1)
    
    # These oversampling settings can be tweaked to
    # change the balance between accuracy and noise in
    # the data.
    sensor1.set_humidity_oversample(bme680.OS_2X)
    sensor1.set_pressure_oversample(bme680.OS_4X)
    sensor1.set_temperature_oversample(bme680.OS_8X)
    sensor1.set_filter(bme680.FILTER_SIZE_3)
    
    # auf sd Karte schreiben
    
    
    
    
    
    # hier wird das Programm ausgefürt
    
    print("Polling:")
    try:
        while True:
            for i in temps:
                temp.start_conversion(i)
            bme_temp = sensor.data.temperature
            bme_pressure = sensor.data.pressure
            bme_humidity = sensor.data.humidity
            bme_temp_1 = sensor.data.temperature
            bme_pressure_1 = sensor.data.pressure
            bme_humidity_1 = sensor.data.humidity
            json=ujson.dumps({ 'heizbett': temp.read_temp_async(temps[0]),
                'zuluft': temp.read_temp_async(temps[1]),
                'abluft': temp.read_temp_async(temps[2]),
                'fortluft': temp.read_temp_async(temps[3]),
                'aussenluft': temp.read_temp_async(temps[4]),
                'globetemp': temp.read_temp_async(temps[5]),
                'schicht_unten': temp.read_temp_async(temps[6]),
                'schicht_oben': temp.read_temp_async(temps[7]),
                'wandtemp1': temp.read_temp_async(temps[8]),
                'wandtemp2': temp.read_temp_async(temps[9]),
                'bme_temp': bme_temp,
                'pressur': bme_pressure,
                'humidity': bme_humidity,
                'bme_temp_aussen': bme_temp_1,
                'pressur_aussen': bme_pressure_1,
                'humidity_aussen': bme_humidity_1
                })
            try:
                time.sleep(5)
                client.publish('Zone2/Messdaten', json)
            except Exception as e:
                print(e)
    
    
    except KeyboardInterrupt:
        pass
    
    

    Traceback (most recent call last):
    File "main.py", line 123, in <module>
    File "/flash/lib/bme680.py", line 25, in init
    File "/flash/lib/bme680.py", line 285, in _get_regs
    File "/flash/lib/i2c.py", line 26, in read_byte_data
    OSError: I2C bus error
    MicroPython v1.8.6-849-83e2f7f on 2018-03-19; WiPy with ESP32
    Type "help()" for more information.



  • @robert-hh Thanks, I'll try that.



  • @modellhaus That could be caused by long wires to the sensor. Both i2c and spi are not designed for long wires. You may try to reduce tha baudrate.



  • @robert-hh I have the same code for another room with just 1 I2C and there it works. Since I wanted to try it in the next room with one sensor inside and one outside , it doesn't work anymore.



  • @modellhaus As @robert-hh mentioned I had a similar problem and it is now resolved. I posted my solution at https://forum.pycom.io/topic/4001/some-magnetometer-sensors-are-incompatible-with-the-pytrack-shield.



  • @modellhaus it seems that this @oldGuyDave came across the same problem: https://forum.pycom.io/topic/4001/some-magnetometer-sensors-are-incompatible-with-the-pytrack-shield/9
    I'll check myself too tonight. Does it work, if you just use I2C-Bus 1, or is it related to using two I2C buses at the same time?



Pycom on Twitter