Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BNO080 reboots/hangs ESP32S3 when accessing it via I2C. #6255

Closed
mjs513 opened this issue Apr 6, 2022 · 8 comments
Closed

BNO080 reboots/hangs ESP32S3 when accessing it via I2C. #6255

mjs513 opened this issue Apr 6, 2022 · 8 comments
Labels
bug busio esp32-s3 third-party Awaiting action on a third party for a fix or an answer to a request
Milestone

Comments

@mjs513
Copy link

mjs513 commented Apr 6, 2022

CircuitPython version

Adafruit CircuitPython 7.3.0-beta.0 on 2022-04-01; ESP32-S3-DevKitC-1-N8 with ESP32S3
Board ID:espressif_esp32s3_devkitc_1_n8

Code/REPL

# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries
# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""CircuitPython I2C Device Address Scan"""
# If you run this and it seems to hang, try manually unlocking
# your I2C bus from the REPL with
#  >>> import board
#  >>> board.I2C().unlock()

import time
import board
import busio

# To use default I2C bus (most boards) scl/sda
i2c = busio.I2C(board.IO10, board.IO11)
i2c1 = busio.I2C(board.IO1, board.IO2)


def i2cportscan():
    print("Wire")
    # Lock the I2C device before we try to scan
    while not i2c.try_lock():
        pass
    # Print the addresses found once
    # print(
    #    "I2C addresses found:", [hex(device_address) for device_address in i2c.scan()]
    # )
    for device_address in i2c.scan():
        print("Device found at address", end=" ")
        print(hex(device_address), end=" (")
        printKnownChips(hex(device_address))
        print(end=")")
        print()
    # Unlock I2C now that we're done scanning.
    i2c.unlock()

def i2cport1scan():
    print("Wire1")
    # Lock the I2C device before we try to scan
    while not i2c1.try_lock():
        pass
    # Print the addresses found once
    for device_address in i2c1.scan():
        print("Device found at address", end=" ")
        print(hex(device_address), end=" (")
        printKnownChips(hex(device_address))
        print(end=")")
        print()
    # Unlock I2C now that we're done scanning.
    i2c1.unlock()


