TDS 200705
Created December 31, 2019

Star Wars Theater

This is a theater that plays with Amazon music songs.

BeginnerShowcase (no instructions)10 hours89
Star Wars Theater

Things used in this project

Hardware components

Mindstorms EV3 Programming Brick / Kit
LEGO Mindstorms EV3 Programming Brick / Kit
×1
Amazon Alexa amazon echo show 5
×1

Software apps and online services

visual studio code

Story

Read more

Schematics

Mechanism : Yoda vs Darth Vader

Backside

Scene: Stage greeting

How the stage rises

How the curtain works

Code

Star Wars Theater

Python
#!/usr/bin/env python3
# Copyright 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
# 
# You may not use this file except in compliance with the terms and conditions 
# set forth in the accompanying LICENSE.TXT file.
#
# THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY DISCLAIMS, WITH 
# RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING 
# THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.

import os
import sys
import time
import logging
import threading
import random

from agt import AlexaGadget

from ev3dev2.led import Leds
from ev3dev2.sound import Sound
from ev3dev2.motor import OUTPUT_A,  MediumMotor
from ev3dev2.motor import OUTPUT_B, OUTPUT_C, OUTPUT_D, LargeMotor

# Set the logging level to INFO to see messages from AlexaGadget
logging.basicConfig(level=logging.INFO, stream=sys.stdout, format='%(message)s')
logging.getLogger().addHandler(logging.StreamHandler(sys.stderr))
logger = logging.getLogger(__name__)


class MindstormsGadget(AlexaGadget):
    """
    A Mindstorms gadget that performs movement in sync with music tempo.
    """

    def __init__(self):
        """
        Performs Alexa Gadget initialization routines and ev3dev resource allocation.
        """
        super().__init__()

        # Ev3dev initialization
        self.leds = Leds()
        self.sound = Sound()
        self.curtain_motor = MediumMotor(OUTPUT_A)
        self.stand_up_motor = LargeMotor(OUTPUT_B)
        self.fight_motor = LargeMotor(OUTPUT_C)
        self.finale_motor = LargeMotor(OUTPUT_D)

        # Gadget states
        self.bpm = 0
        self.trigger_bpm = "off"

    def on_connected(self, device_addr):
        """
        Gadget connected to the paired Echo device.
        :param friendly_name: the friendly name of the gadget that has connected to the echo device
        """
        self.leds.set_color("LEFT", "GREEN")
        self.leds.set_color("RIGHT", "GREEN")
        logger.info("{} connected to Echo device".format(self.friendly_name))

    def on_disconnected(self, device_addr):
        """
        Gadget disconnected from the paired Echo device.
        :param friendly_name: the friendly name of the gadget that has disconnected from the echo device
        """
        self.leds.set_color("LEFT", "BLACK")
        self.leds.set_color("RIGHT", "BLACK")
        logger.info("{} disconnected from Echo device".format(self.friendly_name))

    def on_alexa_gadget_musicdata_tempo(self, directive):
        """
        Provides the music tempo of the song currently playing on the Echo device.
        :param directive: the music data directive containing the beat per minute value
        """
        starwars_action=0
        tempo_data = directive.payload.tempoData
        for tempo in tempo_data:

            print("tempo value: {}".format(tempo.value), file=sys.stderr)
            if tempo.value == 141 and starwars_action == 0:
                time.sleep(10)
                self.curtain_motor.run_timed(speed_sp=300, time_sp=2000)           
                self.leds.set_color("LEFT", "GREEN")
                self.leds.set_color("RIGHT", "GREEN")
                time.sleep(3)
                # starts the wait loop
                self.trigger_bpm = "on"
                starwars_action=1
                threading.Thread(target=self._wait_loop, args=(tempo.value,)).start()
            elif tempo.value == 201 and starwars_action == 0:
                time.sleep(5)
                self.stand_up_motor.run_timed(speed_sp=750, time_sp=3000)
                self.leds.set_color("LEFT", "RED")
                self.leds.set_color("RIGHT", "RED")
                time.sleep(10)
                self.fight_motor.run_timed(speed_sp=750, time_sp=12000)
                time.sleep(10)
                self.stand_up_motor.run_timed(speed_sp=-750, time_sp=3000)
                # starts the wait loop
                self.trigger_bpm = "on"
                starwars_action=1
                threading.Thread(target=self._wait_loop, args=(tempo.value,)).start()
            elif tempo.value == 136 and starwars_action == 0:
                time.sleep(40)
                self.finale_motor.run_timed(speed_sp=750, time_sp=15000)
                self.leds.set_color("LEFT", "AMBER")
                self.leds.set_color("RIGHT", "AMBER")
                time.sleep(60)
                self.finale_motor.run_timed(speed_sp=-300, time_sp=15000)
                self.curtain_motor.run_timed(speed_sp=-300, time_sp=1400)  
                # starts the wait loop
                self.trigger_bpm = "on"
                starwars_action=1
                threading.Thread(target=self._wait_loop, args=(tempo.value,)).start()
            elif tempo.value == 0:
                # stops the wait loop
                self.trigger_bpm = "off"
                self.leds.set_color("LEFT", "BLACK")
                self.leds.set_color("RIGHT", "BLACK")
                starwars_action=0

    def _wait_loop(self, bpm):
        """
        Perform motor movement in sync with the beat per minute value from tempo data.
        :param bpm: beat per minute from AGT
        """
        color_list = ["GREEN", "RED", "AMBER", "YELLOW"]
        led_color = random.choice(color_list)
        motor_speed = 200
        milli_per_beat = min(1000, (round(60000 / bpm)) * 0.65)
        print("Adjusted milli_per_beat: {}".format(milli_per_beat), file=sys.stderr)
        while self.trigger_bpm == "on":

            # Alternate led color and motor direction
            led_color = "BLACK" if led_color != "BLACK" else random.choice(color_list)
            #motor_speed = -motor_speed

            self.leds.set_color("LEFT", led_color)
            self.leds.set_color("RIGHT", led_color)

        print("Exiting BPM process.", file=sys.stderr)


if __name__ == '__main__':

    gadget = MindstormsGadget()

    # Set LCD font and turn off blinking green LEDs
    os.system('setfont Lat7-Terminus12x6')
    gadget.leds.set_color("LEFT", "BLACK")
    gadget.leds.set_color("RIGHT", "BLACK")

    # Startup sequence 
    gadget.sound.play_song((('C4', 'e'), ('D4', 'e'), ('E5', 'q')))
    gadget.leds.set_color("LEFT", "GREEN")
    gadget.leds.set_color("RIGHT", "GREEN")

    # Gadget main entry point
    gadget.main()

    # Shutdown sequence
    gadget.sound.play_song((('E5', 'e'), ('C4', 'e')))
    gadget.leds.set_color("LEFT", "BLACK")
    gadget.leds.set_color("RIGHT", "BLACK")

Credits

TDS 200705

TDS 200705

1 project • 0 followers

Comments