Skip to content

Instantly share code, notes, and snippets.

@stonehippo
Last active April 30, 2021 04:20
Show Gist options
  • Save stonehippo/38d9ae32f96d9cd184c829e32765a76e to your computer and use it in GitHub Desktop.
Save stonehippo/38d9ae32f96d9cd184c829e32765a76e to your computer and use it in GitHub Desktop.
SpaceWing: a portable device for location and inertial information, built from Adafruit Featherwings

SpaceWing

A portable device for location and inertial information, built from Adafruit FeatherWings (plus some other stuff).

What is SpaceWing?

We are working on a project the involves using GPS for anchoring an augmented reality experience. As part of this development, I wanted a device that I could use to hack on for various things, including most of the positional sensors available in smartphones. To get what I wanted, I need GPS, a 9 DoF (accelerometer, gyroscope, and magnetometer), and pressure/altitude. I also wanted the device to have its own display, plus Bluetooth connectivity so I could offload the sensors readings to an app on a phone, tablet, or computer.

Construction

The SpaceWing is built around a Bluetooth enabled Feather nRF52840 Express, with most of the components on FeatherWings. The Feather and the three component FeatherWings are connected together via a FeatherWing Quad adapter, while the BMP390 is connected via the STEMMA QT (I2C) port on the 9 DoF IMU FeatherWing.

The LiPoly battery is attached to the back of the quad adapter with some nice Velcro.

Component Interconnections

Most of the components in the SpaceWing communicate via I2C. The exception is the GPS, which the nRF52840 talks to over a UART.

BOM

Firmware

I wrote all of the SpaceWing firmware using CircuitPython. See code.py.

Component Guides

The various guides for the components are available below

import time
import board
import busio
import adafruit_bus_device
import displayio
from adafruit_displayio_ssd1306 import SSD1306
from adafruit_display_text import label
from adafruit_bmp3xx import BMP3XX_I2C as BMP3XX
from adafruit_lsm6ds.ism330dhcx import ISM330DHCX as LSM6DS
from adafruit_lis3mdl import LIS3MDL
from adafruit_gps import GPS
i2c = board.I2C()
displayio.release_displays()
display_bus = displayio.I2CDisplay(i2c, device_address=0x3c)
display = SSD1306(display_bus, width=128, height=32) # set up the OLED display
bmp = BMP3XX(i2c) # set up the pressure + temperature sensor
accel_gyro = LSM6DS(i2c) # set up the accelerometer + gyroscope
mag = LIS3MDL(i2c) # set up the magnetometer
uart = busio.UART(board.TX, board.RX, baudrate=9600, timeout=10)
gps = GPS(uart, debug=False) # set up the GPS with I2C (rather than UART)
gps.send_command(b"PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") #configure basic GGA and RMC info
gps.send_command(b"PMTK220,1000") # set GPS update rate to 1Hz
# main loop
last_print = time.monotonic()
while True:
gps.update()
current = time.monotonic()
if current - last_print > 1.0: # set the display update to happen once per second or so
acceleration = accel_gyro.acceleration
gyro =accel_gyro.gyro
magnetic = mag.magnetic
# uncomment to print to the console
# if not gps.has_fix:
# print("Waiting for GPS fix...")
# continue
# print("Lat: {:.6f} Long: {:.6f} Qual: {:d}".format(gps.latitude, gps.longitude, gps.fix_quality))
# print("Accel: X:{0:7.2f}, Y:{1:7.2f}, Z:{2:7.2f} m/s^2".format(*acceleration))
# print("Gyro: X:{0:7.2f}, Y:{1:7.2f}, Z:{2:7.2f} rad/s".format(*gyro))
# print("Mag: X:{0:7.2f}, Y:{1:7.2f}, Z:{2:7.2f} uT".format(*magnetic))
# print("Pressure: {:6.4f} Temp: {:5.2f}".format(bmp.pressure, bmp.temperature))
# print(" ")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment