An LSM303 FeatherWing

I wanted to build this project as compactly as possible, meaning I wanted it as a stack of feather/wing boards. And that meant I needed a accelerometer FeatherWing.  Alas there isn't such a thing available so I had to make my own. Since I didn't want to undertake a custom wing PCB, I looked for a breakout I could put onto a protowing.

Whatever accelerometer breakout I chose would need to fit between the header strips. In the end I found that the Flora accelerometer breakouts would fit perfectly. I chose the LSM303 as it was a bit smaller and cheaper. Additionally, all I needed for this project was an accelerometer and the LSM303 is an accelerometer/magnetometer combo. For another project I will be using the LSM9DS0 Flora breakout which includes a gyroscope as well.

Since the LSM303 didn't have a CircuitPython library yet, it gave me the opportunity to delve into writing a CircuitPython I2C driver.

Since I mounted the Flora breakout directly on the protowing I carefully cut the traces between the header holes and their duplicate holes on the bottom of the board; just the few on either side near the center of the board where the breakout would be. This avoided the chance of any undesirable shorts/connections with the signals from the Feather. While I could have mounted it with some non-conductive foam/rubber (I've used bumpers/feet for this in other projects) I wanted a solid, unmoving mounting for this.

The Flora breakout is especially nice as there are just 3.3v, ground, SDA, and SCL to connect. That made wiring quick and simple.

Be very careful to get the LSM303 breakout centered on the wing, and with the X and Y axies aligned with the sides. I oriented the X axis along the length of the wing, with the Y axis aligned along the width.

Wiring is simply a matter of connecting 3v & ground to the breakout along with SDA and SCL. The Flora breakout boards are beautifully minimal.


The API follows the unified sensor approach used in Adafruit's sensor APIs, both in C as well as CircuitPython. This means using standardized naming, as well as implementing as properties in CircuitPython.  Here's an example that uses the core of the API: reading raw and processed accelerometer and magnetometer values.

""" Display both accelerometer and magnetometer data once per second """

import time
import board
import busio

import adafruit_lsm303

i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_lsm303.LSM303(i2c)

while True:
    raw_accel_x, raw_accel_y, raw_accel_z = sensor.raw_acceleration
    accel_x, accel_y, accel_z = sensor.acceleration
    raw_mag_x, raw_mag_y, raw_mag_z = sensor.raw_magnetic
    mag_x, mag_y, mag_z = sensor.magnetic

    print('Acceleration raw: ({0:6d}, {1:6d}, {2:6d}), (m/s^2): ({3:10.3f}, {4:10.3f}, {5:10.3f})'
          .format(raw_accel_x, raw_accel_y, raw_accel_z, accel_x, accel_y, accel_z))
    print('Magnetometer raw: ({0:6d}, {1:6d}, {2:6d}), (gauss): ({3:10.3f}, {4:10.3f}, {5:10.3f})'
          .format(raw_mag_x, raw_mag_y, raw_mag_z, mag_x, mag_y, mag_z))
Last updated on 2018-01-23 at 08.48.27 PM Published on 2018-01-23 at 08.53.11 PM