Wings of Fire- an Interactive Dragon Display

by carbonmk in Circuits > Raspberry Pi

227 Views, 1 Favorites, 0 Comments

Wings of Fire- an Interactive Dragon Display

IMG_9907.jpeg
IMG_9905.jpeg
IMG_9908.jpeg
IMG_9910.jpeg
IMG_9909.jpeg
Wings of Fire: An interactive display demo

This is a project to give to the Campus School students at Boston College. They are students with severe disabilities, so we must make sure that the project is durable and easy to see for the students. After speaking with the technology specialist, we wanted to make a "Wings of Fire" kind of display for the students since they enjoy that series of books.

When one of the pads is pressed, a random dragon sound will play and the servos will start to swing in opposite directions. This makes it look like whatever you place on the servos are fighting. We placed dragons on the servos in the spirit of the "Wings of Fire" series. If the other pad is pressed, then

Supplies

Electronics:

Pico W

LED Strip

Adafruit mpr121

2 Servo motors (180 degree range)

A speaker that has an audio plug

2 Alligator-to-pin clips

2 Alligator-to-Alligator clips

15 Pin-to-pin wires

Stemma QT plug with pins on the end

An Adafruit microSD SPI reader (pins already soldered on).

An SD card (32 gigabytes or less)

A USB cable (to power the microcontroller)

1 Battery pack

Other materials:

Some sort of display box, here we attempted to make a castle out of wood

Action figures/decorations

Adhesive

Copper Tape

Copper Wire

Wire the Pico to the Speaker

IMG_9805.jpeg

1-    Take one of the alligator to pin clips and connect the pin to any ground on the Pico.

2-    Connect the alligator clip to the base of the audio jack cable. 

3-    Take the other alligator to pin clips and connect the pin to GP16 (or your preferred pin) on the Pico. 

4-    Connect the alligator clip to the tip of the audio jack cable.

5-    If applicable, make sure to turn on the speaker.

The speaker will play the audio files you selected for your theme, here we have a selection of dragon sounds.

Wire the Pico to the Micro SD Card Reader

IMG_9809.jpeg
IMG_9808.jpeg

1-    Using the SD card reader for your computer, make a new folder on the SD card and load any sounds you want into that folder. Make sure to remember the name of the folder as this will be the path for your sounds in the code.

2-    If applicable, make sure to solder the pins onto your Adafruit SD card reader.

3-    Take a pin-to-pin wire and connect it to 3.3 Volts on the Pico W and the 3V slot on the SD Card reader.

4-    Using another pin-to-pin wire, connect it to any ground on the Pico W and the ground slot on the SD card reader.

5-    Connect a pin-to-pin wire to GP10, which is SCK, to CLK slot on the SD Card reader.

6-    Connect a pin-to-pin wire to GP11, which is SI or TX, to the “DO SO” slot on the SD card reader.

7-    Connect a pin-to-pin wire to GP12, which is SO or RX, to the “CMD SI” slot on the SD card reader.

8-    Connect a pin-to-pin wire to GP13, which is CS, to the “DE CS” slot on the SD card reader.

9-    Finally, insert the SD card into the slot, you will hear a click when the SD Card is properly inserted. 

The SD card reader will allow you to play large sound files since there is very little space on the Pico W.

Wire the Pico to the Adafruit MPR121

IMG_9807.jpeg

1- Plug the Stemma QT side of the Stemma QT-to-pins wire into the mpr121.

2- The yellow wire is SCL which is connected to GP5 on the Pico.

3- The blue wire is SDA and is connected to GP4 on the Pico.

4- The red wire is power which is connected to 3.3 Volts out, not VBUS!

5- The black wire is ground which is connected to any ground on the Pico W.

This will be used for capacitive touch later when assembling the entire box.

Wire the Pico to the Servos

1- Connect a pin-to-pin wire to the red wire on the servo then connect that to VBUS. 

2- Connect a pin-to-pin wire to the brown wire on the servo then connect that to any ground

3- Connect a pin-to-pin wire to the orange wire on the servo then connect that to GP14 then the other on GP15 (or any other signal pin you wish).

The servos will be used to move our action figures to make them appear they are fighting.

Wire the Pico to the LED Strip

1- Take the LED strip white alligator clip, and connect it to a pin-to-pin wire. Then connect that pin-to-pin wire to GP16

2- Connect the red alligator clip to a pin-to-pin wire. Then connect that pin-to-pin wire to VBUS.

3- Connect the black alligator clip to a pin-to-pin wire. Then connect that pin-to-pin wire to any ground.

The LED strip will be used to make it look like our dragon decorative piece is breathing fire.

Assembling the Castle

IMG_9909.jpeg

1- Assemble the parts you will be using to build your housing. We used laser cut wood and glued them together to make a castle.

2- (optional) Place your decorations

3- Put the electronics in its holding spot as we prepare to place the rest of the electronics.

4- Place a servo in each position and make sure they swing in opposite directions (to give the appearance of characters fighting when we assemble that)

5- Connect some sort of arbitrary platform (we used pieces of popsicle sticks) to the servos then add your characters.

6- Using the copper tape, place it over one of the front panels of the castle.

7- From the inside, connect the copper tape with either a pin-to-pin wire or copper wire. At the other end of the wire, wrap it around the corresponding touchpad on the mpr121 (or use alligator-to-alligator clips and clamp one end to the mpr121 and the other end to the wire connected to the copper tape).

8- Finally, connect the end of the LED Strip to the dragons mouth and wrap it around the castle.

The Code

I have attached the code below in a file for easy download, but here is the code also if you would rather just read it:

import neopixel, board, time, random, mount_sd, pwmio

