Sunday, December 14, 2014

Christmas Hat Debut

Hour of Code last week kept me very busy most of last week working with students and teachers from throughout Vermont.  But It also inspired me to keep working on my Christmas hat.  And today  the hat made its first appearance in public.  I wore it to  visit my friends Deb and Frank, and also wore it out to dinner.

I finished some  last minute changes and solidified the connections with a little soldering.   Here is the current state of The Christmas Hat
1) The Pom Pom lights up green and stays lit
2) The LED's on the body of the hat will stay lit unless the music is playing. Then they will blink in beat with the music.  (originally they sequenced, but that interfered with reading the switch in a timely manner.
3) I got the hat working where I started the music by turning a slider Switch on. I wanted something more subtle.  So I changed it to use a TILT sensor.  And that sort of worked! But the sensor was so sensitive that I switched the program so that the sensor actually turned off the hat.
4) Eventually I decided that I needed a way to have a MUSIC mode  and a NON Music Mode and that the TILT switch would only turn on the Music if the SWITCH for MUSIC Mode was on.  This involved setting up both sensors in serial.    Now I can leave the Switch ON  if I want to 'try to control my hat via tilt" which is just to prove that it can do it and I can turn the Switch Off if I want to STOP annoying my friends by accidentally triggering Christmas buzzer music.
5)  I added a few 3D printed snowflakes and off I went.

As we were leaving for my friends house, the  hat stopped working.  Turns out the lilo battery had drained.  A quick battery change had the hat working for another few hours.   I learned soo soo much doing this project.   On the three hour drive down,  I decided to clean up and document my code.

int speakerPin = A5;  // Buzzer is connected to Pin A5 on LED
int switchPin = A3; // Tilt Sensor is connected to digital pin A3

int ledPom = 6;   // LEDS in the pom pom positive lead connected to pin 6
int led1 = 5;     // LED string 1 is connected to pin 5                       
int led2 = 10;    // LED string 2 is connected to pin 10                       
int led3 = 11;    // LED string 3 is connected to pin 11                      
int led4 = 9;     // LED string 4 is connected to pin 9                       

// next line is not necessary but helpful in troubleshooting
int ledPin = 13; // LED on the Lilypad is connected to digital pin 13 on Lilypad board

// next we need to set up some variables that will keep track of information for us while program runs

int switchValue; // a variable to keep track of when switch is pressed or tilt sensor activated
const int beatLength = 50;  //what is the beat you want for the music
int ledPattern = true;  //check back on this

//int songChoice; 

//------------ this part runs once when you start the program

void setup()  
        // set the speakerPin to be an OUTPUT
          pinMode(speakerPin, OUTPUT);
        // sets all the ledPins to be an output
          pinMode(ledPin, OUTPUT);
          pinMode(led1, OUTPUT);
          pinMode(led2, OUTPUT);
          pinMode(led3, OUTPUT);
          pinMode(led4, OUTPUT);
          pinMode(ledPom, OUTPUT);

      // sets the Switch Pin or tilt sensor to be an input and send it a SIGNAL positive 
        pinMode(switchPin, INPUT); // sets the switchPin to be an input
        digitalWrite(switchPin, HIGH); // sets the default (unpressed) state of switchPin to HIGH
} // end of the SETUP routines  
void loop() // this part of the program runs  over and over again
    digitalWrite(ledPom, HIGH); //turn on 3 green leds in pom pom    
  //check to see whether the switch or tilt is on
    switchValue = digitalRead(switchPin); // check to see if the Switch/tilet is pressed
      if (switchValue == LOW) { // if the switch is not pressed or tilted 
          digitalWrite(ledPin, HIGH); // turn the LED on lilypad on for troubleshooting    
          playTune();  // to do the music functions and blinking

      else { // otherwise,
          digitalWrite(ledPin, LOW); // turn the lilypad  LED off
           sequenceLeds() ;   // display the LEDs according to the sequence function
     } // end  of if else         

} // end of the VOIDE Loop

//-------------------- the functions are below -------------------------------------------
// this function makes your LED blink; it gets called in the middle of playing the music 

