Measuring audio input on microcontroller ADC - Page 1
Forum section: electronics / beginners

author: GiantGnome
author_rank: Contributor
timestamp: July 13, 2014, 05:49:30 pm
content: Hi allIt's funny, isn't it? You just want to connect your music player's (smartphone) audio output to your arduino, maybe making LEDs blink in interesting patterns based on the music. You have a thought that the atmega328 probably won't like to have an AC signal connected to any pins, and next thing you know, you are out of your depth, reading up on analog circuits, opamps, virtual grounds for single supply.So, right now, I am in a bit of a confusion on the details. I basically have a setup with a stereo cable running from my phone to the circuit, with a black, a red and a white wire. In the following, I will stick to the black and the red (I mean, stereo is just a matter of doing things twice, right?)This is what I have gathered so far:For using an opamp with at single supply, treating an AC signal, I need to create a virtual ground (usually halfways between VCC and GND (GND being the GND-pin on the arduino, the 'ordinary' ground in the circuit)). As far as I can tell, a adequate way is to do it with a voltage divider and an opamp buffer - see my first attachment.Then I need to AC couple the input signal to remove any DC component, and amplify the signal with an opamp, using the virtual ground where you normally put ground in a non-inverting amplifier circuit. I have tried to draw this in my second attachment.Now, my questions for you are:0. Does my approach make any sense at all?1. Do I need to bias the signal to virtual ground after AC-coupling it with a capacitor? I have drawn some dashed resistors, that I think would do the job. It would seem the logical step for me, but I have seen circuits that doesn't do this.2. One could think it intuitive to connect the black wire from the audio input to the virtual ground instead of GND, but my gut tells me 'no'. Is my gut correct this time?3. Where are good spots to put noise reducing capacitors? I would have it on the VCC+ pins for the opamp, but maybe elsewhere would be smart?4. If I should design doing this on a PCB, I have read that ground planes are essential in analog circuits - now should I make a 'virtual ground' ground plane around this circuit?The two opamps in my test setup is an LM358, connected to VCC and GND.

author: adi101
author_rank: Contributor
timestamp: July 13, 2014, 08:36:42 pm
content: Your approach makes perfect sense to me.To answer your questions:1. Yes, bias is needed. You can do that as drawn, or by using a single resistor connected to virtual ground.Usually, R3 resistor is connected to GND through a high value capacitor, not to the virtual ground. This has the advantage of setting a DC gain of 1.If the DC gain is not 1, the DC offset gets amplified too and offsets the DC output voltage.2. It depends if the audio input's power supply is also used for the operational amplifier or not.If the circuits share the same power supply, then connect the black wire to GND. Otherwise, you could connect it to virtual ground too.3. Definitely put a high value capacitor on the divider used for the virtual ground.4. No, use the GND for that.The most important thing is avoiding the so called ground loops.Good luck with your project.

author: rob77
author_rank: Super Contributor
timestamp: July 13, 2014, 09:02:42 pm
content: i would give try to the following approach1. bias the adc input of the arduino to 2.5V2. add limiting diodes to the input (fast ones)3. connect the headphone output through a capacitor to the adc pinyou won't get good results, but it should be enough to wigle the adc input and get some readings related to the input signalif you want to blink a led according to the music - then it should be enoughattached a schematic to describe the ida better.

author: GiantGnome
author_rank: Contributor
timestamp: July 14, 2014, 09:24:09 am
content: Thanks for the answers, guys.I will try building it up during this week, hopefully.Rob77, that WOULD be more simple - my first idea was making a 8 led VU-meter, and I think your suggestion would do fine for that sort of low resolution.(And sorry for posting 6 megapixel schematics, next time, I will remember to scale it down before posting - GiantGnomeCAD (or ggCAD) only exports high resolution images)

author: Psi
author_rank: Super Contributor
timestamp: July 14, 2014, 09:26:42 am
content: Quote from: GiantGnome on July 14, 2014, 09:24:09 amYep, a simple voltage divider and decouple cap like rob77 suggests will work perfectly fine for any sort of VU meter or even a simple spectrum display.To get the VU meter to respond better i suggest a low pass filter, a simple running average will work fine.Typically a VU meter cannot physically move the needle fast enough to display high frequencies so trying to display high frequencies just leads to bad looking meter movement.

author: dentaku
author_rank: Frequent Contributor
timestamp: July 14, 2014, 11:31:33 am
content: I've actually never used a microcontroller but I've used audio signals for controlling things before and found this document very useful.https://www.site.uottawa.ca/~rhabash/ELG4135L8.pdfPages 11 and 12 describe "A Precision Peak Rectifier" and "A Precision Peak Detector"I wonder of these would be useful in your situation?

