Week 10 – Musical Instrument

Concept

For this project, I really wanted to make use of the servo motor in some way to produce sound. After fiddling around for quite some time, I found that the lid of my scented candle was the right place to put the motor. I noticed that it made an interesting sound when it dragged against the lid. This, along with an LDR, pushbutton, and sonar sensor are what I used to create my musical instrument.

Implementation

I wanted some way to control the speed at which the servo motor operated to produce a different background noise that the user could control. I also wanted to make it as convenient as possible for the user to operate it since the other hand was supposed to move in front of the sonar sensor to produce notes. So I decided to use an LDR sensor to control the servo motor’s speed. The brighter it gets, the greater the speed of the motor. Since I wanted to make it convenient, I used my phone’s torch and varied its brightness from a distance to control the speed of the motor. In the meanwhile, my other hand controlled the different notes that were being played on the buzzer.

I used an array of notes to store the different tones I was going to play based on the user’s hand position. The distance from the sensor was mapped to the indices of the notes array.

I also made use of a pushbutton to turn the motor off if the user wanted to. While the button is pressed, the motor won’t run. I did this because the other way around would have been to press the button to make the motor run, which would have been inconvenient for the user since they also have to use the light at the same time to control the motor’s speed.

The code I used for this project can be found below:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position
int servoSpeed = 2; // variable to change servo speed based on light

// variables for sonar sensor
int trig = 10;
int echo = 11;
long duration;
long distance;

// variable for pushbutton position
int buttonPin = 2;
// variable for button HIGH or LOW
int buttonState = 0;

void setup() {
  // attaches the servo on pin 9 to the servo object
  myservo.attach(9);  
  // setting the echo and trig pins of the sonar sensor
  pinMode(echo, INPUT);
  pinMode(trig, OUTPUT);
  // setting up the pushbutton
  pinMode(buttonPin, INPUT);
  Serial.begin(9600); // for debugging
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // Serial.println(buttonState);

  //getting distance from the sonar sensor
  digitalWrite(trig, LOW);
  delayMicroseconds(2);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = (duration / 2) * 0.0344;

  // creating an array of frequencies
  // int notes[7] = {261, 294, 329, 349, 392, 440, 494};
  int notes[7] = {523, 587, 659, 698, 784, 880, 988};

  // if the hand is away from the sonar sensor
  if (distance < 0 || distance > 30) {
    // mute the sound
    noTone(12); 
  }

  // else play the tones
  else {
    // map the distance of the hand to the indices of the notes array
    int sound = map(distance, 0, 30, 0, 6);  
    // play the specific note
    tone(12, notes[sound]); 
  }

  // reading from the LDR
  int sensorValue = analogRead(A0);
  // Serial.println(sensorValue);
  // // delay(1);

  // setting the speed of the servo motor based on light intensity
  if (sensorValue < 102) {
    servoSpeed = 1;
  }
  else if (sensorValue < 130) {
    servoSpeed = 2;
  }
  else {
    servoSpeed = 3;
  }

  // making the servo motor move
  if (buttonState == LOW) {
    for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos); // tell servo to go to position in variable 'pos'
      delay(servoSpeed);  // waits 15ms for the servo to reach the position
    }
    for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos); // tell servo to go to position in variable 'pos'
      delay(servoSpeed);  // waits 15ms for the servo to reach the position
    }
  }
}


Challenges

The most challenging aspect for me in this project was to decide how to make the instrument operate. The decision to use the LDR to control the motor’s speed, making use of the pushbutton to control whether the motor was running or not, and using the sonar sensor instead of something like a potentiometer. Making the instrument work is one aspect, but putting everything together in a logical manner that would be easy enough to operate and at the same time sound decent enough was somewhat challenging. Nevertheless, I learned a lot about the piezo buzzer and producing sounds in general using the Arduino in this homework, and it was fun to do.

The Instrument

Leave a Reply