Skip to content

ADC still inaccurate with 2.4.0-rc2 #4009

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
brianjmurrell opened this issue Dec 21, 2017 · 16 comments
Closed

ADC still inaccurate with 2.4.0-rc2 #4009

brianjmurrell opened this issue Dec 21, 2017 · 16 comments

Comments

@brianjmurrell
Copy link

Basic Infos

Hardware

Hardware: ESP-12E (I believe)
Core Version: 2.4.0-rc2?

Description

When putting 3.3V on the ADC (A0) pin a read from it returns 1024 as expected. When I divide the 3.3V using a pair of 100K resistors, my multimeter confirms the voltage at the Vout of the voltage divider to be 1.65V however when that is connected to pin A0, analogRead(A0) returns 486 rather than 512 as I expect.

Settings in IDE

Module: NodeMCU 1.0 (ESP-12E Module)
Flash Size: 4MB (3M SPIFFS)
CPU Frequency: 80Mhz
Flash Mode: ?
Flash Frequency: ?
Upload Using: SERIAL
Reset Method: ?

Sketch

void setup() {
  
  Serial.begin(115200);

}

void loop() {

  Serial.println(analogRead(A0));
  delay(1000);
  
}

Debug Messages

485
486
486
485
486
486
485
486
485
485
485
485
@Pablo2048
Copy link

Do you have pure ESP12 module without any divider on A0? If so, try to read this http://esp8266.github.io/Arduino/versions/2.0.0/doc/reference.html#analog-input ...

@pieman64
Copy link

@brianjmurrell what are the exact resistor values as per your digital multimeter?

@brianjmurrell
Copy link
Author

Do you have pure ESP12 module without any divider on A0?

I'm not sure. How can I determine that?

If so, try to read this http://esp8266.github.io/Arduino/versions/2.0.0/doc/reference.html#analog-input ...

I read. I'm not sure what it supposed to be telling me to do. I added ADC_MODE(ADC_VCC); to my sketch but now it's just reporting 65536 from analogRead(A0).

@brianjmurrell
Copy link
Author

@pieman64 101.55K and 101.2K. Should be close enough I think. Certainly shouldn't account for 485 vs 512. And the multimeter reading 1.65V at the voltage divider's Vout also confirms they are close enough, right?

Ultimately, if I had a direct 1.65V voltage source, without having to use a divider, I'd expect I'd still get the same 485 value from analogRead(A0) with it.

@devyte
Copy link
Collaborator

devyte commented Dec 21, 2017

@brianjmurrell if you are using a standlone ESP-12 module, then the ADC input has a max Vin rating of 1V. If you connect more, you'll likely damage it, which can mean anything from nothing happened, to the readings became less accurate, to the readings are crap, to it's broken.
If you are using a pre-built board, like a Wemos D1 mini, then there is already a resistor divider on the board to scale Vin up to 3.3V max. In this case, your resistor divider is in parallel with the on board one, meaning that if the resistance values are of similar order of magnitude (220K and 100K if memory serves), you won't get the readings that you expect.

                      o-------- your 3.3V
                      |
                      Ra100K
   Board A0 o---------o
            |         |
            Rh        Rb100K
 ESP A0 o---+         |
            Rl        |
            |         |
            V         V
           GND       GND

Assuming that the ESP's ADC input is high impedance, which is usually the case, Rb is in parallel with Rh+Rl, and so your resistor divider doesn't halve the 3.3V as you expect.

In any case, the readings of an ADC such as on the ESP is not exactly very accurate, even between same boards, so you're expected to do your own calibration. I use linear, it's good enough.
Closing.

@devyte devyte closed this as completed Dec 21, 2017
@lawrence-jeff
Copy link

lawrence-jeff commented Dec 21, 2017

@devyte I would disagree with just dismissing this as a one off and closing it - I got the same readings in arduino (#2672 ) yet they were CORRECT using Nodemcu firmware (on the same boards).

@brianjmurrell
Copy link
Author

@devyte Ahhh. Ok. Very interesting. So yes, it would seem that I have a board that has resistor divider between it and the ESP-12 module. If I read the ADC pin on the ESP module while there is 3.3V on the board's ADC, I do get 1V on the ESP's ADC.

So, while straying a bit off-topic a bit I guess, I am hoping you (or anyone else) will indulge me as a really green beginner at this stuff.

Assuming I need to use a voltage divider with my board's 3.3V ADC because the sensor I want to read reports as resistance what is the best way to go about getting an accurate reading from it? In case it's relevant, the 100K resistors I was using were just for testing the ADC. Ultimately the sensor I want to read from is a 1M sensor and so I typically need a 1M resistor in the divider with it.

@devyte
Copy link
Collaborator

devyte commented Dec 21, 2017

@lawrence-jeff if you have a case where, on the same board, latest git here reads different values vs. the Lua firmware, then please open a new issue and present the example code for both.
Be aware that both firmwares depend on the sdk, and I believe we're not on the same version (we're further ahead, I think).

