Triggering different sequences based on context or interaction

How could we trigger different sequences based on user interaction or context? 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 D10, the Servo Motor to pin D12 and the Touch Sensor to D6. 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.D6)
    touch.direction = digitalio.Direction.INPUT

    pin_leds = board.D10
    num_leds = 1
    leds = neopixel.NeoPixel(pin_leds, num_leds, auto_write=False, pixel_order=neopixel.GRBW)

    pwm = pwmio.PWMOut(board.D12, duty_cycle=2 ** 15, frequency=50)  # create a PWMOut object on Pin D12.
    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 LED
    # 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)