Assignment 7: Musical Instrument (DJ)

Idea:

For my musical instrument, I thought it would be cool to create a DJ because I wanted to try and incorporate pretty much all the components we learned up until now.

This was my idea for the components:

  • The Servo Motor could act as the DJ and this can be controlled via the light sensor. So you could move your hand up and down and it would map out the Servo rotation. Additionally, I thought it would be cool to add some cool lights to kinda give that disco vibe so as you change your hand position over the light sensor, the lights would change too.
  • I added a button and a potentiometer and this would essentially play the songs that a regular DJ would play. So essentially, I have a library of songs on the Arduino code, and depending on which position the potentiometer is on, when pressed the button, it would play that appropriate song.

For now, I only added 4 songs. How this worked is, I borrowed the “pitch.h” header file that we used in class to map out the note pitches and frequencies. From that, I constructed several arrays which would be the different songs. Then that would be played out loud through the buzzer.

Schematic:

Arduino Code:

#include <Servo.h>
#include "pitches.h"

const int LightSensorPin = A0;
const int PotPin = A1;
const int Button = A2;

const int ServoPin = 9;
const int BuzzerPin = 8;
const int YPin1 = 13;
const int YPin2 = 12;
const int YPin3 = 7;
const int YPin4 = 4;

const int Melody1_Size = 13;
const int Melody2_Size = 11;
const int Melody3_Size = 30;
const int Melody4_Size = 29;

Servo DJ;

//Melodies:  
int melody1[] = {NOTE_E4, NOTE_D4, NOTE_FS3, NOTE_GS3, NOTE_CS4, NOTE_B3, NOTE_D3, NOTE_E3, NOTE_B3, NOTE_A3, NOTE_CS3, NOTE_E3, NOTE_A3};
int melody2[] = {NOTE_C4, NOTE_DS4, NOTE_F4, NOTE_FS4, NOTE_F4, NOTE_DS4, NOTE_C4, 0, NOTE_AS3, NOTE_D4, NOTE_C4};
int melody3[] = {NOTE_A3, NOTE_B3, NOTE_D4, NOTE_B3, NOTE_FS4, NOTE_FS4, NOTE_E4, 0, NOTE_A3, NOTE_B3, NOTE_D4, NOTE_B3, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_CS4, NOTE_B3, 0, NOTE_A3, NOTE_B3, NOTE_D4, NOTE_B3, NOTE_D4, NOTE_E4, NOTE_CS4, NOTE_B3, NOTE_A3, NOTE_A3, NOTE_E4, NOTE_D4};
int melody4[] = {NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_E4, NOTE_E4, 0, NOTE_D4, NOTE_D4, NOTE_D4, 0, NOTE_E4, NOTE_G4, NOTE_G4, 0, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_E4, NOTE_D4, NOTE_C4};

//Melody Durations
int m1_durations[] = {8, 8, 4, 4, 8, 8, 4, 4, 8, 8, 4, 4, 2};
int m2_durations[] = {4, 4, 4, 4, 4, 4, 4, 2, 8, 8, 2};
int m3_durations[] = {8, 8, 8, 8, 3, 3, 4, 3, 8, 8, 8, 8, 3, 3, 2, 8, 8, 4, 8, 8, 8, 8, 3, 3, 2, 8, 4, 4, 2, 4};
int m4_durations[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};


void setup() {
  Serial.begin(9600);
  DJ.attach(ServoPin);                 //Pin for the Servo Motor 
  
  //Analog Inputs
  pinMode(LightSensorPin, INPUT);     //Pin for the Light Sensor
  pinMode(PotPin, INPUT);             //Pin for the Potentiometer
  pinMode(Button, INPUT);             //Pin for the Button

  //LED Pins
  pinMode(YPin1, OUTPUT);    
  pinMode(YPin2, OUTPUT);    
  pinMode(YPin3, OUTPUT);     
  pinMode(YPin4, OUTPUT);  
}

