Incorrect value returned by analogRead() (D1 mini)


First of all i’m just a software developer, hardly know anything about electronics.

In my first Arduino project i use a D1 mini (V3.1.0) to read some analog value, do some logic, and report the result to my MQTT broker. The external device connected to A0 pin of the D1 mini puts 24V(+/-50%) DC to it’s output or 0V according to it’s state. I use 220kOhm and 20kOhm resistors for voltage devider to stay in the supported range of A0 pin. I call analogRead(A0) quite often (20 times a second). If analogRead() returns more than 320 i consider it as a high input, otherwise a low value.

If i power the D1 mini via its USB port everything works as i expect. The analogRead() returns either with value from the 0-10 range or from the 700-900 range. The logic i have implemented works according to my needs.

However if i power the D1 mini via its +3.3V pin (connected to the output of a HLK-PM03) the analogRead() starts to return interesting values. Whenever it’s expected to report from the 0-10 range it returns randomly from the 0-600 range, and even worse sometimes from the 0-800 range also. Which makes the implemented logic to fail.

Does anyone know and can explain to me what is the reason behind this behaviour?
The issue can be solved if i replace the HLK-PM03 with a HLK-PM01 and powering the D1 mini via its +5V pin?

Thanks in advance!


The reference voltage is tied to Vcc in, unless you change to using an internal reference. If you supply 5.0V and read the A:D you get one value, if you put 4.9 volts in the A:D will give different values.

Try using the internal reference.

Thanks for your reply. My problem is the fluctuation of the output value of the analogRead() function when there is 0V on A0. This can not be observed when the D1 mini is powered via USB. How to change the reference of the A:D?

I'd think one could find out how to change the A:D internal reference voltage by doing a search on either this site or the internet.

I'd think one could find out how to change the A:D internal reference voltage by doing a search on either this site or the internet.

Not an option for the ESP8266 (D1 mini):

I guess I'd monitor the HLK-PM03 output to see if it is drooping under load or try another 3.3v source.

Oi! My bad, I did not get that the board is an ESP8266.

I typically use ESP32's which have a number of options about the AD.

ESP32 AD API Analog to Digital Converter - ESP32 - — ESP-IDF Programming Guide latest documentation. By using the ESP32 AD API, works with the Arduino IDE, I get stable and accurate readings. The ESP32 API includes a AD calibration procedure.

You might look to see if the ESP8266 API has an ADC API.

Don't know how 'clean' the HLK-PM03 is, and how it handles the ~400mA transmit spikes of the ESP8266.
You could try adding a 470uF cap to the 3.3volt supply, close to the D1 mini.
5volt supply (USB or otherwise) could provide the extra filtering that the built-in 3.3volt linear regulator provides.

A0 most likely has the standard 100k:220k voltage divider fitted, so you should not use an external voltage divider, but just a single resistor to complement the built-in divider.
Formula for value is 100k for every volt more than 3.2volt.
So 24-3.2= 20.8 *100k = 2.08 Meg (use 2.2Megohm).

Thank You all for the ideas!

I think the external device just leave its output floating when i expected 0V, because this output is basically for a so called control lamp. And when i power the D1 mini via its +3.3V pin the environment is more noisy than in the case when powering it via USB. Can i solve this with inserting a pull-down resistor between A0 and GND? How much resistance should it have? Sorry i'm still very beginner.

A 10k pull-down resistor between the output of the external device and ground solved the problem.