0

BNO085 I2C on Pi Pico: RuntimeError: No pull up found
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by wingnut64 on Sun Sep 19, 2021 2:21 pm

Hello,

I am unable to get an Adafruit 4754 / BNO085 working over I2C on a Raspberry Pi Pico running CircuitPython. This same device works properly with I2C on an Arduino Nano, but fails on the Pi Pico with CircuitPython. I've tried both 6.3.0 and 7.0.0-rc.3.

I am able to use I2C to control an HT16K33 LED backpack without issue, but when I attempt to connect the BNO085 to I2C it fails and complains that there are no pull-up resistors.

Code: Select all | TOGGLE FULL SIZE
>>> import board
>>> import busio
>>> i2c = busio.I2C(board.GP17, board.GP16)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: No pull up found on SDA or SCL; check your wiring

My understanding is the Adafruit breakout of this already has pull-up resistors built in, but I have also tried adding 4.7Kom resistors between the SDA/SCL lines and 3.3 without success. The IMU is powered via the 3V3_OUT pin from the pico, and the green LED on it is lit. The Pico is powered via USB from a desktop.

wingnut64
 
Posts: 6
Joined: Tue Jul 29, 2008 4:55 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by mikeysklar on Mon Sep 20, 2021 1:18 pm

@wingnut64,

Can you post a photo of your setup Pico to BNO085? I'd like to confirm the wiring and soldering look good. Please do not use any other i2c devices with this setup for troubleshooting purposes right now.

mikeysklar
 
Posts: 5767
Joined: Mon Aug 01, 2016 8:10 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by gridstop on Mon Sep 20, 2021 2:28 pm

Hey, I'm having I think the same problem with a new BNO085 I just bought. In regular micropython on a RPI pico, I was able to send a few hand-built packets back and forth, so I know in general it is working. But I wanted to test out the adafruit circuitpython libs and now have similar problems with circuitpython 6.3 on the rpi pico. I have a M0 that does similar stuff at the raw I2C level, but obviously doesn't have enough ram to load the full bno08x lib.

1) All setups show an odd response to I2C.scan() both on micropython and circuitpython. The BNO08x takes a really long time to respond to the first hit on address 0x4A. In fact, micropython's scan() shows a device on 0x4B instead of 4A, it's so slow. Attached is the result of a scan() on circuitpython. This scan resulted in a "TimeoutError: Clock Stretch Too Long" message, instead of like micropython showing the wrong address.
i2c_capture.png
Capture of i2c.scan() on raspberry pi pico running circuitpython connected to BNO085 showing severely delayed Ack
i2c_capture.png (49.39 KiB) Viewed 111 times


2) The logic analyzer shows whenever circuitpython's i2c lib gets stuck/errors it appears to leave SDA driven low. It leaves it this way and in the future any attempt to do i2c operations results in a missing pullup error, but it's actually caused by the output driven low, not a missing pullup.

3) One time I did briefly get the full BNO08x_i2c library working. No clue what 'worked' or the precise sequence to get it. I haven't been able to recreate it since.

4) Sometimes I have gotten a 'No device at address 0x4A' message when constructing the BNO08x object. I'm assuming this is a similar cause to the weird scan() behaviour above, but I don't have a logic analyzer capture of this exact scenario.

gridstop
 
Posts: 3
Joined: Sat Jul 04, 2020 8:59 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by gammaburst on Mon Sep 20, 2021 4:28 pm

I don't have a Pico, but some of those symptoms sound like I2C driver/library firmware problems that I've seen on a few other microcontrollers. The BNO devices cause such long I2C clock-stretching cycles that some I2C controllers think it's broken and abort with a timeout error. Some I2C controllers don't know how to clear a stuck SDA signal (by sending 9 dummy SCL pulses to put all slaves into idle state), so a slave that's halfway through a previously interrupted transaction could cause the controller to repeatedly abort with a stuck-bus error. I don't know if the Pico environment suffers any of those problems.

gammaburst
 
Posts: 598
Joined: Thu Dec 31, 2015 12:06 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by wingnut64 on Mon Sep 20, 2021 8:11 pm

Here's a picture of the setup. I also tried using the STEMMA QT / Qwiic connector and got the same behavior.

