Strange behaviour with ADC input from a headphone socket.

I’ve been tinkering with the ADCs on a pro mini in the hope of displaying a spectrum analyser on an RGB LED strip. I started off with a simple divider and a coupling cap, which worked but the output level is far too low. I then started a very empirical process to design a basic amplifier circuit to boost the input from a headphone socket by using Qucs.

The schematic is attached although it is modelled with a TL071 because the MCP6022 isn’t in the library. The MCP6022 is a single voltage rail-to-rail chip so the clipping shown on the transient analysis shouldn’t happen. For R1 I’ve used a 10k pot rather than the fixed value so that I can adjust the gain.

I’ve built the circuit on a breadboard and used sox to generate a sine wave of varying frequency to check the input via the Arduino serial plotter. The problem is that I seem to be getting a fixed level, regardless of the volume of the signal, which is via the headphone output of a set of PC speakers. I’ve also tried music, and my mobile phone as the source. I’ve also used my Macbook but it seems to kill the headphone socket. Once I disconnect the headphone lead I don’t get any output from the built-in speakers any more! Ugh! No matter what volume I use, the serial plotter shows a fixed level when looking at the combined ADCH and ADCL output. Changing the amplifier gain by adjusting R1 also has very little effect unless I substitute for a 100k fixed resistor, which drops the gain as expected but it’s still level. I’ve also tried R2 = 10k.

The ADCH and ADCL are combined into a signed int for the FHT (Hartley transform) to work.

I don’t understand why changing the volume has no effect. I’ve spent a few weeks on this now with no success and wondered whether the circuit was to blame, perhaps by providing too much impedance to the headphone input. It’s doing something that my Macbook doesn’t like! The circuit previously didn’t have C3 and R7 but I found a similar circuit, specifically for the MCP6022 in a similar role that had them. There have been around 10 different versions of the circuit but nothing works so it’s probably time to stop the stubbornness and ask for help!

Could somebody point out, without laughing, why this project of mine is failing.

1/The opamp circuit shown will have an ac gain of about -20x. And looks plausible. So far so good.

But...

The TL071 requires at least a 10v supply, and will only swing to within 1.5 volts of either rail.

Use a rail-to-rail 5v opamp to have any chance.

And even then..............

2/ the fastest an arduino can sample is about 10,000/second - which means the maximum frequency it can deal with is 5kHz. Any input frequencies higher than that appear as 'alias's' - ie they wrap around to zero Hz and produce lots of spurious noise. Hence you must restrict the frequency range of the signal by means of a very good low-pass filter.

3/ FFT's by their very name need a lot of speed and a lot of memory. A due might just handle this, but not an AT328-based device. Look at raspberry pi's, or better still, DSP based processors.

eg TI and Motorola (oops - now ON-SEMI) make a range of excellent audio digital processing chips with a/d's and d/a's , and sell demonstration boards. If you're serious about messing with digital audio, this is a good way to go. Time to learn about Z-transforms!

regards

Allan.

I started off with a simple divider and a coupling cap, which worked but the output level is far too low.

I don't know about the Mac but you should get a "usable" level (about 1V) from a cranked-up headphone output, or from a non volume controlled line output. But at "normal" volumes, the signal may be a little low.

You do have too much gain. You've got a gain of more than 20 and 20 x 200mV is 4V. 4V RMS is 11V peak-to-peak and you've only got 5V. But, that's the simulation and we don't know what the actual headphone output is.

You may need "volume" pot to adjust the signal into your amplifier, since you're not going to listen at the same volume all the time. (You can adjust the "gain" (sensitivity) in software too, but of course you can't adjust the gain down if you are clipping.

Once I disconnect the headphone lead I don't get any output from the built-in speakers any more! Ugh!

What? Is your Mac broken? With nothing plugged into the headphone jack, you get nothing from it's built-in speakers?

Normally, the signal goes to the headphones or the speakers, but not both. Are you using a Y-adapter (or something similar) to connect the headphones (or external speakers) and your Arduino circuit at the same time?

perhaps by providing too much impedance to the headphone input. It's doing something that my Macbook doesn't like!

I don't know how the Mac works but you may need a load (lower impedance than your amplifier input) so the Mac "thinks" headphones are plugged in, and you may need a DC load (no capacitor). You do need the capacitor on your amplifier input, but you may need an additional DC load (such as a resistor or headphones). Headphones are typically in the range of 32-64 Ohms and powered speakers should have an input impedance in the ballpark of 10K.

