Synopsis
For this assignment Team Pom Pom tested how the microcontroller’s movement while attached to the chair affected the wind chimes. It was a great success! When Helen moved her chair and sat in it the small movements triggered the wind chimes to move in a slow and jolted motion. When Helen moved her hair from side to side at a faster pace, the wind chime spun around faster in a smooth and controlled spin cycle.
Video Demo
Code
"""
Project 1: Ambient Proxy Body
Team Pom Pom
Helen Yu (heleny1), Celia Kasberg (ckasberg), Elle Smith
Written by Helen Yu
Last Updated: 3/28/21
Summary: As your partner fidgets in their chair, your wind chimes spin
in reaction to your partner's presence. Small and slow movements trigger
a sweeping motion in the servo. Fast and sharp movements trigger a stepping
sweep in the servo.
Inputs: Accelerometer
Outputs: Hobby Servo on SD A5
"""
# ----------------------------------------------------------------
# Import any needed standard Python modules.
import time, math, sys
# Import the board-specific input/output library.
from adafruit_circuitplayground import cp
# Import the low-level hardware libraries.
import board
import digitalio
import analogio
import pwmio
# Import the Adafruit helper library.
from adafruit_motor import servo
# Import the runtime for checking serial port status.
import supervisor
# ----------------------------------------------------------------
# Initialize hardware.
# Create a PWMOut object on pad SDA A5 to generate control signals.
pwm = pwmio.PWMOut(board.A5, duty_cycle=0, frequency=50)
# Create a Servo object which controls a hobby servo using the PWMOut.
actuator = servo.Servo(pwm, min_pulse=50, max_pulse=3000)
# ----------------------------------------------------------------
# Initialize global variables for the main loop.
# The remote move state can be updated via serial port messages.
remote_moves = [0, 0, 0, 0, 0]
# Measure the time since the last remote move message, and reset after a period without data.
remote_moves_timer = False
# Convenient time constant expressed in nanoseconds.
second = 1000000000
# Integer time stamp for the next console output.
sensing_timer = time.monotonic()
# Integer time stamp for next behavior activity to begin.
next_activity_time = time.monotonic_ns() + 2 * second
# Flag to trigger motion.
sweep_slow = False
sweep_fast = False
phase_angle = 0.0
phase_rate = 2*math.pi / 6.0 # one cycle per six seconds, in radians/second
# Integer time stamp for next servo update.
next_servo_update = time.monotonic_ns()
# The serial port output rate is regulated using the following timer variables.
serial_timer = 0.0
serial_interval = 0.5
# ----------------------------------------------------------------
# Begin the main processing loop.
while True:
# Read the current integer clock.
now = time.monotonic()
# Measure and define local acceleration
x, y, z = cp.acceleration
l_x = abs(int(x))
l_y = abs(int(y))
l_z = abs(int(z))
local_moves = l_x, l_y, l_z
# Check the serial input for new line of remote data
if supervisor.runtime.serial_bytes_available:
line = sys.stdin.readline()
tokens = line.split()
if len(tokens) == 5:
try:
remote_moves = [int(token) > 0 for token in tokens]
remote_move_timer = 4.0
except ValueError:
pass
#---- periodic console output -----------------------------------
# Poll the time stamp to decide whether to emit console output.
if now >= sensing_timer:
sensing_timer += 100000000 #0.1sec
if any(local_moves):
remote_moves_timer = now + 4000000000 # 4 sec timeout
if now >= serial_timer:
serial_timer += serial_interval
moves = ["1" if 1 < l_x < 3 else "0", "1" if l_y > 1 else "0", "1" if 1 < l_z < 3 else "0", "1" if l_x > 3 else "0", "1" if l_z > 3 else "0"]
print(" ".join(moves))
# If a slow movement has been received, sweep twice at a constant speed
if sweep_slow is True:
for angle in range(0, 180, 5):
actuator.angle = angle
time.sleep(0.02)
print("Reversing slow sweep.")
for angle in range(180, 0, -5):
actuator.angle = angle
time.sleep(0.02)
print("End of slow cycle")
sweep_slow = False
# If a fast movement has been received, sweep twice in a stepping motion
if sweep_fast is True:
for angle in range(0, 180, 10):
actuator.angle = angle
time.sleep(0.2)
print("Reversing fast sweep.")
for angle in range(180, 0, -10):
actuator.angle = angle
time.sleep(0.2)
print("End of fast cycle")
sweep_fast = False
if any(remote_moves):
# Check whether there was any remote movement
if remote_moves[0] or remote_moves[2]:
if remote_moves[1]:
sweep_slow = True
print("Entering slow cycle.")
if remote_moves[3] or remote_moves[4]:
if remote_moves[1]:
sweep_fast = True
print("Entering fast cycle")
remote_moves = [False]*5
#---- periodic servo motion commands ----------------------------
# If the time has arrived to update the servo command signal:
if now >= next_servo_update:
next_servo_update += 20000000 # 20 msec in nanoseconds (50 Hz update)
Leave a Reply
You must be logged in to post a comment.