Instructables

Arduino Audio Input

Featured
Picture of Arduino Audio Input
Send sound into your Arduino.  This Instructable will show you how to prepare audio so that it can be sampled and processed by an Arduino to make sound responsive projects and audio effects.  (This article is a companion to another Instructable I've written about building an audio output circuit for an Arduino, find that here)

Some ideas that come to mind include:

beat detection- trigger lighting effects, build a set of turntables that beat match themselves, or make a robot that dances along with the music you play for it
amplitude detection- make a simple vu meter with LEDS
frequency analysis- you could make a project that reacts to different frequencies in different ways, recognizes certain melodies, turns audio into MIDI data, or translates incoming frequencies into square waves with the tone() library
digital effects boxes/digital signal processing- check out what I did with my vocal effects box (all processing done with Arduino), lots of possibilities here: pitch bending, distortion, sampling, delay, reverb, granular synthesis, mixing, and much more...  I've provided code in this Instructable that lets you sample at up to 38.5kHz.  Here is another instructable describing how to set up a simple audio out circuit with Arduino.
digital recorder- with the addition of an SD card of course (the Arduino has very limited memory by itself), this opens up the possibility of looping large samples and doing lots of other digital manipulations to pieces of stored audio  The circuits and code provided here are compatible with SD card shields that communicate via SPI.
graphical representations of sound- Arduino oscilloscope/visualizer

Feel free to use any of the info in this Instructable to put together an amazing project for the DIY Audio Contest!  We're giving away an HDTV, some DSLR cameras, and tons of other great stuff!  The contest closes Nov 26.

Parts list:
(x1) Microphone Radioshack 33-3038
(x1) TL072 Digikey 296-14997-5-ND or TL082 Digikey 296-1780-5-ND (TL081/TL071 are fine too)  I used a tl082 in my examples
(x2) 9V battery
(x2) 9V battery snap connector Radioshack 270-324
(x1) mono audio jack 1/4" Radioshack 274-340  or Radioshack 274-252 or 1/8" Radioshack 274-333 or Radioshack 274-251
(x1) LED Digikey C513A-WSN-CV0Y0151-ND
(x1) 10kOhm potentiometer linear Digikey 987-1301-ND
(x3) 100kOhm 1/4watt resistors Digikey CF14JT100KCT-ND
(x1) 10uF electrolytic capacitor Digikey P5134-ND
(x1) 47nF ceramic capacitor Digikey P4307-ND
(x1) Arduino Uno (Duemilanove is fine too) Sparkfun DEV-09950

Additional Materials:
22 gauge wire
solder
 
Remove these adsRemove these ads by Signing Up
calmlunch2 days ago

good

sheepbars4 days ago

that's a good point about the op amp, I hadn't thought of that.

Scaling from 10 bits to 8 bits may be quicker with bit shifting instead of that extra math:

amandaghassaei (author)  creditrepairaid18 days ago

yes it is! I just wanted it to be clear what was going on :)

cmars427 days ago

is +5 - 0 ok too (the arduino power) for vcc+ and vcc- ? (if we want to amplify bigger input signals ?)

amandaghassaei (author)  cmars420 days ago

I don;t think that will work with the tl082, but you can try

azalesov26 days ago

Should such scheme work with regular input from a mp3 player instead of mic? I constantly getting just 3 values 0 1023 and something around 512. I dont have an osciloscope but it obviously It does not look like a waveform. tripple checked the scheme.

amandaghassaei (author)  azalesov20 days ago

yes it should work with any analog signal. is there a hackerspace near you where you can get on an oscilloscope?

stupsi991 month ago
Awesome tutorial!!! Thank you very much, this helped me a lot! Now I already have an amplified signal, might have to apply DC Offset to it though (not a big problem with your tutorial!) . I would like to record it to an sd card!
I've searched the web and so far couldn't find the right information. The file needs to be able to be played on a computer later. Any idea how to get this done?
amandaghassaei (author)  stupsi991 month ago

use the sd library, here's an example of logging analog data to it.

clickyummy1 month ago

super

raghavlite1 month ago

i tried the fast sampling code and it seems like the serial monitor gets struct up with these setup commands .for now i am testing with giving zero input at the A0 pin .
I copied the whole of your code and executed it.is there anything else i am missing

the code is .........



int a;

void setup()

{

Serial.begin(9600);

Serial.println("started");

delay(1000);

cli();//disable interrupts

//set up continuous sampling of analog pin 0

//clear ADCSRA and ADCSRB registers

ADCSRA = 0;

ADCSRB = 0;

ADMUX |= (1 << REFS0); //set reference voltage

ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only

ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz

ADCSRA |= (1 << ADATE); //enabble auto trigger

ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete

ADCSRA |= (1 << ADEN); //enable ADC

ADCSRA |= (1 << ADSC); //start ADC measurements

sei();//enable interrupts

//if you want to add other things to setup(), do it here

pinMode(2,INPUT);digitalWrite(2,HIGH);

attachInterrupt(0,up,FALLING);

// Serial.begin(9600);

a=1;

}