void loop() {
  //Reads all the necessary values from the analog input pins
  int LightValue = analogRead(LightSensorPin);
  int PotValue = analogRead(PotPin);
  int ButtonValue = analogRead(Button);
  int discoLight = LightValue;    //Variable for changing the lights

  //Writing the Light Sensor data onto the Servo:
  LightValue = map(LightValue, 0, 1023, 0, 180);

  //Converting the potentiometer values to the according melody
  int Melody = map(PotValue, 0, 1023, 0, 4);
  DJ.write(LightValue);

  //Writing the data for the disco lights: 
    if(discoLight < 550 && discoLight >= 450) {
    digitalWrite(YPin1, HIGH);
    digitalWrite(YPin2, LOW);
    digitalWrite(YPin3, LOW);
    digitalWrite(YPin4, LOW);
  }

  else if (discoLight < 450 && discoLight >= 350){
    digitalWrite(YPin1, LOW);
    digitalWrite(YPin2, HIGH);
    digitalWrite(YPin3, LOW);
    digitalWrite(YPin4, LOW);
  }

  else if(discoLight < 350 && discoLight >= 250) {
    digitalWrite(YPin1, LOW);
    digitalWrite(YPin2, LOW);
    digitalWrite(YPin3, HIGH);
    digitalWrite(YPin4, LOW);
  }

  else if(discoLight < 250) {
    digitalWrite(YPin1, LOW);
    digitalWrite(YPin2, LOW);
    digitalWrite(YPin3, LOW);
    digitalWrite(YPin4, HIGH);
  }

  //Offsets the PotValue to 3 in case it reaches 4, for stabilization
  if(PotValue == 4) {
    PotValue = 3;
  }
  Serial.println(Melody);

  //If the button is pressed, depending on the potentiometer value, it will play the according melodies. 
  if(ButtonValue > 1000) {
    if(Melody == 0) {
      MelodyPlayer(melody1, m1_durations, Melody1_Size, LightValue);
    }

    else if(Melody == 1) {
      MelodyPlayer(melody2, m2_durations, Melody2_Size, LightValue);
    }

    else if(Melody == 2) {
      MelodyPlayer(melody3, m3_durations, Melody3_Size, LightValue);
    }

    else {
      MelodyPlayer(melody4, m4_durations, Melody4_Size, LightValue);
    }

  }
  delay(50);
}

//This function plays the melody that it was assigned to it. It also registers the LightValue so that way the DJ can play while the song is also playing. 
void MelodyPlayer(int melodyNum[], int melodyDur[], int melodySize, int LightValue) {
    for (int thisNote = 0; thisNote < melodySize; thisNote++) {
      LightValue = analogRead(LightSensorPin);
      LightValue = map(LightValue, 0, 1023, 0, 180);
      DJ.write(LightValue);

      //To calculate the note duration, take one second divided by the note type.
      //Ex: quarter note = 1000 / 4, eighth note = 1000/8, etc.
      int noteDuration = 1000 / melodyDur[thisNote];

      tone(8, melodyNum[thisNote], noteDuration);
      //To distinguish the notes, set a minimum time between them.
      int pauseBetweenNotes = noteDuration * 1.30;
      delay(pauseBetweenNotes);
      
      //Stop the tone playing:
      noTone(8);
    }
}

Video:

Improvements:

I feel that when the song is playing, because it enters the for loop, the sensors stop reading in data, meaning the servo motors and the LED lights stop reading in data so it won’t move while the song is playing. My solution was to pass the LightValue so that the motor would at least move while the song is playing on beat. But if the motor and lights could move while the song is playing freely like it does with no song playing, that would be an amazing improvement.

 

Week 10: Light Theremin (Arslan & Stefan)

Concept:

For this assignment, we wanted to create a version “Theremin” that will be linked with the light sensor and will produce sound based on the light intensity received by the sensor on Arduino board. Additionally, we’ll add the switch to this Light Theremin to change the frequency of the sound and to play different sounds using the light sensor. The frequency only changes while the button is pressed, we did this to change tune while playing the theremin which makes it easier for the user to play different tone from both frequencies. In short, the analog in takes values from the light sensor and these values are converted within a certain limit to be played through the buzzer. When the button is pressed, the limit of these values changes and thus giving us the tone of higher frequency.

SCHEMATIC:
Video:

Code:

// create variable to hold sensor value
int sensorValue;
// UNO's analog read sensors use "analog to digital converter" (ADC),
// which means it divides the reading coming from the sensor (0 to 5 volts) into 1024 equal steps.
// Thus, the reading from our photoresistor could range from 0 to 1023,
// however it is unlikely to use the full range so we will calibrate it.
// For now, create variables to hold the high and low value for our photoresistor range, 
// make them the opposite of the max/min values and we will calibrate them down.
int sensorLow = 1023;
int sensorHigh = 0;
// set the LED pin, 13 is the built in LED
const int ledPin = 13;
int switchFreq = 4;
int switchVal;


void setup() {
  
  
  pinMode(ledPin, OUTPUT);
  pinMode(switchFreq, INPUT);
  
  digitalWrite(ledPin, HIGH);
  
  delay(500);
  
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);  
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);

  // after it blinks for 2 seconds, its time to calibrate the photoresistor readings
  // create a loop with while() that lasts for 5000 ms to calibrate the light sensor according the setting, 
  while (millis() < 5000) {
    // use analogRead() to get a reading from the photoresistor,
    sensorValue = analogRead(A0);
    // create two conditions using if() to calibrate the max and min sensor values,
    // raise the sensorHigh if the current reading is higher:
    if (sensorValue > sensorHigh) {
      sensorHigh = sensorValue;
    }
    // lower the sensorLow if the current reading is lower:
    if (sensorValue < sensorLow) {
      sensorLow = sensorValue;
    } 
  }
  
  // turn the LED off, calibration is done!
  digitalWrite(ledPin, LOW); 
}



