Skip to content

Week 10 Output Devices

My notes from Fab Academy lecture on Outputs can be found here: class lecture notes

In class Mr. Dubick went over stepper motors, and gave us this summary reference guide. Stepper Motors

group assignment:

  • measure the power consumption of an output device

Click to go to our group page

I just noticed I am wearing the same shirt today, as we worked on week 10's group assignment as I did in week 9's photos! But my hair tie is black today.

Camille and I created boards and codes to test a fan and buzzer respectively.

I created this code, in Arduino IDE, based off my own testing. It plays the C_5 note, and turns on the light when the light sensor reads below 500. It plays the C_4 note, and turns off the light when the light sensor reads above 500. It also prints the sensor reading and either “Light on.” or “Light off.” so we can see what should be happening. The sensor, led and speaker are all attached to different pins on the Seeed XIAO RP2040 so they should not affect the readings taken on the speaker path. Within the code are integers for other music notes in case we wanted to make a song.

Code for group output buzzer:

int buzzPin = 1;
int led = 4;
int too_dark = 500;
int stop = 500;
int sensorPin = A0;
int sensorValue;
int button = 3;
// Octave 3
float C_3  = 130.81;
float Csharp3 = 138.59;
float D_3  = 146.83;
float Dsharp3 = 155.56;
float E_3  = 164.81;
float F_3  = 174.61;
float Fsharp3 = 185.00;
float G_3  = 196.00;
float Gsharp3 = 207.65;
float A_3  = 220.00;
float Asharp3 = 233.08;
float B_3  = 246.94;


// Octave 4 (Middle C)
float C_4  = 261.63;
float Csharp4 = 277.18;
float D_4  = 293.66;
float Dsharp4 = 311.13;
float E_4  = 329.63;
float F_4  = 349.23;
float Fsharp4 = 369.99;
float G_4  = 392.00;
float Gsharp4 = 415.30;
float A_4  = 440.00;
float Asharp4 = 466.16;
float B_4  = 493.88;


// Octave 5
float C_5  = 523.25;
float Csharp5 = 554.37;
float D_5  = 587.33;
float Dsharp5 = 622.25;
float E_5  = 659.26;
float F_5  = 698.46;
float Fsharp5 = 739.99;
float G_5  = 783.99;
float Gsharp5 = 830.61;
float A_5  = 880.00;
float Asharp5 = 932.33;
float B_5  = 987.77;


int eighthNote  = 167;   // ms
int quarterNote = 334;   // ms
int halfNote    = 668;   // ms
int wholeNote   = 1336;  // ms


void setup() {
pinMode(buzzPin, OUTPUT);
pinMode(led, OUTPUT);
Serial.begin(9600);
pinMode(sensorPin, INPUT); // Set sensorPin as an INPUT
}


void loop() {
 sensorValue = analogRead(sensorPin);
 sensorValue = map(sensorValue, 0, 1024, 1024, 0);
 Serial.println(sensorValue);


 if(sensorValue > too_dark) {
   digitalWrite(led,HIGH);
   Serial.println("Light on.");
   digitalWrite(buzzPin, HIGH);
   tone(buzzPin, C_5, quarterNote);
   delay(quarterNote);
 }


 else {
   digitalWrite(led,LOW);
   Serial.println("Light off.");
   digitalWrite(buzzPin, LOW);

   tone(buzzPin, C_4, quarterNote);
   delay(quarterNote);
 }
}

At the same time, Camille and Kim set up the motor board with her small hobby motor with a fan attachment. Camille wrote her code and asked Yellow Belt Code Master Kim to review the code and help her get the motor spinning.

After we had both boards set up and ready for testing, as a group we tested one board at a time using a multi meter. We started with the buzzer board.

We tested the current for the speaker at the 2 different output notes by breaking the circuit, and then connecting the multimeter in series. The current was measured as 15.16mA when the output note was C4, LED off, and 15.33mA when the output note was C5, LED on. There was a difference in the voltage drop of only 0.007V between the two notes. The calculated power was 0.00347W for C4/LED off, and 0.00356W for C5/LED on.

It is interesting to see that more power was consumed to make the higher pitched sound.

The way this speaker works is that the piezo crystal compresses when voltage is applied. This moves the attached disk to create a sound. The higher the frequency of the movement, the higher the pitch of the sound.

We also tested the fan that Camille created. The results found on our group page show the power consumption was less than expected. However, the current was also less than expected as a quick search showed a 3V motor using 60mA current, and we only tested 49mA being drawn. So I believe our testing was accurate.

individual assignment:

  • add an output device to a microcontroller board you've designed,
     and program it to do something

I have been wanting to play with piezo anything since learning what a piezo crystal was last year. (Girl Scout encampment was themed "Camp Rocks," and we used quartz, a piezo crystal, make cold fire sparks. It is used to create a spark to light butane fuel in the long lighters too. I took one apart, and connected an led so that when the scouts clicked the lighter the red led would flash on to show how it worked.)

David found a piezo buzzer in the fab lab for me. Paul McWhorter's tutorial Arduino Tutorial 24: Understanding Passive Buzzers explains how to use the buzzer.

In the tutorial he explains that there are passive and active buzzers. You can see the green board on the passive buzzers, and the active buzzers have black tape on the back. (I hope this is a general rule, and not just for the ones in his kit.)

passive buzzer back

So my board is likely a passive buzzer, which means I must turn it on and off to make it buzz.

I pulled up my schematic so that I could easily program.

idea-pcb schematic

Which actually isn't very helpful, so I used CorelDraw to make this:

idea-pcb-pins

I also created this image to easily convert between the XIAO RP2040 and ESP32-C6, because they both have the same footprint.

XIAO RP2040 -vs- ESP32-C6

I also found this music note tone list from another youtube tutorial. Arduino: How to Use a Piezo Buzzer by Sam's Neat Projects.

music note tones

music notes from notebusters.net

Musicscore.com has lots of sheet music, and plays it for you to hear.

  • In this tutorial he used the code
    void loop(){
    tone(Pin,Frequency,Duration)
    delay(buzzTime)
    }
    
    where as McWhorter writes his code using
    void loop(){
    digitalWrite(buzzPin, HIGH);
    delayMicroseconds(buzzTime);
    digitalWrite(buzzPin,LOW);
    delayMicroseconds(buzzTime);
    }
    

This is my code as I was testing 3 different ways to code notes. I will be cleaning it up for the final code, but I want it here for reference later. When the light is on a scale is played. When the light is off, it was supposed to play the "game over" song from Mario, but it sounds nothing like it.

int buzzPin = 1;
int buzzTime = 1;
int buzzTime2 = 500;
int sensorPin = A0;
int sensorValue;
int led = 4;
int too_dark = 500;
int stop = 500;
float midC = 261.;
float Csharp = 277.;
float G_4 = 523.63;
float C_5 = 523.25;
float E_4 = 329.63;
float A_4 = 440.00;
float B_4 = 493.88;
float Gsharp4 = 415.30;
float Asharp4 = 466.16;
float C_4 = 261.63;
float D_5 = 587.33;
float F_5 = 698.46;
float D_4 = 293.66;
int eighthNote = 167;
int fourthNote = 334;
int thirdNote = 222;
int wholeNote = 835;


void setup() {
  // put your setup code here, to run once:
pinMode(buzzPin, OUTPUT);
pinMode(led, OUTPUT);
Serial.begin(9600);
pinMode(sensorPin, INPUT); // Set sensorPin as an INPUT
}

void loop() {
  // put your main code here, to run repeatedly:

  sensorValue = analogRead(sensorPin); 
  sensorValue = map(sensorValue, 0, 1024, 1024, 0);
  Serial.println(sensorValue);

  if(sensorValue > too_dark) {
    digitalWrite(led,HIGH);
    Serial.println("I have an idea!");
    digitalWrite(buzzPin, HIGH);
//delayMicroseconds(buzzTime2);
//digitalWrite(buzzPin,LOW);
//delayMicroseconds(buzzTime2);
    //tone(buzzPin, 261); //middle C
    delay(buzzTime2);
    tone(buzzPin, 277); //C#
    delay(buzzTime2);
    tone(buzzPin, 294); //D
    delay(buzzTime2);
    tone(buzzPin, 311); //D#
    delay(buzzTime2);
    tone(buzzPin, 330); //E
    delay(buzzTime2);
    tone(buzzPin, 349); //F
    delay(buzzTime2);    
    tone(buzzPin, 370); //F#
    delay(buzzTime2);
    tone(buzzPin, 392); //G
    delay(buzzTime2);
    tone(buzzPin, 415); //G#
    delay(buzzTime2);
    tone(buzzPin, 440); //A
    delay(buzzTime2);

    delay(stop);

  } else {
    digitalWrite(led,LOW);
    Serial.println("I see more research is needed.");
    digitalWrite(buzzPin, LOW);
    tone(buzzPin,C_5,fourthNote); 
    delay(fourthNote);
    tone(buzzPin, G_4, fourthNote); 
    delay(fourthNote);
    tone(buzzPin, E_4, fourthNote); 
    delay(fourthNote);

    tone(buzzPin, G_4, fourthNote); 
    delay(fourthNote);
    tone(buzzPin, B_4, fourthNote); 
    delay(fourthNote);
    tone(buzzPin, A_4, fourthNote); 
    delay(fourthNote);

    tone(buzzPin, Gsharp4, eighthNote); 
    delay(eighthNote);
    tone(buzzPin, D_4, eighthNote); 
    delay(eighthNote);
    tone(buzzPin, E_4, wholeNote); 
    delay(wholeNote);
 }
  delay(stop);
}

I tried to replicate the last bit of the Mario Brother's music from the YouTube video Super Mario bros on the Arduino Uno by Blammo, but it did not sound correct. Which may be because I am not using the Arduino Uno, but it shouldn't have been so off.

when I used claude to check my files before commiting, so I don't push large files or make big mistakes, it found an error in my mario code. My G_4 frequency should be 392.00 not 523.63. This is because I copied and pasted the code, then changed the numbers. I must have missed G_4. I will have to try it again later. It occered to me that if Claude noticed this mistake it likely would know the other notes as well. So I gave it this prompt:

"can you make a document "music-notes.md" in the week10-output-devices file that has a table of the frequencies to use for making music notes on the passive piezo speaker?"

Claude then made this document music-notes.md that I will use as a reference for future programing.

I don't like the sound repeating constantly, and the quotes being printed at every sensor reading. I sketched out what I wanted, and worked on programing it.

sketch

  • I had some difficulties with the loop
    • I tried if statements, if and, while
    • I used an integer to set to 1 or 0 instead of reading the led
    • I asked Claude to help me debug. It turns out I renamed the integer inside my loops instead of assigning it a new number. Then when I changed from using the integer to reading the led, I had forgotten the digitalRead command.
    • here is a link to my conversation with Claude so that it doesn't take up too much space here. Claude debug my buzzer

When I was taking a video of my project I noticed it was hard to see the printed words in the serial monitor because the sensor readings were too fast. I added a delay before the if statements so that the words would slowly scroll up the serial monitor to be seen in my videos.

My final code:

I left all the notes in the code so that I could easily make a song later.

int buzzPin = 1;
int buzzTime = 1;
int buzzTime2 = 500;
int sensorPin = A0;
int sensorValue;
int led = 4;
int too_dark = 500;
int stop = 500;
// Octave 3
float C_3  = 130.81;
float Csharp3 = 138.59;
float D_3  = 146.83;
float Dsharp3 = 155.56;
float E_3  = 164.81;
float F_3  = 174.61;
float Fsharp3 = 185.00;
float G_3  = 196.00;
float Gsharp3 = 207.65;
float A_3  = 220.00;
float Asharp3 = 233.08;
float B_3  = 246.94;

// Octave 4 (Middle C)
float C_4  = 261.63;
float Csharp4 = 277.18;
float D_4  = 293.66;
float Dsharp4 = 311.13;
float E_4  = 329.63;
float F_4  = 349.23;
float Fsharp4 = 369.99;
float G_4  = 392.00;
float Gsharp4 = 415.30;
float A_4  = 440.00;
float Asharp4 = 466.16;
float B_4  = 493.88;

