Class 8: Electronic Output Devices


Home


The assignment for this class was to choose an output device that I haven't used before and program a microcontroller to operate it. In class, most of us had experimented with LED strips in breakout rooms, but I never had the chance, as I was busy trying to make a more complicated melody using the buzzer. So I thought it would be a good idea for me to work with the LED strip for this assignment. Since I'm making a piano with the buzzer for my final project, I decided to combine the LED strip with the buzzer, and sync up the lights with some music.

The first step of this assignment was to build the circuit that had an LED strip and buzzer. Using Nathan's tutorial about buzzers and LED strips, I made this a simple circuit with a buzzer and then plugged the LED strip into the correct ports on the Metro board. The circuit looks like this:

circuit

The next step of this process was to make the music using the Ardiuno IDE and the buzzer. For my code, I first found a frequency chart for piano notes. I recorded the frequencies for each note from middle C up two octaves as constants in my code. Each note looked like this:


      const int c = 262;
      const int cS = 277;
      const int d = 294;
      const int dS = 311;
      

Next, I had to start making the first song. I wanted to choose something everyone would know, so I decided to remake Happy Birthday. I found the sheet music for the song, and started writing in each note. To make sure the duration was correct, I made the song a function in which one of the parameters was the beats per minute (bpm) of the song. By inputting the bpm, I realized that it was possible to mathematically determine the length of each note. A quarter note, which marks each beat. To calculate of the duration of a quarter note, I took 60,000 (the number of ms in a minute) and divided it by the bpm. For Happy Birthday, the bpm was 120, so this was 60,000 / 120 = 500 ms. From there, I could calculate the duration of all other necessary notes using my prior knowledge of how each note works. In the code, I had to do float division, as integer division returned 0. I casted the division to a float and then casted the result to an integer. The code looked like this:


      //60,000 because there's 60,000 ms in a minute
      quarterNoteDuration = (int) ((float) 60000 / bpm); //At 120 BPM a quarter note will have a duration of 500 ms
      halfNoteDuration = quarterNoteDuration * 2;                     
      dottedEigthNoteDuration = (int) (quarterNoteDuration * 0.75);       
      sixteenthNoteDuration = (int) ((float) quarterNoteDuration / 4);
      

Once I had each note duration recorded in a variable, I started making the song. To do so, I used the tone() function for the buzzer. I entered the buzzerPin for output, which note it would play, and whether it was a quarter note, half note, etc. After calling tone(), I then delayed the program by the duration of the note, as the tone function can run at the same time as other commands. Without the delay, it tries to play every note at the same time, which turns into a jumbled mess. Next, I repeated this process for each note of the song. I'm not going to paste all of the code for the notes because it's really repetitive, but here's an example of one note:


      tone(buzzerPin, d, quarterNoteDuration);
      delay(quarterNoteDuration);
      

After I put in each note of Happy Birthday, I tested it with the circuit (just with the buzzer, I hadn't done the LED yet) I liked how it sounded, but I decided to go even further and make a much longer and more complicated song. I played Mozart's Rondo Alla Turca on the piano a couple years ago, so I chose to remake the first section. Like Happy Birthday, I used the sheet music to code each note. Since the first section of the song repeats, I broke the song up into two functions, the first section and second section. Doing so allowed me to call the first section function twice to simulate the repeat. After fixing a few of the notes, I had a really great sounding song! This one took a lot more effort, as the song was longer and more complicated, but I think it sounds really good.


After successfully coding the songs to work with the buzzer, it was time to implement the LED. Using Nathan's LED strip tutorial, I read about how the LED strip works and how to code it. The first thing I did was add to both the beginning of my program and the setup() function. They ended up looking like this.


      #include 

      #define PIN        6 
      #define NUMPIXELS 10 
      #define DELAYVAL 500 // Time (in milliseconds) to pause between pixels

      Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

      int buzzerPin = 10;

      void setup() {  
        //Setup pin mode
        pinMode(buzzerPin, OUTPUT);

        strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
        strip.show();            // Turn OFF all pixels ASAP
        strip.setBrightness(10); // Set BRIGHTNESS low to reduce draw (max = 255)
      }
      

After setting up the LED, I decided to make a function that I could call after each tone() for the notes. I didn't want the LED strip to just display a color on the entire strip, but I instead decided to have it display a random color of the rainbow. To implement randomness, I found a website that detailed how the rand() function worked, as I've never worked in C before. After figuring how to generate a random number between 0 and a specficied number, I decided it would be best to put the rainbow RGB colors in a 2D array. I read this page on multidimensional arrays in C and used a chart of the RGB colors of the rainbow to make the 2D array of the colors of the rainbow. To actually make a random spot on the LED strip light up, I used the Adafruit NeoPixel function setPixelColor() to set the spot of the LED strip to light up and what color would appear. At this point, I realized something crucial. I could actually take the delay length as a parameter in the LED function, and delay it after lighting up the LED strip. Doing this would allow me to replace the delay after each note with a call to the LED function, in which the delay length is the note length. The final LED display function looked like this:


      void displayRandomLED(int delayLength){
        strip.clear(); // Set all pixel colors to 'off'

        //Array of the RGB values for each color of the rainbow
        int rainbowColors[7][3] = {{255, 0, 0}, {255, 127, 0}, {255, 255, 0}, {0, 255, 0}, {0, 0, 255}, {75, 0, 130}, {148, 0, 211}};

        //Chooses a random number 0-6 (index of each color of the rainbow)
        int rainbowCol = rand() % 7;

        //Chooses a random spot on the LED strip
        int ledSpot = rand() % 10;

        //Lights up the random spot on the LED strip using the random color of the rainbow
        strip.setPixelColor(ledSpot, rainbowColors[rainbowCol][0], rainbowColors[rainbowCol][1], rainbowColors[rainbowCol][2]);  
        strip.show();
        delay(delayLength);
      }
      

I didn't want to attach the entire code file because it was pretty lengthy, so here's the file if you want to download and view the entire thing: Code (.ino)

Once I tested this, I was really happy with how the LED strip worked with the buzzer. I recorded both songs, and here's the result (Happy Birthday on the left, Rondo Alla Turca on the right):


I learned a lot through this assignment. I worked with the LED strip for the first time and learned a lot of new things about the C programming language, specifically about multidimensional arrays and randomness. I also learned a lot more about how the tone function and buzzer worked, especially with timing the delays. This will all be very helpful as I work on my final project, and I feel much more prepared on the musical and coding side of things than I did prior to this. And I'm now thinking of adding a LED strip onto my piano if I can find room.