The Muses of Ancient Greece are dead and gone, and I’ve discovered why.
The concept is simple: buttons for tones, distance sensor for modulation.
Schematic:
Code:
/* Name: Jan Project: Rusty Trombone */ // keeping track of button input pins int buttonPins[] = {A1, A2, A4, A5}; int buttonRed = A1; int buttonGreen = A2; int buttonYellow = A4; int buttonBlue = A5; // distance sensor pins int pinTrigger = 9; int pinEcho = 8; // buzzer pins int buzzer = 12; // keeping track of base tones {C, E, G, A} float baseNotes[] = {262, 330, 392, 440}; //difference between semitones, for use with modulation float semitone = 15; float modulation = 0; float inches; int fret = 1; void setup() { Serial.begin(9600); //initializing pins pinMode(buzzer, OUTPUT); pinMode(pinTrigger, OUTPUT); pinMode(pinEcho, INPUT); //setting the buttons to INPUT_PULLUP means i don't have to worry about pull down resistors clogging up my board pinMode(buttonRed, INPUT_PULLUP); pinMode(buttonGreen, INPUT_PULLUP); pinMode(buttonYellow, INPUT_PULLUP); pinMode(buttonBlue, INPUT_PULLUP); } void loop() { fret = 0; bool buttonPressed = 0; inches = getDistance(); for (int i = 0; i < 20; i+=2) { fret++; if (inches < i) { modulation = semitone * fret; break; } } if (digitalRead(buttonRed) == LOW) { //if the first key is pressed tone(buzzer, 262 + modulation); Serial.println(inches); } else if (digitalRead(buttonGreen) == LOW) { //if the second key is pressed tone(buzzer, 330 + modulation); } else if (digitalRead(buttonYellow) == LOW) { //if the third key is pressed tone(buzzer, 392 + modulation); } else if (digitalRead(buttonBlue) == LOW) { tone(buzzer, 440 + modulation); } else { noTone(buzzer); //if no key is pressed turn the buzzer off } } float getDistance() { float echoTime; //variable to store the time it takes for a ping to bounce off an object float calculatedDistance; //variable to store the distance calculated from the echo time //send out an ultrasonic pulse that's 10ms long digitalWrite(pinTrigger, HIGH); delayMicroseconds(1); digitalWrite(pinTrigger, LOW); echoTime = pulseIn(pinEcho, HIGH); //use the pulsein command to see how long it takes for the //pulse to bounce back to the sensor calculatedDistance = echoTime / 148.0; //calculate the distance of the object that reflected the pulse (half the bounce time multiplied by the speed of sound) return calculatedDistance; //send back the distance that was calculated }
Reflections: Code as is requires a lot of fine-tuning for the buzzer not to sound like it’s gently caressing a combine harvester. More specifically, changing the changes in tone from continuous to discrete kept the buzzing down. Tweaking the distance intervals at which the tone goes up or down a semitone keeps it from oscillating too much, as might changing how often the tone sounds. The equation for calculating distance from the sensor also has a lot of room for tuning, but I have not the hubris to claim to be a master of time nor space. Fun project though, had a blast.