@lawrence-jeff
Copy link

I provided the details and example code when I had the issue earlier in #2672 (First posting). I'm no longer trying to use the ADC on the ESP (gave up based on the issues) At this point probably best to have @brianjmurrell test the board in this issue with LUA and see if like my experience LUA reports a more expected value and reopen this issue. Brian - it would be better instead of reporting the 1.65 for you to measure the Tout pin and report that voltage and corresponding values in both LUA and Arduino

@brianjmurrell
Copy link
Author

@lawrence-jeff As I mentioned earlier, I am pretty new to all of this. This NodeMCU is my first development board and first foray (for all intents and purposes) into electronics.

Additionally, as mentioned in #2672 I jumped right to Arduino with this board so don't really have any idea how to use LUA with this board.

Also, I am pressed for time on getting a simple project with this board up and running that seems to have gotten complicated now by the use of the two parallel voltage dividers. Being new to all of this, I'm not really wrapping my head around why the result of them isn't just a simple linear division of the previous division. I.e. if the first divider is a 1/2 divider and the second one is a 1/3 divider why doesn't the 1.65V from the first divider linearly divide by 1/3 into ~.50 by the second divider to yield ~512 on the ESP's ADC.

I need to make figuring out the answer to that my priority at the moment.

Happy to do the other testing above if/when I can figure this other thing out but clearly I need to go find somewhere to figure that out.

@lawrence-jeff
Copy link

lawrence-jeff commented Dec 21, 2017 via email

@devyte
Copy link
Collaborator

devyte commented Dec 21, 2017

@brianjmurrell the answer is in the schematic I diagrammed above: Rb || (Rh+Rl) ~ 76Kohm for 100K||320K, so your resistor dividor of 2 100Kohm actually behaves like Ra=100K above in series with 76Kohm below => it doesn't divide the voltage by 0.5 as you expect. This is basic equivalent circuit electronics. If you need further help with that, please refer to a community forum.
If you compare the Lua firmware (developed as Lua script files that execute in an interpreter loaded into the ESP) ADC readings against latest git here, and find wildly different readings, please open a new issue and report the details.

@brianjmurrell
Copy link
Author

brianjmurrell commented Dec 21, 2017

It probably does resolve to .50v (you can check the pin on the module with a meter to know for sure)

Reading on the A0 pin on the ESP, it's actually only 0.44V. But that actually compares exactly to what is on the board's A0 when my voltage divider (2 100K resistors) is connected to the board's A0. What is different here is that if I read the output of the voltage divider with my DMM when it's not connected to the development board, it's 1.65V, But if I connect that to pin A0 of the development board and read that, it drops to 1.42V

analogRead(A0) is reading that 01.42V (0.44V on the ESP) as 485 which translates into .47363V (485/1024). So a significant difference still.

I guess I also don't understand enough about electronics yet either to understand why the voltage drops from 1.65V to 1.42V when connecting that divider's Vout to the development board.

I was using resistive BBQ probes

That's exactly what my end goal is here. :-D

I ended up just building a manual table of temp to ADC value

As in completely discarding any published data about the probes and using something like steinhart-hart to calculate temperature, you just took just "samples" of known temperatures and built your own table of temps to ADC readings?

@brianjmurrell
Copy link
Author

so your resistor dividor of 2 100Kohm actually behaves like Ra=100K above in series with 76Kohm below

That would be consistent with my 1.42V reading on the development board's A0 pin.

I guess I need to understand this behaviour of the parallel dividers and how it yields a final divider of 100K & 76K to get this all figured out.

@brianjmurrell
Copy link
Author

So, much thanks to stackexchange mathematically, the equation for the expected voltage at the ADC at the ESP with both dividers seems to be:

((R2*R4)/(R1*(R2+R3+R4)+R2*(R3+R4)))*3.3

Where: R1 == Ra, R2 == Rb, R3 == Rh and R4 == Rl from the diagram in #4009 (comment).

So, given that we know the values of R3 and R4:

((R2*100000)/(R1*(R2+220000+100000)+R2*(220000+100000)))*3.3

I still have to do the algebra to go the other way... from a reading at the ADC to a resistance value, this all feels like something that ought to be in the esp8266 library, wouldn't you agree? It does seem specific to the fact that there is a voltage divider outside of the development board, but this is probably not at all an uncommon thing when one is reading resistance based sensors.

@leifnel
Copy link

leifnel commented Dec 20, 2019

Necro-replying: If you really just want to half the voltage, measure the resistance between ground and A0, then put a resistor of the same value between A0 and the signal source. That assumes that the resistance of the source is significantly lower than the resistance of the voltage divider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants