Pimoroni LSM303D with pico/micropython: integration issues with I2Cdevice lib

I try to use Pimoroni’s 6-axis LSM303D with Pi pico (Thonny micropython).
The module comes with drivers for RP 2,3,3+,zero etc. but not micropython driver.
Works well with arduino nano as well.
I tried to rewrite the i2cdevice lib to match machine.I2C but it does not seem that easy.
Would appreciate any help.
Thanks! :)

It looks like there is Circuit Python support, if that helps?
LSM303D (Accelerometer & Compass) · Issue #17 · pimoroni/BreakoutGarden (github.com)

I use “pimoroni-pico-v0.2.2-micropython-v1.15.uf2” because my project utilizes both Pimoroni display and Pimoroni LSM303D. I assume the suggested circuit python by adafruit requires another uf2 file that would not fit the display.
if I misunderstand something about this env, you are welcome to shed some light

Yes, if you use the Adafruit Circuit Python uf2, you will have to find Circuit Python libraries for your other hardware. It’s what I had to do with my Pico RGB Keypad Base. The Adafruit Circuit Python has USB HID support but Micro Python doesn’t.

You could also try our MicroPython version with the Blinka compatibility layer baked in, that may let you use the LSM303D CircuitPython drivers from within MicroPython?

1 Like

Well, I put some effort into it but obviously I’m missing something.
Using Thonny, I uploaded PlatformDetect and Blinka onto my pico, clearing some unused directories from blinka. then got some error about missing adafruit_pioasm.
I have adafruit_pioasm.mpy file, but apparently this env requires .py and not .mpy

There looks to be a .py version of adafruit_pioasm in the .py driver bundle at Libraries ?

It’s possible that not all breakouts will work using the Blinka route though, I think it depends on how the hardware is addressed.

1 Like

I managed to control the accelarator without a library driver.
My original goal was to use Pimoroni display with LSM303D together.
I was trying to combine micropython and circuit python altogether with blinka and adafruit lib and pimoroni uf2, and everything got mixed up.
Eventually I took the direct approach and opened the LSM303D datasheet. Enabling the accelerator requires only one I2C command.
It works.
The below example is like a levelling app. you can stick the accelerator behind Pimoroni display, connect LSM303D I2C to pico pins 1-2. (not sure I use I2C most efficiently)
you get a leveler bubble moving on display as you tilt it.

from machine import Pin, I2C
import time
import picodisplay as display

# Initialise display with a bytearray display buffer
xx = display.get_width()
yy = display.get_height()
buf = bytearray(xx * (yy+10) * 2) ## add 10 lines to avoid bottom line corruption
display.init(buf)
display.set_backlight(0.5)

## SET I2C bus - using pico pins 1-2
sda=machine.Pin(0) 
scl=machine.Pin(1)
i2c=machine.I2C(0,sda=sda, scl=scl, freq=100000)

## Enable LSM303D accelerator at I2C addr 0x1D
config=bytearray(1)    
config[0]=39+8
## Reg Control1: (0x20) 50Hz+enable (0x57) + block update
i2c.writeto_mem(29, 32, config)

def get_axis(reg): ## 40 - X , 42 - Y , 44 - Z
    high=bytearray(1)
    low=bytearray(1)
    i2c.readfrom_mem_into(29, reg, low)
    i2c.readfrom_mem_into(29, reg+1, high)
    res = high[0] * 256 + low[0]
    if (res<16384):
        result = res/16384.0
    elif (res>=16384 and res<49152):
        result = (32768-res)/16384.0
    else:
        result = (res-65536)/16384.0
    return result

while True:
    display.set_pen(160, 160, 25)
    display.clear()
    x = ( get_axis(40) + 1) * xx / 2.0
    y = (-get_axis(42) + 1) * yy / 2.0
    display.set_pen(60,60,65)
    display.circle(int(x), int(y), 12)
    display.set_pen(180,180,200)
    display.circle(int(x), int(y), 9)
    display.update()
    time.sleep(0.05)

1 Like