Dawn Dupriest
Published © CC BY-NC-SA

Musical, Light-up Sweater Decal With LilyTiny/LilyTwinkle

A cheap way to create a musical, light-up decal for a wearable. I used these plans in a workshop with middle schoolers and parents.

BeginnerFull instructions provided3 hours369
Musical, Light-up Sweater Decal With LilyTiny/LilyTwinkle

Things used in this project

Hardware components

SparkFun LilyTwinkle
×1
LilyPad Coin Cell Battery Holder - Switched - 20mm
SparkFun LilyPad Coin Cell Battery Holder - Switched - 20mm
×1
SparkFun LilyPad Rainbow LED's
×1
SparkFun LilyPad Buzzer
×1
SparkFun CR 2032 Coin Cell Battery
×1
SparkFun Conductive Thread
×1
Tiny AVR Programmer
SparkFun Tiny AVR Programmer
×1
SparkFun 8-pin IC Test Clip
×1
SparkFun M/F Jumper Wires
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

SparkFun Needle Set
Felt

Story

Read more

Schematics

Circuit Diagram for Light Up, Musical Applique

Created in Fritzing. The LilyTwinkle is in the center. Pin 0 is connected to the buzzer, and pins 1, 2, 3 each go to two LED's. A coin cell holder powers the circuit.

Code

Rudolph the Red Nosed Reindeer

Arduino
This code uses Pin 0, connected to a Piezo buzzer, to create the melody. Pins 1, 2, and 3 are LED's. The array "melody" contains notes that will play. "beats" contains relative durations of the notes. I used "16" for an eighth-note. "lights" contains a list of the LED's that light up with each corresponding note. A 4 in this array means no light.

Look in the comments at the bottom if you want the melody, beats, and lights arrays for Frosty the Snowman and Jingle Bells.
/* Play Melody
 * -----------
 *
 * Program to play a simple melody
 *
 * Tones are created by quickly pulsing a speaker on and off 
 *   using PWM, to create signature frequencies.
 *
 * Each note has a frequency, created by varying the period of 
 *  vibration, measured in microseconds. We'll use pulse-width
 *  modulation (PWM) to create that vibration.

 * We calculate the pulse-width to be half the period; we pulse 
 *  the speaker HIGH for 'pulse-width' microseconds, then LOW 
 *  for 'pulse-width' microseconds.
 *  This pulsing creates a vibration of the desired frequency.
 *
 * (cleft) 2005 D. Cuartielles for K3
 * Refactoring and comments 2006 clay.shirky@nyu.edu
 * See NOTES in comments at end for possible improvements
 */

// TONES  ==========================================
// Start by defining the relationship between 
//       note, period, &  frequency. 
int  c4  =   3830;    // 261 Hz 
int  d4  =   3401;     // 294 Hz
int  e4  =   3038;    // 329 Hz 
int  f4  =   2864;    // 349 Hz 
int  g4  =   2550;    // 392 Hz 
int  a4  =   2272;    // 440 Hz 
int  b4  =   2028;    // 493 Hz 
int  c5  =   1912;    // 523 Hz 
// Define a special note, 'R', to represent a rest
int  R  =   0;

// SETUP ============================================
// Set up speaker on a PWM pin (digital 9, 10 or 11)
int speakerOut = 0;
// Do we want debugging on serial out? 1 for yes, 0 for no
int DEBUG = 0;

