Project tutorial
Measure Any AC Voltage Up to 250V

Measure Any AC Voltage Up to 250V © GPL3+

Using one single module and a proper library you'll be able to measure any AC voltage like a TRMS multimeter.

  • 455 views
  • 0 comments
  • 3 respects

Components and supplies

A000066 iso both
Arduino UNO & Genuino UNO
×1
128x32 OLED display
×1

About this project

Tutorial video, check out for more

Intro:

Please be careful when working on this type of project.

Hello, the tutorial today is about measuring any AC voltage up to 250V, and yes any type of signals: sinewave, square, triangular, "weird"... and where the tutorials that use bridge rectifier + voltage divider will fail like cheap multimeter (check the video for comparison), this only module with a proper code can measure the TRMS (True RMS) of the signal to show you the correct values if you give it enough time to calibrate properly.

Problematic:

To not make it any long for you, here's a summary: here where I live we have 220-230 V / 50Hz, first I wire the module inputs with the power socket to calibrate it then I measure the voltage in an old light bulb, controlled by a Triac based light dimmer.

As you can see the shape of the signal isn't linear, and if you measure using a rectifier it will give you wrong readings, also measuring from peak to peak will give you wrong readings, the only way to do is a real calculation and you know how it's done, and you realize how it's very difficult to implement it in a code, don't worry I have an easy library as always.

Elements

So here are the elements I'm using:

The module is very handy, it takes the signal as is it from the source and adapt it to your Arduino:

Setup:

First thing to do is wiring you module with Arduino board, upload the following code and adjust the potentiometer until you get the shape bellow on your Serial plotter.

void setup() 
{Serial.begin(9600);
}
void loop() 
{Serial.println(analogRead(A0));
} 

Open the serial plotter you should have something like (1st and 2nd picture) turn you knob until you get (3rd picture).

And if you want a sinewave signal you add a delay to the code

void setup() 
{Serial.begin(9600);
}
void loop() 
{Serial.println(analogRead(A0));
delay(100);
} 

and you'll have something like this, don't mind the little peaks, it's because I'm taking the signal after the light dimmer, from the power socket it would be perfect sinewave, the big circle is when I turned my dimmer to lower power

Now your module is calibrated, you need to upload the other code for reading, note that I'm using an OLED display, you can remove the lines that concerns the display.

in the code two lines a very important for good reading and it's very difficult to calibrate from there, if you find another way share it with us.

float intercept = -0.04;
float slope = 0.0405; 

And for further calibration there's a line bellow them in the loop:

current_Volts= current_Volts*(40.3231); 

A big shoutout to the "Filters.h" library, reduces the huge amount of work needed to calculate the RMS of a signal.

You can check the video, even cheap multimeter failed to measure, so be sure to use the right instrument to calibrate.

I hope you like it and if you have any problem comment it here, be safe and subscribe to my channel.

Code

AC_Voltage_Measuring.inoArduino
/* This code works with ZMPT101B AC voltage sensor module and 128x32 OLED display
 * It permits you to measure any AC voltage up to 250V, BE CAREFUL !!!
 * The functions from Filters library permits you to calculate the True RMS of a signal
 * Refer to www.surtrTech.com or SurtrTech YouTube channel for more details
 */

#include <Filters.h> //Easy library to do the calculations
#include <SPI.h>     //Libraries for the OLED display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET    -1 //

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display)

float testFrequency = 50;                     // test signal frequency (Hz)
float windowLength = 40.0/testFrequency;     // how long to average the signal, for statistist

int Sensor = 0; //Sensor analog input, here it's A0

float intercept = -0.04; // to be adjusted based on calibration testing
float slope = 0.0405; // to be adjusted based on calibration testing
float current_Volts; // Voltage

unsigned long printPeriod = 1000; //Refresh rate
unsigned long previousMillis = 0;


void setup() {
  Serial.begin( 9600 );    // start the serial port
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display 
  display.clearDisplay();
  display.setTextSize(2);                   
  display.setTextColor(WHITE);              
  display.setCursor(1,1);               
  display.print("SurtrTech");
  display.setCursor(1,20);
  display.setTextSize(1);
  display.print("AC Voltmeter");
  display.display();
  delay(5000);

}

void loop() {
  
  RunningStatistics inputStats;                //Easy life lines, actual calculation of the RMS requires a load of coding
  inputStats.setWindowSecs( windowLength );
   
  while( true ) {   
    Sensor = analogRead(A0);  // read the analog in value:
    inputStats.input(Sensor);  // log to Stats function
        
    if((unsigned long)(millis() - previousMillis) >= printPeriod) {
      previousMillis = millis();   // update time every second
            
      Serial.print( "\n" );
      
      current_Volts = intercept + slope * inputStats.sigma(); //Calibartions for offset and amplitude
      current_Volts= current_Volts*(40.3231);                //Further calibrations for the amplitude
      
      Serial.print( "\tVoltage: " );
      Serial.print( current_Volts ); //Calculation and Value display is done the rest is if you're using an OLED display
      
      
      display.clearDisplay();
      display.setTextSize(3);       //size of the text that will follow              
      display.setTextColor(WHITE);  //its color            
      display.setCursor(1,1);      //position from where you want to start writing           
      display.print(current_Volts,1);
      display.setCursor(115,00);
      display.setTextSize(2);
      display.print("V");
      display.setCursor(115,15);
      display.setTextSize(1);
      display.print("AC");
      display.display();
    }
  }

}
Filters library
Thanks a lot

Schematics

Wiring
Use an OLED display if you want or not, just pay attention LCD may not work well
Wiring rfltedfuw8

Comments

Similar projects you might like

Measure your reaction time

Project tutorial by Jayraj Desai

  • 29,069 views
  • 9 comments
  • 30 respects

Arduino and AC Devices - Automatic Lights

Project tutorial by Ahmed Hamdy

  • 21,949 views
  • 7 comments
  • 51 respects

How to Measure Air Quality on OpenSensors

Project tutorial by OpenSensors.io

  • 12,791 views
  • 8 comments
  • 60 respects

Measure LUX with Arduino Using BH1750

Project tutorial by afsh_ad

  • 1,967 views
  • 0 comments
  • 3 respects

Light Meter To Measure Plant Growth Conditions

Project tutorial by Jennifer Deegan

  • 1,254 views
  • 2 comments
  • 6 respects
Add projectSign up / Login