Pico_IMU_lowres.jpg
Pico_IMU_lowres.jpg (694.01 KiB) Viewed 101 times


If I try to use the bitbangio library, it seems to get further but I receive an error about clock stretching when I scan the bus:

Code: Select all | TOGGLE FULL SIZE
>>> import board
>>> import bitbangio
>>> bang = bitbangio.I2C(scl=board.GP17,sda=board.GP16)
>>> bang.try_lock()
True
>>> print(bang.scan())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TimeoutError: Clock stretch too long

wingnut64
 
Posts: 6
Joined: Tue Jul 29, 2008 4:55 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by wingnut64 on Mon Sep 20, 2021 9:25 pm

gridstop wrote:1) All setups show an odd response to I2C.scan() both on micropython and circuitpython. The BNO08x takes a really long time to respond to the first hit on address 0x4A. In fact, micropython's scan() shows a device on 0x4B instead of 4A, it's so slow. Attached is the result of a scan() on circuitpython. This scan resulted in a "TimeoutError: Clock Stretch Too Long" message, instead of like micropython showing the wrong address.
i2c_capture.png



That capture was helpful, I was able to at least get I2C initialized and the device showing up on i2c.scan(). I had to use the bitbangio library and increase the timeout to >700us to get it working reliably. I seem to get clock stretch errors most often with a timeout of around 400-500us, which if I'm reading your graph right is close to what you were seeing. This is what I ended up running to narrow down the timing:

Code: Select all | TOGGLE FULL SIZE
import board
import bitbangio
I2C_DATA = board.GP16
I2C_CLOCK = board.GP17

def scan_bus():
    while not i2c.try_lock():
        pass
    try:
        print("I2C addresses found:", [hex(device_address)
              for device_address in i2c.scan()])
    finally:
        i2c.unlock()

test = 1000
while test > 10:
    print("Trying", test)
    for x in range(1,10):
        i2c = bitbangio.I2C(scl=I2C_CLOCK,sda=I2C_DATA,timeout=test)
        scan_bus()
        i2c.deinit()
        i2c = None
    test = test - 10
    print("")


This eventually results in failures:
Code: Select all | TOGGLE FULL SIZE
Trying 540
I2C addresses found: ['0x4a']
I2C addresses found: ['0x4a']
I2C addresses found: ['0x4a']
I2C addresses found: ['0x4a']
I2C addresses found: ['0x4a']
I2C addresses found: ['0x4a']
Traceback (most recent call last):
  File "<stdin>", line 20, in <module>
  File "<stdin>", line 10, in scan_bus
TimeoutError: Clock stretch too long


Specifically, I got failures with the following values for bitbangio.I2C(...,timeout=X):
470,480,700,650,550,410,410,410,620,540

I'm still not able to talk to the BNO085 properly however, there is an error in the adafruit library when processing the packet:

Code: Select all | TOGGLE FULL SIZE
import time
import board
from adafruit_bno08x import (
    BNO_REPORT_ACCELEROMETER,
    BNO_REPORT_GYROSCOPE,
    BNO_REPORT_MAGNETOMETER,
    BNO_REPORT_ROTATION_VECTOR,
    BNO_REPORT_GYRO_INTEGRATED_ROTATION_VECTOR
)

from adafruit_bno08x.i2c import BNO08X_I2C
I2C_DATA = board.GP16
I2C_CLOCK = board.GP17
import bitbangio
i2c = bitbangio.I2C(scl=I2C_CLOCK,sda=I2C_DATA,frequency=400000,timeout=1000)
bno = BNO08X_I2C(i2c)

bno.enable_feature(BNO_REPORT_ACCELEROMETER)
bno.enable_feature(BNO_REPORT_GYROSCOPE)
bno.enable_feature(BNO_REPORT_MAGNETOMETER)
bno.enable_feature(BNO_REPORT_ROTATION_VECTOR)
bno.enable_feature(BNO_REPORT_GYRO_INTEGRATED_ROTATION_VECTOR)
while True:
    time.sleep(2)
    quat_i, quat_j, quat_k, quat_real = bno.quaternion
    print("I: %0.6f  J: %0.6f K: %0.6f  Real: %0.6f" % (quat_i, quat_j, quat_k, quat_real))


Code: Select all | TOGGLE FULL SIZE
      ********** Packet *************
