ZMPT101B AC voltage sensor
The ZMPT101B AC voltage sensor: a transformer, an LM358 and a trimmer that turn the mains into a small sine wave for analogRead().
Mains is dangerous. On the bench the module's screw terminals are across live mains, which can kill. Only a qualified person should wire one; a plug-in step-down transformer is the safer way to bring an AC wave to a bench. In Mokxi the mains side is never wired: the slider stands in for it, and nothing here says that real mains wiring is safe.
It is a small voltage transformer, an LM358 op-amp and a blue multi-turn trimmer, with an analog output that is the mains waveform made small. Aliases: ZMPT101B, ZMPT, AC voltage sensor, mains voltage sensor.
Pins
| Pin | What it does |
|---|---|
VCC |
Supply, 5 V (or 3.3 V; see below). |
OUT |
The mains sine, scaled down, centered at half the supply: wire it to an analog pin. |
GND |
Ground. |
GNDb |
The board's second ground pin, the same ground. |
Properties
| Property | Default | Meaning |
|---|---|---|
mains |
230 | The mains voltage across the primary at the start, in volts rms. |
ratio |
600 | The trimmer's setting: mains volts rms for each volt rms at OUT. |
frequency |
50 | The mains frequency, 50 or 60 Hz. |
While it runs
The first slider is the mains voltage and the second is the trimmer, shown as its ratio.
Turning the trimmer up (a smaller ratio) makes the wave at OUT bigger.
What the model gets right
The output. OUT rests at half the supply, 2.5 V on 5 V (512 counts on an Uno), with
the mains sine on top: 230 V at a ratio of 600 is 0.383 V rms at OUT, 0.542 V peak.
The wave is drawn in 100 steps a cycle, and an RMS taken over whole cycles comes back
to the mains within a percent.
The trimmer is the calibration. The ratio is exactly the number the ZMPT101B
library's setSensitivity() takes. Nobody knows it on a real board until they compare
with a meter, so the default here (600) is not the library's default (500): with the
library left at 500, 230 V reads about 192 V.
Clipping. The LM358 cannot drive its output to its supply: it tops out about 1.5 V short, 3.5 V on 5 V. Turn the trimmer far enough up and the tops of the wave flatten and the RMS reads low. On 3.3 V the top is 1.8 V, only 0.15 V over the middle, so at 3.3 V the trimmer has to be turned well down.
What it does not model
The module's own noise (a real one reads a few volts with no mains at all), the transformer's phase shift, distortion on the mains, the output resistance (taken as 100 ohms), and the resistor values on the board, which vary between makers.
Libraries
ZMPT101B by Abdurraziq Bachmid (ZMPT101B.h): ZMPT101B sensor(A0, 50.0);,
sensor.setSensitivity(600.0f);, then sensor.getRmsVoltage(). It takes two mains
periods a call, 40 ms at 50 Hz. It builds on the AVR, ESP8266 and ESP32 boards only,
as upstream.
Common mistakes
Reading OUT once and calling it the voltage. One analogRead() is one point on a sine
wave: the voltage is the RMS over whole cycles, about the middle.
Forgetting the middle. Subtract the resting level (about 512 counts) before squaring, or the RMS is mostly the 2.5 V bias.
Leaving the sensitivity at the library's 500. Calibrate it against a meter you trust.
See it in action
AC voltmeter takes the RMS of the sine on A0 and scales it to the mains voltage. Open
it at /templates.
The guide Arduino AC voltage and energy meter walks through it and the PZEM-004T.