author: Psi
author_rank: Super Contributor
timestamp: July 14, 2014, 11:43:02 am
content: Peak detect in software is easy.Declare a variable to store the peak value. lets call it "max".Every time you get new ADC data check if the value is greater than max. If it is then set max to the adc value (current value becomes new max). Then, at a much slower rate, keep reducing max by a small amount until its zero.The max variable will now track along with the waveform peaks and slowly decay back to 0 if there's no sound.You can adjust the speed of the reduction to get a faster/slower decay.Tip: If you set the ADC in differential mode with a 2.5V reference you can get a nice signed byte output. Otherwise you have to subtract 512 from the value. You can also rectify the waveform with a simple abs() function.

author: dentaku
author_rank: Frequent Contributor
timestamp: July 22, 2014, 12:20:37 pm
content: Quote from: Psi on July 14, 2014, 11:43:02 amI've got to get myself a cheap Arduino clone sometime because that looks so much easier

author: GiantGnome
author_rank: Contributor
timestamp: July 22, 2014, 01:23:54 pm
content: Hi allI have been experimenting a bit with these circuits, and have come up with something like the attached schematic.I basically have taken my original, made the gain and the bias (VGND) adjustable, and have been using the VGND for the negative input on a differential ADC. The reason for making VGND is to compensate for my op-amp (a lowly LM358) not being rail-to-rail. I observed my postive readings maxing out much sooner than the negative ones.I started to use the differential mode on the ADC (had to go a bit beyond the arduino libraries for that), and used the internal 2.56V (*) reference instead of AVCC.My only way of testing this is using the serial output to display readings, then plotting them in a spreadsheet. I currently get pretty good resolution, but I haven't got a clue about its accuracy.I had to rewrite the analogRead function, to be able to use the ADC in the way I wanted. A good side-effect was a theoretical speed-up, since I could set the ADMUX register once, and then continue making conversions, instead of setting it each time. I had somewhat of an issue converting the 10 bitsignedADC-value to a 16 bitsignedinteger. I think I managed to do it with som bit-juggling, but that probably removes the speed-up from not setting the register each conversion.Thanks for the help!*Since the Atmega328 on my Arduino UNO doesn't seem to support differential conversions, I found my Arduino Leonardo, and started experimenting with that instead. The Atmega32u4 on the Leornardo have a 2.56V internal reference instead of the 1.1V in the Atmega328.

author: GiantGnome
author_rank: Contributor
timestamp: July 22, 2014, 01:28:45 pm
content: And hooraay!!! I forgot to attach my circuit

author: tszaboo
author_rank: Super Contributor
timestamp: July 22, 2014, 03:45:56 pm
content: Yes, the LM358 is the perfect trap for people without analog experience. It would have been easier to just replace it with something more decent, than to write a single line of code. Look for Rail to rail in, out, and offset voltage comparable to your LSB.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: July 22, 2014, 04:37:19 pm
content: You show VGND shorting out the input signal. Bias has to be applied in such a way that the signal itself still gets through. A large series resistance, or even an inductance (more typical of the *very* old days) is usually the way.LM358 has basically no steam left on 5V, try TLV2372 or such.Tim

author: GiantGnome
author_rank: Contributor
timestamp: July 22, 2014, 04:57:56 pm
content: NANDBlog,I must say that I still feel that differential mode feels nicer, so I would probably still use the code. I have wondered if I shouldn't get a better op-amp, but the LM358 was in my box of components.I do have a OPA314 sample lying around which seems to be more within spec. I have no real experience evaluating the specs of op-amps, but...:The OPA314 have a spec input voltage offset of 0.5mV - gain of 10 makes that 5mV on the outputThe 10 bit accuracy at +/- 2,5V -> 5V makes LSB 5mV.This means that I now have a 1 LSB error on the ADC (originating from the op-amp, other sources not-withstanding)The dual version of the opa314 is pin-compatible with the LM358 (and the L1013), so maybe if I choose to spin a PCB, I could try to compare the performance.Is there anything else to look at? For audio frequencies, I wouldn't expect speed to be a problem, but I wouldn't know where to start.

author: GiantGnome
author_rank: Contributor
timestamp: July 22, 2014, 05:02:34 pm
content: Quote from: T3sl4co1l on July 22, 2014, 04:37:19 pmLuckily, this is a CAD error, actual circuit has a 100k (or was that 10k, i forget.) resistor there.Quote from: T3sl4co1l on July 22, 2014, 04:37:19 pmThis is the analog sort of experience I lack. The specs say only a 300mV difference in the minimum supply. I guess some graphs in the data sheet show this?

author: rob77
author_rank: Super Contributor
timestamp: July 22, 2014, 05:13:20 pm
content: actually it's easy - if the opamp goes Vcc-1,5V on the output - then you'll get 3,5V max on the output with 5V supply.find an opamp which can go almost to Vcc ( a real rail-to-rail one ).

author: T3sl4co1l
author_rank: Super Contributor
timestamp: July 22, 2014, 05:27:28 pm
content: Quote from: GiantGnome on July 22, 2014, 05:02:34 pmYeah, sure, "CAD" error...Tim

author: nuno
author_rank: Frequent Contributor
timestamp: July 23, 2014, 01:03:47 am
content: Not sure if you noticed it, but ATmega32u4 has a differential ADC input mode with 10x or 40x gain with 8 meaningful bits.