-
Basic ADC setup with MCU
Posted by
Saimoun
on 20 Mar, 2021 12:27
-
Hi
So the situation is simple, I have:
* an audio signal, coupled to GND (centered around 0V), about 1V peak-to-peak, with low output impedance (about 10-15 Ohm)
* An MCU (STM8) with an internal ADC, with a 3.3V rail
This is for a test device, so I only want the MCU to check that the audio signal kinda ressemble what it should - it is also very short so I can have a copy of the signal in the internal MCU memory to compare it with the incoming audio.
My question - what circuit should I setup?
I have pretty much no experience with ADC's, I was kinda looking for an input impedance in the datasheet (see pic attached -
https://www.st.com/resource/en/datasheet/stm8l151g6.pdf) but could not find one.
Thank you!
Cheers
Simon
-
#1 Reply
Posted by
Siwastaja
on 20 Mar, 2021 12:41
-
ADC input is the tiny sampling capacitor (in order of 10pF) which needs to charge up during the sampling time (in order of tens of ns to a few dozen µs). These values are in the datasheet, sampling time is adjustable on some controllers.
Optimally, you would like your driver to have zero output impedance to drive the ADC. Practically, with this sampling cap / sampling time RC time constant, you can calculate the maximum error your input impedance causes. Depending on the required accuracy and sampling time setting, you typically end up needing something below between 10 to maybe 500 ohms. Rarely you can accept multiple kilo-ohms.
If you need to AC couple and bias your audio signal, likely buffering it with an opamp is a good idea to feed the ADC with low enough impedance.
Note there is very little DC leakage in the ADC so if you don't need high BW nor need to sample at high sample rate, a simple capacitor satisfies the low impedance requirement easily. To approximately 10-bit accuracy, you want the filter cap to be 1000 times the sampling cap. 100n to 1u is typical. Now this filter cap only needs to charge during the time between samplings (not sampling length) which eases the input impedance requirement. Now it forms an RC filter for the signal though, sometimes you want this so two flies with one stone. Temperature and battery voltage measurements are typical applications.
-
#2 Reply
Posted by
T3sl4co1l
on 20 Mar, 2021 12:45
-
The ADC is easy, good beginner question.
Just AC couple it -- audio rarely needs to be DC coupled. Series capacitor between source and ADC, maybe 10uF (electrolytic, don't use ceramic as they are microphonic), resistor divider from VCC to ADC to GND (equal values, say 100k). ADCREF and AVCC from VCC, filtered.
The matching however -- good luck! In what way do you want to check the signal? Vrms? Frequency? Statistics? Distortion (given a known, ideally pure sine, source)? Frequency response (given some other known source, and probably an FFT)?
The number of possible combinations is exponential with however many samples are in the window -- this is very far from a well-defined problem, even for relatively well defined problems! (You haven't defined your problem at all except in the most vague way, therefore I'm left to assume anything and everything...)
Or for example, even if the source is very well known and repeatable (e.g., a playback of the same sample), how do you know the gain or phase or delay will be similar? If you simply subtract them, sample by sample, they will only cancel out when everything is the same -- even though all of these parameters can change and still be "the same signal" to a listener. If the comparison should be done on every sample (as a sliding window), you need to compare the entire window every sample -- an STM8 isn't going to be powerful enough to do that, at least at typical audio rates and for more than a few hundred samples. It's definitely not going to be able to do that while adjusting for gain (one multiply per sample). A magnitude FFT may give a better behaved signature, but the gain still needs to be accounted for, let alone if there's any difference in frequency response. And an STM8 is definitely not going to be powerful enough to do this real-time, except maybe for trivial (<= 32 samples?) FFTs.
Tim
-
#3 Reply
Posted by
MikeK
on 20 Mar, 2021 13:55
-
I would use 22k resistors, or less, for the resistor divider given that the microcontroller input is probably expecting less than 10K source impedance (e.g. PIC).
-
#4 Reply
Posted by
Saimoun
on 20 Mar, 2021 14:00
-
Thank you all for your replies.
So for the ADC if I am not mistaken something as simple as this would work (attached - V2 is the incoming signal), correct? R5 and C1 creates a low-cut at around 72Hz but that is ok for me to test it.
Now, regarding the testing, the signal is a very short sample sound, about 100ms played at 32kHz. I do not need "precise" checking, the testing should only fail if the signal is very different, meaning the device under test DUT is sending either nothing, the wrong sample, or just gibberish.
I was thinking doing the following:
* once I have the test device, converting the audio from a DUT a few times, a DUT which I know works
* seeing how much the values change from one conversion to another (hopefully not much)
* Then saving those values in the MCU's memory
* Then the test device will simply compare the incoming audio values to the ones in memory, with quite a large margin
I think this would work, unless the incoming signal can change *a lot* from one device to another, or from one conversion to another.
Another idea I had was to re-create the same sample from the DAC inside the MCU, then send that signal and the incoming signal to a substractor opamp, which should then have almost all the time a 0V output, which I could check with a comparator.
-
#5 Reply
Posted by
Siwastaja
on 20 Mar, 2021 14:55
-
I think you are underestimating the complexity of the comparison. You will likely see that the result is almost always "very different".
You have chances of succeeding in the simplest way if you can send a sync signal at the same point in time every time, so that the recording of the signal-to-be-verified is synchronized to the reference signal.
If this is not possible, simply subtracting values and looking for sum of differences is absolutely of no value. For example, if there is a 1Vp-p signal at 1kHz (T = 1ms), depending on the luck (timing), the difference signal will be anything between 0 Vpp to 2 Vpp, indicating perfect match or "extremely different".
If you want to just indicate "nothing at all" and similar clearly bad conditions, it's likely easier to come up with suitable checks ad-hoc - for example, the sum of absolute values of all samples must be between certain min and max threshold -, instead of trying to compare to a reference signal.
-
#6 Reply
Posted by
Saimoun
on 20 Mar, 2021 15:29
-
Ok good thinking about the max and min values - that could also work.
And yes I forgot to say
: I will have a precise way to know when the sample starts. Could it work in this case or am I still underestimating the precision of ADC and/or the stability of the audio signal (from the DUT to the test board)?
-
#7 Reply
Posted by
ledtester
on 20 Mar, 2021 15:38
-
What's the nature of the reference signal? Is it a single tone or could it be a complex fragment of music?
And how will the sample be getting to the ADC -- through a microphone? This goes to the question of how much noise can be expected.
Some examples of audio signal processing with an 8-bit micro:
- DTMF decoder -- can pick out the presence of two tones
- guitar tuner -- can determine the frequency of a note being played
- beat detector -- can determine the beats in a sample of music
- spectrum visualizer -- gives a visual display of the frequencies in a sample of music
-
#8 Reply
Posted by
Siwastaja
on 20 Mar, 2021 15:41
-
Well, I would say the timing accuracy of your sync signal should be like 10 times better than the period of the highest frequency component of the signal. Say, for 10kHz cutoff, sync accurate to +/- 5µs would work quite well. Trig the ADC to this sync signal for both reference signal and the signal-to-be-verified. With such short signals, clock frequency drift won't cause problems as long as it's a crystal (not RC).
Then all that's left is to figure out how any gain differences causing false result. Looking at average absolute value of the reference, then average absolute value of signal, and amplifying the signal to match before comparison would be quite easy. Add min/max thresholds (like 0.5 to 2.0) to the amplification step to make it fail if too much gain adjustment is needed.
Different frequency response along the path would still cause differences but I guess you would be in the territory of being able to say "totally different" vs. "the same" quite reliably given you have tackled the phase and amplitude issues.
-
#9 Reply
Posted by
T3sl4co1l
on 20 Mar, 2021 16:02
-
You need to figure the Thevenin equivalent of the resistors. So, that would give 144Hz, not 72Hz.
That's still ~3200 samples, a huge amount for such a simple micro to be working on. If it can take its time (or say a few seconds), that's fine at least -- enough time to do most analyses you'd want to do. Uh, give or take how much time is spent diddling with external memory, anyway -- the linked device only has 2k SRAM, which will hold at most 1k samples of unpacked 12 bit audio, so you'll need external to hold onto that much at once. And if it's slow like SPI RAM, it'll take quite a few cycles to get at; at least DMA can handle that in the background.
Being able to doing a synchronized acquisition, and comparing to a reference envelope, is promising. You'll have to build a statistically representative sample set to derive go/no-go values from, and analysis on that will also tell you whether the method is effective, or if more detailed analysis is necessary. Remember, that 3200 sample buffer is a 3200-dimensional vector: I'm not kidding when I say complexity is exponential in length! There is a lot of volume inside a 3200-dimensional cube. If your analysis is reliable/effective enough using only simple linear and statistical methods, that greatly reduces the complexity of that space (down to perhaps linear or quadratic with length, or even less than that, as there's really only so many linear algebraic operations you'd want to perform on a single vector). For example, vector norm (= RMS) and FFT (= multiplication by DFT matrix) are common signal processing operations that might be used. Subtraction against a reference works, if every single dimension of both vectors cancels out very neatly -- but with 3200 dimensions, what are the chances of that? Maybe doing statistics on the residual would prove valuable.
If this is like, mass production test equipment, it will be well worth doing all this analysis, gathering reference data and preparing a method; if for just a few off, like... would you not be better off just reading the output with a scope and eyeballing it? Economy matters too!
Tim
-
#10 Reply
Posted by
Saimoun
on 20 Mar, 2021 17:34
-
Thanks everybody for your answers!
@ledtester: the signal will come from a wire on a test connector on the DUT. The signal is a "sound", i.e. has a lot of frequencies, but short.
@Siwastaja: the sync signal should pretty much be as accurate as the 16Mhz crystal (used on both DUT and testing board) can be - so a lot more precise than 5µs
I do not understand why adjusting the gain would be necessary: the digital values I will put in the MCU (i.e. the values that the incoming signal will be tested against) will be taken from a read of that same signal. Are you saying that from one DUT to another, or from one ADC conversion to another there will be so much difference?
I was thinking having a quite large "digital" threshold, for example ignoring the last 6 bits of the 12-bit value will mean any sample could be +/- 26mV and still be valid.
@Tim: yes true good point about the filter! 144Hz is still ok though
And yes about 3000 samples (32kHz sampling). They will be in the program memory.
The idea is not complex analysis though, just a simple sample-by-sample comparison with a threshold as explained above, which I was thinking of doing real time as the samples are coming through.
It might sound "amateur-ish", but if it does the job then it works for me
Like I said the only thing that could happen is the signal changing a lot from DUT to DUT or from one ADC conversion to another - if that's the case then I probably need something more robust
And yes this is to be used for production, to make the manual test of the PCBA faster.
-
#11 Reply
Posted by
rstofer
on 20 Mar, 2021 19:55
-
Can you send the samples to a PC? If so, you could run a Fast Fourier Transform and see the various frequencies and amplitudes.
The signal must be bandwidth limited to less than twice the sample rate so sample at least 60 kHz for a 30 kHz signal. For a 100 ms signal duration, that would be 6000 samples.
Here is sample code from MATLAB and it works perfectly on Octave (FREE).
https://www.mathworks.com/help/matlab/ref/fft.htmlHere is the code after I pulled out some text comments and added the figure() statements:
[font=courier]
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1500; % Length of signal
t = (0:L-1)*T; % Time vector
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
X = S + 2*randn(size(t));
figure()
plot(1000*t(1:50),X(1:50))
title('Signal Corrupted with Zero-Mean Random Noise')
xlabel('t (milliseconds)')
ylabel('X(t)')
Y = fft(X);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
figure()
plot(f,P1)
title('Single-Sided Amplitude Spectrum of X(t)')
xlabel('f (Hz)')
ylabel('|P1(f)|')
Y = fft(S);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
figure()
plot(f,P1)
title('Single-Sided Amplitude Spectrum of S(t)')
xlabel('f (Hz)')
ylabel('|P1(f)|')
[/font]
Attached are the 3 plots
-
#12 Reply
Posted by
JustMeHere
on 20 Mar, 2021 22:03
-
Alot of this is covered in the data sheets and app notes if ADC ICs. Print one off and put it on the magazine stack in your bathroom.
-
#13 Reply
Posted by
Siwastaja
on 21 Mar, 2021 08:30
-
Well if your reference signal comes from the same product as the test signal, it's made using same components, even from the same batch, and run in same environmental conditions, and you have the accurate sync signal, chances are high you get a good indication from simple sum-of-differences as phase differences are ruled out by the sync, and having the same signal chain components, gain and frequency response likely do not vary by more than a few %.
If this matches your case and expectations, by all means keep it simple, there's nothing amateurish in that. It's not a generic use-everywhere "compare two signals" algorithm, but it doesn't need to be.
-
#14 Reply
Posted by
Saimoun
on 21 Mar, 2021 19:14
-
@rstofer: thanks for the info that is definitely nice to know
But in this case the test has to go super fast and be "automatic", as in just a simple button and if everything is ok a green LED lights up right away.
@JustMeHere:
@Siwastaja: ok that's great! Yes it will be from the same product, but not necessarily the same batch, and not necessarily the same environmental conditions. For the batch one might hope there is not too much difference (same components and same PCB), and as for the environment the cable between the DUT and the test board will be a short IDC cable so I'm hoping there will not be too much place for noise picking up there. I have surrounded the audio pin with GND pins to protect it as much as I can.
-
#15 Reply
Posted by
rstofer
on 22 Mar, 2021 02:00
-
If things don't work out and you want to take another look at FFT, consider that MATLAB has the ability to do automatic testing. You could possibly build a project in MATLAB that has a virtual button on the screen that does the entire process including analyzing the FFT for frequencies and amplitudes against a template. Of course, for commercial use, MATLAB tends to be expensive so I guess it won't be a popular solution.
You could always code up the FFT in C or Fortran and run a command line application to run the test, fetch the data, take the FFT and compare to a template. Maybe it could even be done in Visual Basic with a form and 'Go' button. I'm thinking USB to Serial and USB to GPIOs on a couple of adapters. FTDI makes a bunch of adapters.
I concede that this is the hard way to get it done. I also have more faith in the results.
-
#16 Reply
Posted by
rstofer
on 22 Mar, 2021 16:22
-
The Digilent Analog Discovery 2, if you could get one, might be another way to do the test. It can generate an arbitrary waveform (2 separate channels) and produce an FFT or any other kind of waveform. It can also measure harmonic distortion.
The test can be scripted such that it results in a pass/fail.
Here's an Audio Analyzer project (script) for the AD that has proven useful for audio folks:
https://youtu.be/7yXUbU5bSGwYou can Google for 'analog discovery audio analyzer' to find more links.
There are also threads on eevBlog like:
https://www.eevblog.com/forum/projects/analog-disovery-as-audio-analyzer/
-
#17 Reply
Posted by
Saimoun
on 23 Mar, 2021 11:12
-
Thank you again rstofer it makes sense, and yes a setup with a computer would probably be much more stable and would give less false positive.
But it would require me adding a USB interface on the test board, which would require more buying, testing, coding, plus the coding or configuration of the computer software, and it would also require the testing people (my PCBA house) to have a computer, also I would hope they already have that
But overall it will just take more time, and this project is already taking forever
So I am trying to find a middle ground (pun intended) between no testing at all (other than the automatic pcb and assembly checks) and a full proper manual test.
Basically I am only testing for manufacturing failures. My first idea was simply to test if there is any sound at all but then I realized there would be scenarios where something would be very wrong (for the end user) and it would not be detected. I am thinking the following failure scenarios could happen on the DUT:
- no audio at all (could be anything on the chain from MCU-DAC)
- wrong/missing connection from MCU to DAC => some audio is sent but it's just gibberish and not the sample
- one of the feedback resistors of the gain circuit did not get soldered properly => sample is sent but it has a completely wrong gain
(a last option could be nothing wrong on the pcb/assembly but the code is sending the wrong sample - if this happens it is acceptable).
Taking all of this in consideration, I still thinking a simple sample-by-sample comparison with a large threshold seems a good bargain between simplicity and stability - if someone has a better idea I am all ears
-
#18 Reply
Posted by
Saimoun
on 23 Mar, 2021 11:20
-
On the other side - my incoming signal is not 1V but only about 180mV peak to peak, so I have added a gain circuit on the test board.
"AudioTestSig" is the signal coming from the DUT and "Audio" is the signal sent to the ADC pin on the MCU.
The gain should be 360/22, which should give about 3V peak to peak coming in the ADC. The opamp is rail-to-rail with +3.3V and GND as supplies.
Do you guys see anything wrong with the circuit (attached)?
Thank you!
Simon
-
#19 Reply
Posted by
cheater
on 23 Mar, 2021 15:45
-
It might be helpful if you explained what you mean when you say that "the audio signal kinda ressembles what it should". There are different ways of achieving this - what's your idea?
-
#20 Reply
Posted by
ledtester
on 24 Mar, 2021 03:03
-
Now that I understand better what you are trying to do I think I would do this...
Program modes into the device so you can have it emit various sine waves. Then your test procedure activates those modes. Identifying sine waves is pretty easy, and by superposition if your DUT can emit sine waves at various frequencies then it it's a good indication it will work on more complex wave forms.
-
#21 Reply
Posted by
Saimoun
on 27 Mar, 2021 15:48
-
@cheater: true, like the others said. But the subject has been discussed quite a lot now
@ledtester: great idea! I'll investigate!
-
#22 Reply
Posted by
perieanuo
on 27 Mar, 2021 16:51
-
* an audio signal, coupled to GND (centered around 0V), about 1V peak-to-peak, with low output impedance (about 10-15 Ohm)
correct me if i'm wrong, but adc 'sees' (samples) only positive values
centering the signal on half VCC of your micro should be the technique otherwise you loose the whole negative part of audio signal, what correctly calculated fourier transfo you can do with this setup?
-
#23 Reply
Posted by
Saimoun
on 27 Mar, 2021 16:57
-
@perieanuo: Correct - see my diagram 5 posts above