Using a ModeMCU as a voltmeter

Measure volts with an ESP8266

Don't have a multimeter? No problem! Did you know that you can use your NodeMCU (or any ESP8266) as if it were a voltmeter?

Sometimes a voltmeter is almost essential to be able to solve any problem that arises when we work with microcontrollers, or with any electronic circuit usually.

In this article we will see how we can use the NodeMCU as a basic voltmeter, that can get us out of trouble if we don't have a multimeter.

This is very easy. My advice: Watch the video first, where I explain all this in a very simple and to the point, so that you can be measuring voltages quickly. Later read the rest of the article before trying to measure anything, to know the details you should know.

Video tutorial: How to use a ModeMCU as a voltmeter

I'm sorry, I haven't finished mounting the video, but as a colleague from the Telegram group needed the tutorial, I decided to publish it. Better to have only the tutorial on the blog than to have nothing. Don't you think? 😉

What, what is an Analog to Digital Converter (or ADC)?

Surely you know that, in the world of computers, and microcontrollers, what these strange animals with wire legs handle are zeros and ones.

Among the wonders that the ESP8266 has in such a small space, there is a pin (the A0 or ADC0) that includes an analog to digital converter or ADC (of TOnalog Digital Converter).

An ADC is an electronic circuit that converts a real-world analog signal that can have any value, with an infinite number of decimal places, into a sequence of ones and zeros that the microcontroller can understand.

What if, inside the ESP8266 there is an ADC circuit.

The ESP8266 ADC

I want this blog post to be eminently practical, for beginners, so I'm not going to go into the fine print details of the ADC (which is a lot, and a very small). Just tell you the basics, so that you can use it:

The ACD of the ESP8266, which is the microcontroller on boards like NodeMCU, Wemos D1 Mini, and the like, includes a 10-bit 1-volt ADC maximum.

What do you mean that the ADC is 10bit?

What has that «resolution«.

The numbers in decimal that can be represented with 10bits go from 0 to 1023 And that means that, whatever we do, the ADC will give its output in one of those 1023 jumps (without the possibility of decimals, or intermediate points, so that we understand each other).