Of course, the headphone connection on the computer is an output, not an input. ;)

No matter what volume I use, the serial plotter...

How about simply displaying the ADC readings directly (like the Analog Read Serial example)? It would also be helpful to do that experiment without the amplifier (but with the bias circuit) to get an idea of how much gain you need.

P.S.

I've been tinkering with the ADCs on a pro mini in the hope of displaying a spectrum analyser on an RGB LED strip.

People have FFT spectrum analyzers with the Arduino, but I believe it's usually a spectrum analyzer effect, rather than an accurate-usable spectrum analyzer instrument...

If you can get by with 7 frequency bands or less, the [u]MSGEQ7[/u] does 7-bands of filtering in hardware (so you don't need FFT) and it takes care of the DC bias problem. (I don't recall if it provides any gain.)

Hi there. Thanks for the replies.

@ DVDdoug My Macbook still works. The built-in speakers just temporarily stop once I plug the headphone cable that feeds the circuit and then pull it out again. No splitters. I think the headphone out also has some other functions such as optical, with the right cable, which is why it might be playing up a a bit. My mobile phone can detect some types of headphone and it has a bit of a problem at first but eventually allows me to play.

I did think I was saturating the ADCs at one point but after swapping some resistors I'm not so sure any more. I'll take a more analytical approach but I do lapse into the more empirical method out of frustration at times.

I did consider the MSGEQ7 but I wanted some flexibility in determining how many bands I displayed. I have seen some LED matrices running with a reasonable output. By that, I mean the output appears plausible rather than bob-on accurate. My Raspberry Pi stuff is as accurate as I can make it as far as ballistics are concerned but that's only a VU meter for now.

I'll try some more basic functions and test the code from the ground up rather than start at such a high level.

Your comment regarding the RMS gain has made me think. I was basing everything off peak values so I'll ponder over that and see if I can figure something out.

@allanhurst I had to model with the TL071 as the op-amp I intended to use doesn't have a representative model in Qucs. Also, the FHT does appear to work really well. My mini is a 16MHz 5V version so with a divider of 32 I can sample 2 channels at roughly 19kHz after allowing for the 11 duty cycle for each ADC conversion. It is adequate given the 20Hz - 20kHz perceptible audio range. I think it is also possible to go higher, not just by decreasing the divider further, but also by using 8-bit mode.

I'll look into the kits. Audio is a big thing for me but electronics is fairly new territory.

alidaf: I've been tinkering with the ADCs on a pro mini in the hope of displaying a spectrum analyser on an RGB LED strip. I started off with a simple divider and a coupling cap, which worked but the output level is far too low. I then started a very empirical process to design a basic amplifier circuit to boost the input from a headphone socket by using Qucs.

You can simplify that circuit: Change R4 and R5 to 100k each, lose C3, and replace R7 and C2 by a direct connections.

That still gives you an AC coupled input, a 50% voltage divider and a 50k input impedance (47k is standard-ish for audio) and a high-pass characteristic. I'd make C1 a bit larger if you want flat frequency response down to 20Hz.

No splitters.

You're going to need a [u]Y-Adapter[/u] if you want to listen while using the spectrum analyzer. And, it would be really helpful to be listening at normal-loudness so calibrate the gain/sensitivity of your lighting effect.

Your comment regarding the RMS gain has made me think. I was basing everything off peak values so I'll ponder over that and see if I can figure something out.

The peaks are the critical measure since it's the peaks that cause clipping. But, I assume 200mV in your simulation is RMS.

Of course, regular music is not a constant tone and music can have a peak-to-average (or peak-to-RMS) ratio of 15-20dB.

The mini clock may be 16MHz, but the a/d takes 100us whatever the clock rate.

You imply your mini can sample in about 1 / 2(channels) x 19kHz x 2(Nyquist) == about 13uS

Nope.

And you forgot about the low-pass filter. At least a 7-pole Chebyshev or elliptic. Or if you're fussy about phase a MUCH bigger Bessel.

It ain't that easy.

Allan.

@MarkT Thanks, I think I've had an iteration that was very similar but I'll try those changes tomorrow.

@DVDdoug My thought was to adjust by having a peak level hold indicator for each band and adjusting the gain until I had a visual effect that I was happy with. Plus I don't have the parts to create an input and pass-through, or even a splitter cable. Yet! I had thought about integrating over time to get a more VU meter feel for each band, which would be less twitchy from the peak values but I'll get over this bit first. Thanks for the input.

@allanhurst You are undoubtedly correct on all of these issues and I appreciate the input. I'm not trying to create a professional reference tool, just something that works well enough visually to give a good feel. It isn't easy at all. I'm completely lost on the maths of the FHT but this whole process is a learning tool for me. I can't read a book and understand. I have to try things out and build up some frame of reference as I stumble about. I jump in the deep end and try and learn to swim. I'll follow up on the things you have mentioned but please don't have a go at me for trying. I have a difficult enough time getting on with things as it is.

The mini clock may be 16MHz, but the a/d takes 100us whatever the clock rate.

That is simply not correct.

The A/D conversion takes [u]13 ADC clock cycles[/u] on an ATMega328, and the ADC may be clocked at up to 200 kHz for full 10 bits resolution with specified accuracy.

You can clock at much higher rates with some loss of resolution (that is, noise added). People have used up to 1 MHz ADC clock rates with acceptable results.

@OP you [u]must sample at 40kHz[/u] to digitize a [u]single[/u] channel of audio with 20 kHz maximum frequency.

If you sample at less than that, it is absolutely essential to prevent frequencies higher than half the sample rate from getting to the ADC, or the results will be hopelessly muddied by aliasing.

Example: if you sample at 10 kHz and allow a 6 kHz signal to reach the ADC, a spurious signal will appear at at the folded frequency of 4 kHz.

@jremington Thank you for jumping in. Without the op-amp I could actually see a small peak traversing across the frequency bins when playing a sine wave increasing in frequency from 100-18kHz so I knew that statement wasn't true. I just don't have the patience to argue against fervent dogma.

With the op-amp I am seeing an awful lot of what I thought were harmonics. I'll push the divider down to sample both channels at a minimum of 80Hz but may have to go for an 8-bit approach. If the noise is low enough then I won't be too bothered by it as my frequency bands will only have 15 LEDs each so accuracy isn't an issue. I'll read up on folded frequencies as it isn't something I've heard of. With a complex signal I won't know which frequency bins have real content or spurious 'folded' content so that is an important issue. At the end of the day, I have a start and the more I learn from the experience the better. I'm not doing this as a project to create something to show off, but to try something I never have.

For now though, it's a case of stripping back to basics and looking at exactly what the ADCs are giving so I can get the gain issue sorted. Many thanks.

Hi, The MAC may have differential output for its loudspeakers. The speaker terminals are fed two signals, 180deg out of phase, instead of having one speaker terminal at gnd.

When you plug your plug in with one terminal at gnd, you short that amp, it shuts down to protect itself.

That way the speaker is supplied with a signal that is Vpp of the power supply, rather than 1/2 power supply via an output capacitor.

Tom.... :)

Thanks @TomGeorge.

With the op-amp I am seeing an awful lot of what I thought were harmonics.

You need an active low pass filter (Sallen-Key is the simplest and it can supply some gain), with a cutoff below half the sampling frequency, and make sure that the op amps aren't clipping.

alidaf: With the op-amp I am seeing an awful lot of what I thought were harmonics. I'll push the divider down to sample both channels at a minimum of 80Hz but may have to go for an 8-bit approach. If the noise is low enough then I won't be too bothered by it as my frequency bands will only have 15 LEDs each so accuracy isn't an issue.

Hi alidaf. Have you reduced the gain of your op-amp circuit yet? Letting it saturate will definitely give you harmonics.

If you want to keep your external circuitry to a minimum, have you thought about just reducing the Aref signal instead of amplifying your audio? Using a voltage divider (and smoothing cap) for example on the analog reference input? You could perhaps even use just the internal 1.1V reference, though that might be a little bit too low for your peak to peak input.

Another thought. How much spectral variation do you get between L and R audio channels for typical music content. Personal I would have thought not very much. Perhaps you could ease you sample rate constraints by combining the channels into mono (very simple passive cct) before sampling.

Also, I was wondering what method your are using for processing. Are you storing a short burst of data samples and then processing that non real time (I assume that you can't take the full DHT in real time). Or are you just evaluating the DHT at a relatively small number of discrete frequencies and managing to do that in real time?