Week 9: Musical Instrument

IDEA

For this week I tried several thins. First, I wanted to recreate a song I played long, long time ago. Then I focused more on having a somewhat randomly generated melody which can be changed on the go through analog and digital input. I sticked with this idea and kept adding more ideas. Unfortunately, it seemed to be too much at some point and I could not find the error. I also wanted two different melodies to be triggered by two different buttons but for some reason the second button would not connect properly.

PROCESS

For the stage of ideation and prototyping that you can see in the video, holding down the blue button triggers a melody. The speed can be adjusted with the potentiometer. To the arms of the servo, two metal earrings are attached that make another sound when clinging to a glass or to each other. As they also swing a little bit, this adds a variable that is out of Arduino control.

OUTCOME

In the time I committed to this exercise, I did not quite manage to achieve the output I envisioned at the beginning but I enjoyed wandering off and adding new ideas and trying out different things on the go. At first, I also had no idea how to extend the sound making beyond Arduino into a physical level but the little holes in the plastic part that I attached to the Servo served quite well to attach earrings and I think it would be fun to have little metal bells attached to the Servo with little strings and see (rather hear) what that sounds like.

 

 

#include <Servo.h> //include servo (hardware)
#include "pitches.h" //include pitches extrta tab

Servo servo;
int servoPos = 100; //position
int whichNote = 0;
int notes[10] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5, NOTE_D5, NOTE_E5};
int durations[10];
int bluebuttonPin = 6;
int redbuttonPin = 9;
//int knob = A0;

void setup() {
  servo.attach(2); //attach to Pin 2
  pinMode(8, OUTPUT); //for blue LED
  pinMode(bluebuttonPin, INPUT); //get button input
  pinMode(redbuttonPin, INPUT);
  Serial.begin(9600);

  //  // set the durations with a random coinflip
  //  for (int i = 0; i < 10; i++) {
  //    int coinFlip = random(2);
  //    if (coinFlip == 0)
  //      durations[i] = knobValue;
  //    else
  //      durations[i] = knobValue/2;
  //  }
}

void loop() {
  int knobValue = analogRead(A0); //get analog input from knob
  map(knobValue, 0, 1023, 3, 8); //mapping knowbvalue to use for durations
  Serial.println (knobValue);

  // set the durations with a random coinflip and analog input from knob
  for (int i = 0; i < 10; i++) {
    int coinFlip = random(2);
    if (coinFlip == 0)
      durations[i] = knobValue;
    else
      durations[i] = knobValue / 2;
  }


  int val = analogRead(A0); //to use knob input
  int bluebuttonState = digitalRead(bluebuttonPin);
  int redbuttonState = digitalRead(redbuttonPin);

  // the rate is 1 second divided by the duration of the note
  int rate = 1000 / durations[whichNote];

  // get the current time
  unsigned long currentTime = millis(); //unsigned long to store long number

  //two different songs for two different buttons
  if (bluebuttonState == HIGH) {
    // trigger a note
    if (currentTime % rate == 0  ) {
      tone(4, notes[whichNote], random(100, 400)); //random within range
      whichNote = random(10);
      delay(1); //seemed to help Aaron
    }

    // do the servo at half speed
    if (currentTime % (rate * 2) == 0  ) {
      servoPos = 30;
      servo.write(servoPos);
    }

    // else if not triggereing the servo, then every 10 milliseconds move the servo arm back a little bit
    // can't do it every frame as that is too fast for the servo
    else if (currentTime % 10 == 0) { //every ten millisec substract 1 from servo position
      servoPos -= 1;
      servo.write(servoPos);
    }

  } else {
    return;
  }

  if (redbuttonState == HIGH) {
    // trigger a note
    if (currentTime % rate == 0  ) {
      tone(4, notes[whichNote], random(100, 400)); //random within range
      whichNote = random(10);
      delay(1); //seemed to help Aaron
    }

    // do the servo at half speed
    if (currentTime % (rate * 2) == 0  ) {
      servoPos = 30;
      servo.write(servoPos);
    }

    // else if not triggereing the servo, then every 10 milliseconds move the servo arm back a little bit
    // can't do it every frame as that is too fast for the servo
    else if (currentTime % 10 == 0) { //every ten millisec substract 1 from servo position
      servoPos -= 1;
      servo.write(servoPos);
    }

  } else {
    return;
  }

}

 

Leave a Reply