IMU I2C Error with CircuitPython using XIAO BLE Sense

I am trying to use the builtin 6-Axis IMU on the XIAO BLE SENSE using CircuitPython and am running into the error No pull up found on SDA or SCL; check your wiring.

The Arduino example from the official documentation using the Seeed_Arduino_LSM6DS3 Library worked for me, so I know that the hardware works well without needing any sort of external pullup configuration. I was hoping to be able to use the Adafruit_CircuitPython_LSMDS3 library to integrate the IMU code with the rest of my project which I am writing in CircuitPython.

I have experimented with modifying both my own python code and the CircuitPython source code to get around the error, but so far have had no luck. Things I have tried are:

  • pulling up the pin before initializing i2c. (fails due to IMU_SCL in use error)
scl = board.IMU_SCL
dscl = digitalio.DigitalInOut(scl)
dscl.pull = digitalio.Pull.UP
  • in CurcuitPython source code file circuitpython/ports/nrf/common-hal/busio/I2C.c enabling a pullup using nrf_gpio_cfg_input(scl->number, NRF_GPIO_PIN_PULLUP);. This did not raise an error, but I was not able to get any readings from the IMU.

  • commenting out the error in CircuitPython source code file circuitpython/ports/nrf/common-hal/busio/I2C.c. Again, this did not help to actually communicate with the accelerometer

I was wondering if anyone has figured out how to use the IMU on this board and could point me to documentation. I also know this board is still new and was wondering if anyone knows when we might be able to expect support for the IMU in CircuitPython?

In researching this issue I found a seemingly relevant feature request in CircuitPython related to enabling internal pullups for I2C pins, but I had no success implementing and testing the feature.

Any help is appreciated!

Well after the many hours of research it turns out all I had to do was wait (literally time.sleep(1)) after powering the IMU before initializing I2C. For anyone else looking to get this to work, here it is:

import board
import time
import digitalio
import busio
from adafruit_lsm6ds.lsm6ds3 import LSM6DS3


class IMU(LSM6DS3):
    def __init__(self):
        dpwr = digitalio.DigitalInOut(board.IMU_PWR)
        dpwr.direction = digitalio.Direction.OUTPUT
        dpwr.value = 1
        time.sleep(1)
        i2c = busio.I2C(board.IMU_SCL, board.IMU_SDA)
        super().__init__(i2c)
        

if __name__ == "__main__":
    imu = IMU()
    while True:
        print("Acceleration: X:%.2f, Y: %.2f, Z: %.2f m/s^2" % (imu.acceleration))
        print("Gyro X:%.2f, Y: %.2f, Z: %.2f radians/s" % (imu.gyro))
        print("")
        time.sleep(0.5)

2 Likes

Thank you so much for posting this solution!!! I was attempting the same thing and you saved me a great deal of time!!!