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 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.


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:
// 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

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:

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:
// 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:
  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.
  // 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

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 ) {
    else if ( pulse < 8 ) {
    else if ( pulse < 11 ) {
    else if ( pulse < 14 ) {
    else if ( pulse < 17 ) {
    else if ( pulse < 20 ) {
    else if ( pulse < 23 )  {
    else if ( pulse < 26 ) {
    else if ( pulse < 29 ) {
    else if ( pulse < 32 ) {
    else if ( pulse < 35 ) {
    else if ( pulse < 38 ) {
    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]


  • Love your stuff! Keep up the good work!

    • hey thanks… just glad others can use what I’ve found out. :)

      • Yeah, I’m just starting with Arduino, but fell in love with it from my first experiment. :)

        • I started off with programming and find its very satisfying to have a phyiscal effect rather than just contained within a screen. If only I could get paid to work with Arduino! :)

          • Hehe, these are my exact thoughts! I’ve been coding for more than 15 years and it’s such a delight to affect physical world with my code :)

  • Hey, this has been super helpful. I am have been trying to connect a parallax 28015 range finder in place of the one that you have used. It only has one signal pin though. Can it still be done? and if so how would I modify the code?


    • Yep it can be done with just a single pin. What that means is the single pin is doing both the trigger and echo functions – the SRF05 can do this also but I like the simplicity of 2 pins (as I can understand that) Check this tutorial here:

  • Thanks for your response! I went ahead and used this ping code – and it definitely communicates with the processing code but I get no actual sonar interaction it just keeps playing only one of the notes over and over. It isn’t recognizing any of the distancing data – therefore not playing any of the other notes.

    I am sure I am missing something here. I am new and sincerely appreciate your help with this!

    Thanks again.

    • you can mail me the code via the contact form on the site or post it up in the comments and I’ll take a look at it.

  • hey, im studendt from mexico and your information is amazing ¡¡¡¡¡¡¡¡¡ love your blog¡¡¡¡

    • Hey no problem Gary, glad it helped.

  • I’m getting a message that keeps repeating saying
    -Minim Error-
    – Likely buffer underrun in AudioOutput.

    how do i fix this? there is no sound coming out but no other error messages

  • Hello I’m new to a lot of this and I am getting confused with all the programs needed to make this work. I am getting confused on what all the programs are needed for processor and arduino and in what sequence. I ran the serial library and the firmata and the minim, but i keep getting error messages like “avrdude: stk500_rec(): programmer is not responding”. Then in processing when I run the arduino examples sketch It says “note that release 1.0, libraries must be installed in a folder named “libraries” inside the “sketchbook” folder.”

    I’m just utterly confused on what codes I need to run and in what order. I appreciate any help you an give. Thanks.

  • I love the website, but I too am getting the minim error “likely buffer underrun in AudioOutput”. I checked out ddf’s site that you linked to (compartmental) but can’t find any help in the documentation regarding the problem. In the processing forums ddf said that he added this error message but didn’t list a solution there either haha. I’m thinking it could be something between my serial communication and processing…

    Were you using Windows when running your sketch?

    • mine was on windows XP. I make sure I’m not running anything on the USB ports at the same time as processing as it does tend to get funny about that. Try a different port, also try a set of test code with minim to see if it’s any of my code going wrong – my blog updated and messed up a fair few code examples.

    • Hi! I love that website too!

      But, also, I have the same problem… the error “likely buffer underrun in AudioOutput”
      I don’t know what to fo :(

      I’ve tried changing the function Audiosample by another one, but I didn’t work at all :(

      If you had some idea, I’d be very pleased!!

  • […] [Michele] and [Larry] […]

  • […] [Michele] and [Larry] Share this:ShareFacebookDiggStumbleUponRedditEmailPrint Address: […]

  • […] Via: Arduino Blog, Source: Larry […]

  • Getting an ArrayIndexOutOfBoundsException: 1 on myPort = new Serial(this, Serial.list()[1], 9600);
    as well as the “likely underrun” error as everyone else. ): any recommendations?

  • i’m getting an error in processing while compiling…….
    i get an error saying NullPointerException
    and then it highlights the GSharp = minim. loadSample(“GSharp.wav”, 2048);

  • I am also getting the:

    Minim Error
    Likely buffer underrun in AudioOutput

    Any thoughts or suggestions?

  • Hey, It’s not working for me either. im using mac osx, should this make a difference

  • Hello Larry . I;m having a problem , my code is working it ‘s getting compiled but when i approach my hand on the ultrasonic sensor it doesn’t get me the .wav sound . Do u know why ?

  • Hello Larry, I’m wondering if you’ve tried your projects if it can detect stairs or surface discontinuities? May i know what can be a possible sensor that can be use?
    thanks! Sorry for the trouble :)

Join the Discussion

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>