Open nassks opened 7 years ago
The ADC has a non-linear response, and we are working on producing characterisation data which will be added to esp-idf to produce a linear output.
When you say "noisy", are you getting noisy readings on a constant voltage or is this noise caused by the non-linearity?
There's some more in this related Arduino bug: https://github.com/espressif/arduino-esp32/issues/92
@CarlosGS : for issues, it is much better to start a new one than to post off-topic in an existing one.
For questions like this, the http://esp32.com forum may be an even better choice.
@projectgus : I think nassks means the "noise" within same values - additional I have seen that there is a "noise" between the inputs. put 1 Volt (with capacititor) on inputs CH4 ..CH7 I get such results: (using 0bd and 11db for the values)
ADC1 CH4 value: 3719 @ 0db, 1056 @ 11db
ADC1 CH5 value: 3889 @ 0db, 1052 @ 11db
ADC1 CH6 value: 3883 @ 0db, 1052 @ 11db
ADC1 CH7 value: 3891 @ 0db, 1052 @ 11db
-------
ADC1 CH4 value: 3867 @ 0db, 1056 @ 11db
ADC1 CH5 value: 3885 @ 0db, 1053 @ 11db
ADC1 CH6 value: 3887 @ 0db, 1040 @ 11db
ADC1 CH7 value: 3886 @ 0db, 1057 @ 11db
-------
ADC1 CH4 value: 3894 @ 0db, 1056 @ 11db
ADC1 CH5 value: 3855 @ 0db, 1061 @ 11db
ADC1 CH6 value: 3887 @ 0db, 1049 @ 11db
ADC1 CH7 value: 3875 @ 0db, 1053 @ 11db
-------
Difference is up to 5% - maybe it is normal?
But for 0V - I get a value "0" ... without "noise" - it is ok for me
Michael
Do not know why the crazy style came up before ;)
Code snippet for reference:
...
adc1_config_width(ADC_WIDTH_12Bit);
...
adc1_config_channel_atten(ADC1_CHANNEL_4,ADC_ATTEN_0db);
int val=adc1_get_voltage(ADC1_CHANNEL_4);
adc1_config_channel_atten(ADC1_CHANNEL_4,ADC_ATTEN_11db);
int val1=adc1_get_voltage(ADC1_CHANNEL_4);
printf("ADC1 CH4 value: %d @ 0db, %d @ 11db\n", val, val1);
....
Michael
So, in case anyone finds this ADC bug, I've found another ADC issue apparently where it will return data between 0-50% input, and cap out at 4096 from 50 to 100% input, but only after I try to use RMT. Details here: https://github.com/espressif/esp-idf/issues/462
So, the lastest arduino-esp32 fixes the issue I just reported when RMT is turned on, analogread values would get damaged.
Hi nassks, is this problem solved?
@FayeY not yet, @Spritetm is working on it.
Just leaving my two cents on this... I was hoping to use an inexpensive Voltage Reference IC (LM4040C30ILP) to help increase the accuracy of measured values. I too found the ADC to be non linear and have included my data below for anyone interested. voltage, ADC 2 2222 3 3730 1 1033 1.5 1629 0 0 0.5 422 2.5 2840 2.8 3300 3.1 3980 3.007 3750
took another crack at this, and assuming the ADC readings are related to the 3.3V regulator voltage (mine is at 3.275 V on a developer board). Here's what I found.
@dmody interesting, have you tried to fit curves to the upper range and lower range separately?
In the future, are you planning to include linearization of adc1_get_voltage or it will be in charge to the user to correct non linear behavior?
Just to know, because if we implement linearization on user app and then adc1_get_voltage will change behavior we'll have to remove all those parts.
I did not consider doing that. Sounds like a decent idea. I wonder which would be faster to execute. Sounds like a fun experiment to see.
I think the bigger problem I'm having is the noise. I haven't put my scope on the unit to see if the noise is real or not, but my approach to filtering was to do a for loop acquiring 100 samples, and to do a moving average of 10 samples. Ie For I= 1 to 100 Daq = (analog input value + daq*9)/10
Would love to hear other people's thoughts on this.
On Sun, May 7, 2017 at 7:08 PM negativekelvin notifications@github.com wrote:
@dmody https://github.com/dmody interesting, have you tried to fit curves to the upper range and lower range separately?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espressif/esp-idf/issues/164#issuecomment-299742244, or mute the thread https://github.com/notifications/unsubscribe-auth/ARtFwIoqc_VQwfuKdMKY0gdDNeBqlh1eks5r3k70gaJpZM4LNbPn .
really interested in this
Are we going to fix this soon? I feel like many applications depend on this feature. Is there a workaround at least?
Yes, we are. It took us some time to build an automated testing rig to accurately and reliably grab the characteristics of a representative sample of ESP32s; that has rendered the first curves this week and we're working on converting these into some linearization code.
@Spritetm any updates on this? Perhaps a timeline to when this might be fixed? Thanks!
@Spritetm @igrr I would love to hear an update on this - or if there is an effective workaround?
@MaxSNi The best workaround for me was to write a little function that returns the voltage based on the DAQ value using the formula I presented above. I can post the function if you like.
@dmody I would love to see your function. I made a quick function from my own excel trend equation and while it does work better, its pretty crude...
@MaxSNi //*** Analog to Digital Conversion Function **** float A2D(float SenVal) { if(SenVal<1) return(0); else if (SenVal>4094) return(99); else return(-0.000000000023926 pow(SenVal,3) + 0.000000094746 pow(SenVal,2) + 0.00074539 * SenVal + 0.14925);
}
Is there any update on this issue? It sounds me really crazy that on an IoT chip there's no way to have a good ADC reading.
Probably time to look at other options. i realised a few months ago its simply not going to be ready anytime this calendar year for production use
we have a simmulair problem , i can live with a correction factor but we discoverd in testing 10 esp32 samples , the difference between samples can be >10 to 20% , making a calibration nessesery for each esp , making it unusable for serios work
Hi @jan-bozelie. I'm aware there should be huge differences betweens samples due to the internal reference voltage regulator, but at the moment ADCs suffer of two distinct issues:
I think we should split ADC issue in two steps. Once we have corrected the non linearities, the EOS issue could be easily faced using an external voltage reference or a calibration procedure.
This problem has been totally ignored by Espressif, and I think ADCs are really important for an IoT application.
@igrr ... can we have an official response from Espressif about the fact ADC issue can or cannot be solved? At the moment we have a peripheral which is absolutely useless.
The official response has been already given by @Spritetm above (well, that is as official as you will get). We are working on both parts of the issue (nonlinearities and different v_ref):
V_REF compensation works pretty well, the errors which remain are due to run-time variation of V_REF. If you add an external reference voltage source and connect it to one of the ADC pins, you can apply correction at runtime, compensating even for temperature changes.
Linearization works best for low attenuation settings (0 and 1), as for these settings the transfer curve is closest to being linear. At attenuation setting 3 things get a bit more messy and hard to correct for, so we advise using lowest attenuation if possible. You will still not get rail-to-rail performance, but the result may be sufficient for a non-precision application.
(1): currently I can not give you any indication what that date might be.
Hi @igrr, really thank you for your feedback!
We have 10 samples of a custom board with an external 1.2V voltage reference (TI LM4041A12) and operational amplifier to filter input signals and adapt impedance. They have an output range of 0.15V to 1.8V (in order to avoid start end end of scale).
We tried to implement many of the linearization tables found (they are all different!) and also used an heavy software filter on the external voltage reference pad to correct dynamic fluctuations caused by the internal voltage reference instability and work always with the correct end of scale.
I tried this approach on 10 different boards, and with all of them we have acquisition errors close to the 5-10% (which is useless for an ADC).
In my opinion, the non-linear characteristic is something different chip by chip, it's not only a matter of the internal voltage reference. And if this true, there's absolutely no way to compensate it.
@Spritetm did you try to plot non-linear characteristic on different ESP32 chips?
Few users tried to plot it and they all get different results. I personally tried on few samples and always get something different...
No we have as utility a pilot development for in the medium gas distribution grid ( ongoing)
1 natural gas presure sensor 0-300mBar gauge --> 5V suply 0-3.3V output per home ( the sensor is max 0.5% error and is ok)
And also not sensitive for 0.5V voltage variations in the supply
There is no noticeble noice on the suply voltage during this experiments
The ESP board has a stabelizer 5V tot 3.3V feeded with a usb adapter / or laptop usb port
We did make 10 samples ahead of a pilot of 5000pc
For each 10 sensors we did make a voltage measurement readung compared to a voltage calibrator , with oversampling and avagaging
From these measurements we did make a correction curve, reducing 10%relative eror to 1% we can live with that
Than we checked the other , assuming the correction curve is aplicapable for all esp
But no --> worst case error between 10 ESP32 samples is 20% , what would inplement we would have to calibrate each sensor seperate
What would take at lease 20min labour , and not afordable
Conclusion , we have to look for an other solution , or a fix
One experiment we planed = ( put more analog inputs in parallel of the same ESP32 )
Van: imotion-software [mailto:notifications@github.com] Verzonden: dinsdag 22 augustus 2017 13:53 Aan: espressif/esp-idf esp-idf@noreply.github.com CC: jan-bozelie jan@bozelie.com; Mention mention@noreply.github.com Onderwerp: Re: [espressif/esp-idf] [TW#12287] ESP32 ADC accuracy (#164)
@Spritetm https://github.com/spritetm did you try to plot non-linear characteristic on different ESP32 chips?
Few users tried to plot it and they all get different results. I personally tried on few samples and always get something different...
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espressif/esp-idf/issues/164#issuecomment-324003352 , or mute the thread https://github.com/notifications/unsubscribe-auth/AdBrfwkasXeWB1AM092yUDkt9DIz518Cks5sasEvgaJpZM4LNbPn . https://github.com/notifications/beacon/AdBrf07IBwKQbKUCYoXl0WmIRHGEFMX4ks5sasEvgaJpZM4LNbPn.gif
I can confirm that is is chip to chip different from our 10 samples
In my aplication , (one sensor one esp32), i could live with an havy correction algoritm
I cant live with labour time and cost , for calibrating each analog input & each esp seperatly
Is there a bad sample ranproduction range ??
Van: imotion-software [mailto:notifications@github.com] Verzonden: dinsdag 22 augustus 2017 13:51 Aan: espressif/esp-idf esp-idf@noreply.github.com CC: jan-bozelie jan@bozelie.com; Mention mention@noreply.github.com Onderwerp: Re: [espressif/esp-idf] [TW#12287] ESP32 ADC accuracy (#164)
Hi @igrr https://github.com/igrr , really thank you for your feedback!
We have 10 samples of a custom board with an external 1.2V voltage reference (TI LM4041A12) and operational amplifier to filter input signals and adapt impedance. They have an output range of 0.15V to 1.8V (in order to avoid start end end of scale).
We tried to implement many of the linearization tables found (they are all different!) and also used an heavy software filter on the external voltage reference pad to correct dynamic fluctuations caused by the internal voltage reference instability and work always with the correct end of scale.
I tried this approach on 10 different boards, and with all of them we have acquisition errors close to the 5-10% (which is useless for an ADC).
In my opinion, the non-linear characteristic is something different chip by chip, it's not only a matter of the internal voltage reference. And if this true, there's absolutely no way to compensate it.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espressif/esp-idf/issues/164#issuecomment-324002843 , or mute the thread https://github.com/notifications/unsubscribe-auth/AdBrf7BUz9ceTEpFCbc8SlpLlfbWp4WHks5sasCYgaJpZM4LNbPn . https://github.com/notifications/beacon/AdBrfyvs8QiQJywI5olP6KUU632b_-7fks5sasCYgaJpZM4LNbPn.gif
http://i.imgur.com/mTkip9V.png This is a set of a few boards. (We have more, but this is data I have right here). As you can see, the reference voltage of all ESP32s is slightly different (hence the steepness of the curve differs from esp to esp) and the start and ends of each curve as well as the entire attn=3 curve is non-linear, but apart from the reference voltage, the ESPs do not really have that different-looking curves.
Hi @Spritetm ! Is it possibile to have raw excel data of the graph you posted with those 8 devices?
Here is some testing I did tonight using freshly pulled code from repo and built firmware. 12-bit and atten at -11db (defaults). I do not know enough to change the atten or width...I can hack away at Arduino sketches but I don't know if I can change it from there and I'm not sure where to change it in the source before I build the firmware. If anyone can tell me I'll try the -6db setting instead of the default -11db and see if it's better:
Hi @vseven,
if you want to change attenuation, there's a specific function "adc1_config_channel_atten". For width, you can change it calling "adc1_config_width".
I think -6dB should have a more linear characteristic, but probably reducing width will simply reduce noise but not non-linearities.
If you make a test at -6dB, please share result because I'm interested too.
Ive tried those commands in my Arduino sketch, multiple times, and just get a compile error. I must not have the syntax correct nor can i find it anywhere. I made a post on ESP32.com's forums asking but no reply yet. Once i change it i will retest and post.
Clarification: I have tried "analogReadResolution" and "analogSetAttenuation" from Arduino and it fails to compile. I guess I can try changing the static set values in the code and recompile the firmware? Only place I have found this would be in adc.h and platform.h and I would just hack it, changing the enum for 11db to equal 2 instead of 3 but that doesn't sound like a great idea.
EDIT: Figured it out...had to put the statements in my Setup().
Does this bug get fixed?
No but i did a lot of work on getting better results that might help you: https://esp32.com/viewtopic.php?f=19&t=2881
ok, so basically vref needs to be routed to gpio, measured and recorded in the particular device so it can apply the right correction values. this is unfortunate. i assume this will be fixed in the future revisions of the chip?
in the mean time, i have an application where i only need to measure value of one thermistor. i wonder if i can use vref to gpio routing to avoid the extra calibration step. say, i have a circuit like this:
IO25 (Vref) ---,
|
RT
|
IO34 ----------*
|
RB
|
---
-
.
RT
is the thermistor, RB
is a bias resistor, value TBD. will using Vref
like this allow me to get accurate reading of drop across RT
on IO34 without calibration? using attenuation of 0, naturally.
How would we "burn" the Vref into the fuses? I'd like to make the test for every ESP32, store the value and not worrying about measuring it again.
@rojer they say chips will ship with factory cal burned to efuse at some unspecified time in the future or possibly by special order.
@negativekelvin that makes sense.
@DrBomb i know you're a mOS user, so this may be handy - mos
utility can operate on eFuses:
$ mos -X esp32-efuse-get
...
$ mos -X esp32-efuse-set
Error: one or more ops required. op is 'fuse=value', 'fuse=@file' or 'fuse.{WD|RD}=1'
i guess you could use (part of) the user_key
field for this.
FWIW, here are my results from 10 devices i had lying around, calculated error % before calibration and after. 12 bits, 11 db atten. columns are: id, measured voltage on input: raw reading => voltage @ vref 1100 (error %); measured vref => voltage @ vref (error %).
00, 1.648: 1953 => 1.697 (3.0%); vref 1.070 => 1.657 (0.5%)
04, 1.669: 1886 => 1.642 (1.6%); vref 1.100 => 1.642 (1.6%)
05, 1.650: 1835 => 1.600 (3.1%); vref 1.130 => 1.639 (0.7%)
06, 1.653: 1856 => 1.618 (2.2%); vref 1.122 => 1.648 (0.3%)
AC, 1.651: 1819 => 1.586 (4.1%); vref 1.132 => 1.628 (1.4%)
03, 1.643: 1776 => 1.552 (5.8%); vref 1.143 => 1.608 (2.2%)
tt, 1.635: 1778 => 1.556 (5.1%); vref 1.129 => 1.595 (2.5%)
SL, 1.658: 1839 => 1.604 (3.4%); vref 1.119 => 1.629 (1.2%)
5C, 1.640: 1819 => 1.587 (3.3%); vref 1.129 => 1.625 (0.9%)
9C, 1.654: 1891 => 1.646 (0.5%); vref 1.105 => 1.652 (0.1%)
so, calibration gets the errors down, but doesn't quite eliminate them.
also, i found that reading ADC disables vref output to the pin, which is unfortunate.
Are you averaging multiple samples?
Yes we did and it improved the noice error , as we could expect
Van: negativekelvin [mailto:notifications@github.com] Verzonden: zaterdag 30 september 2017 09:22 Aan: espressif/esp-idf esp-idf@noreply.github.com CC: jan-bozelie jan@bozelie.com; Mention mention@noreply.github.com Onderwerp: Re: [espressif/esp-idf] [TW#12287] ESP32 ADC accuracy (#164)
Are you averaging multiple samples?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espressif/esp-idf/issues/164#issuecomment-333290111 , or mute the thread https://github.com/notifications/unsubscribe-auth/AdBrf7zTC-cTKnUmmpiwW-jCk_qbKrEZks5snewNgaJpZM4LNbPn . https://github.com/notifications/beacon/AdBrf5Hmjj5auK5I-dNJKTJB8nnL_Bx1ks5snewNgaJpZM4LNbPn.gif
Thanks , for the info --> informative
however, calibrating each io is killing each business case
I did buy pressure sensors with 0.25% accuracy , adding than 2.5% is a lot
Van: Deomid Ryabkov [mailto:notifications@github.com] Verzonden: vrijdag 29 september 2017 23:34 Aan: espressif/esp-idf esp-idf@noreply.github.com CC: jan-bozelie jan@bozelie.com; Mention mention@noreply.github.com Onderwerp: Re: [espressif/esp-idf] [TW#12287] ESP32 ADC accuracy (#164)
FWIW, here are my results from 10 devices i had lying around, calculated error % before calibration and after. columns are: id, measured voltage on input: raw reading => voltage @ vref 1100 (error %); measured vref => voltage @ vref (error %).
00, 1.648: 1953 => 1.697 (3.0%); vref 1.070 => 1.657 (0.5%) 04, 1.669: 1886 => 1.642 (1.6%); vref 1.100 => 1.642 (1.6%) 05, 1.650: 1835 => 1.600 (3.1%); vref 1.130 => 1.639 (0.7%) 06, 1.653: 1856 => 1.618 (2.2%); vref 1.122 => 1.648 (0.3%) AC, 1.651: 1819 => 1.586 (4.1%); vref 1.132 => 1.628 (1.4%) 03, 1.643: 1776 => 1.552 (5.8%); vref 1.143 => 1.608 (2.2%) tt, 1.635: 1778 => 1.556 (5.1%); vref 1.129 => 1.595 (2.5%) SL, 1.658: 1839 => 1.604 (3.4%); vref 1.119 => 1.629 (1.2%) 5C, 1.640: 1819 => 1.587 (3.3%); vref 1.129 => 1.625 (0.9%) 9C, 1.654: 1891 => 1.646 (0.5%); vref 1.105 => 1.652 (0.1%)
so, calibration gets the errors down, but doesn't quite eliminate them.
also, i found that reading ADC disables vref output to the pin, which is unfortunate.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espressif/esp-idf/issues/164#issuecomment-333244540 , or mute the thread https://github.com/notifications/unsubscribe-auth/AdBrf3Rxzrq8sTqrvyQKnSoxqQgmv8etks5snWJZgaJpZM4LNbPn . https://github.com/notifications/beacon/AdBrf4j0b-sqdV7HFJ6Pi_c8XKsNcrGOks5snWJZgaJpZM4LNbPn.gif
Are you averaging multiple samples?
i was not. i'd take a reading every second, print it out, and then use one of these lines to compute.
[Sep 29 22:25:36.037] timer_cb Tick 1890 1645 (vref 1100) 1651 (vref 1105)
[Sep 29 22:25:37.037] timer_cb Tock 1887 1643 (vref 1100) 1649 (vref 1105)
[Sep 29 22:25:38.037] timer_cb Tick 1886 1642 (vref 1100) 1648 (vref 1105)
[Sep 29 22:25:39.037] timer_cb Tock 1891 1646 (vref 1100) 1652 (vref 1105)
[Sep 29 22:25:40.037] timer_cb Tick 1894 1649 (vref 1100) 1655 (vref 1105)
[Sep 29 22:25:41.037] timer_cb Tock 1888 1644 (vref 1100) 1650 (vref 1105)
calibrating each io is killing each business case
exactly my thinking. it's imperative that Espressif starts doing it at some point, or we can forget about ADC for all but the most trivial applications.
So we won't get linearization data integrated into ESP-IDF? Very bad if that's the case..
So we won't get linearization data integrated into ESP-IDF? Very bad if that's the case..
Linearization of ADC readings is integrated into ESP-IDF now via the esp_adc_cal API. The part which is still pending is being able to calibrate the chip's internal Vref (a fixed voltage offset applied to the linearized value) from a value shipped in the ESP32 from the factory.
Right now the options are:
Future revisions of the ESP32 will have VRef measured as part of the in-factory test, with the value stored in efuse.
Hi,
I'm testing the ESP32's ADC on the SparkFun ESP32 Thing. Currently my measure seems very noisy, it constantly varies on the 5 first bits, and the zero value is around 90mV. Is there a way to achieve better accuracy?
My test code :
Thank you in advance for your help.