ISR(ADC_vect) {//when new ADC value ready

Serial.println("yes");

// incomingAudio = ADCH;//update the variable incomingAudio with new value from A0 (between 0 and 255)

}

void up()

{

a=0;

}

void loop()

{

Serial.println("aaaa");

if(a==0)

{

Serial.println("0000");

delay(5000);

}

a=1;

}

amandaghassaei (author)  raghavlite1 month ago

remove the line:

Serial.println("yes");

you can't put any commands that take a long time in the interrupt - Serial.print takes a long time to execute.

foobar86752 months ago
This is really excellent Amanda. thank you. I have a few questions
  1. Instead of the mic, I have an old USB mic. Can I use that instead?
  2. I'm having a hard time finding the 47nF cap. Can I use a larger one instead? Or is it not necessary as akellyirl says? If it is, is there a rule of thumb that can be applied to the size of the capacitor to remove the signal noise?
amandaghassaei (author)  foobar86751 month ago

you should be fine w/o the 47nf cap. Does your mic output digital usb data? that will not work, you need to use an analog signal.

mavriksc1 month ago

How is the 0V reference not a short?

bearblue1 month ago

wonderful

raghavlite2 months ago

hello amanda,
that was a great tutorial,can you please tell me how to extend this sampling at 40khz to some other(say 3) analog pin of arduino.

anyway thanks in advance

amandaghassaei (author)  raghavlite2 months ago

try putting the line:

ADMUX |= 3;

in the setup

ss13062 months ago

Hi, this maybe a stupid question but how do we prepare the audio signal to be used in this project? can we use any audio signal? Thanks!

amandaghassaei (author)  ss13062 months ago
anything will work, you might have to adjust the gain of the amplifier depending on your audio source.
chimplost3 months ago

that's a good point about the op amp, I hadn't thought of that.

bowerymarc4 months ago
- you should never leave an op-amp unconnected, it'll oscillate or pick up the signal from the other side and clip and heat the package, draw lots of current, and cause the other one to misbehave. Hook it up as a unity gain buffer and ground the input.

- the circuit could damage the arduino since it can drive the input past the arduino's rails. Better to run the op-amp off 0-5V (maybe something with RRIO). Create the VCC/2 bias with a bias network on the + input of the opamp, and AC couple the input and configure as an inverting stage. There's an example of that here: http://www.ecircuitcenter.com/Circuits/opinv_ss/opinv_ss.htm just don't need the output cap (or load R), just go to the Arduino from the opamp output. Also putting a cap in parallel with R2 (from the linked schematic) will give you a bit of a low pass filter, to help with aliasing. with a 200K R, 100pF would give you a corner of 8KHz, first order filter which would be a good start.
amandaghassaei (author)  bowerymarc3 months ago

that's a good point about the op amp, I hadn't thought of that.

hilukasz4 months ago
hey sorry for the stupid question, but you mention you are wiring in series to get 9v, but wouldn't that actually give you 18v if you did series and not the 9v you suggest?
amandaghassaei (author)  hilukasz3 months ago

it gives me +9 and -9, yes technically an 18v spread, but usually when you talk about the power supply for an op amp you talk about the +/-V, in this case +/-9V

steveazhocar4 months ago
yes it is automatically triggered every time a new analog measurement is complete.
matteoM19835 months ago
Hi Amanda, thank you for this excellent tutorial! I'd have a couple of questions about the circuit and will be very grateful if you could answer! :-)

As in many other tutorials, the choice of resistors and capacitors seems to me (I'm very uneducated in hardware) a bit mysterious.

Question 1) From what I understand, the choice of 100k/10k resistors for the opamp is arbitrary, all that matters is the 10:1 ratio. Is this correct? Similarly, the choice of 100k/100k for the voltage divider is arbitrary: you could have used 10k/10k or 100ohm/100ohm

Question 2) Somebody else already asked bout the 49nF capacitor. Interpreting your answer (reducing noise) I guess what this capacitor does is, basically, trying to compensate (i.e., average) changes in the signal. Since this is a very small cap, it helps compensating changes in (what we could consider as) the least important bits of the signal, which are what rumor is about (hopefully).

Question 3) What about the 10uF capacitor? What does it do? Why 10uF? Could we eliminate it entirely from the circuit? What would change? And if not, why?

It seems to me that, without the 10uF cap, the opamp (at the moment when it is emitting -2.5V) would receive some current from the +2.5 side (I guess (5/100k)A = 0.05mA having the 100k resistor). Is this correct?

THANKS!!!!
Hi Matteo,

1) The resistor values can't be too small (100Ohms) because the op-amp has to drive that current e.g. 1V/100 = 10mA. It also can't be too big because op-amp leakage current will cause an offset voltage that gets gained up by the amplifier too.

2) The 49nF cap is usually used to reduce high frequency noise. But it's ineffective in this circuit because it being driven by a 10uF capacitor.

3) The 10uF cap is used to block DC. It forms a high-pass filter with the 100k resistors. It will pass frequencies above 1/(2*pi*R*C) i.e. 1/(2*pi*50k*10u) = 0.32Hz. The reason you need to block DC here is because you want to bias the Arduino Analogue input to Vdd/2 but you don't want that the DC current to flow into the op-amp.
Thank you very much for the nice and instructive answer!

A) Answer 1) is very clear! thanks!

B) Could you please elaborate on answer 2) ?

Which Cap value should be chosen in place of 49nF to effectively reduce high-frequency noise? And how this work precisely? I guess It should work as a Low-Pass filter, but where is the associated resistance? (I have this picture in mind: http://upload.wikimedia.org/wikipedia/commons/3/3b/RC_Divider.svg )

C) shouldn't the expression be 1/(2*pi*100k*10u) = 0.16Hz ?

It seems from your explanation that the value 10uF for the cap (which is anyway necessary to block DC as you explained) is chosen as a function of 100kOhm, basically to allow all frequencies to pass.

Is it correct to say that a 1F cap would work in this context even better? (but of course it would be much bigger and expensive and give just a very small better result in terms of filtering)

Or perhaps a 1F cap would create problems, as it will allow the DC to pass (just after the circuit starts running) for a way too long time? Thank you very much again!
B) The associated resistance is actually the reactance of the 10uF cap. Because there is no resistance involved there is no value of capacitance that will make this arrangement work.

C) It's actually 50k because the 100k resistors appear to be in parallel for AC analysis (because both GND and +Ve are GND from an AC perspective).

As a rule you choose the smallest practical value of capacitance, even if a larger one might work.
Searching the web for ideas about question 3) above, I discovered this is probably a so-called "coupling capacitor".

I only found very generic and not clear informations about how this work. Basically "stops DC and allow AC to pass". This is compatible with the idea that the +2.5 stay fixed on the left, and the -2.5,..,+2.5 can pass making up 0..+5v.

However I'd like to understand how this can happen, in a (relatively) precise way.
Could you spend a few words on this please? It seems to me that this is a very interesting and possibly crucial part of the circuit :)

THANKS!
hi amandaghassaei.
Thanks a lot for this HQ tutorial!
Could yo please expand on how hacking the A/D conversion rate works on a fundamental level?
I thought its conversion rate was a fundamental aspect of A/D and could not be changed.
What negative aspects does this bypassing carry?
Thank you!
amandaghassaei (author)  arodriguez cueto5 months ago
the conversion from A to D takes a certain number of clock cycles (13), but the length of each clock cycle can be changed. That's essentially what I did here. By speeding up the clock to 500kHz, 13 clock cycles takes less time and the analog to digital conversion happens faster. There are some trade-offs though, it's best to keep the clock slow to give time for the analog pins to settle and minimize noise in your analog measurements. Hope that helps!
Thanks so much Amanda!

I have I question for you though, what is the purpose of the 10uF Cap? My understanding is that the output from the amp is -/+ 2.5V. Connecting it directly to the +2.5V wouldn't have the same result? (I know that the answer is no, but it would be nice to explain deeply the flow of electron for the DC offset and why we need the cap).

Also the cap will "store" 5V right? Delta V from +2.5V divider and -2.5V from the amp. Not sure how it works when it is discharging. Vout from the cap will be 5V, and DeltaV from cap to voltage divider will be 2.5V, will this create a 5V signal?

If am correct, a cap with just 2.5V "stored" will not discharge at all since delta V would be 0 between Vcap and Vdivider, am I right?
mjconver6 months ago
Doesn't two 9 volts in series = 18 V? That's higher than 15, not lower.
It's 18V but from -9V to +9V! The total input voltage allowed is 30V (+-15V).
amandaghassaei (author)  mjconver6 months ago
it's +9 and -9 vs +15 and -15
timmyadu5 months ago
Hi Amada, thanks for the awesome instructable.
Quick question: you have set the ADC to be auto triggered. So what's the auto-trigger source?
amandaghassaei (author)  timmyadu5 months ago
yes it is automatically triggered every time a new analog measurement is complete.
Pro

Get More Out of Instructables

Already have an Account?

close

PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!