void alternateLeds() 

        if (ledPattern == true) {
            digitalWrite(led1, LOW);
            digitalWrite(led2, HIGH);
            digitalWrite(led3, LOW);
            digitalWrite(led4, HIGH);
            ledPattern = false;  // keeps tract of where blinking left off

        } else {

            digitalWrite(led1, HIGH);
            digitalWrite(led2, LOW);
            digitalWrite(led3, HIGH);
            digitalWrite(led4, LOW);
            ledPattern = true;  //keeps tract of where blinking left off
        } // end of if else
} // end of alternateLED function

// this function tells the program what to do with the LED lights when not playing music
// I have them all lit for now

void sequenceLeds() 


    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
 }  // stop sequence function 

Play music functions The next few functions are all needed for music to play
This is a pretty complex group of related function for playing music and was set up so that you can add 
code that will let you play several different songs.  I took that part out


//this is the function that starts tells the buzzer to make a sound and long to make that sound
// can I put the alternate blink here 

void playTone(int tone, int duration) {

      for (long i = 0; i < duration * 1000L; i += tone * 2) {
      digitalWrite(speakerPin, HIGH);
      digitalWrite(speakerPin, LOW);
          } //end the for loop
    }  //end the playTone function

//teach Lilypad how to play music ~ what the notes and sharps sound like and play that sound for each note in my song 

void playNote(char note, int duration, boolean sharp) {

  char names[] ={'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'D', 'E', 'F', 'G', 'A', 'B' };
  int tones[]  = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956, 851, 758, 716, 636, 568, 506 };
  char names_sharp[] = { 'c', 'd', 'f', 'g', 'a', 'C', 'D', 'F', 'G', 'A' };
  int tones_sharp[] = { 1804, 1607, 1351, 1204, 1073, 902, 804, 676, 602, 536 };

    if (sharp == false) {
        for (int i = 0; i < 14; i++) {
            if (names[i] == note) {
            playTone(tones[i], duration);
          }//end the for loop

     } else {
        for (int i = 0; i < 10; i++) {
            if (names_sharp[i] == note) {playTone(tones_sharp[i], duration);
        }// end the for loop
    } // end the if else routine

} // end the playNote function

//----- what song do you want to play and what what notes and beats make up that song

void playTune () {

 // Jingle Bells notes and beats

    char notes[]="b4b4b8b4b4b8b4D4g6a2b12,4C4C4C6C2C4b4b4b2b2b4a4a4b4a8D8b4b4b8b4b4b8b4D4g6a2b12,4,C4C4C6C2C4b4b4b2b2D4D4C4a4g12,8.";

    parseTune(notes, beatLength, false); // send these notes and beats to the parseTune function

}// end of play Tune function

//this function actually figures out which note to play, how long to play it and if its a sharp or not

void parseTune(char notes[], int beatLength, boolean loopSong) {boolean play = true;

  for (int i = 0; notes[i] != '.' && play == true; i++) {  //do the for loop til I run out of notes

     alternateLeds();  //go do the function that makes the LEDs blink then continue below

  if (notes[i] == ',') {
      char len[3];
      int count = 0;

  while (notes[i+1] >= '0' && notes[i+1] <= '9' && count < 2) {
      len[count] = notes[i+1];
      len[count] = '\0';
      int duration = atoi(len);
      delay(duration * beatLength);

  } else {

//alternateLeds();  erase this I think..cause I did it on top of the loop 

  char note = notes[i];
  boolean sharp;

    if (notes[i+1] == '#') {
      sharp = true;
    } else {
      sharp = false;

    char len[3];
    int count = 0;
    while (notes[i+1] >= '0' && notes[i+1] <= '9' && count < 2) {
        len[count] = notes[i+1];
    }len[count] = '\0';
      int duration = atoi(len);
      playNote(note, duration * beatLength, sharp);  // go ahead and do the Play Note function
      delay(beatLength / 2);

}  // end of the parse tune function

// This is the end of the group of music functions

1 comment:

  1. This is fantastic! I am too overwhelmed by what you wrote to look at your code right now! Nice work! I want my project to have a musical and non-musical mode, too.