Gopika and Leo’s Arduino Bagpipes

For this week’s assignment, we started off with wanting to do something with the distance sensors. There’s something really cool about moving your hands in thin air and creating music. 

 We wanted to use the distance sensor to record the distance and convert that into musical notes and have lasers put in just for the aesthetics and as a guide for the player to know where to move. We took inspiration from the laser keyboard/bass featured in this video.

We soon realized that lasers were too complicated to integrate into the instrument as we would need some kind of smoke in the air to trace the path of the beam and that was a huge, complicated process to replicate on campus. So, we decided to work with just air.

For the instrument, we decided to have a one-octave scale and a button that would take digital input, which would shift the scale by an octave. We replicated the same thing with another Arduino so that we could play in harmony with different octaves. There’s also a button that acts like an on/off switch in the beginning and once the instrument is switched on, it acts as a momentary pause. 

We had a few issues with balancing the tone() function from both the digital input of the push button and the input from the distance sensor, but it was some wiring issues, once that was sorted out, all was done.

We added a few lines of codes that would convert distances beyond a certain point to 0 so that we don’t hear any annoying noise when there is no object in front of the instrument.

Interestingly, what we achieved, in the end, sounded a lot like bagpipes.

Here are a few demos. The first one is just using one octave and the second one is by shifting octaves midway. It’s ‘The Lion Sleeps Tonight’:

Here’s the code:

#define echoPinC 12 
#define trigPinC 11 
const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int BUTTON_PIN2 = 8;
# include "pitches.h"

String notes6[7] = {"C4", "D4", "E4", "F4", "G4", "A4", "B4"};

int notes[7] = {NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_A5, NOTE_B5};
int notesHigh[7] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4};

long durationC;
int distanceC;

int playNote;

bool start = false;

void setup() {
  pinMode(trigPinC, OUTPUT);
  pinMode(echoPinC, INPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(BUTTON_PIN2, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  
   int buttonState = digitalRead(BUTTON_PIN); // read new state
   int offState = digitalRead(BUTTON_PIN2); 

  //switch on 
   if (offState == LOW) {
    start=true;
   }

  if(start)
  {
  
    // put your main code here, to run repeatedly:
  digitalWrite(trigPinC, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPinC, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPinC, LOW);
    durationC = pulseIn(echoPinC, HIGH);
    distanceC = durationC * 0.034 / 2; 
  
    Serial.print("DistanceC: ");
    Serial.print(distanceC);
    Serial.print(" cm");
    Serial.print("mapped: ");
  
    int constrainedInput=constrain(distanceC, 1, 70);
    
    int mappedNoteC = map(constrainedInput, 1, 70, 0, 6);
  
  Serial.println(notes6[mappedNoteC]);
  
    if (buttonState == LOW) {
     Serial.print("button unpressed: ");
  
    
    // noTone(4);
    playNote = notesHigh[mappedNoteC];
    
    if(distanceC > 70){
     noTone(4);
    } 
    
    }
    else
    if (buttonState == HIGH) {
     Serial.print("button pressed: ");
        playNote = notes[mappedNoteC];
    }

  //no note when button is triggered
    if (offState == LOW) {
       Serial.print("button unpressed: ");
       noTone(4);
    }
    else

    //when the button is not triggered play a note
      if (offState == HIGH) { 
        tone(4, playNote);
      }

      //distances beyonf a point has no tone
      if(distanceC > 70){
        noTone(4);
      }

}

}

 

Leave a Reply