Feel the excitement, the thrill, the rushing air beneath your wings - without having to leave home or run any risk of injury or sweating!
This Flying Trapeze bot uses a servo claw to grip onto a willing gymnast, and release it into the air when the detected acceleration has reached a sufficient peak!
The servo claw we used had a built in metal gear servo that could draw significant current when actuated! We found a 4xAA battery pack with good NiMH batteries would last a while but 3xNiMH couldn't power it sufficiently
Boot.py
Since we want to have the ability to data log the accelerometer, we need to put the CPX into 'filesystem write mode' - this boot.py will let you use the switch on the CPX to select whether you want to log data or go into trapeze-release mode
# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT
# Save as boot.py to turn on/off datalogging capability
import digitalio
import board
import storage
switch = digitalio.DigitalInOut(board.D7) # For Circuit Playground Express
switch.direction = digitalio.Direction.INPUT
switch.pull = digitalio.Pull.UP
# If the switch pin is connected to ground CircuitPython can write to the drive
storage.remount("/", readonly=switch.value)
CircuitPython Code
Our Python code is dual use. You can use the slide switch to select whether you want to log the accelerometer data to the onboard storage. If you do, its easy to plot it and see the magnitude of the forces on your trapeze artist!
We mostly used data log mode to calibrate how 'hard' we required the person to push the trapeze to make the servo release the gymnast-stand-in.
We also have two buttons on the CPX we use for different tasks. In logging mode, you use button A to turn on/off logging. The red LED blinks to let you know logging is occuring. In trapeze mode, A and B let you manually open/close the servo gripper so you can have it grab the gymnasts head. Hey life's tough all around!
Finally, if we're in trapeze mode, we look for when we're at the beginning of a swing, that's when the Z axis acceleration drops below 3 m/s2 and the Y axis has positive acceleration (we used the data log info to figure this out!) If so, the next time we reach max-acceleration, at the lowest point of the swing, we start opening the gripper, which takes a little time so that when we are at the end of the swing, it's opened enough for the gymnast to be released!
We change the NeoPixel colors to help debug, by flashing when we reach the different sensor states, since we don't have wireless data transfer on the CPX.
# SPDX-FileCopyrightText: 2018 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
from digitalio import DigitalInOut, Direction, Pull
import adafruit_lis3dh
from busio import I2C
from adafruit_seesaw.seesaw import Seesaw
from adafruit_seesaw.pwmout import PWMOut
from adafruit_motor import servo
import neopixel
import board
# create accelerometer
i2c1 = I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c1, address=0x19)
lis3dh.range = adafruit_lis3dh.RANGE_8_G
# Create seesaw object
i2c = I2C(board.SCL, board.SDA)
seesaw = Seesaw(i2c)
# Create servo object
pwm = PWMOut(seesaw, 17) # Servo 1 is on s.s. pin 17
pwm.frequency = 50 # Servos like 50 Hz signals
my_servo = servo.Servo(pwm) # Create my_servo with pwm signal
# LED for debugging
led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT
# two buttons!
button_a = DigitalInOut(board.BUTTON_A)
button_a.direction = Direction.INPUT
button_a.pull = Pull.DOWN
button_b = DigitalInOut(board.BUTTON_B)
button_b.direction = Direction.INPUT
button_b.pull = Pull.DOWN
# NeoPixels!
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=1)
pixels.fill((0,0,0))
#################### log file for logging mode!
logfile = "/log.csv"
# check that we could append if wanted to
try:
fp = None
fp = open(logfile, "a")
print("File system writable!")
# pylint: disable=bare-except
except:
print("Not logging, trapeeze mode!")
# If we log, have some helper variables
logging = False
logpoints = 0
outstr = ""
# When its time to release the trapeze
release = False
while True:
if button_a.value: # A pressed
while button_a.value: # wait for release
pass
if fp: # start or stop logging
logging = not logging
print("Logging: ", logging)
time.sleep(0.25)
else:
my_servo.angle = 180 # open
if button_b.value: # B pressed
while button_b.value: # wait for release
pass
my_servo.angle = 0 # close
x, y, z = lis3dh.acceleration
# To keep from corrupting the filesys, take 25 readings at once
if logging and fp:
outstr += "%0.2F, %0.2F, %0.2F\n" % (x, y, z)
logpoints += 1
if logpoints > 25:
led.value = True
#print("Writing: "+outstr)
fp.write(outstr+"\n")
fp.flush()
led.value = False
logpoints = 0
else:
# display some neopixel output!
if z > 20:
# MAXIMUM EFFORT!
pixels.fill((0, 255, 0))
if release:
my_servo.angle = 180
elif z < 3 and y > 0: # means at the outer edge
release = True
# flash red when we peak
pixels.fill((255, 0, 0))
else:
pixels.fill((0,0,int(abs(z)*2)))
time.sleep(0.05)
For the curious, our data log file is here!
Page last edited January 22, 2025
Text editor powered by tinymce.