DBG::       HEADER:
DBG::       Data Len: 14
DBG::       Channel: GYRO_ROTATION_VECTOR (5)
DBG::       Sequence number: 2

DBG::       Data:
DBG::      [0x04] 0x1B 0x00 0x2C 0x01
DBG::      [0x08] 0x05 0x00 0xFD 0x3F
DBG::      [0x0C] 0x00 0x00 0x00 0x00
DBG::      [0x10] 0x00 0x00
      *******************************

Traceback (most recent call last):
  File "<stdin>", line 25, in <module>
  File "adafruit_bno08x/__init__.py", line 547, in quaternion
  File "adafruit_bno08x/__init__.py", line 797, in _process_available_packets
  File "adafruit_bno08x/__init__.py", line 855, in _handle_packet
  File "adafruit_bno08x/__init__.py", line 850, in _handle_packet
  File "adafruit_bno08x/__init__.py", line 361, in _separate_batch
  File "adafruit_bno08x/__init__.py", line 350, in _report_length
KeyError: 27

(above is captured via the console in Thonny)

wingnut64
 
Posts: 6
Joined: Tue Jul 29, 2008 4:55 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by gridstop on Tue Sep 21, 2021 9:03 am

Thanks for the info wingnut, I'll try out bitbangio soon and see if it works the same for me.

On a semi-related note, if you do try UART mode see if you run into an issue where you receive packets for a few seconds, but eventually something in the input stream gets off by a byte (uart dropped one? or math error somewhere in the library consuming the buffer?) and it doesn't see the end-of-message 0x7E and errors out.

gridstop
 
Posts: 3
Joined: Sat Jul 04, 2020 8:59 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by wingnut64 on Thu Sep 23, 2021 9:16 pm

gridstop wrote:On a semi-related note, if you do try UART mode see if you run into an issue where you receive packets for a few seconds, but eventually something in the input stream gets off by a byte (uart dropped one? or math error somewhere in the library consuming the buffer?) and it doesn't see the end-of-message 0x7E and errors out.

I'm not sure if this is equivalent, but I had given the RVC mode a shot. I had some issues, it seemed all data coming in was significantly delayed. That is, I would be constantly measuring what it was returning and it would only update that the IMU was moved around 5-10 seconds after it happened.

wingnut64
 
Posts: 6
Joined: Tue Jul 29, 2008 4:55 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by gridstop on Fri Sep 24, 2021 9:26 am

I did get the bitbangio i2c to work a bit. Occasionally at start I would still see the clock stretch error, it was intermittent. But once it was running it was fine.

I tested the calibration and find heading examples and didn't get any KeyError like you're seeing, they worked properly.

gridstop
 
Posts: 3
Joined: Sat Jul 04, 2020 8:59 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by MikeB35 on Sun Oct 03, 2021 5:48 pm

Hello,
I am using a Raspberry Pico and I have exactly the same problems with two Adafruit BNO08x modules and the 'busio' + 'adafruit_bno08x' libraries:
* "TimeoutError: Clock stretch too long"
* "RuntimeError: No pull up found on SDA or SCL; check your wiring"
These two errors appear all the time, each at random.

I also tested with the 'bitbangio' library with a timeout of 1000, but I also get these errors less systematically.

Does anyone have a solution to this problem?
Thanks in advance,

Mike

MikeB35
 
Posts: 56
Joined: Thu Feb 05, 2015 10:18 am

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by gammaburst on Sun Oct 03, 2021 7:02 pm

1000 microsecond clock-stretching timeout is insufficient for BNO devices.

Try ten times that amount.

I see no reason to specify a timeout that's "just barely enough".

gammaburst
 
Posts: 598
Joined: Thu Dec 31, 2015 12:06 pm

Re: BNO085 I2C on Pi Pico: RuntimeError: No pull up found

by MikeB35 on Sat Oct 09, 2021 9:19 am

gammaburst wrote:1000 microsecond clock-stretching timeout is insufficient for BNO devices.

Try ten times that amount.

I see no reason to specify a timeout that's "just barely enough".


Thanks a lot, it works !!

Mike

MikeB35
 
Posts: 56
Joined: Thu Feb 05, 2015 10:18 am

Please be positive and constructive with your questions and comments.