void setup() { 
  pinMode(speakerOut, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  
}

// MELODY and TIMING  =======================================
//  melody[] is an array of notes, accompanied by beats[], 
//  which sets each note's relative length (higher #, longer note) 
int melody[] = {  g4,  a4,  g4,  e4,  c5,   a4,  g4,  g4,  a4,  g4, a4, g4,  c5,  b4,  f4,  g4,  f4,  d4, b4, a4, g4, g4, a4, g4, a4, g4, a4,  e4,  R};
int beats[]  = { 16, 16, 32,  32,  32,  32, 96, 16, 16, 16, 16, 32, 32, 128, 16, 16, 32, 32, 32, 32, 96, 16, 16, 16, 16, 32, 32, 128, 128};
                  
// pin numbers of corresponding lights, or "4" if no light
int lights[] = { 3, 1, 2, 1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 1, 3, 2, 3, 1, 2, 3, 1, 3, 2, 1, 3, 2, 1, 2, 4};   
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.

// Set overall tempo
long tempo = 15000;
// Set length of pause between notes
int pause = 1000;
// Loop variable to increase Rest length
int rest_count = 100; //<-BLETCHEROUS HACK; See NOTES

// Initialize core variables
int tone_ = 0;
int beat = 0;
long duration  = 0;

// PLAY TONE  ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone() {
  long elapsed_time = 0;
  if (tone_ > 0) { // if this isn't a Rest beat, while the tone has 
    //  played less long than 'duration', pulse speaker HIGH and LOW
    while (elapsed_time < duration) {

      digitalWrite(speakerOut,HIGH);
      delayMicroseconds(tone_ / 2);

      // DOWN
      digitalWrite(speakerOut, LOW);
      delayMicroseconds(tone_ / 2);

      // Keep track of how long we pulsed
      elapsed_time += (tone_);
    } 
  }
  else { // Rest beat; loop times delay
    for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
      delayMicroseconds(duration);  
    }                                
  }                                 
}

// LET THE WILD RUMPUS BEGIN =============================
void loop() {
  // Set up a counter to pull from melody[] and beats[]
  for (int i=0; i<MAX_COUNT; i++) {
    tone_ = melody[i];
    beat = beats[i];

    duration = beat * tempo; // Set up timing
    if(lights[i] != 4)
    {
      digitalWrite(lights[i],HIGH);
    }
    playTone(); 
    if(lights[i] != 4)
    {
      digitalWrite(lights[i],LOW);
    }
    // A pause between notes...
    delayMicroseconds(pause);

    
  }
}

/* Notes for FROSTY THE SNOWMAN
int melody[] = { g4, e4, f4, g4, c5, b4, c5, d5, c5, b4, a4, g4, b4, c5, d5, c5, b4, a4, a4, g4, c5, e4, g4, a4, g4, f4, e4, f4, g4, R};
int beats[]  = { 64, 48, 16, 32, 64, 16, 16, 32, 32, 32, 32, 96, 16, 16, 32, 32, 32, 16, 16, 32, 32, 32, 16, 16, 32, 32, 32, 32, 128, 128 };
                  
// pin numbers of corresponding lights, or "4" if no light
int lights[] = {1, 3, 2, 3, 1, 2, 3, 1, 2, 1, 3, 2, 1, 2, 3, 2, 1, 3, 2, 3, 1, 2, 1, 3, 2, 1, 3, 1, 2, 4 };   
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.

// Set overall tempo
long tempo = 10000;
*/

/* Notes for JINGLE BELLS
int melody[] = {  e4,  e4,  e4,  e4,  e4,   e4,  e4,  g4,  c4,  d4, e4, f4,  f4,  f4,  f4,  f4,  e4,  e4, e4, e4, e4, d4, d4, e4, d4, g4,
                  e4,  e4,  e4,  e4,  e4,   e4,  e4,  g4,  c4,  d4, e4, f4,  f4,  f4,  f4,  f4,  e4,  e4, e4, e4, g4, g4, f4, d4, c4, R,};
int beats[]  = { 16, 16, 32,  16,  16,  32, 16, 16, 24, 8, 64, 16, 16, 24, 8, 16, 16, 16, 8, 8, 16, 16, 16, 16, 32, 32,
                  16, 16, 32,  16,  16,  32, 16, 16, 24, 8, 64, 16, 16, 24, 8, 16, 16, 16, 8, 8, 16, 16, 16, 16, 64, 128};
// pin numbers of corresponding lights, or "4" if no light
int lights[] = { 1,   2,  3,  1,  2,  3,  1, 2, 3, 1, 3, 1, 2, 3, 2, 1, 3, 1, 2, 3, 2, 1, 2, 3, 1, 3, 
                 1,   2,  3,  1,  2,  3,  1, 2, 3, 1, 3, 1, 2, 3, 2, 1, 3, 1, 2, 3, 2, 1, 2, 3, 1, 4,};  
int MAX_COUNT = sizeof(melody) / 2; // Melody length, for looping.

// Set overall tempo
long tempo = 15000;
*/

Credits

Dawn Dupriest

Dawn Dupriest

4 projects • 5 followers
Middle School Computer Science teacher, Feminist, Maker. 2012 Poudre School District Teacher of the Year. 2016 Allen Distinguished Educator.

Comments