from adafruit_motor import servo

from audiomp3 import MP3Decoder

from audiopwmio import PWMAudioOut as AudioOut

import adafruit_mpr121

from adafruit_debouncer import Button

from audiocore import WaveFile


#Set up audio

audio = AudioOut(board.GP16)


#set up LEDs and colors

fire_strip = neopixel.NeoPixel(board.GP17, 30, brightness = 1, auto_write=True)

winner_strip = neopixel.NeoPixel(board.GP18, 20, brightness = 1, auto_write=True)

from adafruit_led_animation.color import (

  AMBER, #(255, 100, 0)

  AQUA, # (50, 255, 255)

  BLACK, #OFF (0, 0, 0)

  BLUE, # (0, 0, 255)

  CYAN, # (0, 255, 255)

  GOLD, # (255, 222, 30)

  GREEN, # (0, 255, 0)

  JADE, # (0, 255, 40)

  MAGENTA, #(255, 0, 20)

  OLD_LACE, # (253, 245, 230)

  ORANGE, # (255, 40, 0)

  PINK, # (242, 90, 255)

  PURPLE, # (180, 0, 255)

  RED, # (255, 0, 0)

  TEAL, # (0, 255, 120)

  WHITE, # (255, 255, 255)

  YELLOW, # (255, 150, 0)

  RAINBOW # a list of colors to cycle through

  # RAINBOW is RED, ORANGE, YELLOW, GREEN, BLUE, and PURPLE ((255, 0, 0), (255, 40, 0), (255, 150, 0), (0, 255, 0), (0, 0, 255), (180, 0, 255))

)

INDIGO = (63, 0, 255)

VIOLET = (127, 0, 255)


# We often use these colors, but be sure to check colors used when taking exams

colors = [RED, MAGENTA, ORANGE, YELLOW, GREEN, JADE, TEAL, BLUE, INDIGO, VIOLET, PURPLE, WHITE]

winner_color = [BLUE, GREEN]


def breath_fire():

  for i in reversed(range(30)):

    fire_strip[i]=ORANGE

    time.sleep(.02)

  for i in range(5):

    fire_strip.fill(RED)

    time.sleep(.05)

    fire_strip.fill(YELLOW)

    time.sleep(.05)

  fire_strip.fill(BLACK)

  time.sleep(.1)

def breath_blue_fire():

  for i in reversed(range(30)):

    fire_strip[i]=BLUE

    time.sleep(.02)

  for i in range(5):

    fire_strip.fill(PURPLE)

    time.sleep(.05)

    fire_strip.fill(WHITE)

    time.sleep(.05)

  fire_strip.fill(BLACK)

  time.sleep(.1)

fire_strip.fill(BLACK)


def flash_winner_strip():

  random_color = random.choice(winner_color)

  for _ in range(8):

    winner_strip.fill(random_color)

    time.sleep(0.1)

    winner_strip.fill(BLACK)

    time.sleep(0.1)

  winner_strip.fill(WHITE)

winner_strip.fill(WHITE)


#set up i2c object

i2c = board.STEMMA_I2C()

touch_pad = adafruit_mpr121.MPR121(i2c)


pwm1 = pwmio.PWMOut(board.GP14, frequency=50)

servo_1 = servo.Servo(pwm1, min_pulse = 750, max_pulse = 2500)

pwm2 = pwmio.PWMOut(board.GP15, frequency=50)

servo_2 = servo.Servo(pwm2, min_pulse = 750, max_pulse = 2500)


# Example usage

start_angle = 0

end_angle = 180

step = 5

delay = 0.01 # Adjust this value to control the movement speed


def move_servos_face_to_face(servo1, servo2, start_angle, end_angle, step, delay):

  # Move servos from start_angle to end_angle in steps of step degrees

  for angle in range(start_angle, end_angle + 1, step):

    servo1.angle = angle

    servo2.angle = end_angle - angle + start_angle

    time.sleep(delay)


  # Move servos back to start_angle in steps of step degrees

  for angle in range(end_angle, start_angle - 1, -step):

    servo1.angle = angle

    servo2.angle = end_angle - angle + start_angle

    time.sleep(delay)



path = "/sd/dragonSounds/"

is_playing = False


sounds1 = ["dragon-growl.wav", "dragon-howl.wav", "dragon-roar.wav", "fire-breath.wav"]

sounds2 = ["dragon-growl.wav", "dragon-howl.wav", "dragon-roar.wav"]


def play_sound1(filename):

  with open(path + filename, "rb") as wave_file:

    wave = WaveFile(wave_file)

    audio.play(wave)

    while audio.playing:

      move_servos_face_to_face(servo_1, servo_2, start_angle, end_angle, step, delay)

    servo_1.angle = start_angle

    servo_2.angle = start_angle


def play_sound2(filename):

  with open(path + filename, "rb") as wave_file:

    wave = WaveFile(wave_file)

    audio.play(wave)

    while audio.playing:

      breath_fire()


def play_sound3(filename):

  with open(path + filename, "rb") as wave_file:

    wave = WaveFile(wave_file)

    audio.play(wave)

    while audio.playing:

      breath_blue_fire()



while True:

  if touch_pad[0].value:

    print("TOUCHBAD 0 PRESSED")

    random_sound1 = random.choice(sounds2)

    play_sound1(random_sound1)

    flash_winner_strip()

  if touch_pad[5].value:

    print("TOUCHBAD 5 PRESSED")

    random_sound2 = random.choice(sounds1)

    play_sound2(random_sound2)

  if touch_pad[6].value:

    print("TOUCHBAD 6 PRESSED")

    random_sound3 = random.choice(sounds1)

    play_sound3(random_sound3)


Downloads