;-; I like playing instruments not making them

Description:

This is an instrument (don’t ask me the name) in which the user can play by utilizing a straight object and locating it at a certain position to play a note. The user can also distort that sound by turning the cup if so they wish.

Idea:

I actually got the inspiration from the clarinet. I wanted something that would be able to play in between the ranges of notes. However, at the end I think that I tried to simulate a piano more. I wanted to use the ultrasonic sensor to play the main notes and then have something similar to a pedal to change them. Now it is more of a distorter than a pedal, but the idea is there.

This is how the project looks like from the player’s perspective.

Process

I started by adding an ultrasonic sensor and a speaker to the circuit. (Please ignore the capacitor, it was there for class). I learned how to send and receive waves with the sensor in order to calculate distance. Afterwards, I made an array of sounds (middle C section) and mapped the distance to the number of notes in the array in order to assign a specific note to each distance. I then tested it out with my hand.

The sensor did not gave perfect values so there was a need to clean the information that it was getting. Even then there were still values that were off and I found it better to use a straight surface rather than my hand to make the sounds.

It was very difficult to control when a sound would change only with that so I added a button so that the instrument plays only when the button is pressed.

I thought that it would be interesting if the user could modify the pitch of the note by using some sort of additional feature and after much pondering, I decided to use the photosensor. To have better control of the amount of light received I choose to put the photosensor inside a cup. It was a very weird thing to do, specially with all the tape and I had to use female jumper wires for this.

Then I put it all together: the code for the ultrasonic sensor and that for the distortion (photosensor). This part was by far the hardest because merging them messed up some of the sounds and I had to find a way to make the notes sound normal when the photosensor is in the rest position. It took a lot of experimentation and debugging to get this part right. I still think there are better ways of doing what I did, but it works.

This is how it looked at the end:

For a better user experience, I decided to add the location of each of the notes as can be seen in the first image of this post.

Challenges:

SO MANY.  This was a very stressful process because one moment something was working and the next everything was crashing.

  • Figuring out what to do for the project in the first place.
  • My ultrasonic sensor throws random values most of the time, even when I refined the noise there still were some values that were off, but 7amdullah it didn’t interfere with the program that much for playing. I also used a straight surface rather than my hand to play from the distance sensor side which helped regulate the values.
  • Been able to play a melody without the program crashing
  • The button sometimes continued to read pressed even though it wasn’t (specially after a couple minutes of running the program).
  • Combining the distortion effect of the photosensor with the actual note been played from the distance.
  • Just figuring out how to do things in general. (So many ideas, so few good ones ;-; cries in Arduino)
  • I am very bad with tape and keeping the photosensor in contact with the wire.
  • I had other problems (as you will noticed from all the prints in my code) but I am so glad that it now works that I don’t want to remember the trauma.
  • Not my most aesthetic project: There are wires everywhere!

Circuit

*Note: in this image the ultrasonic sensor is inverted because I could’t flip its image. Furthermore, there is not cup for the photosensor since TinkerCad doesn’t have that feature

Final Result

Code

# include "pitches.h"

int echoPin = 5;                //pin of the echo of the distance sensor: receives the wave
int trigPin = 6;                //pin of the trigger of the distance sensor: sends the wave
long duration;                  //duration of sending and receiving the wave
long distance;                  //distance calculate by the sensor

int buttonPin = 2;              //pin of the button

const int numReadings = 10;     //number of readings to get the average

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int noteFreq = 0;               // the final frequency used to play the note

int photocensorPin = A0;        //pin of the photosensor
float photoValue;               //value received from the photosensor

void setup() {

  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);

  pinMode(buttonPin, INPUT);

  pinMode(photocensorPin, INPUT);


  //int notes[8] = {NOTE_C4,NOTE_D4,NOTE_E4,NOTE_F4,NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5};

  //int sound = 0;
  //tone(11, notes[sound]);

  // you have to round this
  // it allows you to access the
  //you go up one note to change to a Sharp/bemol
  // (pow(2,(noteNumber-69.)/12.)*440)

  // initialize all the readings to 0
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }

  Serial.begin(9600);
}

void loop() {

  //PROGRAMMING THE ULTRASONIC SENSOR---------------------------------------------------------

  //send the wave and receive it
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  //collect the data of the duration of the pulse
  duration = pulseIn(echoPin, HIGH);

  //convert the duration to distance
  //0.340 is the speed (centimeters per microseconds)
  distance = (duration / 2) * .0340;
  //Serial.println(distance);

  //GETTING VALUES FROM THE PHOTOSENSOR-------------------------------------------------------

  photoValue = analogRead(photocensorPin);
  //Serial.println(photoValue);

  int distortion = map(photoValue, 300, 800, 0, 50);

  //int noteNumber = map(photoValue, 0, 1023, 0, 120);
  //int note = (pow(2, (noteNumber - 69.) / 12.) * 440);
  // tone(11, note);


  //UPLOAD NOTES-----------------------------------------------------------------------------
  //make an array with the note pitches
  int notes[8] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5};

  //if the parst ten values are some note and it doesn't change, then leave that note
  //if the note changes for more than 3 than change the note

  //CHECK BUTTON STATE-----------------------------------------------------------------------
  bool currButtonState = digitalRead(buttonPin);
  //Serial.println(currButtonState);

  //PLAY INSTRUMENT--------------------------------------------------------------------------

  // if button is not pressed and distance is not within range, don't play anything
  if (distance < 0 && distance > 20 && !currButtonState)
  {
    noTone(11);
  }
  //play the note
  else
  {
    //this variable changed the distance to a value for the array
    int sound = map(distance, 0, 20, 0, 8);
    //Serial.println("Distance");
    //Serial.println(distance);
    //Serial.println("Sound");
    //Serial.println(sound);

    total = total - readings[readIndex];

    // read from the sensor:
    readings[readIndex] = sound;

    // add the reading to the total:
    total = total + readings[readIndex];

    // advance to the next position in the array:
    readIndex = readIndex + 1;

    // if we're at the end of the array...
    if (readIndex >= numReadings) {
      // ...wrap around to the beginning:
      readIndex = 0;
    }

    // calculate the average:
    average = total / numReadings;

    //Serial.print(sound);
    //Serial.print(" ");
    //Serial.println(average);

    //Serial.println(distortion);

    //Change NOTE FREQUENCY

    //if there it distortion
    if (distortion > 0, distortion < 50)
    {
      //add the distotion to the note
      noteFreq = notes[average] + distortion;
    }
    else
    {
      //just have the note without distortion
      noteFreq = notes[average];
    }

    //if button is pressed
    if (currButtonState)
    {
      //play the note
      tone(11, noteFreq, 100);
    }
    //tone(11, notes[average], 100);
    //Serial.println(average);
  }
}

 

One thought on “;-; I like playing instruments not making them”

Leave a Reply