In other words, if we wanted to measure from 0 to 1023 volts, the ADC would give us a resolution of 1 volt (we couldn't measure 534.7 volts, only 534 or 535 volts). If we wanted to measure a range of 5 volts, the ADC would give us a resolution of 1024/5 = 0.00488 volts.

What do you mean that the ADC is 1 volt maximum?

It means that the maximum voltage that we can apply, directly, to the ADC is 1 volts (in other words, it has a range that goes from 0 volts to 1 volt).

In practice, this means that, if we put exactly 1 volt into the ADC of the ESP8266, without using an external voltage divider, it will give us the maximum value, which is 1023.

Maybe you are also interested in:  Active or passive buzzer for Arduino, ESP8266, NodeMCU, ESP32, etc

What if we want to measure voltages over 1 volt?

Nothing happens. We will only have to use a voltage divider, which is formed by two resistors, putting the resistances of the values that suit us best (later we will see how to calculate those resistances, and I will give you some examples already calculated so that you do not have to do it yourself).

Surely you are not using an ESP8266 microcontroller directly, but most likely you are using a board like NodeMCU (in any of its variants) or Wemos D1 Mini and I have one great news for you: Those plates already come with the resistors on.

The problem that you are going to find is that the manufacturer has put some resistors on most of these plates, to create the voltage divider that we talked about before, suitabledays to measure a maximum of 3.3V (or what is the same, that will give us a value of 1023 when we put 3.3 volts).

Logically, in many cases this does not work for us. You are going to want to measure many times, more than 3.3 volts. You will want to measure voltages of 5 volts, 12 volts, or more. The solution is easy, we only have to modify the voltage divider, putting an external resistance to measure the voltage you want.

ESP8266 ADC Limitations

There are ADC circuits on the market with a precision amazing, a resolution amazing and a repeatability amazing. The ADC of the ESP8266 is not among them, unfortunately, but for our purposes it is enough.

The ESP8266 ADC has relatively low resolution (only those 1024 jumps, of which we have spoken before), little precision (we do not know with much accuracy if the measurement that indicates us is correct) and the worst thing is that it has a lot of noise.

Having a lot of noise causes the ESP8266's ADC to be a bit «myopic»And that the voltage that we put in it does not see it completely clear, but it sees it as if it were looking at it through a«broken glass»And that means that sometimes you can make mistakes. That is not important for most of the uses that we are going to give it (measure voltages) because that's what we are for, with our privileged brain, we will put to ignore the erroneous measurements very easily when seeing them, almost without realizing it.

There are some other limitations such as linearity and others in which I am not going to go into, but, if it is a topic that interests you, on the internet you can find a lot of information about it.

To the practical: How do I measure voltage with the NodeMCU?

To measure any voltage, you will need two parts: The hardware and software.

As hardware, in this first explanation, we are going to use only a NodeMCU without any additional resistance because we are going to measure a 3.3 volt maximum Do you remember what I told you about the fact that the NodeMCU already has the necessary voltage divider on its board to be able to measure up to 3.3 volts?

As a software, I'm going to teach you do it with ESP Easy, which does not require any programming and allows you to do a lot of things with that voltage, such as graphs, calculations, rules, send it to other systems and more.

The first thing is to install ESP Easy in your NodeMCU (in the tutorial of the Homemade CO2 Meter you have the detailed instructions to do it).

Now you have to tell ESP Easy that you want to use the ADC pin (A0) to read voltage. You just have to go to the tab «Devices»(Devices) and add the analog input and configure it:

Add the analog input in ESPEasy
Configure ESPEasy analog input

And now notice one thing: Do you see that I have written a formula that says %value% * 0.3125?

I put that formula to give me the actual voltage value that I apply to it, instead of the number from 0 to 1023 that we talked about before (which uses the ESP8266 internally).

What ESPEasy will do is, before displaying the internal value from 0 to 1023 (that %value% in the formula), multiply it by the number 0.3125.

Imagine that we put the voltage of a 1.5V battery, instead of showing us a number like 465 (which would be 1024 / 3.3 * 1.5) it will show us 145.31 which is the real voltage (approximately).

Maybe you are also interested in:  Color touch screen for CO medidor meter Wow!

Then we will talk about that approximation to the real voltage and the formula used.

By the way, I have not told you where you have to connect the stack of the example:

The voltage to be measured (the battery) you have to connect it to GND (which is negative) and pin A0 (which is the analog input of the NodeMCU).

Measure more than 3.3 volts with the NodeMCU

The previous example helps you to measure up to a maximum of 3.3 volts, because the voltage divider that the NodeMCU brings is calculated for that.

If we want to measure more than 3.3 volts, we will have to modify the voltage divider (remember that the function of the existing voltage divider in the NodeMCU is to adapt the voltage that we want to measure to a range of 0 to 1 volt, which is the maximum that we can put ESP8266).

Fortunately, modifying it is very simple. I leave you here how to modify it by adding just a resistance (let's get to the point and then I'll tell you why and how to calculate those resistances).

To measure up to 5 volts: It is best if you put a resistance of 270KΩ (270 kilohms). With this value the maximum you could measure would be 5.7 volts and the formula for ESPEasy would be %value% * 0,0,05566 (5.5/1024 = 0,0556640625).

To measure up to 12 volts: It is best if you put a resistance of 1MΩ (1 megohm). With this value the maximum you could measure would be 13.2 volts and the formula for ESPEasy would be %value% * 0.1289 (13.2/1024 = 0,12890625).

And how to make a voltmeter with a Wemos D1 Mini?

Exactly the same as we have done for the NodeMCU. The only difference is that the pin you have to use is somewhere else:

What if I am brave and want to measure volts with an ESP8266, directly?

If you want to measure volts with an ESP8266 directly, an ESP-12E for example, you will have to put a suitable voltage divider.

For this you will have to calculate the necessary resistances to make your own voltage divider, taking into account that the maximum voltage that you must apply to the ESP8266 is 1 volt, as indicated in the next point.

Keep in mind that, you will have to check which is the pin that corresponds to the analog input, and that will depend on the module you are using (for example, an ESP12E like the one in the image).

What if the examples you have given me are not worth it? How to calculate the resistors needed to make my own voltage divider?

To measure more than 3.3 volts, We'll have to modify the voltage divider, which we have talked about before.

Let's first see the voltage meter that the NodeMCU brings, looking at that part of the diagram:

NodeMCU analog input to ESP8266

I explain this scheme, it is very simple: The bottom part goes to negative, the top part (where it says ADC EX) goes to the NodeMCU pin marked A0 (analog input) and the left part (where it says ADC) goes to the ESP8266 microcontroller.

It is these two resistors that form the voltage divider, and at the central point (where ADC comes from) there is a value proportional to what we put above (ADC EX) but divided according to a formula.

I leave you a formula that, if mathematics is your thing, will tell you more than 1000 words and explanations:

V1023 = 1V * (100kΩ + 220kΩ + R) / 100kΩ
Where R is the resistance that you put in series with pin A0.

I recommend that you use a voltage divider calculator like this.

Below you have an example of how it is used to calculate the resistance if we want to measure a maximum of 4.2V

In case you have any doubts, I leave you a clear example, with the development of the formula, so that it is as easy as possible to calculate yourself:

The accuracy of the voltage divider resistors

The precision of the measurements you obtain will depend a lot on the resistance precision that you use.

In quality commercial measuring instruments, resistors are used with the 1% and even 0.1% and lower tolerance.

Common, inexpensive, and easy-to-find resistors typically have tolerances of a 5% or 10%, which means that if you choose a 270KΩ resistor and it has a 10% tolerance you will not know the exact value of the resistor (unless you measure it) and it may be between 243KΩ and 297KΩ.

Maybe you are also interested in:  Experiments with ESP Easy (ESP8266) and low consumption - v1.0

This assumes that the measure you obtain will also have a relatively large tolerance.

If you need to get very accurate voltage measurements, you will have to take this into account.

Another thing you have to keep in mind is that there are no resistors of all values and you will have to use resistors with standard values (those available commercially). Fortunately you can easily adjust the ESPEasy formula at any time to correct it.


The ideal is calibrate the meter using a voltage source of known valuea to check the accuracy of the measurement, but what if you don't have a voltage source of known value?

Surprise: You do have one! The NodeMCU (and the Wemos D1 Mini and other similar boards) include a fairly accurate 3.3V voltage regulator on the board, so you can use one of the 3.3V pins to, by measuring it, calibrate the meter until the reading reads exactly 3.3V.

The calibration consists of two parts:

Formula setting: To correct possible deviations in resistor values and the like.

Calibration point adjustment: Allows you to calibrate at two intermediate points of the measurement range to correct linearity errors (For this you will need a reference voltmeter or a multimeter).

But I don't have resistors, do I have to buy them?

If you don't have a resistor, don't worry, just yet there is a solution

The good thing is that the resistance you need will be within a huge range, so it will be easy for you to locate a valid one in any damaged or old device that you have out there. You will simply have to learn to read its value, which is quite easy, and adjust formula according to the resistance that you have been able to find. You skin it off the old device and use it to measure.

Soon I will teach you to read its value. For now, ask in the chat and I'll help you.

Measure the battery that powers a NodeMCU

This is a widely used utility of this type of application. If you have a NodeMCU (or other similar board) powered by battery you can use this same technique to measure the battery voltage and, in this way, know the charge that it has left.

For example, if you are feeding it with a Li-Po or Li-Ion battery that can give up to 4.2V, you only have to connect the positive of the battery to pin A0 through a 100Kohm resistance, as I have indicated before.

With a resistance of 100K, the maximum that you can measure will be 4.2V, perfect for measuring a battery of this type using the maximum possible range of the ADC.

Here you can see the calculation of the necessary resistance made with the voltage divider calculator on-line.

Remember that the resistance we have to put is 100K (and not 320K) because the NodeMCU already has a 220K one installed on the board and we are going to put it in series.

With this voltage divider when you put 4.2V at the input you will have 1V at the output and since the NodeMCU measures from 0 to 1020 = 0 to 1V, you will have to put a formula to give you the value in volts (instead of a number which is 0 = 0V and 1023 = 1V), do you remember what we have seen before?

The formula will be %value% * 0.0041015625 (because 4.2V / 1024 = 0.0041015625V).

Think about it, when you put 4.2V into the 1V output that will give you a value of 1023. If you multiply 0.0041015625Vx1024 = 4.2V Just the voltage you have at the input!

You can check the rest of the values, to confirm that the formula is correct, using a rule of three or using the formula you have above.

Leave a Comment