2021-09-20 08:17 AM
I've been messing around with a LMT86 temperature sensor
This sensor is deemed high output impedance as the documented loads it drives is 50uA.
ADC noise on STM32 isn't 'new'. Just that for a first time I'm observing such volatility up close. The problem is mere millivolts differences means a different temperature reading from the sensor, and accordingly there is already a sort of 'amplification' from the sensor itself.
Threads found from a Google search are like such.
https://embdev.net/topic/stm32f0-adc-input-noise-investigations
https://itectec.com/electrical/electronic-stm32-adc-noise-2/
https://www.eevblog.com/forum/microcontrollers/stm32-adc-noise/
It is explored in a thread discussing the temperature sensor here:
https://forum.allaboutcircuits.com/threads/lmt86-2-2v-temperature-sensor.181850/
Among the discussions is that given this is a high impedance source, an Op-Amp is needed to buffer inputs to the ADC.
So next I strapped up an LMV358 Op-Amp as a buffer and here are the observations. This is with the Op-Amp
common parameters for charts below: adc clock 84 mhz / 4 ~ 21 mhz, 84 clocks sample time
2000 samples, 10 samples/s, measuring room temperature about 30.5-31 deg C
count 2000.000000
mean 30.882000
std 6.782125
min -213.360000
median 30.960000
max 57.800000
No, temperature did not accidentally drop to near absolute zero. It is room temperature all the while during measurement, a multimeter did not change a single millivolt while variances are recorded by the ADC.
Next, I set up a filter to remove all values outside +/- 2 deg C from the median, 555 outlier values removed.
count 1445.000000
mean 30.973156
std 0.733296
min 29.030000
median 30.890000
max 32.950000
Next remove that Op Amp and connect the sensor LMT86 directly to the ADC (on stm32f401)
2000 samples, 10 samples/s, measuring room temperature about 30.5-31 deg C
count 2000.000000
mean 30.930100
std 4.062343
min 3.670000
median 30.810000
max 59.260000
Next, I set up a filter to remove all values outside +/- 2 deg C from the median, 500 outlier values removed.
count 1500.000000
mean 30.817787
std 0.698166
min 28.810000
median 30.810000
max 32.800000
It is a dilemma kind of. The Op-Amp probably reduce the impedance (significantly?), but that the errors/variance are about the same !
What is more concerning is the large outlier values as those are observed in the unfiltered input. This didn't seem to go away when the OpAmp is placed as a buffer between the sensor to stm32f401.
Solved! Go to Solution.
2021-09-22 10:57 AM
Here is an update, I patched a LMT86 directly on the breadboard - no long wires / no cords / no op amps etc.
2000 samples, LMT86 direct to STM32F401 ADC PA0
LMT86 direct to STM32F401 ADC PA0 discarding 122 values outside 0.5 deg C range from median, this is barely around 5% of 2000 samples.
count 1878.000000
mean 31.195000
std 0.162021
min 30.740000
25% 31.110000
median 31.180000
75% 31.330000
max 31.620000
This result is astonishing, standard deviation is 0.162 deg C. 95% confidence interval is 1.959 sigma ~ 0.31736.
Now LMT86 measured on stm32f401 ADC pa0 is +/- 0.31736 deg C accurate at 95% confidence interval.
Then taking the full 0.5 deg C interval, that is 3.08 sigma, that is > 99.8% (accurate) confidence interval
https://en.wikipedia.org/wiki/Normal_distribution#Quantile_function
LMT86 is an accurate device, and it meets the specs published by TI, when a near noiseless measurement on stm32f401 ADC is possible.
The histogram is showing bars for temperatures well within 0.1 of a degree C. And I'm using only 12 bins for 2000 samples.
Working this back to the specs for LMT86, it is -10.9 mV average gain per deg C.
This translates to a +/-3.46 mV accuracy measured on STM32F401 ADC at 95% confidence interval.
And at 0.5 deg C at 3.08 sigma (> 99.8% confidence interval) it is +/- 5.45 mV at pretty much > 99.8% confidence interval measured on stm32f401 ADC.
Measurements are still stochastic, as I can observe varying numbers with each sample. But the samples and mean conforms well to a bell curve (normal distribution), after dropping the *outliers*.
Still can't rule out radio interference etc as noise sources which probably cause the variations and especially the outliers.
The data analysis looks like such
each line of these is the Anderson–Darling statistics
https://en.wikipedia.org/wiki/Anderson%E2%80%93Darling_test
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.anderson.html
This analysis is done by rejecting values outside a tolerance starting with 2 deg C and reducing it.
The Anderson–Darling statistic reduces to the smallest and finally increase, showing a poorer fit as tolerance is narrowed.
Now the tightest fit to normal distribution is 0.5 deg C at 99.8% confidence interval
n = 2000, lmt86 direct - no cord
no filter
145.97371710597236 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 2 del 13
95.23121766618078 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 1.5 del 29
59.96725246650158 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 1 del 56
33.59035490934821 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 0.5 del 122
20.692436455313555 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
count 1878.000000
mean 31.195000
std 0.162021
min 30.740000
25% 31.110000
median 31.180000
75% 31.330000
max 31.620000
tol = 0.3 del 197
22.802556095985665 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
This kind of also confirms the 'radio waves' interference hypothesis, that those outliers, and variances are due to interferences from radio waves.
But that'd need 1 more set of 'scope' charts, to verify it.
2021-09-20 08:34 AM
Temperature changes very slowly. Implementing a low pass filter either in hardware or digitally will help.
> a multimeter did not change a single millivolt while variances are recorded by the ADC.
While true, this isn't an apples to apples comparison. A multimeter will provide a time-averaged voltage reading. The ADC is providing a near-instantaneous reading.
Measure a high frequency square wave and you'll see the multimeter will happily report a constant voltage value at mid-scale.
Chips which report temperature digitally (such as over I2C) are typically much more accurate as they control all aspects of the measurement and can do the closed loop calibration.
2021-09-20 08:41 AM
Thanks, Those extreme outlier values are a concern, as one single very large swing outlier can throw the averages out significantly as well. I'm kind of thinking of doing a 20 samples moving median filter and removing samples outside +/- 2 deg C range from the median.
A feeling is that it would work. There are various implications, as this is simply used to calibrate a thermistor. Subsequently, this sensor gets replaced by a 100k thermistor on a 3d printer hot end. The impedance from that 100k thermistor resistor divider could be just as bad or worse than that LMT86 sensor.
Here are the same charts in millivolts (that is derived from ADC value * 3.3 / 4096)
this is for LMT86 temperature sensor - LMV358 Op Amp - STM32F401 ADC pa0
count 2000.000000
mean 1765.447655
std 45.694276
min 1466.310000
median 1765.210000
max 2223.630000
removing 561 outliers outside 0.5 std from previous count 1439.000000
mean 1765.045448
std 8.352023
min 1742.650000
median 1765.210000
max 1787.770000
This is for LMT86 temperature sensor - STM32F401 ADC pa0 direct
count 2000.000000
mean 1766.020125
std 44.989596
min 1449.390000
median 1766.820000
max 2061.690000
removing 519 outliers outside 0.5 std from prior count 1481.000000
mean 1766.806712
std 7.830439
min 1745.070000
median 1766.820000
max 1788.570000
So it seemed the range of the outliers can be pretty large, they seem to be about 0.7-1V. That accounts for the extreme temperature readings.
As LMT86 has a spec of -10.9 mV / C, that kind of translate to a 64 deg C range for the volatility as seen in the ADC readings.
The unfiltered graphs are also noticeably not a normal distribution.
I'd try some other things, place large caps at power supply, run off batteries etc to see if those makes a difference.
2021-09-20 11:55 AM
Some findings, adding a 220 uF capacitor at the 5v supply before the LDO (it is the usb from PC actually)
count 2000.000000
mean 30.809150
std 2.734337
min 5.710000
median 30.600000
max 54.450000
Next, I set up a filter to remove all values outside +/- 2 deg C from the median, 147 outlier values removed.
This is significantly less than previous
count 1853.000000
mean 30.639255
std 0.589653
min 28.660000
median 30.600000
max 32.580000
220 uF is a little extreme, but it did reduce the count of outliers outside +/- 2 deg C significantly
Unfortunately, the range of that outliers did not reduce significantly. It seemed there is a possibility the ADC is picking up signals from sources other than the sensor alone. Though at the pin, only the sensor is connected (across a wire to the probe).
2021-09-21 04:53 AM
This is a data analysis post. I used the Anderson–Darling test to test for fit to normal distribution. After removing the outliers
https://en.wikipedia.org/wiki/Anderson%E2%80%93Darling_test
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.anderson.html
n = 2000, 220uf
no fil
338.0688373916323 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 5 del 80
37.65825596079503 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 3 del 106
16.639158835365834 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 2 del 147
6.330279064999559 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 1.5 del 184
5.565211685938493 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
count 1816.000000
mean 30.629251
std 0.540934
min 29.100000
median 30.600000
max 32.070000
tol = 1 del 311
9.129102640304609 [0.575 0.654 0.785 0.916 1.089] [15. 10. 5. 2.5 1. ]
tol = 0.5 del 908
12.947477639850604 [0.574 0.654 0.784 0.915 1.088] [15. 10. 5. 2.5 1. ]
----
n = 2000, lmv358 op amp
no fil
286.11314396470016 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 5 del 246
49.1890842386847 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 3 del 404
21.53082374676842 [0.575 0.654 0.785 0.916 1.089] [15. 10. 5. 2.5 1. ]
tol = 2 del 555
6.184812017836293 [0.574 0.654 0.785 0.915 1.089] [15. 10. 5. 2.5 1. ]
tol = 1.5 del 643
2.5784588330257066 [0.574 0.654 0.785 0.915 1.089] [15. 10. 5. 2.5 1. ]
count 1357.000000
mean 30.939005
std 0.605743
min 29.480000
median 30.890000
max 32.430000
tol = 1 del 781
4.116979988109961 [0.574 0.654 0.784 0.915 1.088] [15. 10. 5. 2.5 1. ]
tol = 0.5 del 1203
11.753081703721705 [0.573 0.653 0.783 0.913 1.087] [15. 10. 5. 2.5 1. ]
---
n = 2000, lmt86 direct
no fil
192.2082880456942 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 5 del 254
64.04789448918518 [0.575 0.655 0.785 0.916 1.09 ] [15. 10. 5. 2.5 1. ]
tol = 3 del 380
28.67826080132636 [0.575 0.654 0.785 0.916 1.089] [15. 10. 5. 2.5 1. ]
tol = 2 del 500
9.98471395356546 [0.574 0.654 0.785 0.916 1.089] [15. 10. 5. 2.5 1. ]
tol = 1.5 del 588
3.7181488303444894 [0.574 0.654 0.785 0.915 1.089] [15. 10. 5. 2.5 1. ]
count 1412.000000
mean 30.791516
std 0.567874
min 29.330000
median 30.810000
max 32.290000
tol = 1 del 705
4.255539391071579 [0.574 0.654 0.785 0.915 1.089] [15. 10. 5. 2.5 1. ]
tol = 0.5 del 1203
9.760407662442503 [0.573 0.653 0.783 0.914 1.087] [15. 10. 5. 2.5 1. ]
This result is important. The Anderson-Darling statistics started high and reduce to the smallest after values outside +/- 1.5 deg C from the median are removed. Below that, the statistic increase again showing a poorer fit. So +/- 1.5 deg C is the best fit. This is based on 2000 samples and a static (room) temperature.
After removing outliers beyond 1.5 deg C,
with the 220 uF cap at 5v, standard deviation is 0.540934, 184 values removed
with the Op-Amp (no cap), standard deviation is 0.605743, 643 values removed
LMT86 direct (no cap, no Op-Amp) standard deviation is 0.567874 588, values removed
The graphs is like such:
95% confidence interval is about 1.96, so that gives an accuracy of +/- 1.11 deg C at 95% confidence interval measured at the ADC !
If we simply take the +/- 1.5 deg C range, that is 2.64 sigma, this is pretty much 99% confidence interval
https://en.wikipedia.org/wiki/Normal_distribution#Quantile_function
Then we go back to the specs for LMT86 , which provides -10.9 mV/C.
This means the stm32f401 ADC under test has an accuracy of about +/- 12 mV at 95% confidence interval and +/- 16 mV at 99% confidence interval 😉
But these results are very stochastic, it takes lots of measurements and requires a static value to achieve such accuracy.
The 220 uF capacitor obviously made a difference, as only about 10% (184 values) are outside 1.5 deg C. Without the capacitor, no Op Amp, (30%) 588 values are outside +/- 1.5 C. The capacitor made a difference if smaller sample sizes are needed for averaging purposes, this may be particularly important if the temperature is changing rather than static.
2021-09-21 05:05 AM
How about specify the adc noise on the supply voltage, the output impedencd of the external temp sensor, the adc clock frequency, the chosen sampling time, and which parameter of the stm32401 adc ip electrical spec seems challenged?
2021-09-21 05:56 AM
If adding capacitance BEFORE the LDO helps so much, it suggests rails are not as stable as they could be. I would expect capacitance on the 3.3V line to help even more.
Massaging bad data can help, but correcting the source of the problem will help more.
2021-09-21 06:13 AM
The stm32f401 is running at 84 MHz, ADC clock is 84 MHz / 4 = 21 MHz, sampling time is 84 ADC clocks, then add 12 cycles conversion time ~ 96 cycles. So that is about 208.33 k samples / s max. The actual sample rates are 10 samples per sec for these graphs.
LMT86 has a spec of 50 uA max, so it is kind of high impedance. But the last test with the added LMV358 Op-Amp shows little improvement for the variance at least.
IMHO, the outliers are hazards, it is a little crazy to get sample points near absolute zero when actual temperature is room temperature. That volatility isn't easy to deal with. I'd think a median filter can deal with it, but that these tactics are (very) expensive, especially on microcontrollers.
I'd try putting the 220 uF cap after the LDO at the 3.3v rail. That might be interesting for a comparison. The 3.3v rail powers, the stm32f401 + a ssd1306 LCD (I'm not sure how much noise that can produce) + the LMT86 temperature sensor + optionally that LMV358 Op Amp. Maybe it is too small an LDO :D
2021-09-21 07:58 AM
OK here is it 220 uF on 3.3v after LDO, LMT86 direct to STM32F401 ADC pa0, no Op Amp, 2000 samples, 10 samples per sec, 84 cycle sample time as is previous
count 2000.000000
mean 30.730650
std 7.015711
min -176.190000
median 30.810000
max 56.960000
The above data after removing 193 values > 1.5 deg C from the median:
LMT86 to STM32F401 ADC, 220 uF on 3.3v
removed 193 values > +/- 1.5 deg C from median
count 1807.000000
mean 30.796469
std 0.492922
min 29.330000
median 30.810000
max 32.290000
The count of outliers outside 1.5 deg C from median is comparable to that if 220 uF is placed before LDO at the 5v rail. 'Wild' outliers still occurs, there is one at -176 deg C (that one has a reading about 2.124 V), temperature measured is room temperature, values closer to room temperature 30 deg C is about 1.776 V. (edit: there is a bug for this value kind of 2.2v should be about 0 deg C as that's the spec for LMT86, Newton's method isn't a most stable solution search algorithm. But that this is still pretty much an outlier. 2.124 - 1.776 = 0.348 v, so using 10.9mV/C as an estimate that makes for a 31.9 deg C difference)
Oh, but the standard deviation after removing the outliers is the smallest so far at 0.49, so 95% confidence interval is +/- 0.96 deg C. at 1.5 deg C based on the filter, that is > 99% confidence interval at > 3 sigma.
It'd take a while to figure out where else are the noise sources, I'd guess. One of those tests I intend to do is to run it on batteries, that would take some work. Currently, it is pushing the values over usb-serial connection to the pc.
The sketch is here, for stm32duino
https://forum.allaboutcircuits.com/threads/lmt86-2-2v-temperature-sensor.181850/
2021-09-21 08:42 AM
You need to check your design with a scope. Make sure that regulator input voltage is enough so it is actually regulating. Voltmeter may show steady values, but actual voltage may be mearlndered at 1vpp. Replace your sensor with a battery! If you do not have a scope, connect earphones to Op-Amp buffer output through capacitors and hear what's going on there. If there is strong hiss which disappears when MCU reset pin (capacitor) is shorted, then you did not filter buffer power enough.
I would do the following:
1) C-L-C filter on MCU VDD. Main purpose of this filter is to filter out noise leaking from MCU/LCD to regulator side (LDO-CLC-MCU)
2) op-amp buffer and sensor must be powered from regulator side, and not from MCU side (relative to CLC filter).
3) Investigate if any data transfer induces significant noise on power lines.
4) Analyze whole system with battery-only power. Replace temperature sensor with 1.5v battery too.
5) Compare noise levels on all power lines while shorting MCU reset and in normal operation.
6) After everything is polished, try additional methods, like putting MCU to low power mode while sampling.
7) Largest sampling time is not always the best option. Assume you have constant data pumping between serveral ICs. It may be beneficial to increase inter-chip communication speeds, but decrease sampling time, so there is enough margin to reduce or eliminate time overlap between sampling and data transfer activities.