Closed q-bird closed 5 years ago
ADC_ATTEN_11db gives a full-scale voltage of 3.9V, so at 12bits 4095=3.9V. Although you wont see any readings higher than VDD_A, you should be using 3.9V in your calculation instead of the VDD_A voltage.
@MarkyAD Thank you for your support! But if I use 3.9V 1104*3.9/4096 = 1.051V it's still different from 0.99V
And what about 0db - 1.1V full-scale? with the range of 0-1.1V + 12bits, I should get a better result when I measure 0.99V right? But in fact the ESP got 1.06V. Then how to know exactly the Vref? they said 1.1V (0db) in datasheet and we follow, but maybe the real Vref is different and we never know?
@MarkyAD
BTW, I aslo see this note and this one: So, what's the 1/3.6 in the first picture and 3.9V in the second one In fact if we use 3.6V for the formula, it's better than 3.9V
Do you have any idea about this point?
Yes but on that page it also states that "At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage." As to the error offset, I would attribute it to both Vref differences and the non-linear response of the ADC. See this page https://esp-idf.readthedocs.io/en/latest/api-reference/peripherals/adc.html#example-of-reading-calibrated-values regarding ADC calibration.
There are many threads on this in both the esp-idf repository and on esp32.com, search ADC calibration or ADC vref. A thread on esp32.com mentions that Vref variations can typically deviate +/- 100mV from the reference 1.1V, more than enough to account for the error your seeing.
ADC_ATTEN_11db = 3 The input voltage of ADC will be reduced to about 1/3.6
What its showing here is the effect of the attenuator on input voltage. In other words, at -11dB, the input voltage is reduced to 1/3.6 of its actual value (it has to fit in the range of 0-Vref). I tested 3 different esp32, routing Vref to a gpio, and got a range of Vref voltages from 1.18-1.24V. Even such a small sampling shows the variation, and running uncalibrated only puts you in the ballpark of any sort of accuracy.
@q-bird if you need better accuracy, consider using an external adc. There are many adc with spi or i2c (analog devices, microchip, etc) that will work nicely with esp32. Probably most people use the internal adc to read e.g. a potentiometer, light sensor or as a relative indicator of battery voltage where a bit of inaccuracy isnt much of a problem. Anyway you can probably close this, its not really a core issue, and it sounds like your adc is working.
Hi,
Is this function used to route the Vref to a GPIO pin? Is there only one Vref inside the ESP and is it used for both ADC1 and ADC2?
adc2_vref_to_gpio(GPIO_NUM_25);
I'm using ADC1, not ADC2 but I can't use adc1_vref_to_gpio
, it's an invalid function.
So I used adc2_vref_to_gpio(GPIO_NUM_25);
instead, and got the Vref = 1.09V (measured by meter). Will the ADC1 also refer to this Vref?
BTW, many thanks for your support! I will close this!
Now I'm questioning my own sanity (or lack thereof) on this one. The documentation mentions 3 different voltages or scales...
I took this to mean "full-scale = 3.9V = 4095 but you will never see a raw reading that corresponds to more than VDD_A volts". I tested a 1V reference with VDD_A=3.35V and got raw values around 1103, plugging these in I get 3 different voltages:
(full scale) 1103 3.9 / 4096 = 1.0502 (1/3.6 input) 1103 3.6 / 4096 = 0.9694 (VDD_A) 1103 * 3.35 / 4096 = 0.9021
The 3.6volt formula is closest, but why mention the 3.9V full-scale at all if its not important. Which is it lol.
@q-bird yes thats what I used to measure Vref, its the same for adc1 and 2.
@MarkyAD
So in this case of ESP32, what's the sense of 12bits I still don't know :) In theory, with 12bits we will have 4096 points for the range of 0-3.6V (in case 11db) So one adc step (unit) will correspond with 3.6/4096 = 0.000879V...
And if we select 0db, meaning 1.1V, one adc step can read upto 1.1/4096 = 0.00027V which we expected
Based on your result if we calculate the expected Vref to have exactly 1V: Vref = 1V*4096/1103 = 3.71V (between 3.6 and 3.9)... But of course it will be wrong with another input voltage such as 0.5V or 2V...
I had been using the "3.9v full-scale" calculation in a project and just accepted the 0.05V offset. I didn't worry about it much as it wasn't all that critical, plus I got the same 0.05V offset with the 0db mode and known 1.1V full scale, which is why I blamed Vref.
#include <esp_adc_cal.h>
#define REF_VOLTAGE 1100
const uint8_t TMP_PIN = 33;
esp_adc_cal_characteristics_t *adc_chars = new esp_adc_cal_characteristics_t;
uint16_t avgAnalogRead(uint8_t pin, uint16_t samples = 8) {
adc1_channel_t chan;
switch (pin) {
case 32:
chan = ADC1_CHANNEL_4;
case 33:
chan = ADC1_CHANNEL_5;
case 34:
chan = ADC1_CHANNEL_6;
case 35:
chan = ADC1_CHANNEL_7;
case 36:
chan = ADC1_CHANNEL_3;
case 39:
chan = ADC1_CHANNEL_0;
}
uint32_t sum = 0;
for (int x=0; x<samples; x++) {
sum += adc1_get_raw(chan);
}
sum /= samples;
return esp_adc_cal_raw_to_voltage(sum, adc_chars);
}
void setup() {
Serial.begin(115200);
pinMode(TMP_PIN, INPUT);
adc1_config_width(ADC_WIDTH_BIT_11);
adc1_config_channel_atten(ADC1_CHANNEL_5,ADC_ATTEN_DB_11);
esp_adc_cal_value_t val_type =
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_11, REF_VOLTAGE, adc_chars);
}
void loop() {
Serial.println(avgAnalogRead(TMP_PIN));
delay(5000);
}
@lbernstone Nice, with that code and the code in examples/peripherals/adc in esp-idf I was able to get measurements to within 3mV of actual after substituting my measured Vref. Maybe the cal_characterize and raw_to_voltage functions can be exposed/wrapped in arduino ide somehow?
@q-bird make sure when you measure your external reference voltage and the internal Vref that you zero out any lead resistance in your test instrument using relative mode, this was at least part of the offset I was getting.
They will be wrapped when @me-no-dev gets some spare cycles. raw_to_voltage doesn't follow Arduino standards, so probably will just be a separate method.
Hi @lbernstone @MarkyAD
I used your code to test @lbernstone
But I changed something: remove pinMode(TMP_PIN, INPUT);
and increase the resolution to 12bits
With 0.99V input, the result is:
sum = 1103
but esp_adc_cal_raw_to_voltage(sum, adc_chars) = 1023
When we calculate 1103/4096(3.36 to 3.9) and 1023/4096(3.36 to 3.9) Which one is better? will use 3.9V in the formula in this case?
@q-bird esp_adc_cal_raw_to_voltage() already converts to voltage for you so you dont have to calculate it. 1023 = 1023mV = 1.023V. You should be substituting your measured Vref (also in mV) in the line with esp_adc_cal_characterize() where it says 1100.
I find 12 bit to be too jittery in most cases. You need to figure out whether you need precision or accuracy. Take more samples to improve accuracy. If you need that extra bit of precision, get a dedicated ADC.
Thank you both of you @MarkyAD and @lbernstone (BTW, with 11db I got 1023mV, and with 2_5db I got 1001-1004mV better than 11db like the theory :) )
This is an interesting discussion. Using a DOIT v1 board, I have found that the sketch is ineffective at switching outputs. e.g. selecting TMP_PIN = 32 and only a voltage applied to pins 36 and 39 returns a value.
Can you satisfy my curiosity please. adc1_config_channel_atten(ADC1_CHANNEL_5,ADC_ATTEN_DB_11); is not changed when the TMP_PIN is selected - I would have expected it to but perhaps I misunderstand it?
Hi @9H5G,
Can you try this?
Hi @q-bird, thanks for this. I'd expected the parameters should match the pin and tried what you suggested. However, pins 36 and 39 still returned readings. It was only by commenting out sum += adc1_get_raw(chan); and substituting sum += adc1_get_raw(ADC1_CHANNEL_7); that correct operation on pin 35 was achieved. Correct operation of all other pins confirmed. Thanks :)
Just starting to get involved with analogue in on the esp 32 so this thread should be very useful.
For reference, according to my calculator (square root of (10 to the power of (decibels over 10))): 11db = voltage ratio of 3.548 to 1 6db = voltage ratio of 1.995 to 1 2.5db = voltage ratio of 1.334 to 1
so it looks like the 3.9 ratio could be a typing error
@lbernstone FYI, the switch case in avgAnalogRead
needs break statements. Switch statements in C 'fall through', meaning if you switch to the case where pin=33, you're then subsequently executing all the cases below it...
I appreciate the code, but caught this bug because I put a default case at the bottom, where it just returns 42, and that's all that I get until I put in break statements.
@NoelWalters Those are negative values:
-11db -6db -2.5db
Reference voltage value measured by esp32 on ADC pins is 1.1V. This way you have:
@lbernstone I edited your code and i added the Arduino's functions where was possible.
/*
ESP32 ADC multi readings
All time ADC pins:
ADC1_CH0,ADC1_CH03,ADC1_CH04
ADC1_CH05,ADC1_CH06,ADC1_CH07
Use only without WiFi:
ADC2_CH0,ADC2_CH01,ADC2_CH02,ADC2_CH03
ADC2_CH04,ADC2_CH05,ADC2_CH06
ADC2_CH07,ADC2_CH08,ADC2_CH09
Arduino espressif doc: https://goo.gl/NpUo3Z
Espressif doc: https://goo.gl/hcUy5U
GPIO: https://goo.gl/k8FGGD
*/
#include <esp_adc_cal.h>
// Command to see the REF_VOLTAGE: espefuse.py --port /dev/ttyUSB0 adc_info
// or dc2_vref_to_gpio(25)
#define REF_VOLTAGE 1128
byte pins[6] = {36, 39, 34, 35, 32, 33};
esp_adc_cal_characteristics_t *adc_chars = new esp_adc_cal_characteristics_t;
// ========= analogRead_cal =========
int analogRead_cal(uint8_t channel, adc_atten_t attenuation) {
adc1_channel_t channelNum;
/*
Set number of cycles per sample
Default is 8 and seems to do well
Range is 1 - 255
* */
// analogSetCycles(uint8_t cycles);
/*
Set number of samples in the range.
Default is 1
Range is 1 - 255
This setting splits the range into
"samples" pieces, which could look
like the sensitivity has been multiplied
that many times
* */
// analogSetSamples(uint8_t samples);
switch (channel) {
case (36):
channelNum = ADC1_CHANNEL_0;
break;
case (39):
channelNum = ADC1_CHANNEL_3;
break;
case (34):
channelNum = ADC1_CHANNEL_6;
break;
case (35):
channelNum = ADC1_CHANNEL_7;
break;
case (32):
channelNum = ADC1_CHANNEL_4;
break;
case (33):
channelNum = ADC1_CHANNEL_5;
break;
}
adc1_config_channel_atten(channelNum, attenuation);
return esp_adc_cal_raw_to_voltage(analogRead(channel), adc_chars);
}
// ========= SETUP =========
void setup() {
Serial.begin(115200);
// -- Fixed for the all adc1 ---
// 4095 for 12-bits -> VDD_A / 4095 = 805uV too jittery
// 2048 for 11-bits -> 3.9 / 2048 = 1.9mV looks fine
/*
Set the resolution of analogRead return values. Default is 12 bits (range from 0 to 4096).
If between 9 and 12, it will equal the set hardware resolution, else value will be shifted.
Range is 1 - 16
*/
analogReadResolution(11); // https://goo.gl/qwUx2d
// Calibration function
esp_adc_cal_value_t val_type =
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_11, REF_VOLTAGE, adc_chars);
}
// ========= LOOP =========
void loop() {
// ====== Read all pins on ADC_1 ======
for (byte i = 0; i < 6; i++) {
Serial.print("Pin ");
Serial.print(pins[i]);
Serial.print(": ");
/*
The maximum voltage is limited by VDD_A
- 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
- 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
- 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
- 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V
*/
// Default is 11db, full scale
Serial.print(analogRead_cal(pins[i], ADC_ATTEN_DB_11));
Serial.println(" mV");
delay(4000);
}
Serial.println("----------");
}
It works.
i measure voltage battery (lipo 18650). 3.7 at normal/4.2 max. so 4.2v is harm to esp32 then i run voltage divider +4.2 -->27k -->measure here (3.3v) --> 10k --> ground. so which atten Attenuation level should i use?
for example if i use
for (int x=0; x<samples; x++) { sum += adc1_get_raw(chan); } sum /= samples; return esp_adc_cal_raw_to_voltage(sum, adc_chars); }
if my battery is 4.2v then i will see 3.3v in monitor? "The maximum voltage is limited by VDD_A" @DaveCalaway
The VDD_A is the voltage applied to the ESP32 board, in most case is 3.3V (not 3.9V). For safety resone, I advise you to use a voltage divider, https://is.gd/U2iKhd, with: Vin= 4.2 R1= 3570 ohm R2 = 11500 ohm
The Vout is around 3.2V. Don't try to measure 3.3V, or higher, with a 3.3V as VDD_A.
You can use "ADC_ATTEN_DB_11".
The VDD_A is the voltage applied to the ESP32 board, in most case is 3.3V (not 3.9V). For safety resone, I advise you to use a voltage divider, https://is.gd/U2iKhd, with: Vin= 4.2 R1= 3570 ohm R2 = 11500 ohm
The Vout is around 3.2V. Don't try to measure 3.3V, or higher, with a 3.3V as VDD_A.
You can use "ADC_ATTEN_DB_11".
my currently setup is powered up esp32 board by usb cable, so it's will be 3.3v. +battery-->27k-->measure here-->10k-->ground . 11db atten and 11bit resolution, i get 3.66v, seem good; then i use lifepo4 battery. 3.32v -->measurehere -->ground, 11db attenation, i always get 2047 adc value, i think i set 3.9 as max scale so any voltage above 3.9 i get 2047, but i applied 3.32v i still got 2047, plz correct me, i dont know how inter adc work correctly. should i always need voltage divider aplied voltage <3.3v to GPIO36 to use internal ADC, for example if i want to use 1.1 scale, voltage input <1.1v like 0.9v ` float R1 = 27000.0; // resistance of R1 (1.1v at GPIO36) float R2 = 10000.0; // resistance of R2
for (int i = 0; i < 100; i++)
{
sum += adc1_get_voltage(ADC1_CHANNEL_0);
delayMicroseconds(1000);
}
// calculate the voltage
voltage = sum / (float)100;
Serial.println(voltage);
voltage = (voltage * 3.9) / 2047.0; //for internal 3.9v reference
// use if added divider circuit
voltage_in = voltage / (R2/(R1+R2));`
The VDD_A is the voltage applied to the ESP32 board, in most case is 3.3V (not 3.9V). For safety resone, I advise you to use a voltage divider, https://is.gd/U2iKhd, with: Vin= 4.2 R1= 3570 ohm R2 = 11500 ohm
The Vout is around 3.2V. Don't try to measure 3.3V, or higher, with a 3.3V as VDD_A.
You can use "ADC_ATTEN_DB_11".
so esp32 voltage operator 3.0 -> 3.6. so the 11db 3.9 max scale is useless because we can use 3.9v to esp32. then the max scale is always 3.3 ?
Use my function to read the mV correctly, https://github.com/espressif/arduino-esp32/issues/1804#issuecomment-475281577 :
analogRead_cal(pins[i], ADC_ATTEN_DB_11);
You can't read a value up to the VDD_A, in your case, the 3v3, see the datasheet:
If you want to use the 1.1v , aka 0dB attenuation (ADC_ATTEN_DB_0), you must have a voltage divider with the Vout under 1.1V. Something like 1V or 0.9V.
Use my function to read the mV correctly, #1804 (comment) :
analogRead_cal(pins[i], ADC_ATTEN_DB_11);
You can't read a value up to the VDD_A, in your case, the 3v3, see the datasheet:
If you want to use the 1.1v , aka 0dB attenuation (ADC_ATTEN_DB_0), you must have a voltage divider with the Vout under 1.1V. Something like 1V or 0.9V.
i run voltage divider from 4.6-->100k-->measure here (0.978)-->27k-->ground. just use this code . 11 width, 0db.
for (int i = 0; i < 100; i++)
{
sum += adc1_get_voltage(ADC1_CHANNEL_0);
delayMicroseconds(1000);
}
// calculate the voltage
voltage = sum / (float)100;
Serial.println(voltage);
voltage = (voltage * 1.1) / 2047.0; //for internal 1.1v reference
// use if added divider circuit
voltage_in = voltage / (R2/(R1+R2));`
When i applied 3.6v the voltage_in i get is 3.0; --> 0.6 eror. i will test with your code later
When i applied 3.6v the voltage_in i get is 3.0; --> 0.6 eror. i will test with your code later
This is the reason: https://is.gd/gsyEoR My function take care about the no linearity :rocket:
When i applied 3.6v the voltage_in i get is 3.0; --> 0.6 eror. i will test with your code later
This is the reason: https://is.gd/gsyEoR My function take care about the no linearity 🚀
Thank you for the code. it's work now :D last question. i also have lipo 4.2v max and lifepo 3.6v max. as i see when the measure voltage above 3.3v it is notaccuracy much? (measure 3.32v but receive 3144 at monitor); is it?. should i run voltage divider and use 1.1 max scale and
I suggest you use the internal 1.1v. Because for 3.3v if your battery becomes low the board would feed on ADC pin which is not desirable and you need to avoid that
When i applied 3.6v the voltage_in i get is 3.0; --> 0.6 eror. i will test with your code later
This is the reason: https://is.gd/gsyEoR My function take care about the no linearity 🚀
i found your code always fail for the first time run. do you have any idea? i'm doing with deep sleep so it's always incorrect, link here,
After deep sleep, probably, you need to wait some mS before starting the first reading. It's a warm up.
After deep sleep, probably, you need to wait some mS before starting the first reading. It's a warm up.
i try to put delay but nothing happen. so i add 1 line: analogRead(channel)
in top of analogRead_cal() and it work. dont know why also :D
i try to put delay but nothing happen. so i add 1 line:
analogRead(channel)
in top of analogRead_cal() and it work. dont know why also :D
Very interesting, is it works after the deep sleep also? or you need to wait some cycles?
Maybe you may want to test:
https://github.com/MacLeod-D/ESP32-ADC
You may calibrate your own ESP32( the nonlinear 11DB curve) with this program.
All you need is a wire from pin 25 to pin 35 and a normal voltmeter.
Calibration is done automatically.
It produces a LookUpTable[4096] to correct your values like:
CalibratedValue = LookUpTable[Read Value];
I do NOT use a fitted curve but a real LookUpTable with 4096 values !
I get correct values +/- 0.01V compared to the voltmeter. :D
@MacLeod-D but +/- 0.01V with what full scale voltage? 1.1V ? with a 0.02v step that's only 55 LSBs...
Am I missing something?
Full scale voltage. The +/- 0.01 V are NOT absolute precision but the delta from expected (linearized) value. For example if you have steps 0.7 and 0,9 that means you get 0.7 +/- 0.01V and 0.8 +/- 0.1V And that is ment with linearity.
You have to calibrate: measure the full scale voltage. So full scale output may be 3.05 V instead of 3.3 V, That means expected halfscale output will be 1.525 V and THAT value is met +/- 0.01 V And this should be true even if you only have 5 steps - meaning 0.61 V per step (3.05/5).
Mathematically: If you have a straight line going through (0,0) you have the expression y=x*m where y is the output value, x the input value and m=(fullscale-output) / (fullscale-input) That should be true for any ADC or DAC. Error is the delta from calculated y to measured y. 1) There will be delta because of noise! 2) And another comes from non-linearity. Here we try to correct the last one!
Example: 10 bit (1023 steps) Measured full scale: 3.069 V This method will gtive you 1.53V output for input of 511 instead of maybe 1.3V without correction because of the converters deviation from limearity.
+/- 0.01V are NOT the stepsize!
Cheers @MacLeod-D, I now understand, thanks for your explanation!
From observations the ESP32 vRef may vary based on the PSU, noise on the supply, battery etc. Would it make sense to use a simple independent ADC that has its own internal vRef to measure the ESP32 vREF? Then all the ESP ADC channels could be used reliably?
[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.
[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.
@lbernstone I edited your code and i added the Arduino's functions where was possible.
/* ESP32 ADC multi readings All time ADC pins: ADC1_CH0,ADC1_CH03,ADC1_CH04 ADC1_CH05,ADC1_CH06,ADC1_CH07 Use only without WiFi: ADC2_CH0,ADC2_CH01,ADC2_CH02,ADC2_CH03 ADC2_CH04,ADC2_CH05,ADC2_CH06 ADC2_CH07,ADC2_CH08,ADC2_CH09 Arduino espressif doc: https://goo.gl/NpUo3Z Espressif doc: https://goo.gl/hcUy5U GPIO: https://goo.gl/k8FGGD */ #include <esp_adc_cal.h> // Command to see the REF_VOLTAGE: espefuse.py --port /dev/ttyUSB0 adc_info // or dc2_vref_to_gpio(25) #define REF_VOLTAGE 1128 byte pins[6] = {36, 39, 34, 35, 32, 33}; esp_adc_cal_characteristics_t *adc_chars = new esp_adc_cal_characteristics_t; // ========= analogRead_cal ========= int analogRead_cal(uint8_t channel, adc_atten_t attenuation) { adc1_channel_t channelNum; /* Set number of cycles per sample Default is 8 and seems to do well Range is 1 - 255 * */ // analogSetCycles(uint8_t cycles); /* Set number of samples in the range. Default is 1 Range is 1 - 255 This setting splits the range into "samples" pieces, which could look like the sensitivity has been multiplied that many times * */ // analogSetSamples(uint8_t samples); switch (channel) { case (36): channelNum = ADC1_CHANNEL_0; break; case (39): channelNum = ADC1_CHANNEL_3; break; case (34): channelNum = ADC1_CHANNEL_6; break; case (35): channelNum = ADC1_CHANNEL_7; break; case (32): channelNum = ADC1_CHANNEL_4; break; case (33): channelNum = ADC1_CHANNEL_5; break; } adc1_config_channel_atten(channelNum, attenuation); return esp_adc_cal_raw_to_voltage(analogRead(channel), adc_chars); } // ========= SETUP ========= void setup() { Serial.begin(115200); // -- Fixed for the all adc1 --- // 4095 for 12-bits -> VDD_A / 4095 = 805uV too jittery // 2048 for 11-bits -> 3.9 / 2048 = 1.9mV looks fine /* Set the resolution of analogRead return values. Default is 12 bits (range from 0 to 4096). If between 9 and 12, it will equal the set hardware resolution, else value will be shifted. Range is 1 - 16 */ analogReadResolution(11); // https://goo.gl/qwUx2d // Calibration function esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_11, REF_VOLTAGE, adc_chars); } // ========= LOOP ========= void loop() { // ====== Read all pins on ADC_1 ====== for (byte i = 0; i < 6; i++) { Serial.print("Pin "); Serial.print(pins[i]); Serial.print(": "); /* The maximum voltage is limited by VDD_A - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V */ // Default is 11db, full scale Serial.print(analogRead_cal(pins[i], ADC_ATTEN_DB_11)); Serial.println(" mV"); delay(4000); } Serial.println("----------"); }
It works.
@lbernstone - How do I incorporate this information into a sketch? Again, I do apologize for not being able to figure this out. Have tried researching and the brain is getting a bit scrambled. If I can see one example, maybe with an explanation of the parameters, I should be able to go from there. Thank you!!!
https://www.google.com/search?q=arduino%20read%20analog%20thermistor%20voltage%20example
Thank you for the link to google. Maybe my question was not very clear. I have SUCCESSFULLY created a project that measures multiple temps using thermistors and discovered (like this issue reveals) an inconsistency between actual voltage into the GPIO and what the MCU is using as a measured voltage. After trying the program provided here, I obtained the output readings as shown.
Since many of the calibration approaches I've researched seem to use a 'correction' factor' is seemed reasonable that the output of this program did something similar - but I don't know. Hence my question about how to incorporate this information. I would GREATLY appreciate if you could spare a moment to help me understand how to use this information. Is it a correction factor? Is it a precise measurement of a certain ref voltage?
Thank you again.
Hi. I tried solution, suggested by lbernstone and then extended by DaveCalaway. In my case I use ADC2 channel 3 (pin 15). I used adc2_vref_to_gpio(), figured out that Vref is 1.07 and adapter constant in code. Before applying this solution I noticed that ADC gives value 4095 in case there is 3.09V on ADC input. So, further increase of input from 3.09 to 3.28V is not captured by ADC - it is always 4095. Unfortunately after applying solution, mentioned above, I didn't see any difference. Is that solution helps to make results linear in case input is close to the maximum value? Or it makes result more linear only in case input is quite far from max value? Maybe I'm doing something wrong? Or may be there is another solution for my issue? I would appreciate any info.
Hi there, I'm using ESP32-WROOM-32D to measure ADC But I see it's not good If I setup 11db (full-scale upto the VDD_A supply - I measure the power voltage about 3.36V) I applied the adc voltage input is 0.99V ==> the expected is around 1206-1207 (0.99/3.36 4096) But the real value that ESP read is just 1102-1104 ==> 11043.36/4096 = 0.906V Error = 10%
If I setup 0db (full-scale is 1.1V), ESP got 1.06V but the real value is 0.99V
Is there anyone has the same problem with me? Is the ADC of ESP32 not good or there is some problems with my firmware?
Thanks in advance