Once you've finished setting up your nRF52840 LED Glasses Driver with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.

To do this, click on the Download Project Bundle button in the window below. It will download as a zipped folder.

# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
# SPDX-License-Identifier: MIT

import time
import board
import adafruit_lis3dh
import simpleio
import adafruit_ble
from adafruit_ble.advertising import Advertisement
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.standard.hid import HIDService
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode

#  I2C setup
i2c = board.I2C()
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c)

#  range of LIS3DH
lis3dh.range = adafruit_lis3dh.RANGE_2_G

#  BLE HID setup
hid = HIDService()

advertisement = ProvideServicesAdvertisement(hid)
advertisement.appearance = 961
scan_response = Advertisement()
scan_response.complete_name = "CircuitPython HID"

#  BLE instance
ble = adafruit_ble.BLERadio()

#  keyboard HID setup
keyboard = Keyboard(hid.devices)

#  BLE advertisement
if not ble.connected:
    print("advertising")
    ble.start_advertising(advertisement, scan_response)
else:
    print("connected")
    print(ble.connections)

while True:
    while not ble.connected:
        pass
	#  while BLE connected
    while ble.connected:
        #  read LIS3DH
        x, y, z = [
            value / adafruit_lis3dh.STANDARD_GRAVITY for value in lis3dh.acceleration
        ]
        #  map Y coordinate of LIS3DH
        mapped_y = simpleio.map_range(y, -1.1, 1.1, 0, 3)
        #  convert mapped value to an integer
        plane = int(mapped_y)

        #  if you're tilting down...
        if plane == 0:
            #  send R, glider moves right
            keyboard.press(Keycode.R)
            #  debug
            #  print("right")
        #  if there's no tilt...
        if plane == 1:
            #  release all keys, send nothing to glider
            keyboard.release_all()
            #  debug
            #  print("none")
        #  if you're tilting up...
        if plane == 2:
            #  send L, glider moves left
            keyboard.press(Keycode.L)
            #  debug
            #  print("left")
        time.sleep(0.01)
    #  if BLE disconnects, begin advertising again
    ble.start_advertising(advertisement)

Upload the Code and Libraries to the nRF52840 LED Glasses Driver

After downloading the Project Bundle, plug your nRF52840 LED Glasses Driver into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the nRF52840 LED Glasses Driver's CIRCUITPY drive. 

  • lib folder
  • code.py

Your nRF52840 LED Glasses Driver CIRCUITPY drive should look like this after copying the lib folder and the code.py file.

CIRCUITPY

Other Board Options

You could also use the Feather nRF52840 Sense board, since it also has BLE and an onboard accelerometer. The Feather nRF52840 Sense's accelerometer is a LSM6DS33, different from the nRF52840 LED Glasses Driver's LIS3DH. As a result, you would need to change the code to use the LSM6DS33 library.

Additionally, the LIS3DH accelerometer is available as a STEMMA board. You could use that breakout with any CircuitPython compatible board with the code included on this page.

How the CircuitPython Code Works

Before the loop, the LIS3DH accelerometer, HID keyboard and BLE are setup.

#  I2C setup
i2c = board.I2C()
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c)

#  range of LIS3DH
lis3dh.range = adafruit_lis3dh.RANGE_2_G

#  BLE HID setup
hid = HIDService()

advertisement = ProvideServicesAdvertisement(hid)
advertisement.appearance = 961
scan_response = Advertisement()
scan_response.complete_name = "CircuitPython HID"

#  BLE instance
ble = adafruit_ble.BLERadio()

#  keyboard HID setup
keyboard = Keyboard(hid.devices)

#  BLE advertisement
if not ble.connected:
    print("advertising")
    ble.start_advertising(advertisement, scan_response)
else:
    print("connected")
    print(ble.connections)

Reading and Mapping Y

The accelerometer's value is read in the loop. For the purposes of controlling Glider, you only need to look at the y axis. The y axis will tell you whether you are tilting the board up or down.

The range of y is mapped to a range of 0 to 3 and then converted to an integer. As a result, when you're tilting the board down plane will be 0. When you're not tilting the board at all, plane will be 1. When you're tilting the board up, plane will be 2.

x, y, z = [
            value / adafruit_lis3dh.STANDARD_GRAVITY for value in lis3dh.acceleration
        ]
        #  map Y coordinate of LIS3DH
        mapped_y = simpleio.map_range(y, -1.1, 1.1, 0, 3)
        #  convert mapped value to an integer
        plane = int(mapped_y)

Sending Key Presses

With the y axis mapped, you have three states for the tilt of your board: up, none and down. Each of these states has an assigned keyboard command. When you are tilting the board down, Keycode.R is sent. This moves the glider right in the game. When you are tilting the board up, Keycode.L is sent. This moves the glider left in the game. When you aren't tilting the board at all, all keys are released with the keyboard.release_all() function.

If you wanted to change the keycodes, you would edit this portion of the code.

#  if you're tilting down...
        if plane == 0:
            #  send R, glider moves right
            keyboard.press(Keycode.R)
            #  debug
            #  print("right")
        #  if there's no tilt...
        if plane == 1:
            #  release all keys, send nothing to glider
            keyboard.release_all()
            #  debug
            #  print("none")
        #  if you're tilting up...
        if plane == 2:
            #  send L, glider moves left
            keyboard.press(Keycode.L)
            #  debug
            #  print("left")

This guide was first published on Apr 19, 2022. It was last updated on 2022-04-19 17:31:37 -0400.

This page (Coding the Glider Paper Airplane Controller) was last updated on May 24, 2022.

Text editor powered by tinymce.