def printKnownChips(address):
    # print("passed address:", address)
    if address == "0x00":
        print("AS3935", end=" ")
        return
    if address == "0x01":
        print("AS3935", end=" ")
        return
    if address == "0x02":
        print("AS3935", end=" ")
        return
    if address == "0x03":
        print("AS3935", end=" ")
        return
    if address == "0x04":
        print("ADAU1966", end=" ")
        return
    if address == "0x0a":
        print("SGTL5000", end=" ")
        return
    if address == "0x0b":
        print("SMBusBattery?", end=" ")
        return
    if address == "0x0c":
        print("AK8963", end=" ")
        return
    if address == "0x10":
        print("CS4272", end=" ")
        return
    if address == "0x11":
        print("Si4713", end=" ")
        return
    if address == "0x13":
        print("VCNL4000,AK4558", end=" ")
        return
    if address == "0x18":
        print("LIS331DLH", end=" ")
        return
    if address == "0x19":
        print("LSM303,LIS331DLH", end=" ")
        return
    if address == "0x1a":
        print("WM8731", end=" ")
        return
    if address == "0x1c":
        print("LIS3MDL", end=" ")
        return
    if address == "0x1d":
        print("LSM303D,LSM9DS0,ADXL345,MMA7455L,LSM9DS1,LIS3DSH", end=" ")
        return
    if address == "0x1e":
        print("LSM303D,HMC5883L,FXOS8700,LIS3DSH", end=" ")
        return
    if address == "0x20":
        print("MCP23017,MCP23008,PCF8574,FXAS21002,SoilMoisture", end=" ")
        return
    if address == "0x21":
        print("MCP23017,MCP23008,PCF8574", end=" ")
        return
    if address == "0x22":
        print("MCP23017,MCP23008,PCF8574", end=" ")
        return
    if address == "0x23":
        print("MCP23017,MCP23008,PCF8574", end=" ")
        return
    if address == "0x24":
        print("MCP23017,MCP23008,PCF8574,ADAU1966,HM01B0", end=" ")
        return
    if address == "0x25":
        print("MCP23017,MCP23008,PCF8574", end=" ")
        return
    if address == "0x26":
        print("MCP23017,MCP23008,PCF8574", end=" ")
        return
    if address == "0x27":
        print("MCP23017,MCP23008,PCF8574,LCD16x2,DigoleDisplay", end=" ")
        return
    if address == "0x28":
        print("BNO055,EM7180,CAP1188", end=" ")
        return
    if address == "0x29":
        print("TSL2561,VL6180,TSL2561,TSL2591,BNO055,CAP1188", end=" ")
        return
    if address == "0x2a":
        print("SGTL5000,CAP1188", end=" ")
        return
    if address == "0x2b":
        print("CAP1188", end=" ")
        return
    if address == "0x2c":
        print("MCP44XX ePot", end=" ")
        return
    if address == "0x2d":
        print("MCP44XX ePot", end=" ")
        return
    if address == "0x2e":
        print("MCP44XX ePot", end=" ")
        return
    if address == "0x2f":
        print("MCP44XX ePot", end=" ")
        return
    if address == "0x30":
        print("Si7210", end=" ")
        return
    if address == "0x31":
        print("Si7210", end=" ")
        return
    if address == "0x32":
        print("Si7210", end=" ")
        return
    if address == "0x33":
        print("MAX11614,MAX11615,Si7210", end=" ")
        return
    if address == "0x34":
        print("MAX11612,MAX11613", end=" ")
        return
    if address == "0x35":
        print("MAX11616,MAX11617", end=" ")
        return
    if address == "0x38":
        print("RA8875,FT6206,MAX98390", end=" ")
        return
    if address == "0x39":
        print("TSL2561, APDS9960", end=" ")
        return
    if address == "0x3c":
        print("SSD1306,DigisparkOLED", end=" ")
        return
    if address == "0x3d":
        print("SSD1306", end=" ")
        return
    if address == "0x40":
        print("PCA9685,Si7021,MS8607", end=" ")
        return
    if address == "0x41":
        print("STMPE610,PCA9685", end=" ")
        return
    if address == "0x42":
        print("PCA9685", end=" ")
        return
    if address == "0x43":
        print("PCA9685", end=" ")
        return
    if address == "0x44":
        print("PCA9685, SHT3X, ADAU1966", end=" ")
        return
    if address == "0x45":
        print("PCA9685, SHT3X", end=" ")
        return
    if address == "0x46":
        print("PCA9685", end=" ")
        return
    if address == "0x47":
        print("PCA9685", end=" ")
        return
    if address == "0x48":
        print("ADS1115,PN532,TMP102,LM75,PCF8591,CS42448", end=" ")
        return
    if address == "0x49":
        print("ADS1115,TSL2561,PCF8591,CS42448", end=" ")
        return
    if address == "0x4a":
        print("ADS1115,Qwiic Keypad,CS42448", end=" ")
        return
    if address == "0x4b":
        print("ADS1115,TMP102,BNO080,Qwiic Keypad,CS42448", end=" ")
        return
    if address == "0x50":
        print("EEPROM,FRAM", end=" ")
        return
    if address == "0x51":
        print("EEPROM", end=" ")
        return
    if address == "0x52":
        print("Nunchuk,EEPROM", end=" ")
        return
    if address == "0x53":
        print("ADXL345,EEPROM", end=" ")
        return
    if address == "0x54":
        print("EEPROM", end=" ")
        return
    if address == "0x55":
        print("EEPROM", end=" ")
        return
    if address == "0x56":
        print("EEPROM", end=" ")
        return
    if address == "0x57":
        print("EEPROM", end=" ")
        return
    if address == "0x58":
        print("TPA2016,MAX21100", end=" ")
        return
    if address == "0x5a":
        print("MPR121", end=" ")
        return
    if address == "0x60":
        print("MPL3115,MCP4725,MCP4728,TEA5767,Si5351", end=" ")
        return
    if address == "0x61":
        print("MCP4725,AtlasEzoDO", end=" ")
        return
    if address == "0x62":
        print("LidarLite,MCP4725,AtlasEzoORP", end=" ")
        return
    if address == "0x63":
        print("MCP4725,AtlasEzoPH", end=" ")
        return
    if address == "0x64":
        print("AtlasEzoEC, ADAU1966", end=" ")
        return
    if address == "0x66":
        print("AtlasEzoRTD", end=" ")
        return
    if address == "0x68":
        print("DS1307/3231,MPU6050/9050,MPU9250,ITG3200/3701,LSM9DS0,L3G4200D", end=" ")
        return
    if address == "0x69":
        print("MPU6050,MPU9050,MPU9250,ITG3701,L3G4200D", end=" ")
        return
    if address == "0x6a":
        print("LSM9DS1", end=" ")
        return
    if address == "0x6b":
        print("LSM9DS0", end=" ")
        return
    if address == "0x6f":
        print("Qwiic Button", end=" ")
        return
    if address == "0x70":
        print("HT16K33,TCA9548A", end=" ")
        return
    if address == "0x71":
        print("SFE7SEG,HT16K33", end=" ")
        return
    if address == "0x72":
        print("HT16K33", end=" ")
        return
    if address == "0x73":
        print("HT16K33", end=" ")
        return
    if address == "0x76":
        print("MS5607,MS5611,MS5637,BMP280", end=" ")
        return
    if address == "0x77":
        print("BMP085,BMA180,BMP280,MS5611", end=" ")
        return
    if address == "0x7c":
        print("FRAM_ID", end=" ")
        return
    print("UNKNOWN DEVICE", end=" ")
    return


