Basic ADC setup with MCU - Page 1
Forum section: electronics / beginners

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 20, 2021, 12:27:08 pm
content: HiSo 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 railThis 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!CheersSimon

author: Siwastaja
author_rank: Super Contributor
timestamp: March 20, 2021, 12:41:30 pm
content: 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 timebetween 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.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: March 20, 2021, 12:45:19 pm
content: 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

author: MikeK
author_rank: Super Contributor
timestamp: March 20, 2021, 01:55:11 pm
content: 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).

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 20, 2021, 02:00:21 pm
content: 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 marginI 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.

author: Siwastaja
author_rank: Super Contributor
timestamp: March 20, 2021, 02:55:54 pm
content: 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.

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 20, 2021, 03:29:19 pm
content: 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)?

author: ledtester
author_rank: Super Contributor
timestamp: March 20, 2021, 03:38:09 pm
content: 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

author: Siwastaja
author_rank: Super Contributor
timestamp: March 20, 2021, 03:41:44 pm
content: 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 matchbeforecomparison 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.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: March 20, 2021, 04:02:07 pm
content: 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

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 20, 2021, 05:34:25 pm
content: 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µsI 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 thoughAnd 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 meLike 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 robustAnd yes this is to be used for production, to make the manual test of the PCBA faster.

author: rstofer
author_rank: Super Contributor
timestamp: March 20, 2021, 07:55:04 pm
content: 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:Code:[font=courier]Fs = 1000; % Sampling frequencyT = 1/Fs; % Sampling periodL = 1500; % Length of signalt = (0:L-1)*T; % Time vectorS = 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)|')Attached are the 3 plots

author: JustMeHere
author_rank: Frequent Contributor
timestamp: March 20, 2021, 10:03:55 pm
content: 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.

author: Siwastaja
author_rank: Super Contributor
timestamp: March 21, 2021, 08:30:16 am
content: 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 simplesum-of-differencesas 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.

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 21, 2021, 07:14:22 pm
content: @rstofer: thanks for the info that is definitely nice to knowBut 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.

author: rstofer
author_rank: Super Contributor
timestamp: March 22, 2021, 02:00:18 am
content: 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.

author: rstofer
author_rank: Super Contributor
timestamp: March 22, 2021, 04:22:32 pm
content: 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/

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 23, 2021, 11:12:00 am
content: 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 thatBut overall it will just take more time, and this project is already taking foreverSo 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 sampleone 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

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 23, 2021, 11:20:42 am
content: 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

author: cheater
author_rank: Regular Contributor
timestamp: March 23, 2021, 03:45:02 pm
content: 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?

author: ledtester
author_rank: Super Contributor
timestamp: March 24, 2021, 03:03:08 am
content: 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.

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 27, 2021, 03:48:55 pm
content: @cheater: true, like the others said. But the subject has been discussed quite a lot now@ledtester: great idea! I'll investigate!

author: perieanuo
author_rank: Frequent Contributor
timestamp: March 27, 2021, 04:51:22 pm
content: Quote from: simonlasnier on March 20, 2021, 12:27:08 pmcorrect me if i'm wrong, but adc 'sees' (samples) only positive valuescentering 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?

author: Saimoun
author_rank: Frequent Contributor
timestamp: March 27, 2021, 04:57:31 pm
content: @perieanuo: Correct - see my diagram 5 posts above