Rusty Trombone

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
}

Evidence of My Crimes

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.

Leave a Reply