void loop() {
  //read the input from A0 and store it in a variable
  sensorValue = analogRead(A0);
  switchVal = digitalRead(switchFreq);

  // map(currentValue, oldRange1, oldRange2, newRange1, newRange2)
  // I reverse their order (high, low) so that shading the photoresister will cause a higher tone.
  // the new range is the range of Hz to use to produce sound, which for UNO can be from 31 to 65535 Hz.
  // I set it from 0 to 300, which is a more normal sound range and if a button is pressed I change the values between 500 to 1000
  // since we start at 0, full light will make no tone, full shade will make the highest tone.
  if (switchVal == HIGH){
  int pitch = map(sensorValue, sensorHigh, sensorLow, 500, 1000);
  tone(8, pitch, 10);
  }
  else{
    int pitch = map(sensorValue, sensorHigh, sensorLow, 0, 300);
    tone(8, pitch, 10);
  }
  // use the tone function to create sound in the piezo, 
  // tone(pin#, value, milliseconds)
  

  // add a delay to make the current tone sustained for a few ms to adjust the quality of the tone
  delay(15);
}

 

Future improvements:

For future, we want to use more than 2 limits of frequencies and we want to add instruments that could be switched using the button. After completing this project, we realised that playing sound using the light sensor is easier than any other sensor since it only requires basic movements of hands to block the light or allow the light to the sensor. Thus, in future, we’d like to add more instruments like electric guitar frequencies and allow users to switch between these instruments using the switch buttons.

PIANO

Concept:
After going over several examples of musical instruments that we could create using the specified digital and analog sensors, Sanjana Nambiar and I decided to settle on the old but gold piano. The concept behind our project is simple and straightforward: our piano will consist of 8 buttons that will correspond to piano tiles and the buzzer will play a corresponding musical note when the user presses one of the eight switch buttons. We integrated an analog input to our project by getting the value from the potentiometer and mapping it to one of the four octaves. Based on this mapping, the button will play different variations of the same note i.e. A or a or a’ or a’’. Below is the illustration of the four octaves that we used and the corresponding notes and frequencies.

Code:

// arduino-equivalent frequencies of the musical notes for each tile of the piano
// each note is stored in a list consisitning of three other notes of  different pitch
int T_C[4] = {65, 130, 262, 523};
int T_D[4] = {73, 147, 294, 587};
int T_E[4] = {82, 165, 330, 659};
int T_F[4] = {87, 175, 349, 698};
int T_G[4] = {98, 196, 392, 784};
int T_A[4] = {110, 220, 440, 880};
int T_H[4] = {123, 247, 493, 988};
int T_c[4] = {130, 262, 523, 1046};

//names of each tile and the corresponding digital  pins
const int A = 11;
const int C = 5;
const int D = 6;
const int E = 7;
const int F = 8;
const int G = 10;
const int H = 12;
const int c = 13;

const int Buzz = A0;

void setup()
{
  Serial.begin(9600); 

  //declare the switches as digital input devices
  pinMode(C, INPUT);
  pinMode(D, INPUT);
  pinMode(E, INPUT);
  pinMode(F, INPUT);
  pinMode(G, INPUT);
  pinMode(A, INPUT);
  pinMode(H, INPUT);
  pinMode(c, INPUT);
}

void loop()
{
  //read the analog input from the potentiometer
  int potPosition = analogRead(A3);

  //map that input to the the value in the range 0-4
  potPosition = map(potPosition, 0, 1023, 0, 4);
  Serial.println(potPosition);

  //value 4 is just a dummy value that will be used to detect the end of the potentiometer, 
  //so when we get value 4 from the poentiometer, we treat it as 3
  if(potPosition == 4){ potPosition = 3; }

  //play the correspondting tone for each of the 8 swithces
  while(digitalRead(C) == HIGH){ tone(Buzz,T_C[potPosition]); }
  while(digitalRead(D) == HIGH){ tone(Buzz,T_D[potPosition]); }
  while(digitalRead(E) == HIGH){ tone(Buzz,T_E[potPosition]); }
  while(digitalRead(F) == HIGH){ tone(Buzz,T_F[potPosition]); }
  while(digitalRead(G) == HIGH){ tone(Buzz,T_G[potPosition]); }
  while(digitalRead(A) == HIGH){ tone(Buzz,T_A[potPosition]); }
  while(digitalRead(H) == HIGH){ tone(Buzz,T_H[potPosition]); }
  while(digitalRead(c) == HIGH){ tone(Buzz,T_c[potPosition]); }

  noTone(Buzz);
}

Schematic:

Demo:

Future Improvements

Since we were limited in the use of sensors that we could use, our piano doesn’t really look like a real-world piano. So, one of the improvements we could make is to create a separate portable piano i.e. a cardboard piano covered with aluminum foil or equipped with force sensors, and adapt our code to play the same sounds when the corresponding tile will get pressed. We could also work on implementing the logic to handle the case when two tiles are pressed simultaneously.

 

Week 10 – Musical Instrument: Piano

Concept

