Skip to content

Instantly share code, notes, and snippets.

@timpulver
Last active November 28, 2017 19:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save timpulver/5ba4a29cddd543b4a900 to your computer and use it in GitHub Desktop.
Save timpulver/5ba4a29cddd543b4a900 to your computer and use it in GitHub Desktop.
How to trigger an audio file with an analog sensor using Processing and Arduino

Keywords: Arduino, Processing, Serial, Communication, Analog, Sensor, Distance, Pressure, Prototyping, Minim, Audio, MP3, Play, Audio File
Author: Tim Pulver
Last update: 2015-12-07

Wiring

In this example we are using an analog distance sensor (Sharp 2Y0A02). The setup will be very similar when you are using another sort of analog sensor (e.g. an analog pressure sensor). Make sure to know the right pin order. What mostly works here is to google for the part you want to use (e.g. pressure sensor) together with the keyword arduino, so e.g. arduino pressure sensor. You will then find some images showing how to wire the sensor up. In all cases you need to connect one wire to 5V on the Arduino (red here), one to GND / Ground (black here) and one to an analog pin – in this case A0 (yellow / white / green wire).

Distance Sensor Hookup Image

Now that everything is wired up, let’s upload some code…

Arduino

Open the example File —> Examples —> Basics —> AnalogReadSerial. As examples are read-only, we need to create a copy in order to edit it, click on File —> Save As then choose a name, e.g. ArduinoSoundTrigger. Your sketch should look like this now:

/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

 This example code is in the public domain.
 */

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}

Before you upload the code to test if the sensor is working and everything is hooked up right, you need to make sure that the right Board and Port are selected. Go to Tools —> Board and select the board you are using (here we are using an Arduino Leonardo. Check out the writing on the board to find out which one you use.

Board Selection

Additionally we need to set the correct port. Go to Tools —> Port and select the one with your board name. If there is no port with your board name close the Arduino app, reconnect the Arduino and run Arduino App again. If it still does not show up try another USB port.

Port Selection

Now let’s upload the code, by pressing the upload button (second icon).

Upload button

After some seconds you should see a message like Upload successful.

Successfull

Open up the Serial Monitor by pressing the magnifier-icon in the top right corner.

Serial Monitor Icon

Make sure the correct baud rate is selected. It basically is the speed data is transferred between the Arduino and the computer. In our case we are using 9600, which should be a good choice for most applications.

Serial Monitor Baud Rate

Code Baud Rate

You will now see the live sensor data sent from the arduino. Experiment a bit by interacting with the sensor and get a feeling how the values change.

Serial Data

In order to trigger something using a sensor, we need to create the trigger logic, so let’s say we want to trigger an audio file once something is very near the distance sensor. Close the serial monitor and go to Arduino —> Settings and check Show line numbers.

Line numbers

Now add the following code below the line Serial.println(sensorValue); (line 20):

if(sensorValue > 200) {
    Serial.println("T"); // send the letter T (for Trigger) once the sensor value is bigger than 200  
}

Your whole sketch should look like this now:

 /*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

 This example code is in the public domain.
 */

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  if(sensorValue > 200) {
    Serial.println("T"); // send the letter T (for Trigger) once the sensor value is bigger than 200  
  }
  delay(1);        // delay in between reads for stability
}