// Octave 5
float C_5  = 523.25;
float Csharp5 = 554.37;
float D_5  = 587.33;
float Dsharp5 = 622.25;
float E_5  = 659.26;
float F_5  = 698.46;
float Fsharp5 = 739.99;
float G_5  = 783.99;
float Gsharp5 = 830.61;
float A_5  = 880.00;
float Asharp5 = 932.33;
float B_5  = 987.77;
int eighthNote = 167;
int fourthNote = 334;
int thirdNote = 222;
int halfNote = 668;
int wholeNote = 835;


void setup() {                                                                  
  // put your setup code here, to run once:                                     
pinMode(buzzPin, OUTPUT);                                                       
pinMode(led, OUTPUT);                                                           
Serial.begin(9600);                                                             
pinMode(sensorPin, INPUT); // Set sensorPin as an INPUT                         
}                                                                               

void loop() {                                                                                                                                      

  sensorValue = analogRead(sensorPin);                                          
  sensorValue = map(sensorValue, 0, 1024, 1024, 0);                             
  Serial.println(sensorValue);                                                  

  while (digitalRead(led) == LOW) {                                                          
    sensorValue = analogRead(sensorPin);                                        
    sensorValue = map(sensorValue, 0, 1024, 1024, 0);                           
    Serial.println(sensorValue);                                                

     if(sensorValue > too_dark) {                                               
      digitalWrite(led,HIGH);                                                   
      Serial.println("I have an idea!");                                        
      digitalWrite(buzzPin, HIGH);                                              

      tone(buzzPin, C_5, fourthNote);                                           
      delay(fourthNote);                                                        
      tone(buzzPin, D_5, fourthNote);                                           
      delay(fourthNote);                                                        

      delay(fourthNote);                                                        
      tone(buzzPin, F_5,fourthNote);                                            
      delay(fourthNote);                                                        

      delay(stop);

     }                                                                          
  }                                                                             

  while (digitalRead(led) == HIGH) {                                                         
    sensorValue = analogRead(sensorPin);                                        
    sensorValue = map(sensorValue, 0, 1024, 1024, 0);                           
    Serial.println(sensorValue);      
    delay(stop);                                          

    if(sensorValue < too_dark){                                                 
      digitalWrite(led,LOW);                                                    
      Serial.println("I see more research is needed.");                         
      digitalWrite(buzzPin, LOW);                                               

      tone(buzzPin, C_5, fourthNote);                                           
      delay(fourthNote);                                                        
      tone(buzzPin, A_4, fourthNote);                                           
      delay(fourthNote);                                                        

      delay(fourthNote);                                                        
      tone(buzzPin, F_4,fourthNote);                                            
      delay(fourthNote);                                                        

      delay(stop);                                                              
    }                                                                           
  }   
}

Problems & Solutions:

  • Milling my boards — finding time on the 2 machines currently working

  • I was having trouble loading my code onto my RP2040. I got help from Claude, and had it create a transcript linked here

    • my board needed to be reset by pressing reset and boot together

My board will not load unless it is connected in the exact same port!

  • I don't know how to read music. I had referenced the images above, and hoped for the best.
    • I guessed I might have trouble, and decided to name all the notes as variables (floats because they had decimals) so that I can change them if needed.
    • I will figure it out by ear.
  • C++ does not like using # when naming
    • I typed out sharp instead
  • C++ does not like a letter followed by a number when naming
    • I added a _ between them
  • I didn't like the sound repeating continually
    • I added a while loop so that when the light is on it will take action when the sensor is low, and if the light is off it will take action when the sensor is high.
  • My sensor stopped working correctly, which was confusing since it had been working correctly for 2 days.

    • it was a bad solder on D0, although it is hard to see in the picture, when I applied pressure, the sensor worked better

    bad solder D0

  • I had some difficulties with the loop

    • this is the correct coding for a while command
      if (digitalRead(button == LOW)) {
      digitalWrite(buzzPin, LOW);
      

      == is equal, != is not equal

  • I kept forgetting which pin connected to which part of my board. I used my multimeter to find the current, and trace it back. Then I looked up my pcb design, but they were confusing.

    • I fixed my confusion by labeling my headers, and having my pinout handy to convert D5 into GPIO7. labeled headers

Files for speaker board

peizo-buzzer-Edge_Cuts.gbr peizo-buzzer-F_Cu.gbr peizo-buzzer-Edge_Cuts.dxf peizo-buzzer-F_Cu.dxf

speaker-pcb