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);
}
}






Nice performance! Twinkle twinkle little strange star…. Great job!