After going over several examples of musical instruments that we could create using the specified digital and analog sensors, Sanjana Nambiar and I decided to settle on the old but gold piano. The concept behind our project is simple and straightforward: our piano will consist of 8 buttons that will correspond to piano tiles and the buzzer will play a corresponding musical note when the user presses one of the eight switch buttons. We integrated an analog input to our project by getting the value from the potentiometer and  mapping it to one of the four octaves. Based on this mapping, the button will play different variations of the same note i.e. A or a or a’ or a’’. Below is the illustration of the four octaves that we used and the corresponding notes and frequencies.

Code

// arduino-equivalent frequencies of the musical notes for each tile of the piano
// each note is stored in a list consisitning of three other notes of  different pitch
int T_C[4] = {65, 130, 262, 523};
int T_D[4] = {73, 147, 294, 587};
int T_E[4] = {82, 165, 330, 659};
int T_F[4] = {87, 175, 349, 698};
int T_G[4] = {98, 196, 392, 784};
int T_A[4] = {110, 220, 440, 880};
int T_H[4] = {123, 247, 493, 988};
int T_c[4] = {130, 262, 523, 1046};

//names of each tile and the corresponding digital  pins
const int A = 11;
const int C = 5;
const int D = 6;
const int E = 7;
const int F = 8;
const int G = 10;
const int H = 12;
const int c = 13;

const int Buzz = A0;

void setup()
{
  Serial.begin(9600); 

  //declare the switches as digital input devices
  pinMode(C, INPUT);
  pinMode(D, INPUT);
  pinMode(E, INPUT);
  pinMode(F, INPUT);
  pinMode(G, INPUT);
  pinMode(A, INPUT);
  pinMode(H, INPUT);
  pinMode(c, INPUT);
}

void loop()
{
  //read the analog input from the potentiometer
  int potPosition = analogRead(A3);

  //map that input to the the value in the range 0-4
  potPosition = map(potPosition, 0, 1023, 0, 4);
  Serial.println(potPosition);

  //value 4 is just a dummy value that will be used to detect the end of the potentiometer, 
  //so when we get value 4 from the poentiometer, we treat it as 3
  if(potPosition == 4){ potPosition = 3; }

  //play the correspondting tone for each of the 8 swithces
  while(digitalRead(C) == HIGH){ tone(Buzz,T_C[potPosition]); }
  while(digitalRead(D) == HIGH){ tone(Buzz,T_D[potPosition]); }
  while(digitalRead(E) == HIGH){ tone(Buzz,T_E[potPosition]); }
  while(digitalRead(F) == HIGH){ tone(Buzz,T_F[potPosition]); }
  while(digitalRead(G) == HIGH){ tone(Buzz,T_G[potPosition]); }
  while(digitalRead(A) == HIGH){ tone(Buzz,T_A[potPosition]); }
  while(digitalRead(H) == HIGH){ tone(Buzz,T_H[potPosition]); }
  while(digitalRead(c) == HIGH){ tone(Buzz,T_c[potPosition]); }

  noTone(Buzz);
}

Schematic

Demo

Future Improvements

Since we were limited in the use of sensors that we could use, our piano doesn’t really look like a real-world piano. So, one of the improvements we could make is to create a separate portable piano i.e. a cardboard piano covered with aluminum foil or equipped with force sensors, and adapt our code to play the same sounds when the corresponding tile will get pressed. We could also work on implementing the logic to handle the case when two tiles are pressed simultaneously.

 

Musical Instrument – Light Sensitive Tabla

Idea:

Saamia and I created a unique version of the tabla, a pair of hand drums commonly used in traditional South Asian music.

The Tabla: Paired Drum of South Asia - Center for World Music

Initially, we thought of recreating the same instrument with the use of pressure sensor resistors but then we decided to make it light-sensitive. Our vision was to make the tabla come alive with an ethereal quality, allowing it to be played not by hand, but by the interaction of light. It was an interesting and fun project that resulted in a unique musical instrument.

Code:

#include "pitches.h"

//==========First resistor=============
int photoPin1 = A0;
int speakerpin = 7;

int melody[] = {

  NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_F4, NOTE_G4,
  NOTE_G4, NOTE_A4, NOTE_G4, NOTE_E4, NOTE_D4, NOTE_E4, NOTE_F4,
  NOTE_F4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_E4,
  NOTE_E4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_E4,
  NOTE_G4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_D4
};
//==========Second resistor=============
int photoPin2 = A1;
int speakerpin2 = 4;
int melody2[] = {

  NOTE_G4, NOTE_F4, NOTE_D4, NOTE_G4, NOTE_D4, NOTE_F4, NOTE_G4,
  NOTE_G4, NOTE_D4, NOTE_E4, NOTE_G4, NOTE_C4, NOTE_E4, NOTE_G4,
  NOTE_G4, NOTE_G4, NOTE_F4, NOTE_A4, NOTE_G4, NOTE_D4, NOTE_D4,
  NOTE_E4, NOTE_E4, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_C4, NOTE_F4,
  NOTE_G4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_D4, NOTE_E4, NOTE_D4, NOTE_F4
};

