03: Triggering different sequences based on context or interaction
How could we trigger different sequences based on user or context interaction? In this example, we will create a little ItsyCreature that sleeps peacefully until disturbed – in that case it wakes up and gets angry at the disturbance!
Connect the Chainable LED to pin D13
, the Servo Motor to pin D2
and the Touch Sensor to D3
. By default, the creature will “sleep” in peace, but when touched get angry until the sensor is released again.
##--- Library Imports
import time
import board
import neopixel
import pwmio
import digitalio
from adafruit_motor import servo
from varspeed import Vspeed
##--- VarSpeed Variables
MIN_LED = 0 # The minimum possible value of our component
MAX_LED = 255 # The maximum possible value of our component
vs_led = Vspeed(init_position=MIN_LED, result="int") # init_position = initial start position // result = float, int
vs_led.set_bounds(lower_bound=MIN_LED, upper_bound=MAX_LED) # make the output of the function be within the bounds set
MIN_SERVO = 0 # The minimum possible value of our component
MAX_SERVO = 180 # The maximum possible value of our component
vs_servo = Vspeed(init_position=MIN_SERVO,
result="int") # init_position = initial start position // result = float, int
vs_servo.set_bounds(lower_bound=MIN_SERVO,
upper_bound=MAX_SERVO) # make the output of the function be within the bounds set
##--- Hardware Setup
# Add a touch sensor
touch = digitalio.DigitalInOut(board.D3)
touch.direction = digitalio.Direction.INPUT
pin_leds = board.D13
num_leds = 1
leds = neopixel.NeoPixel(pin_leds, num_leds, auto_write=False, pixel_order=neopixel.GRBW)
pwm = pwmio.PWMOut(board.D2, duty_cycle=2 ** 15, frequency=50) # create a PWMOut object on Pin D2.
my_servo = servo.Servo(pwm) # Create a servo object, my_servo
my_servo.angle = MIN_SERVO # set the servo to a known starting point
##--- Custom Movement Sequence
# This is where we can define the brightness of our LDED
# The sequence will go through each entry and move to the next entry
# The sequence is defined in this format: (next-position,seconds-to-move,number-of-steps,easing function)
# Take a look at different easing functions here: https://easings.net
led_sequence_sleep = [
(80, 3, 80, "QuadEaseIn"),
(80, 2, 1, "LinearInOut"),
(0, 3, 80, "QuadEaseInOut"),
(0, 2, 1, "LinearInOut")
]
led_sequence_angry = [
(MAX_LED, 0.01, 1, "QuadEaseInOut"),
(MIN_LED, 0.01, 1, "QuadEaseInOut")
]
servo_sequence_sleep = [
(0, 1.0, 1, "LinearInOut"),
(10, 0.1, 2, "LinearInOut"),
(0, 0.1, 2, "LinearInOut"),
(10, 0.1, 2, "LinearInOut"),
(0, 0.1, 2, "LinearInOut"),
(0, 10.0, 11, "LinearInOut")
]
servo_sequence_angry = [
(10, 0.01, 1, "LinearInOut"),
(MIN_SERVO, 0.01, 1, "LinearInOut")
]
# Define what should happen when we get to the end of our LED sequence
led_looping = 0 # play the sequence in an endless loop forever
# led_looping = 1 # play the sequence only once
# led_looping = 10 # play the sequence 10 times
# led_looping = 15 # play the sequence 15 times
# Define what should happen when we get to the end of our servo sequence
servo_looping = 0 # play the sequence in an endless loop forever
# servo_looping = 1 # play the sequence only once
# servo_looping = 10 # play the sequence 10 times
# servo_looping = 15 # play the sequence 15 times
# Set the LEDs to off
leds.fill((0, 0, 0))
leds.show()
##--- Main loop
while True:
if touch.value == False:
print("sleeping 😴")
# Make a call to the library and request the desired of our LED
position_led, running_led, changed_led = vs_led.sequence(sequence=led_sequence_sleep, loop_max=led_looping)
# See if the values changed for the next move, then do so
if changed_led:
# print(f'Sequence Num: {vs_led.seq_pos}, Step: {vs_led.step}, Position: {position_led}')
# Turn LED White
led_value = int(position_led)
leds.fill((0, 0, 0, led_value))
leds.show()
# Make a call to the library and request the desired of our servo motor
position_servo, running_servo, changed_servo = vs_servo.sequence(sequence=servo_sequence_sleep,
loop_max=servo_looping)
# See if the values changed for the next move, then do so
if changed_servo:
# print(f'Sequence Num: {vs_servo.seq_pos}, Step: {vs_servo.step}, Position: {position_servo}')
my_servo.angle = position_servo
elif touch.value == True:
print("angry!!! 😡")
# Make a call to the library and request the desired of our LED
position_led, running_led, changed_led = vs_led.sequence(sequence=led_sequence_angry, loop_max=led_looping)
# See if the values changed for the next move, then do so
if changed_led:
# print(f'Sequence Num: {vs_led.seq_pos}, Step: {vs_led.step}, Position: {position_led}')
# Turn LED Red
led_value = int(position_led)
leds.fill((led_value, 0, 0))
leds.show()
# Make a call to the library and request the desired of our servo motor
position_servo, running_servo, changed_servo = vs_servo.sequence(sequence=servo_sequence_angry,
loop_max=servo_looping)
# See if the values changed for the next move, then do so
if changed_servo:
# print(f'Sequence Num: {vs_servo.seq_pos}, Step: {vs_servo.step}, Position: {position_servo}')
my_servo.angle = position_servo
time.sleep(0.05)