Piezo Phase

Description:
Using a force sensor, an LED and a piezo I tried to control the famous 12-note melody of Steve Reich’s Piano Phase and tried to place it to the studio version. The effect that leads to certain parts of the phrase being highlighted was accentuated by the LED effect.

Components:

  • Arduino Uno
  • 1 Piezo Buzzer
  • 1 Force Sensor Resistor
  • 1 Green LED
  • Green Scotch tape
  • Ping pong ball to diffuse
  • 10K and 220 Ohm resistors
  • Jumper wires

Code:


/* Piezo Phase - inspired by Steve Reich
 *  (to be played along with Piano Phase)
 * ------------
 *
 * Program to play tones depending on the data coming from the serial port.
 *
 * The calculation of the tones is made following the mathematical
 * operation:
 *
 *       timeHigh = 1/(2 * toneFrequency) = period / 2
 *
 * where the different tones are described as in the table:
 * 
 * Piano Phase notes:
 * 
 * E4 F♯4 B4 C♯5 D5 F♯4 E4 C♯5 B4 F♯4 D5 C♯5
 * 
 * Updated table below (thanks Tod Kurt):
 *
 * note   frequency   PW (timeHigh)  
 * E4     329.63 Hz   1516.85   
 * F#4    369.99 Hz   1351.38   
 * B4     493.88 Hz   1012.39   
 * C#5    554.37 Hz   901.92   
 * D5     587.30 Hz   851.35 
 * 
 * Transposed
 * note   frequency   PW (timeHigh)  
 * E4     349.228 Hz   1432   
 * F#4    391.995 Hz   1276   
 * B4     523.251 Hz   956   
 * C#5    587.330 Hz   851   
 * D5     622.254 Hz   804 
 * 
 * Transposing to one-step lower
 * Base code by Tod E. Kurt <tod@todbot.com> to use new Serial. commands
 * and have a longer cycle time.
 */

int speakerPin = 13;
int ledPin = 7;

int fsrPin = A0;
int fsrReading;

int length = 12; // the number of notes

char notes[] = "EFBcdFEcBFdc";

int beats[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};

//bool toggle = HIGH;

float tempo = 96.1538461538;

// everything good till here

void playTone(int tone, int duration){
  
  for (long i = 0; i < duration * 1000L; i += tone*2){
    digitalWrite(ledPin, HIGH);
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(ledPin, LOW);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNothing(){
//  toggle = LOW;
  // this means that the melody is stopped
  digitalWrite(ledPin, LOW);
  digitalWrite(speakerPin, LOW);
}

void playNote(char note, int duration){
//  toggle = HIGH;
  // this means that the melody is running

  char names[] = {'C', 'D', 'E', 'F', 'G', 'A', 'B',           

                 'c', 'd', 'e', 'f', 'g', 'a', 'b',

                 'x', 'y' };

  int tones[] = { 1915, 1700, 1432, 1276, 1275, 1136, 956,

                 851,  804,  765,  593,  468,  346,  224,

                 655 , 715 };

  int SPEED = 5;

  for (int i = 0; i < 12; i++){
    if (names[i] == note){
      int newduration = duration/SPEED;
      playTone(tones[i], newduration);
    }
  }
}

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

void loop() {
  fsrReading = analogRead(fsrPin);
  Serial.print("FSR Reading: ");
  Serial.print(fsrReading);
  Serial.print("\n");
//
//  Serial.print("Toggle: ");
//  Serial.print(toggle);
//  Serial.print("\n");

//  while (fsrReading > 200){
//    toggle = !toggle;
//  }
  
  if (fsrReading > 300){
        for (int i = 0; i < length; i++) {
          if (notes[i] == ' ') {
            delay(beats[i] * tempo); // rest
          } 
   
          else {
            playNote(notes[i], beats[i] * tempo);
          }
        
        delay(tempo);
        }
  }
}

Video link

Leave a Reply