The Automatic Tune Player — Diya and Bowen

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

PROGRAM

#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. 

Leave a Reply

Your email address will not be published. Required fields are marked *