Concept
For this week’s assignment, we decided to create a make-shift piano using the DIY aluminum foil compression button we used in previous assignments. The piano only plays one song; each time you press one of the piano “keys,” the next note in the sequence plays.
For the analog input, we used a potentiometer to control the pitch/frequency of the notes.
Demo:
Implementation:
We created 3 foil switches, taping one side of each switch to GND and the other to a digital pin. Then, we connected the buzzer and potentiometer.
For the code, we used sound files from the same Github repo we used in class. I used the notes for the song “It’s a Small World.”
On every loop iteration, it reads the state of all three buttons and checks if any of them just transitioned from unpressed to pressed, if a button was HIGH last loop and is LOW now, that counts as a single press.
void loop(){
//...
bool justPressed = (state_yellow == LOW && prev_yellow == HIGH)
|| (state_blue == LOW && prev_blue == HIGH)
|| (state_red == LOW && prev_red == HIGH);
//...
}
When a press is detected, it looks up the current note’s frequency and duration from two parallel arrays, scales the frequency up or down based on the potentiometer reading, plays it through the buzzer, waits for it to finish, then advances to the next note in the melody. The previous button states are saved at the end of every loop so the next iteration can do the same comparison, ensuring each physical press only ever triggers one note no matter how long you hold it down.
Initially, I had the code so that the note plays every time the button is pressed; however, this was causing the entire melody to continuously play as long as the button is pressed. So, we had to come up with a different way to ensure a note is only played when the button changes from unpressed to pressed.
Due to the way the foils are made, it does appear that only one note is playing when the button is pressed. Sometimes when I press the foil button, the foil may touch from one side by accident, or the wires may move which closes and opens the circuit without my intent. Therefore, the device appears to still be playing multiple notes at once but it eventually pauses.
We had to figure out a way to change the pitch of the notes without completely changing what the note was. Since there is a trend among the notes where if you want to move from a note from higher pitch to a lower or vice versa, the note’s pitch value/frequency would need to either be divided by 2 or multiplied by 2.
For example: standard Do sound = C4; a lower pitch would be C3. The difference between the pitch of the two is that C4 is double C3
For that we mapped the potentiometer’s input values (0, 1023) to (50, 200) and divided by 100, this allows us to shift between notes and their pitches smoothly using the potentiometer.
We multiplied this factor to the original note that would have been played and set the tone to include the multiplied value as the frequency in the tone statement.
void loop(){
float pitchMultiplier = map(pot_value, 0, 1023, 50, 200) / 100.0;
}
Reflection:
Reflecting on the issue of the foils touching and playing more notes than I want them to, I thought of a way to fix them using cloth pins. I can attach two foils to the inside of the end you use to open the pin, so when you are opening the pin, the foils touch and it counts as a “press.” I imagine this method to function more smoothly than the sponge compression I built for this assignment because the cloth pin is stable and forces the foils away from each other after every press.
