Assignment:
This week we had to make a musical instrument with at least one analog and one digital input. At first I wanted to try and make a guitar or piano as I am more familiar with them and can play them in a limited sense. Looking at the supplies in our kits I realized a full on instrument with the limited sensors and space we had would be hard. I ended up implementing a sort of 4 string bass that could play a full range of notes that one would find on a standard 4 string bass.
Result:
To play my Arduino bass, you use the distance finder to set the fret where you would be placing your finger. You then can press one of the buttons at a time to represent plucking a string on the bass.
Attached is the note layout that I modeled
You can imagine that the Arduino is at the base of the bass and so moving your hand further away from the distance sensor would be like moving your hand further up the neck.
Playing:
While I intended for the musician to move their hand closer and further to change frets, I found that the distance measurement was less consistent this way and as a result harder to control. Instead I ended up placing a flat box and moving the Arduino relative to that. I also placed marks on the table for the first few frets that I would need to play a basic C scale.
Here are the results
Wiring
(As TinkerCAD’s distance sensor is a three pin version while we used four pins I just placed the wires where the sensor would go in the top left of the board)
Code:
#include "pitches.h" //Pins const int string1Pin = 2; //E string const int string2Pin = 3; //A string const int string3Pin = 4; //D string const int string4Pin = 5; //G string const int echoPin = 6; // Echo Pin of Ultrasonic Sensor const int pingPin = 7; // Trigger Pin of Ultrasonic Sensor const int buzzerPin = 8; bool stringOne = false; bool stringTwo = false; bool stringThree = false; bool stringFour = false; //20 fret (21 when including open strings) 4 string bass tuned to equal temperment tuning and standard pitch int fourStringBass[21][4] = { {NOTE_E1, NOTE_A1, NOTE_D2, NOTE_G2}, {NOTE_F1, NOTE_AS1, NOTE_DS2, NOTE_GS2}, {NOTE_FS1, NOTE_B1, NOTE_E2, NOTE_A2}, {NOTE_G1, NOTE_C2, NOTE_F2, NOTE_AS2}, {NOTE_GS1, NOTE_CS2, NOTE_FS2, NOTE_B2}, {NOTE_A1, NOTE_D2, NOTE_G2, NOTE_C3}, {NOTE_AS1, NOTE_DS2, NOTE_GS2, NOTE_CS3}, {NOTE_B1, NOTE_E2, NOTE_A2, NOTE_D3}, {NOTE_C2, NOTE_F2, NOTE_AS2, NOTE_DS3}, {NOTE_CS2, NOTE_FS2, NOTE_B2, NOTE_E3}, {NOTE_D2, NOTE_G2, NOTE_C3, NOTE_F3}, {NOTE_DS2, NOTE_GS2, NOTE_CS3, NOTE_FS3}, {NOTE_E2, NOTE_A2, NOTE_D3, NOTE_G3}, {NOTE_F2, NOTE_AS2, NOTE_DS3, NOTE_GS3}, {NOTE_FS2, NOTE_B2, NOTE_E3, NOTE_A3}, {NOTE_G2, NOTE_C3, NOTE_F3, NOTE_AS3}, {NOTE_GS2, NOTE_CS3, NOTE_FS3, NOTE_B4}, {NOTE_A2, NOTE_D3, NOTE_G3, NOTE_C4}, {NOTE_AS2, NOTE_DS3, NOTE_GS3, NOTE_CS4}, {NOTE_B2, NOTE_E3, NOTE_A3, NOTE_D4}, {NOTE_C3, NOTE_F3, NOTE_AS3, NOTE_DS4}, }; int fret = 0; int string = -1; //-1 means no string, 0 is E string, 1 is A string, 2 is D string, 3 is G string //Datastructure used to determine which button to play to the buzzer, if two are pressed play last pushed one void setup() { Serial.begin(9600); // put your setup code here, to run once: pinMode(string1Pin, INPUT); pinMode(string2Pin, INPUT); pinMode(string3Pin, INPUT); pinMode(string4Pin, INPUT); pinMode(pingPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { //=============================Deal with buttons and play sound============================= //Get button values, check to see if they were pushed and are now unpushed or vice versa int newStringOne = digitalRead(string1Pin); int newStringTwo = digitalRead(string2Pin); int newStringThree = digitalRead(string3Pin); int newStringFour = digitalRead(string4Pin); //Check if the buttons being pressed if(newStringOne && !stringOne){ string = 0; stringOne = true; } if(newStringTwo && !stringTwo){ string = 1; stringTwo = true; } if(newStringThree && !stringThree){ string = 2; stringThree = true; } if(newStringFour && !stringFour){ string = 3; stringFour = true; } //Check if button being unpressed if(!newStringOne && stringOne){ string = -1; stringOne = false; noTone(buzzerPin); } if(!newStringTwo && stringTwo){ string = -1; stringTwo = false; noTone(buzzerPin); } if(!newStringThree && stringThree){ string = -1; stringThree = false; noTone(buzzerPin); } if(!newStringFour && stringFour){ string = -1; stringFour = false; noTone(buzzerPin); } //===============Get distance of hand from ultrasonic sensor, usable range is 5-30 cm accuratley===================== long duration; int cm; digitalWrite(pingPin, LOW); //Send a ping out with sensor delayMicroseconds(2); digitalWrite(pingPin, HIGH); delayMicroseconds(10); digitalWrite(pingPin, LOW); //Ping sent duration = pulseIn(echoPin, HIGH); //Wait for return on echo Pin cm = duration / 29 / 2; //Convert to cm //If value is too large or small just set it at 35 or 5 if (cm > 35) { cm = 35; } else if (cm < 5) { cm = 5; } //Map the value 35-5 to 0-20 for frets fret = (int)map(cm, 35, 5, 0, 20); //=================Play Sound====================== Serial.print("Fret: "); Serial.print(fret); Serial.print(", String:"); Serial.println(string); if(string != -1){ tone(buzzerPin, fourStringBass[fret][string]); } }
Nice job Cole. It sounds like when it is on the edge between two notes it gets a little noisy oscillating between the two notes. You and Armaan can start a bass band!