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("/", 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!