void setup() {
  pinMode(speakerpin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  //====================First Speaker
  int lightRaw = analogRead(photoPin1);

  int light = map(lightRaw, 0, 700, -12, 35);

  if (light > 0 && light<33) 
  {
    tone(speakerpin, melody[light], 500);
  }
  else if(light == 35 || light < 33){
    noTone(speakerpin);
  }
  //===================Second Speaker
  int lightRaw2 = analogRead(photoPin2);

  int light2 = map(lightRaw2, 0, 700, -12, 35);

  if (light2 > 0 && light2<33) 
  {
    tone(speakerpin2, melody2[light2], 500);
  }
  else if(light2 == 35 || light2 < 33){
    noTone(speakerpin2);
  }

}

Process:

Initially, we began the project by connecting a single light sensor to a speaker. The main challenge we encountered was mapping the readings from the light sensor to play the correct melody from an array of notes. During the process of setting these thresholds, we decided to make the instrument turn off in bright conditions and start playing sound when the light sensor was covered by a hand in dimmer conditions. This approach created a similar hand action to that of hitting the tabla with the hand, resulting in a more authentic and natural playing experience.

After the initial phase, we decided to expand our project by adding another light sensor to take readings of the surrounding light. However, we faced a challenge when we realized that the changes in light conditions on the two light sensors were not being accurately reflected by the single speaker we were using. To solve this issue, we decided to divide the instrument into two separate speakers, with each speaker connected to one light sensor individually. This allowed for more distinct and clear sound production based on the readings of each light sensor.

Circuit:

Demo:

Musical Instrument: Light Sensitive Tabla

Idea:

Khadija and I created a unique version of the tabla, a pair of hand drums commonly used in traditional South Asian music.

The Tabla: Paired Drum of South Asia - Center for World Music

Initially, we thought of recreating the same instrument with the use of pressure sensor resistors but then we decided to make it light-sensitive. Our vision was to make the tabla come alive with an ethereal quality, allowing it to be played not by hand, but by the interaction of light. It was an interesting and fun project that resulted in a unique musical instrument.

Code:

#include "pitches.h"

//==========First resistor=============
int photoPin1 = A0;
int speakerpin = 7;

int melody[] = {

  NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_F4, NOTE_G4,
  NOTE_G4, NOTE_A4, NOTE_G4, NOTE_E4, NOTE_D4, NOTE_E4, NOTE_F4,
  NOTE_F4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_E4,
  NOTE_E4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_D4, NOTE_E4,
  NOTE_G4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_D4
};
//==========Second resistor=============
int photoPin2 = A1;
int speakerpin2 = 4;
int melody2[] = {

  NOTE_G4, NOTE_F4, NOTE_D4, NOTE_G4, NOTE_D4, NOTE_F4, NOTE_G4,
  NOTE_G4, NOTE_D4, NOTE_E4, NOTE_G4, NOTE_C4, NOTE_E4, NOTE_G4,
  NOTE_G4, NOTE_G4, NOTE_F4, NOTE_A4, NOTE_G4, NOTE_D4, NOTE_D4,
  NOTE_E4, NOTE_E4, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_C4, NOTE_F4,
  NOTE_G4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_D4, NOTE_E4, NOTE_D4, NOTE_F4
};

void setup() {
  pinMode(speakerpin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  //====================First Speaker
  int lightRaw = analogRead(photoPin1);

  int light = map(lightRaw, 0, 700, -12, 35);

  if (light > 0 && light<33) 
  {
    tone(speakerpin, melody[light], 500);
  }
  else if(light == 35 || light < 33){
    noTone(speakerpin);
  }
  //===================Second Speaker
  int lightRaw2 = analogRead(photoPin2);

  int light2 = map(lightRaw2, 0, 700, -12, 35);

  if (light2 > 0 && light2<33) 
  {
    tone(speakerpin2, melody2[light2], 500);
  }
  else if(light2 == 35 || light2 < 33){
    noTone(speakerpin2);
  }

}

Process:

Initially, we began the project by connecting a single light sensor to a speaker. The main challenge we encountered was mapping the readings from the light sensor to play the correct melody from an array of notes. During the process of setting these thresholds, we decided to make the instrument turn off in bright conditions and start playing sound when the light sensor was covered by a hand in dimmer conditions. This approach created a similar hand action to that of hitting the tabla with the hand, resulting in a more authentic and natural playing experience.

After the initial phase, we decided to expand our project by adding another light sensor to take readings of the surrounding light. However, we faced a challenge when we realized that the changes in light conditions on the two light sensors were not being accurately reflected by the single speaker we were using. To solve this issue, we decided to divide the instrument into two separate speakers, with each speaker connected to one light sensor individually. This allowed for more distinct and clear sound production based on the readings of each light sensor.

Circuit:

Demo:

Home Work 10 – Sarthak and Yerk (AutoTune)

AutoTune

Concept:

For this project, we were inspired by AutoTune. AutoTune allows you to take a certain musical key and make sure all the notes are aligned within that key, thereby perfecting the sound.

Execution: 

For the circuit, we used a buzzer, three switches, and a distance sensor. Initially, we used the key of C major and the note C as our reference point. Having calculated the mathematic relationships that exist between notes in a major key, we assigned different intervals of distance to different notes for that key. For instance, if the user’s hand is 0-5 cm away from the sensor, the circuit will play a C note. If the hand is 5-10 cm away, the circuit will play a D note. This method does not let notes that do not belong in the C major key to be played, which perfects the sound of the board. Just like AutoTune.

When the yellow button is pressed, the key that is being played is transposed up a half step. So if the user is playing in a C major key, once the yellow button is pressed, the user will now play in D flat major. The green button executes the opposite effect – it transposes the key down a half step. If a user is playing in F major, upon pressing the button, they will play in E major.

Finally, if the blue button is pressed, the user will now play in the natural minor key, completely changing the mathematical relationships that underlie the notes. For instance, if the user was playing in the G major key, once they press the button, they will hear the G minor key. This process goes the other way around: if the button is pressed again, the user will go back to the major key.

Circuit: 

 

Code:

int note_c = 262;

const int beeperPin = 12;
const int trigPin = 7;
const int echoPin = 8;
const int yellowSwitch = A0;
const int greenSwitch = A2;
const int blueSwitch = A4;

const int division = 5;

int flag = 1;

// this is the number of notes in an octave
const int num = 8;

int all_notes[num];

int getDistance() {
  // this bit of code was taken from https://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/

  // calculating the distance between the user and the sensor
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  int duration = pulseIn(echoPin, HIGH);
  int distance = duration * 0.034/2;

  Serial.print("Distance: ");

  return distance;
}

int getNote(int distance) {
  int index = distance / division;

  return all_notes[index];
}

void makeMajorKey() {
  // making an array of all the notes in an octave given in the major key.
  all_notes[0] = note_c;
  int n = 1;
  for (int i = 1; i < num; i++) {
    // the third and seventh note change is a half step.
    if ((n % 3 == 0 && n % 6 != 0) || n % 7 == 0){
      all_notes[i] = all_notes[i-1] * pow(2, 1.0/12.0);
    } else {
      all_notes[i] = all_notes[i-1] * pow(2, 1.0/6.0);
    }
    n++;
  }
}

void makeMinorKey() {
  // making an array of all the notes in an octave in the minor key.
  all_notes[0] = note_c;
  int n = 1;
  for (int i = 1; i < num; i++) {
    // the second and fifth note change is a half step.
    if ((n % 2 == 0 && n % 4 != 0 && n % 6 != 0 && n % 8 != 0) || n % 5 == 0){
      all_notes[i] = all_notes[i-1] * pow(2, 1.0/12.0);
    } else {
      all_notes[i] = all_notes[i-1] * pow(2, 1.0/6.0);
    }
    n++;
  }
}

void setup() {
  pinMode(beeperPin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(yellowSwitch, INPUT);

  Serial.begin(9600);

  makeMajorKey();
}

void loop() {
  // PipeLine
  // get the distance of an object
  int distance = getDistance();
  if (distance <= division * num) {
    // create note for that distance
    int note_to_play = getNote(distance);

    // play the note
    tone(beeperPin, note_to_play);

    // switch to transpose up
    int yellow_state = digitalRead(yellowSwitch);

    // switch to transpose down
    int green_state = digitalRead(greenSwitch);

    // switch to toggle between major and natural minor key
    int blue_state = digitalRead(blueSwitch);

    if (yellow_state == HIGH) {
      // transposing the key of the instrument a half-step up, when the switch is clicked.
      note_c = note_c * pow(2, 1.0/12.0);
      makeMajorKey();
    }

    if (green_state == HIGH) {
      // transposing the key of the instrument a half-step down, when the switch is clicked.
      note_c = note_c / pow(2, 1.0/12.0);
      makeMajorKey();
    }

    // changes major key to natural minor key and vice versa.
    if (blue_state == HIGH) {
      if (flag == 1) {
        makeMinorKey();
        flag = 0;
      } else {
        makeMajorKey();
        flag = 1;
      }
    }
  }
}

 

Video:

Future Improvements: 

One of the issues with the current board is that the code may register the clicking of the button as multiple clicks, even if the user had pressed the button once. With the yellow and the green buttons, this leads to a higher or a lower transposition than expected. With the blue button, there are instances when it simply skips over the shift to the minor key because it registers one click as two. In the future, we want to work toward eliminating that inconvenience.

 

Home Work 10 – Sarthak and Yerk (AutoTune)

AutoTune

Concept:

For this project, we were inspired by AutoTune. AutoTune allows you to take a certain musical key and make sure all the notes are aligned within that key, thereby perfecting the sound.

Execution: 

For the circuit, we used a buzzer, three switches, and a distance sensor. Initially, we used the key of C major and the note C as our reference point. Having calculated the mathematic relationships that exist between notes in a major key, we assigned different intervals of distance to different notes for that key. For instance, if the user’s hand is 0-5 cm away from the sensor, the circuit will play a C note. If the hand is 5-10 cm away, the circuit will play a D note. This method does not let notes that do not belong in the C major key to be played, which perfects the sound of the board. Just like AutoTune.

When the yellow button is pressed, the key that is being played is transposed up a half step. So if the user is playing in a C major key, once the yellow button is pressed, the user will now play in D flat major. The green button executes the opposite effect – it transposes the key down a half step. If a user is playing in F major, upon pressing the button, they will play in E major.

Finally, if the blue button is pressed, the user will now play in the natural minor key, completely changing the mathematical relationships that underlie the notes. For instance, if the user was playing in the G major key, once they press the button, they will hear the G minor key. This process goes the other way around: if the button is pressed again, the user will go back to the major key.

Circuit: 

Code:

int note_c = 262;

const int beeperPin = 12;
const int trigPin = 7;
const int echoPin = 8;
const int yellowSwitch = A0;
const int greenSwitch = A2;
const int blueSwitch = A4;

const int division = 5;

int flag = 1;

// this is the number of notes in an octave
const int num = 8;

int all_notes[num];

int getDistance() {
  // this bit of code was taken from https://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/

  // calculating the distance between the user and the sensor
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  int duration = pulseIn(echoPin, HIGH);
  int distance = duration * 0.034/2;

  Serial.print("Distance: ");

  return distance;
}

int getNote(int distance) {
  int index = distance / division;

  return all_notes[index];
}

void makeMajorKey() {
  // making an array of all the notes in an octave given in the major key.
  all_notes[0] = note_c;
  int n = 1;
  for (int i = 1; i < num; i++) {
    // the third and seventh note change is a half step.
    if ((n % 3 == 0 && n % 6 != 0) || n % 7 == 0){
      all_notes[i] = all_notes[i-1] * pow(2, 1.0/12.0);
    } else {
      all_notes[i] = all_notes[i-1] * pow(2, 1.0/6.0);
    }
    n++;
  }
}

void makeMinorKey() {
  // making an array of all the notes in an octave in the minor key.
  all_notes[0] = note_c;
  int n = 1;
  for (int i = 1; i < num; i++) {
    // the second and fifth note change is a half step.
    if ((n % 2 == 0 && n % 4 != 0 && n % 6 != 0 && n % 8 != 0) || n % 5 == 0){
      all_notes[i] = all_notes[i-1] * pow(2, 1.0/12.0);
    } else {
      all_notes[i] = all_notes[i-1] * pow(2, 1.0/6.0);
    }
    n++;
  }
}

void setup() {
  pinMode(beeperPin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(yellowSwitch, INPUT);

  Serial.begin(9600);

  makeMajorKey();
}

void loop() {
  // PipeLine
  // get the distance of an object
  int distance = getDistance();
  if (distance <= division * num) {
    // create note for that distance
    int note_to_play = getNote(distance);

    // play the note
    tone(beeperPin, note_to_play);

    // switch to transpose up
    int yellow_state = digitalRead(yellowSwitch);

    // switch to transpose down
    int green_state = digitalRead(greenSwitch);

    // switch to toggle between major and natural minor key
    int blue_state = digitalRead(blueSwitch);

    if (yellow_state == HIGH) {
      // transposing the key of the instrument a half-step up, when the switch is clicked.
      note_c = note_c * pow(2, 1.0/12.0);
      makeMajorKey();
    }

    if (green_state == HIGH) {
      // transposing the key of the instrument a half-step down, when the switch is clicked.
      note_c = note_c / pow(2, 1.0/12.0);
      makeMajorKey();
    }

    // changes major key to natural minor key and vice versa.
    if (blue_state == HIGH) {
      if (flag == 1) {
        makeMinorKey();
        flag = 0;
      } else {
        makeMajorKey();
        flag = 1;
      }
    }
  }
}

Video:

Future Improvements: 

One of the issues with the current board is that the code may register the clicking of the button as multiple clicks, even if the user had pressed the button once. With the yellow and the green buttons, this leads to a higher or a lower transposition than expected. With the blue button, there are instances when it simply skips over the shift to the minor key because it registers one click as two. In the future, we want to work toward eliminating that inconvenience.

Week 9: NEVER HAVE I EVER with Arduino

Concept:

For this assignment, I wanted to create a basic version of “Never have I ever” game. The rules of this game are simple, usually there’s a narrator who says something and if any of the player has done that they say, “I have”. I wanted to create this game on Arduino using the LCD screen, the switch button, and the red led. Instead of the narrator, I wanted to display a text on the lcd screen and if the player has done that thing, they press the switch that will light up the led to show the other players. In short, pressing the button is equivalent to saying, “I HAVE” in the real game. For this reason, I went on internet and tried to understand the working of the LCD screen that comes with Arduino UNO and linked it with the switch to control the texts that were displayed on the screen. I was able to create a basic version of this game with just one prompt as I was struggling to reset the cursor placement on the screen. There’s a welcome message that is displayed and is shown until the user presses the switch. Then the first prompt is there, and the user can press the switch to indicate that he/she has done that.

Schematic:
COde:

 

// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
int redLEDPin = 8;
int trueSwitch = A1;

String welcome = "Welcome Players! The rules of the game are simple: Press RED button if you have! Press RED button to Proceed";
int leng = welcome.length();
char myText[50] = "Never have I ever got on the wrong train or bus?";
bool StartGame = false;
int promptcount = 0;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 1);
  pinMode(redLEDPin, OUTPUT);
  pinMode(trueSwitch, INPUT);
}

void loop() {

  // set the cursor to (0,0):
  
 

  lcd.setCursor(0, 0);

  // print from 0 to 9:
  // lcd.autoscroll();
  for (int thisChar = 0; thisChar < leng; thisChar++) {
    int truePos = digitalRead(trueSwitch);
    if (truePos == HIGH){
        digitalWrite(redLEDPin, HIGH);
        delay(600);
        StartGame = true; 
        digitalWrite(redLEDPin, LOW);
        break;  
      } 

    lcd.print(welcome[thisChar]);

    if (thisChar == 15){
      lcd.autoscroll();
    }

    delay(200);

  }
  lcd.clear();
  lcd.noAutoscroll();
  delay(2000);
  

  

  // set the cursor to (16,1):

  
  // clear screen for the next loop:

  while (StartGame){
    
 
    lcd.clear();

    lcd.setCursor(0, 0);

    // print from 0 to 9:
    // lcd.autoscroll();
    for (int thisChar = 0; thisChar < 50; thisChar++) {
      int truePos = digitalRead(trueSwitch);
      if (truePos == HIGH){
        digitalWrite(redLEDPin, HIGH);
        promptcount++;
        delay(300);   
      } 
      lcd.print(myText[thisChar]);
      if (thisChar == 15){
        lcd.autoscroll();
      }

      delay(300);

      digitalWrite(redLEDPin, LOW);

    }

    // set the cursor to (16,1):

  
    // clear screen for the next loop:

  
    lcd.noAutoscroll();
    lcd.clear();
  }
}

 

 

Video:

Future Improvements:

As I mentioned earlier, I couldn’t add more than one prompt to this project. For future, I would like to create an array of different prompts that switches as soon as the user presses the switch. Moreover, to make the game more interesting I would like to add more switches with more LEDs to involve more than one player in the game.

Week 9: A – Blue, B – Yellow, C – Green, D – Red

Idea:

In high school, I remember having O-level exams with 40 Multiple Choice Questions and each MCQ had 4 options to choose from. In class, everyone was supposed to work on their paper for a set amount of time after which the teacher would one by one say the correct answer out loud. The problem started when in a class of 30 energetic students the teacher’s voice was reduced to a mere muffle. The other issue was the confusion between the option ‘B’ and ‘D’ which sounds so similar that a clarification of ‘B for Ball’ and ‘D for Dog’ was always followed. This gave me the idea to make a 4 LED structure that can be used to communicate the correct answer for each MCQ one by one. The teacher can click the corresponding number of times and display the correct option and then follow it with an explanation of the respective MCQ.

Code:

int buttonPin = 7;
int LED1 = 13;
int LED2 = 12;
int LED3 = 11;
int LED4 = 10;
int initial = 0;
int lastState = 0;
int buttonState = LOW;


void setup()
 {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(7, INPUT);
}

void loop() 
{
  // put your main code here, to run repeatedly:
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
    delay(500);
    buttonState = digitalRead(buttonPin);
     if (buttonState == LOW) //when pressed move to next led
     {
      initial = lastState + 1;
     }
  }
  else 
  {
    delay(100);
  }
  
    if(initial == 1) //first time blue is lit up
    {
      digitalWrite (13, HIGH);
      digitalWrite (12, LOW);
      digitalWrite (11, LOW);
      digitalWrite (10, LOW);
      lastState = 1;
    }
    else if(initial == 2) //second time yellow is lit up
    {
      digitalWrite (13, LOW);
      digitalWrite (12, HIGH);
      digitalWrite (11, LOW);
      digitalWrite (10, LOW);
      lastState = 2;
    }
   else if (initial == 3) //third time green is lit up
   {
      digitalWrite (13, LOW);
      digitalWrite (12, LOW);
      digitalWrite (11, HIGH);
      digitalWrite (10, LOW);
      lastState = 3;
   }
    else if (initial == 4) //fourth time red is lit up
    {
        digitalWrite (13, LOW);
        digitalWrite (12, LOW);
        digitalWrite (11, LOW);
        digitalWrite (10, HIGH);
        lastState = 4;
    }
    else //all LEDs off
    {
        digitalWrite (13, LOW);
        digitalWrite (12, LOW);
        digitalWrite (11, LOW);
        digitalWrite (10, LOW);
        lastState = 0;
    }

}

Video: