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.