rhoadley.net   music   research   courses   software   blogs

ARU    Seminars    Comp&Imp    NMP    CMC2a    CBHH
Sensor Technology    Sonic Art    Major Project    MA Resources


Resources:    Bioacoustics    Jitter    MaxMSP    OSC    Physical    PD       CBHH    sTech    SuperCollider    C/Xcode

sTech Resources:     Home     Blog     Forum     Examples     Projects     Tasks     Tutorials


Sensor Technology Tasks

Vibrating a Piezo to Create Pitch

Task 2 Name: Vibrating a Piezo Set: w3i Due: Thursday 16th December 2010 Weighting: 0% Courses: stech
Prev Task: Hello World Next Task: Arduino, MaxMSP and SuperCollider
Task Summary All stech tasks

Making Sounds with an Arduino (including via Max).

To cover:


Using a Piezo disc to make sounds
Give the sounds a duration
Generate and Modulate Pulses
Notes Over the Serial Port with Duration Controlled by a Potentiometer
Use the Arduino Board with Max

 

Use a Piezo to Make Sounds

First, use a Piezo to make sounds via the Arduino, (piezos can be used to create sounds as well as 'receive' them, as in the knock example we've covered.


/* Play notes over serial
 * v0.2 February 2010
 * arduino example: arduino.cc
 * mods by rhoadley, rhoadley.net, rhoadley.net/stech
 * 
 * Arduino Code Example - playing sounds
 * Example 1: just playing sounds
 * The following program is an example that will play notes 
 * out of the characters received over the serial port. 
 * To try it out, upload this file to Arduino, hook up a piezo 
 * or a speaker to digital pin 8 (black to ground) and send characters to play 
 * each note.
 * Do this by opening the Serial Monitor (button in bar above), 
 * typing a letter in the field that appears below and clicking 
 * on the 'Send' button.
 *
 * It's tricky to get two piezos/speakers working together.  Why is this?
 * 
 * 
 * ----------------------
 * 
 * note - half period (uS)
 * ----------------------- 
 * c    -   1,911
 * d    -   1,703
 * e    -   1,517
 * f    -   1,432
 * g    -   1,276
 * a    -   1,136
 * b    -   1,012
 * C    -   956
 */

int val = 0;      // to check if there is data available from the serial port
int val2 = 0;     // stores the data that came from the port
int piezoPin = 8; // pin number where to hook the speaker
int pulso = 0;    // value of half pulse

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

void loop() {
  val = Serial.available();
  if (val > 0) {
    val2 = Serial.read();
    if (val2 == 'c') {
      pulso = 1911;
    }
    if (val2 == 'd') {
      pulso = 1703;
    }
    if (val2 == 'e') {
      pulso = 1517;
    }
    if (val2 == 'f') {
      pulso = 1432;
    }
    if (val2 == 'g') {
      pulso = 1276;
    }
    if (val2 == 'a') {
      pulso = 1136;
    }
    if (val2 == 'b') {
      pulso = 1012;
    }
    if (val2 == 'C') {
      pulso = 956;
    }
  }
  digitalWrite(piezoPin, HIGH);
  delayMicroseconds(pulso);
  digitalWrite(piezoPin, LOW);
  delayMicroseconds(pulso);
}


 

Give the Notes Duration


/* Play Notes Over Serial Port with Duration
 * v0.2 October 2010
 * arduino example: arduino.cc
 * mods by rhoadley, rhoadley.net, rhoadley.net/stech
 *
 * Example 2: upgrading to notes
 * Notes have duration in time, this program will play a tone for some time, 
 * and then go silent, instead of keeping it sounding forever, 
 * as the previous program does.
 * This example also plays strings of letters.
 *
 * To try it out, upload this file to Arduino, hook up a piezo 
 * or a speaker to digital pin 8 (black to ground) and send characters to play 
 * each note.
 *
 * Send the Arduino letters by opening the Serial Monitor (button in bar above), 
 * typing a letter in the field that appears below and clicking 
 * on the 'Send' button.
 *
 * ----------------------------
 * 
 * note - half period (uS)
 * ----------------------- 
 * c    -   1,911
 * d    -   1,703
 * e    -   1,517
 * f    -   1,432
 * g    -   1,276
 * a    -   1,136
 * b    -   1,012
 * C    -   956
 *
 * We create a function that will take care of
 * playing a tone for a while and go silent
 * afterwards
 */

int val = 0;      // to check if there is data available from the serial port
int val2 = 0;     // stores the data that came from the port
int piezoPin = 8; // pin number where to hook the speaker
int dur = 150;
// int randDur = 500; // Use if you want random values

void playNote(int note) {
  // in the following line, dur represents the duration of the note in milliseconds
  
  // randDur = random(dur); // Use if you want random values
  // in the below change 'dur' to 'randDur' if you want random values
  for( int a=0; a <= dur; a++) { 
    digitalWrite(piezoPin, HIGH);
    delayMicroseconds(note);
    digitalWrite(piezoPin, LOW);
    delayMicroseconds(note);
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(piezoPin, OUTPUT);
  // randomSeed(analogRead(0)); // Use if you want to use random durations (see above)
}

void loop() {
  val = Serial.available();
  if (val > 0) {
    val2 = Serial.read();
    if (val2 == 'c') {
      playNote(1911);
    }
    if (val2 == 'd') {
      playNote(1703);
    }
    if (val2 == 'e') {
      playNote(1517);
    }
    if (val2 == 'f') {
      playNote(1432);
    }
    if (val2 == 'g') {
      playNote(1276);
    }
    if (val2 == 'a') {
      playNote(1136);
    }
    if (val2 == 'b') {
      playNote(1012);
    }
    if (val2 == 'C') {
      playNote(956);
    }
  }
}




 

Generate and Modulate Pulses


/* Play Siren-like Pulses
 * v0.2 October 2010
 * arduino example: arduino.cc
 * mods by rhoadley, rhoadley.net
 * 
 * Example 3: Playing Pulses
 * The following program is an example that will play notes 
 * out of the characters received over the serial port. 
 * To try it out, upload this file to Arduino, hook up a piezo 
 * or a speaker to digital pin 8 (black to ground) and send characters to play 
 * each note.
 * Do this by opening the Serial Monitor (button in bar above), 
 * typing a letter in the field that appears below and clicking 
 * on the 'Send' button.
 * 
 * 
 * ----------------------
 * 
 * note - half period (uS)
 * ----------------------- 
 * c    -   1,911
 * d    -   1,703
 * e    -   1,517
 * f    -   1,432
 * g    -   1,276
 * a    -   1,136
 * b    -   1,012
 * C    -   956
 */

int val = 0;      // to check if there is data available from the serial port
int val2 = 0;     // stores the data that came from the port
int piezoPin = 8; // pin number where to hook the speaker
int pulso = 0;    // initialise the pulse
int del1 = 400;   // delay
int pulso2;       // initialise
// int dur = 800; // uncomment if you want random duration
// int randDur = 800; // uncomment if you want random duration

// so you can send values to the board
void setup() {
  Serial.begin(9600);
  pinMode(piezoPin, OUTPUT);
//   randomSeed(analogRead(0)); // uncomment if you want random duration
}

void loop() {
  val = Serial.available();
  // randDur = random(dur); // uncomment if you want random duration
  if (val > 0) {
    val2 = Serial.read();
    
    if (val2 == 'c') {
      pulso = 1911;
    }
    if (val2 == 'd') {
      pulso = 1703;
    }
    if (val2 == 'e') {
      pulso = 1517;
    }
    if (val2 == 'f') {
      pulso = 1432;
    }
    if (val2 == 'g') {
      pulso = 1276;
    }
    if (val2 == 'a') {
      pulso = 1136;
    }
    if (val2 == 'b') {
      pulso = 1012;
    }
    if (val2 == 'C') {
      pulso = 956;
    }
  }
  
  
  digitalWrite(piezoPin, HIGH);
  delayMicroseconds(pulso2);
  digitalWrite(piezoPin, LOW);
  delayMicroseconds(pulso2);
  
    delayMicroseconds(del1);
      pulso2 = (pulso2-10);
    delayMicroseconds(del1);
        if (pulso2 < 200) // change 200 to 'randDur' if you want random Duration
        {
          pulso2 = pulso;
        }
}




 

Notes Over the Serial Port with Duration Controlled by a Potentiometer


/* Play Notes Over Serial Port with Duration
 * v0.2 December 2010
 * arduino example: arduino.cc
 * mods by rhoadley, rhoadley.net
 *
 * Example 2: upgrading to notes
 * Notes have duration in time, this program will play a tone for some time, 
 * and then go silent, instead of keeping it sounding forever, 
 * as the previous program does.
 * This example also plays strings of letters.
 *
 * To try it out, upload this file to Arduino, hook up a piezo 
 * or a speaker to digital pin 8 (black to ground) and send characters to play 
 * each note.
 
 * Then, connect a potentiometer (for example, 470K log or lin) in the following fashion: the outer connections to 5v and ground,
 * the central connection to Analogue In 0.
 *
 * Send the Arduino letters by opening the Serial Monitor (button in bar above), 
 * typing a letter in the field that appears below and clicking 
 * on the 'Send' button.
 *
 * ----------------------------
 * 
 * note - half period (uS)
 * ----------------------- 
 * c    -   1,911
 * d    -   1,703
 * e    -   1,517
 * f    -   1,432
 * g    -   1,276
 * a    -   1,136
 * b    -   1,012
 * C    -   956
 *
 * We create a function that will take care of
 * playing a tone for a while and go silent
 * afterwards
 */

int val = 0;        // to check if there is data available from the serial port
int val2 = 0;       // stores the data that came from the port
int piezoPin = 8;   // pin number where to hook the speaker
int potVal = 150;   // the value of the potentiometer
int potPin = 0;     // select the input pin for the potentiometer

void playNote(int note) {
  // in the following line, dur represents the duration of the note in milliseconds
  for( int a=0; a <= potVal; a++) {
    digitalWrite(piezoPin, HIGH);
    delayMicroseconds(note);
    digitalWrite(piezoPin, LOW);
    delayMicroseconds(note);
  }
}

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

void loop() {
  potVal = analogRead(potPin);    // read the value from the sensor
  Serial.println(potVal);
    
  val = Serial.available();
  if (val > 0) {
    val2 = Serial.read();
    if (val2 == 'c') {
      playNote(1911);
    }
    if (val2 == 'd') {
      playNote(1703);
    }
    if (val2 == 'e') {
      playNote(1517);
    }
    if (val2 == 'f') {
      playNote(1432);
    }
    if (val2 == 'g') {
      playNote(1276);
    }
    if (val2 == 'a') {
      playNote(1136);
    }
    if (val2 == 'b') {
      playNote(1012);
    }
    if (val2 == 'C') {
      playNote(956);
    }
  }
}





 

Notes Over the Serial Port with Frequency Controlled by a Potentiometer


/* Play Notes Over the Serial Port with Frequency Controlled by a Potentiometer
 * v0.2 February 2010
 * arduino example: arduino.cc
 * mods by rhoadley, rhoadley.net
 *
 * Example 2: upgrading to notes
 * Notes have duration in time, this program will play a tone for some time, 
 * and then go silent, instead of keeping it sounding forever, 
 * as the previous program does.
 * This example also plays strings of letters.
 *
 * To try it out, upload this file to Arduino, hook up a piezo 
 * or a speaker to digital pin 8 (black to ground) and send characters to play 
 * each note.
 
 * Then, connect a potentiometer (for example, 470K log or lin) in the following fashion: the outer connections to 5v and ground,
 * the central connection to Analogue In 0.
 *
 * Send the Arduino letters by opening the Serial Monitor (button in bar above), 
 * typing a letter in the field that appears below and clicking 
 * on the 'Send' button.
 *
 * ----------------------------
 * 
 * note - half period (uS)
 * ----------------------- 
 * c    -   1,911
 * d    -   1,703
 * e    -   1,517
 * f    -   1,432
 * g    -   1,276
 * a    -   1,136
 * b    -   1,012
 * C    -   956
 *
 * We create a function that will take care of
 * playing a tone for a while and go silent
 * afterwards
 */

int val = 0;        // to check if there is data available from the serial port
int val2 = 0;       // stores the data that came from the port
int piezoPin = 8;   // pin number where to hook the speaker
int potVal = 150;   // the value of the potentiometer
int potPin = 0;     // select the input pin for the potentiometer

void playNote(int note) {
  // in the following line, dur represents the duration of the note in milliseconds
  for( int a=0; a <= 20; a++) {
    digitalWrite(piezoPin, HIGH);
    delayMicroseconds(note);
    digitalWrite(piezoPin, LOW);
    delayMicroseconds(note);
  }
}

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

void loop() {
  potVal = analogRead(potPin);    // read the value from the sensor
  Serial.println(potVal+1);
    
  val = Serial.available();
  if (val > 0) {
      playNote(potVal+1);
    }
}


 

Connecting Arduino and Max

For those of you eager to get on with connecting to Max, here are some patches to be playing with. Incidentally, you need to be a little careful with properly opening and closing your serial ports, whether USB or Bluetooth. If you don't, you stand the very real risk of crashing one or other requiring a reboot of your computer.

Please see here for the latest versions of these patches, as well as other methods of communicating.





to top of page The Task

  • Make sure you do the above. Not just once, but a number of times through the week. At least twice. You need to do it enough so that you feel reasonably comfortable and confident.

  • Once you're comfortable, create a few examples using one or more piezo discs. While accepting the limitations of the technology, make something as interesting as possible. Investigate ways of improving playback.

  • For this task, no software other than Arduino (or Processing) is necessary.



  • Added value
    By completing the details of the task you will achieve at least a pass mark. By imaginatively and creatively considering how you might implement the task originally you can add value to your submission, and this added value may increase your mark significantly. Even when making videos of short demonstration tasks try to consider musical and performance criteria.

    What to submit
  • Clearly, I don't want you to submit your Arduinos. That means you need to submit some documentary evidence that you've completed your task. The most obvious way to do this is to submit some sort of video of your task working, as well as of the code running. If you can't do this, take photos.

  • Media files
    You must submit media files, such as video, audio or image files, but please ensure that video files are compressed to a reasonable degree. You should never submit dv files, but compress these to mp4. You should submit no file that is greater in size than 25MB/minute.

  • Compress (zip) your patches, demos, etc. into one file called your_student_number_"vibratingpiezo" (e.g. 0504335_vibratingpiezo.zip), include a readme with your name and student number and, if necessary, how to use or just open the patch.

  • Submit a copy of the files to the i-Centre on Thursday 15th December 2011

You might also be interested in:


The Projects

The projects and tasks are designed to help you through the various courses and materials that you'll have to deal with, and also to provide an active and practical element to what could otherwise become a rather dry and technical exercise. Tasks are small exercises - you may be asked to complete one or two per week. Projects are larger and carry a higher percentage of the mark. We will undertake two, three, four or more projects and tasks. The final project is usually an individual choice project, and will be worth significantly more than the others in terms of percentages in your portfolio. We will usually try to set aside a time to perform the projects in a public setting.