Now upload the code and check the serial monitor again. Once our hand is very near the sensor we now should see the letter T in the serial output. If you are using a different sensor you probably want to replace 200 with another value and maybe you need to replace the > sign with < as well, so that it only triggers when the sensor value is smaller than the threshold value (200). So depending on your sensor line 21 should look like this: if(sensorValue > 200) { or if(sensorValue < 200) { or if(sensorValue > 500) {. Experiment a bit to find the perfect threshold for you. That should be quite easy as you can always check the serial monitor to see when the letter T is printed. When you change the value you have to reupload the code of course.

Processing

So now we have everything set up to use our analog sensor trigger with Processing. Make sure you have the newest version installed, run it and paste the following code:

import processing.serial.*;

int lf = 10;    // Linefeed in ASCII
String myString = null;
Serial myPort;  // The serial port
int sensorValue = 0;

void setup() {
  // List all the available serial ports
  printArray(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[0], 9600);
  myPort.clear();
  // Throw out the first reading, in case we started reading 
  // in the middle of a string from the sender.
  myString = myPort.readStringUntil(lf);
  myString = null;
}

void draw() {
  // check if there is something new on the serial port
  while (myPort.available() > 0) {
    // store the data in myString 
    myString = myPort.readStringUntil(lf);
    // check if we really have something
    if (myString != null) {
      myString = myString.trim(); // let's remove whitespace characters
      // if we have at least one character...
      if(myString.length() > 0) {
        println(myString); // print out the data we just received
        // if we received a number (e.g. 123) store it in sensorValue, we sill use this to change the background color. 
        try {
          sensorValue = Integer.parseInt(myString);
          // As the range of an analog sensor is between 0 and 1023, we need to 
          // convert it in order to use it for the background color brightness
          int brightness = (int)map(sensorValue, 0, 1023, 0, 255);
          background(brightness);
          // do some other stuff with the sensor value?
          // ...
        } catch(Exception e){}
      }
    }
  }
}

Click on File —> Save and name it SerialDataColorChange.

In order to receive data / messages from the Arduino, we have to make sure the right serial port is selected. This is important. Run the Processing sketch by pressing the play button.

Processing Play Button

In the black area on the bottom of the Processing window you should see an output similar to this:

[0] "/dev/cu.Bluetooth-Incoming-Port"
[1] "/dev/cu.LightBlue-Bean"
[2] "/dev/cu.SMiRFDEViCE-RNI-SPP"
[3] "/dev/cu.usbmodem14231"
[4] "/dev/cu.usbserial-AI02KLKK"
[5] "/dev/tty.Bluetooth-Incoming-Port"
[6] "/dev/tty.LightBlue-Bean"
[7] "/dev/tty.SMiRFDEViCE-RNI-SPP"
[8] "/dev/tty.usbmodem14231"
[9] "/dev/tty.usbserial-AI02KLKK"

One of them is the port we want. To find out which one open Arduino, then go to Tools —> Port.

Port Search

In my case it’s /dev/cu.usbmodem14231 (Arduino Leonardo). Go back to Processing and look at the output in the debug console (the black area on the bottom) again. Find the serial port name we just looked up in the Arduino app. For me this is [3] "/dev/cu.usbmodem14231".

Okay, now that we know the correct serial port we need to change the line String portName = Serial.list()[0]; (line 12). Replace the 0 with the number we just found out. In my case it’s 3. Mine looks like this now: String portName = Serial.list()[3];.

Run the sketch (by pressing the play button) and you should see the background color of the sketch changing according to the sensor data.

Good. Now let’s trigger an audio file.

To play audio we need to add a library. Go to Sketch —> Import Library —> Add Library and search for minim. Install minim by pressing Install in the bottom right.

Install Minim

In order to use the library we need to restart Processing.

Create a new sketch and save it as TriggerAudioSampleByArduino.

Paste the following code:

import processing.serial.*;
import ddf.minim.*;

Minim minim;
AudioPlayer player;

int lf = 10;    // Linefeed in ASCII
String myString = null;
Serial myPort;  // The serial port
int sensorValue = 0;

void setup() {
  // List all the available serial ports
  printArray(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[0], 9600);
  myPort.clear();
  // Throw out the first reading, in case we started reading 
  // in the middle of a string from the sender.
  myString = myPort.readStringUntil(lf);
  myString = null;
  // we pass this to Minim so that it can load files from the data directory
  minim = new Minim(this);
  // loadFile will look in all the same places as loadImage does.
  // this means you can find files that are in the data folder and the 
  // sketch folder. you can also pass an absolute path, or a URL.
  // Change the name of the audio file here and add it by clicking on "Sketch —> Import File"
  player = minim.loadFile("some_audio_file.mp3"); 
}

void draw() {
  // check if there is something new on the serial port
  while (myPort.available() > 0) {
    // store the data in myString 
    myString = myPort.readStringUntil(lf);
    // check if we really have something
    if (myString != null) {
      myString = myString.trim(); // let's remove whitespace characters
      // if we have at least one character...
      if(myString.length() > 0) {
        println(myString); // print out the data we just received
        // if we received a number (e.g. 123) store it in sensorValue, we sill use this to change the background color. 
        try {
          sensorValue = Integer.parseInt(myString);
          // As the range of an analog sensor is between 0 and 1023, we need to 
          // convert it in order to use it for the background color brightness
          int brightness = (int)map(sensorValue, 0, 1023, 0, 255);
          background(brightness);
        } catch(Exception e){}
        if(myString.equals("T")){
          if(player.isPlaying() == false){
            player.play();
          }
        }
      }
    }
  }
}

As we did in the sketch before, change the line myPort = new Serial(this, Serial.list()[0], 9600); (line 16) to fit your serial port. In my case myPort = new Serial(this, Serial.list()[3], 9600);. Now add an audio file by pressing Sketch —> Add file. Additionally you need to change the line player = minim.loadFile("some_audio_file.mp3"); (line 28) accordingly to fit your filename. Mine looks like this now: player = minim.loadFile("Pulpo-Untitled_(CCCP016_Track_2).mp3");

Now press play again, interact with your sensor and the audio file should start playing.

Wohoo!

@zzzunaaa
Copy link

Hi,

I am working on a project with four analog sensors that are supposed to trigger four different samples. I was using your code but I'm not sure how to adapt to make the sensors each play individual files.
Could you give any advice? I am a beginner with both Arduino and Processing so it might be something simple that I just can't work out.
Thanks!

@stillwalks
Copy link

I am wanting to do the same thing - multiple sensors to trigger different sounds. Any help is appreciated. Thanks.

@JordanParry
Copy link

Hi Tim, thanks for the info! Very comprehensive however could you please explain how to use a single sensor to trigger different samples based on higher or lower numbers coming from the sensor? Also, is it possible to connect two sensors to the Arduino and have them do the same thing on their own channels or is it necessary to have two Arduinos, one per channel?

Thanks again.

@Millstone99
Copy link

Millstone99 commented Nov 28, 2017

Excellent tutorial. I'm making a program to help me move more while at work, and I wanted my arduino to sound through my PC and this does the trick. I've edited your sample code slightly to play three separate audio files that I cycle through with a button, but I'm having one problem. The files are only playing once until I stop and rerun the sketch. Any suggestion as to how to allow them to play each time I press the button?

Edit after 30 minutes of googleing. I need to add player.rewind(); after each player.play(); in order to move the playerhead back to the beginning of the audio files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment