Posts Tagged ‘Music’

Arduino – Basic Theremin meets Processing!

Arduino piano theremin

My last theremin involved a small speaker. Now I’ve replaced the speaker with my PC, using processing to pick up the values from the SRF05 ultrasound sonar distance sensor and play different notes accordingly – which gives multiple possibilities and far better sounds.

So to start with check out my previous theremin, the circuit is the same except for removing the speaker and the Arduino code now prints values to the serial port instead of outputing directly to a speaker. The only thing that I’m doing here that is really new is using the minim libary for Processing, built by this chap (thankyou). What this allows us is to assign a sound file to a variable in Processing and then gives us functions to start/stop the sound.

In my processing code you’ll see that I’ve got 12 sounds, one for each chromatic note and at the moment they’re from a piano. To get sounds and samples to use you can sign up to freesound.org. Mine I got here from ‘pinkyfinger’ and once you’ve decided which sounds you want to use then the rest is fairly easy – the more samples and octaves the better. I’ve used the piano set here just so I can hear the different notes and I’ve only 12 notes (chromatic scale) but eventually Iwould like to expand this to say 48 notes.

When you get your sounds I’ve found it’s easiest to use .wavs but minim will allow you to use WAV, AIFF, AU, SND, and MP3 files. Also I store my sounds in the root of the folder where I’m saving my processing sketch.

Ok, lets start with the Arduino parts, circuit and sketch.

Arduino Theremin Parts

SRF05 Ultrasonic range finder
Arduino Deumilanove w/ ATMEGA328
Breadboard / Prototyping board (you can actually do this without a breadboard)
Jumper/ Connector wires

The Theremin Arduino Circuit

Basically the same as before just without the speaker on it. For more info on the SRF05 checkout my past stuff here. In this instance Processing is going to do all the work, so the circuit just needs to pass values from the SRF05 to Arduino, which in turn passes values to my PC via the USB cable.

piano-theremin

The Arduino Theremin Sketch

Very cut down version, it takes the value as before and converts it to a distance and then just prints it to a new line in on the serial port.

// written at: luckylarry.co.uk
// very easy Theremin combined with processing
// sketch prints out distance to the serial port
// processing picks up value and plays notes accordingly
// no annoying speaker drone! πŸ™‚

// setup pins and variables for SRF05 sonar device
int echoPin = 2;                                // SRF05 echo pin (digital 2)
int initPin = 3;                                // SRF05 trigger pin (digital 3)
unsigned long pulseTime = 0;                    // stores the pulse in Micro Seconds
unsigned long distance = 0;                     // variable for storing the distance (cm) we'll use distance as a switch for the speaker

//setup
void setup() {

  pinMode(initPin, OUTPUT);                     // set init pin 3 as output
  pinMode(echoPin, INPUT);                      // set echo pin 2 as input
  Serial.begin(9600);                           // start the serial port

} 

// execute
void loop() {
  digitalWrite(initPin, HIGH);                  // send 10 microsecond pulse
  delayMicroseconds(10);                        // wait 10 microseconds before turning off
  digitalWrite(initPin, LOW);                   // stop sending the pulse
  pulseTime = pulseIn(echoPin, HIGH);           // Look for a return pulse, it should be high as the pulse goes low-high-low
  distance = pulseTime/58;                      // convert the pulse into distance (cm)

  // make the sound.
  // check the distance, if over 50cm make no sound - send no signal
  if (distance > 50) {
    Serial.println(distance);                   // print the distance value to the serial port
    delay(50);                                  // delay for 50 milliseconds before starting again...
  }
}

[ad#Google Ad in content]
Next up we have processing, which will look for values on the serial port, so first upload the Arduino code to your board and test it works. Next start up Processing to finish off the code. If like me you’re fairly new to processing there’s lots of info to be had at: http://www.arduino.cc/playground/Interfacing/Processing

The Processing Theremin Sketch

With your code now running on the Arduino board we now need processing to pick up these values. Previously I had something of an issue getting these values and reading them. But in hindsight I was being a bit dim when I realised I could just look in the serial port for when a new line (n) was printed which would tell me that a new value was about to be sent. Of course thats providing your Arduino sketch is using Serial.println() (print line) instead of Serial.print() which just chucks every value into one long string – and if you look at my previous attempts with processing you can laugh at how I started splitting this huge string up etc… Oh hindsight is a wonderful thing, anyway, I digress, below is the processing sketch:

// written at: luckylarry.co.uk
// very easy Theremin combined with processing
// sketch prints out distance to the serial port
// processing picks up value and plays notes accordingly
// no annoying speaker drone! πŸ™‚ replace the sounds and delays with
// your own...

import processing.serial.*;                // import serial library so we can read the serial port
import ddf.minim.*;                        // import minim library

// define the serial port
Serial myPort;          

// define minim variables:
// here we say that variable A is an audiosample etc...
Minim minim;
AudioSample GSharp;
AudioSample A;
AudioSample Bb;
AudioSample B;
AudioSample C;
AudioSample CSharp;
AudioSample D;
AudioSample Eb;
AudioSample E;
AudioSample F;
AudioSample FSharp;
AudioSample G;

// setup
void setup () {

  // set up the variables, loading in the sound files from your project folder
  // which should be the same place as where you save this sketch
  // details on using minim and audioSample are here: http://code.compartmental.net/tools/minim/manual-audiosample/
  minim = new Minim(this);
  GSharp = minim.loadSample("GSharp.wav", 2048);
  A = minim.loadSample("A.wav", 2048);
  Bb = minim.loadSample("Bb.wav", 2048);
  B = minim.loadSample("B.wav", 2048);
  C = minim.loadSample("C.wav", 2048);
  CSharp = minim.loadSample("CSharp.wav", 2048);
  D = minim.loadSample("D.wav", 2048);
  Eb = minim.loadSample("Eb.wav", 2048);
  E = minim.loadSample("E.wav", 2048);
  F = minim.loadSample("F.wav", 2048);
  FSharp = minim.loadSample("FSharp.wav", 2048);
  G = minim.loadSample("G.wav", 2048);

  // List serial ports, saves us trying to figure out which COM we're using.
  println(Serial.list());
  // Open the active port - providing you've only got one sending serial data (which you should)
  myPort = new Serial(this, Serial.list()[1], 9600);
  // don’t read the serial buffer until we see a new line - this is genius and simple compared with my last efforts
  myPort.bufferUntil('n');
}

void draw() {
  // we need to declare the draw function even though we're not using it!!
}

void serialEvent (Serial myPort) {
  // get the string from the serial buffer - gets all chars until the next line break...
  String bufferString = myPort.readStringUntil('n');

  if (bufferString != null) {
    // get rid of any whitespace - sometimes the serial buffer can have blanks etc.. in the string
    bufferString = trim(bufferString);
    // convert the value to an int - we're only sending numbers over the serial port so parsing it to an int shouldn't ever be an issue.
    float inByte = float(bufferString);
    int pulse = int(bufferString);         // declare a variable to hold our value.
    println(pulse);                        // for debug print the value so we can check it.

    // remember that our pulse is in CM so if its less than 5cm then do this etc... else do this... else do this.. for as many sound samples
    if ( pulse < 5 ) {
      GSharp.trigger();
      delay(25);
    }
    else if ( pulse < 8 ) {
      A.trigger();
      delay(25);
    }
    else if ( pulse < 11 ) {
      Bb.trigger();
      delay(25);
    }
    else if ( pulse < 14 ) {
      B.trigger();
      delay(25);
    }
    else if ( pulse < 17 ) {
      C.trigger();
      delay(25);
    }
    else if ( pulse < 20 ) {
      CSharp.trigger();
      delay(25);
    }
    else if ( pulse < 23 )  {
      D.trigger();
      delay(25);
    }
    else if ( pulse < 26 ) {
      Eb.trigger();
      delay(25);
    }
    else if ( pulse < 29 ) {
      E.trigger();
      delay(25);
    }
    else if ( pulse < 32 ) {
      F.trigger();
      delay(25);
    }
    else if ( pulse < 35 ) {
      FSharp.trigger();
      delay(25);
    }
    else if ( pulse < 38 ) {
      G.trigger();
      delay(25);
    }
    else if ( pulse > 50 ) {
      // if the distance is greater than 50cm then play nothing
    }

  } // end if there's a value in the serial bufferstring

}   // end void serialevent()

[ad#Google Ad in content]

Arduino – A Basic Theremin

basic theremin

Theremins are cool. Fact. You may also have heard of them as either aetherphone/ etherophone or termenvox/ thereminvox. Essentially its an electronic music instrument that plays a certain note depending on the position of your hand and its distance from an antenna.

Building a very basic one with Arduino is easy – easier than my basic Arduino drum machine. Very easy. Basically we can replicate one by building a circuit of a speaker and a distance sensor, such as my favourite the SRF05 ultrasound thingy. We calculate the distance and the nearer you get the difference in note/frequency emitted from the speaker.

You’re going to need only a few parts and not much code. You can read more about my applications of the SRF05 along with sample code here: Arduino SRF05 Projects. If you can’t be arsed with reading any of that then no worries all is revealed below…

Arduino Theremin Parts List

1x speaker
SRF05 Ultrasonic range finder
Arduino Deumilanove w/ ATMEGA328
Breadboard / Prototyping board
Jumper/ Connector wires

Arduino Theremin Circuit

Very simple,we have a speaker with the negative running to Arduino’s GND, and it’s positive going to digital pin 6 on the Arduino board. The code will tell the speaker to turn on and off rapidly based on the objects distance from the ultrasound sensor. This rapid turning on and off of the speaker is what will generate different sounds (like my drum machine). The only other part of the circuit is the SRF05 distance/ proximity sensor. It has a positive and negative connected to the Arduino and then 2 pins for trigger and echoing an ultrasound wave both going to digital pins 2 and 3 respectively on the Arduino board.

basic-theremin-circuit

Theremin Arduino Sketch

To save the annoyance of those around you I’ve added in a small statement that basically says if your hand is not within 30 cm of the sensor then don’t play a sound. But otherwise basically we measure distance constantly and when an object is detected we convert the distance in to a value for which to use in the oscillation of the speaker to generate different pitchs and frequencies.

// written at: luckylarry.co.uk
// very easy Theremin

// setup pins and variables for SRF05 sonar device
int echoPin = 2;                                // SRF05 echo pin (digital 2)
int initPin = 3;                                // SRF05 trigger pin (digital 3)
int speakerPin = 6;                             // Speaker pin
unsigned long pulseTime = 0;                    // stores the pulse in Micro Seconds
unsigned long distance = 0;                     // variable for storing the distance (cm) we'll use distance as a switch for the speaker
unsigned long soundDelay = 0;                   // variable for storing the deay needed for the pitch

//setup
void setup() {

  pinMode(speakerPin, OUTPUT);                  // sets pin 6 as output
  pinMode(initPin, OUTPUT);                     // set init pin 3 as output
  pinMode(echoPin, INPUT);                      // set echo pin 2 as input

 } 

// execute
void loop() {
  digitalWrite(initPin, HIGH);                  // send 10 microsecond pulse
  delayMicroseconds(10);                        // wait 10 microseconds before turning off
  digitalWrite(initPin, LOW);                   // stop sending the pulse
  pulseTime = pulseIn(echoPin, HIGH);           // Look for a return pulse, it should be high as the pulse goes low-high-low
  distance = pulseTime/58;                      // convert the pulse into distance (cm)
  soundDelay = pulseTime/3;                     // alter this variable to alter the pitch of the sound emitted

  // make the sound.
  // check the distance, if over 30cm make no sound
  if (distance < 30) {
  digitalWrite(speakerPin, HIGH);
  delayMicroseconds(soundDelay);
  digitalWrite(speakerPin, LOW);
  delayMicroseconds(soundDelay);
  }
}

[ad#Google Ad in content]

Pretty cool for no parts - but of course the sound quality isn't great. I guess you could add a switch in the circuit so you could manually start and stop it to produce clearer notes.

Arduino – making a basic drum machine

arduino piezo

Had a quick look round at turning a piezoelectric speaker in to a sensor that will detect a tap or knock. I also then had a search around for setting the output of a speaker to a different note. Combining this has given me a small basic Arduino drum machine and a headache to my girlfriend.

First of all a piezoelectric speaker works kind of like a guitar string in that it vibrates to generate sound. Typically we pass a current through the 2 pins and this then vibrates the piezo element accordingly, using Pulse Width Modulation allows us to alter the volume and the frequency of the sound wave by altering how frequent we vibrate the piezo material.

So if we reverse this we get a knock sensor which means we vibrate the piezo element by hitting it this then creates a signal that we detect as an input. By sensing the vibrations we can crudely detect how hard it was hit. But because we constantly read the input and the vibrations will reach a peak we need to take the peak value to get a decent result rather than the first or last reading. To do this we write a small chunk of code to take the highest reading.

Next we have a normal speaker as our output, by altering the frequency we can alter the note that it produces, much like creating an Infrared signal in my tutorial here. The frequency is basically created by the microsecond time length of the soundwave and we rapidly pulse the speaker to this length so half the length is on, the other is off. Different notes and octaves have different wave lengths on the chromatic scale. A basic 12 note scale is shown below with the chromatic notes and their frequency along with the timings:

Chromatic Note Frequency Hz Time of soundwave (micro seconds) ?s Pulse On/Off (divide time by 2) ?s
C 261 Hz 3830 ?s 1915 ?s
C# 277 Hz 3610 ?s 1805 ?s
D 294 Hz 3400 ?s 1700 ?s
D# 311 Hz 3216 ?s 1608 ?s
E 329 Hz 3038 ?s 1519 ?s
F 349 Hz 2864 ?s 1432 ?s
F# 370 Hz 2702 ?s 1351 ?s
G 392 Hz 2550 ?s 1275 ?s
G# 415 Hz 2410 ?s 1205 ?s
A 440 Hz 2272 ?s 1136 ?s
A# 466 Hz 2146 ?s 1073 ?s
B 493 Hz 2028 ?s 1014 ?s

To calculate the time of a wave we can use the following calculation:

Time (T) = 1 / frequency (Hz)

This will give us the value in seconds. To obtain microseconds multiply this value by 1,000,000 (There are a million microseconds to 1 second). Conversely we can obtain the frequency by dividing 1 by the Time (in seconds).

I’m going to have 2 piezo speakers as knock sensors which will light up a corresponding LED and play a different note, in this case a C or a D.

Arduino Drum Machine Parts

2x 220 Ohm resistor (Red, Red, Brown, Gold)
2x 1Mega Ohm resistor (Brown, Black, Green, Gold) – that’s 1,000,000 Ohms
2x piezoelectric speakers
1x speaker
2x LED
Arduino Deumilanove w/ ATMEGA328
Breadboard / Prototyping board
Jumper/ Connector wires
Optional 9V DC power supply or use the USB power for the Arduino

Arduino Piezo Speaker Drum Machine Circuit

Arduino-piezo-drums

Piezo Sensor Drum Machine Code

[ad#Google Ad in content]

/*

LUCKYLARRY.CO.UK - Very basic drum machine/ knock sensors and chromatic scale

We measure the force at which the piezo speakers are hit, the maximum on time is 1024 so when
this is lower than a set threshold we execute our code. In order to take the peak reading we
continously monitor the values and everytime it's lower we save that value. At the end of the loop
we reset the value.

The soundwave function uses a custom monitor for counting microseconds as this seems to be
a bit more accurate for measuring the delays needed. We produce our count by making a value
of microseconds, 35,000, which seems to give a good range of note lengths when multiplied by
how hard the sensor was hit.

We output the sound to another speaker, creating a soundwave based on the Hertz of any given
note in the chromatic scale. Taking this value we calculate the times in microseconds needed
to oscillate and generate the required frequency. Time = (1 / Hz) * 1,000,000.

*/

int leftPadPin = 2;                                             // set the pins for the piezo speakers
int rightPadPin = 5;                                            // these are analog pins for input
int leftLEDPin = 9;                                             // set the LED pins which are digital
int rightLEDPin = 10;
int speakerPin = 6;                                             // set the speaker pin on digital pin 6
int padLimit = 1010;                                            // the limit/ threshold at which to activate the logic
int howHard = 1024;                                             // variable to store how hard the sensor is hit, the lower the value the harder the hit
int  Cnote = 1915;                                              // set the pulse on/off time for each note.
int  Dnote = 1700;  

void setup(){
  pinMode(speakerPin, OUTPUT);                                  // set the speaker as output
  pinMode(leftLEDPin, OUTPUT);                                  // set the LEDs as outputs
  pinMode(rightLEDPin, OUTPUT);
  pinMode(leftPadPin, INPUT);                                   // set the piezo speakers as inputs
  pinMode(rightPadPin, INPUT);
}

void soundwave(int note, int howHard ) {                        // function that takes 2 parameters, the note we want to play and how hard the sensor has been hit
  unsigned long endSoundWave = micros() + (35000 * howHard);    // start a count from the microseconds currently registered since the program first ran. And add on an arbitary value multiplied by howHard value
  while(micros() < endSoundWave){                               // while the count is not reached
    analogWrite(speakerPin, 1023);                              // set the speaker to on/ high
    delayMicroseconds(note);                                    // wait the number of microseconds for the note
    analogWrite(speakerPin, 0);                                 // set the speaker to off/ low
    delayMicroseconds(note);                                    // wait for the same number again to complete our oscillation/ soundwave.
  }                                                             // repeat for the length of time.
}

void loop(){

   if (analogRead(leftPadPin) < padLimit) {                     // if the sensor is hit and the reading is less than our threshold
     digitalWrite(leftLEDPin, HIGH);                            // turn an LED on.
     while (analogRead(leftPadPin) < padLimit) {                // while the analog reading is less than the limit
       if (analogRead(leftPadPin) < howHard) {                  // if the reading valueis less than our howHard value (1024)
         howHard = padLimit - analogRead(leftPadPin);           // then rewrite howHard with the new value
       }                                                        // this allows us to capture the peak value.
       soundwave(Cnote, howHard);                               // now generate the soundwave with our note and how had the sensor was hit
    }
  } 

  if (analogRead(rightPadPin) < padLimit){
     digitalWrite(rightLEDPin, HIGH);
     while (analogRead(rightPadPin) < padLimit) {
       if (analogRead(rightPadPin) < howHard) {
       howHard = padLimit - analogRead(rightPadPin);
       }
       soundwave(Dnote, howHard);
    }
  }

  digitalWrite(rightLEDPin, LOW);
  digitalWrite(leftLEDPin, LOW);                                // set the LED's back to low
  howHard = 1024;                                               // set the variable back to the original value

}

[ad#Google Ad in content]

Well what we could do is to add in extra speakers to allow for chords or alternatively work out the frequency of the chord but then you wouldn't get harmonics and it may sound a bit funny. And perhaps I shouldn't have spent all day playing with this annoying my girlfriend.