i2cportscan()
i2cport1scan()

Behavior

Device found at address 0x3c (SSD1306,DigisparkOLED )
Device found at address 0x50 (EEPROM,FRAM )
Device found at address 0x62 (LidarLite,MCP4725,AtlasEzoORP )
Device found at address 0x6f (Qwiic Button )
Wire1
Device found at address 0x29 (TSL2561,VL6180,TSL2561,TSL2591,BNO055,CAP1188 )
Device found at address 0x68 (DS1307/3231,MPU6050/9050,MPU9250,ITG3200/3701,LSM9DS0,L3G4200D )

Code done running.

When working but if I try to add a BNO080 (Adafruit or Sparkfun) it reboots the ESP32S3 and seems to hang. No error messages

Description

Using a I2c test board that we used for testing the Teens 4.1:
Image_20220406_092212

I attached the ESP32S3. All worked well until I tried to add the BNO080 to either I2c or I2c1 bus (Arduino verbiage Wire or Wire1). When I add the BNO080 it reboots the ESP32S3 and seems to hang Mu edit and I have to power cycle to get it running again. No error messages appear.

If I run the same script using CircuitPython on the T4.1 it picks up all devices including the BNO080. I do have a QT PY RP204 on order to test it with that as well.

Additional information

No response

@mjs513 mjs513 added the bug label Apr 6, 2022
@mjs513
Copy link
Author

mjs513 commented Apr 7, 2022

As a follow up believe it related to a clock stretching issue with the BNO080: adafruit/Adafruit_CircuitPython_BNO08x#33

Will try a i2c1 = bitbangio.I2C(board.I2C_SCL1, board.I2C_SDA1, timeout = 500)
next time I have it set up

@jepler
Copy link
Member

jepler commented Apr 11, 2022

There are known problems with esp32-s3 in i2c as well, which we are tracking. But it's true, the BNO chips have some interesting I2C behavior as well.

@jepler jepler added this to the 7.x.x milestone Apr 11, 2022
@mjs513
Copy link
Author

mjs513 commented Apr 11, 2022

Yeah. Was doing some research this morning and seems to be a known problem. Unfortunately also happening on the RP2040, Teensy Micromod and Teensy 4.1 as well.

Early on in the development of the Teensy 4 we had similar issues with the BNO055 and BNO080 and required a changed to I2C. For ref here was the fix = at least for the teensy in i2c: PaulStoffregen/Wire@08d870f
Maybe a clue for you all to look at

@dhalbert dhalbert modified the milestones: 7.x.x, 8.0.0 May 24, 2022
@jepler jepler added the third-party Awaiting action on a third party for a fix or an answer to a request label Jul 6, 2022
@dhalbert
Copy link
Collaborator

dhalbert commented Jul 6, 2022

Will re-test after pending S3 I2C fixes are added to ESP-IDF v4.4.x.

@dhalbert
Copy link
Collaborator

I retested with a BNO055 on Feather ESP32-S3 with the latest build, and it still fails. It works fine on ESP32-S2, and also with bitbangio.I2C(). This may have the same root cause as #6311.

@dhalbert dhalbert added the busio label Nov 29, 2022
@dhalbert dhalbert modified the milestones: 8.0.0, 8.x.x Nov 29, 2022
@dhalbert
Copy link
Collaborator

Pushing this forward to 8.x.x because I don't see an upstream fix in sight.

@dhalbert
Copy link
Collaborator

The BNO0xx sensors are known to violate the I2C bus protocol under certain conditions. I did some testing of the BNO055 here: adafruit/Adafruit_CircuitPython_BNO055#115. I expect similar results with the BNO080. Perhaps we can make the library do some error recovery, but given that the BNO sensors themselves are flaky, I'm not sure we should characterize this as a bug that we expect the ESP-IDF to fix. The ultimate bug is in the BNO sensors themselves.

I will close this as "can't fix" in the core for now. If you disagree let me know. I will add some warnings to the BNO080 learn guide, and have opened this library issue: adafruit/Adafruit_CircuitPython_BNO08x#41

@dhalbert dhalbert closed this as not planned Won't fix, can't repro, duplicate, stale Apr 11, 2023
@dhalbert
Copy link
Collaborator

dhalbert commented Nov 5, 2023

I retested after we upgraded to ESP-IDF v5.1 in CircuitPython 9.0.0-alpha.2. BNO055 still does not work. This is not so surprising. I added warnings to the appropriate BNO guides a while ago.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug busio esp32-s3 third-party Awaiting action on a third party for a fix or an answer to a request
Projects
None yet
Development

No branches or pull requests

3 participants