CONCEPT
The concept of our instrument is to automatically play a predefined tune (Mary had a little lamb) when the grey button is pressed and also be able to control the speed at which the tune is played. We wanted the Servos to directly play the tune which is why we incorporated them in such a way in the circuit that enabled them to press the switches and play the tune.
SCHEMATIC
#include <Servo.h> #include "pitches.h" Servo servo1; //controls red and green Servo servo2; //controls yellow and blue const int potentiometer = A0; //controls tempo const int grey = 6; //controls power const int red = 2; //C3 const int green = 3; //E3 const int yellow = 4; //D3 const int blue = 5; //G3 int melodySize = 27; int melody[] = { green, yellow, red, yellow, green, green, green, yellow, yellow, yellow, green, blue, blue, green, yellow, red, yellow, green, green, green, green, yellow, yellow, green, yellow, red, 0 }; int duration[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4 }; void setup() { Serial.begin(9600); servo1.attach(10); servo1.write(90); servo2.attach(9); servo2.write(90); delay(10); pinMode(red, INPUT_PULLUP); pinMode(green, INPUT_PULLUP); pinMode(yellow, INPUT_PULLUP); pinMode(blue, INPUT_PULLUP); pinMode(grey, INPUT_PULLUP); } void loop() { //press the button to start the melody if (!digitalRead(grey)) { delay(500); for (int i = 0; i < melodySize; i ++) { if (!playTone(melody[i], duration[i])) { //continue if true, stop if false //press the button during the melody to stop delay(500); break; } } } delayAndPlay(100); //so that user can play their own music } bool playTone(int color, int duration) { //move the servo if (color == green) { servo1.write(30); } if (color == red) { servo1.write(140); } if (color == yellow) { servo2.write(30); } if (color == blue) { servo2.write(140); } int interval = map(analogRead(potentiometer), 0, 1023, 200, 500); bool off = delayAndPlay(interval * duration); //restore the position servo1.write(90); servo2.write(90); //return false if button press is detected return (off && delayAndPlay(100 * duration)); } bool delayAndPlay(long interval) { long currentTime = millis(); for (long i = millis(); i < currentTime + interval; i = millis()) { //if button is pressed during the melody, stop immediately if (!digitalRead(grey)) { return false; } //make the tone if (!digitalRead(red)) { tone(8, NOTE_C3, 10); } if (!digitalRead(green)) { tone(8, NOTE_E3, 10); } if (!digitalRead(yellow)) { tone(8, NOTE_D3, 10); } if (!digitalRead(blue)) { tone(8, NOTE_G3, 10); } } return true; }
BEHAVIOR
We used two servos as our music players. We attached two long arms to each servo and each end of the arm falls on one of the four buttons on our breadboards. Each button corresponds to a different note that is played by the speaker.
PROBLEMS
1. We needed the servo to hit the respective switches from a higher level than the switch itself. However, it was very hard to find a material that was high enough as well as strong enough to support the movement of the servo. We tried to use different materials like cardboard, wood, styrofoam, plastic boxes, etc. but none of them worked very well except for the wooden block. Even with the wooden block, if it wasn’t in the correct position, the servo would not hit the switch at the correct angle and the note would not be played which would interrupt the flow of the song.
2. There was a problem with using the pushbutton to stop the tune while it is playing. The programme would run so fast that when the button was pressed to stop the tune, the tune would stop but it would immediately restart the loop. Since the finger had not been removed from the button fast enough, it would start playing again so it sounded like the song would not stop at all and just restart when the button was pressed. The solution for this was to include a delay after the command for stopping the tune.