SurtrTech
Published © GPL3+

Measure Any AC Current with ACS712

Module tutorial, signal visualisation and a simple code to measure not only sinewave signals but all types, like TRMS Ammeter. + LCD/OLED.

BeginnerFull instructions provided1 hour96,627
Measure Any AC Current with ACS712

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
OLED i²c 128x32
×1
ACS712 30A
×1
LCD 16x2 i²c
×1

Story

Read more

Schematics

Wiring 1

Wiring used of tests 1,2 and 3

Wiring_LCD

Use LCD i²c

Wiring_OLED

Use OLED 128x32

Code

Code_1.ino

Arduino
This code is to test the module and visualize the signal shap
/*This code works with ACS712 Current sensor, it permits to read the raw data
  It's better to use it with Serial Plotter
  More details on www.surtrtech.com
*/

#define Current_sensor A0  //The sensor analog input pin

float i;


void setup() {

Serial.begin(9600);
pinMode(Current_sensor, INPUT);

}

void loop() {
  i = analogRead(Current_sensor);
  Serial.println(i);
  delay(100);                     //Modifying or removing the delay will change the way the signal is shown 
                                  //set it until you get the correct sinewave shap

}

Code_2.ino

Arduino
This code uses the peak-to-peak measuring method to calculate the RMS of a sinewave signal
/* This code works with ACS712 current sensor, it permits to calculate the RMS of a sinewave Alternating Current
 * it uses the Peak to Peak method to calculate the RMS
 * For more information check www.surtrtech.com
 */

#define SAMPLES 300   //Number of samples you want to take everytime you loop
#define ACS_Pin A0    //ACS712 data pin analong input


float High_peak,Low_peak;         //Variables to measure or calculate
float Amps_Peak_Peak, Amps_RMS;


void setup() 
{
  Serial.begin(9600);
  pinMode(ACS_Pin,INPUT);        //Define pin mode
}

void loop() 
{
 
  read_Amps();                               //Launch the read_Amps function
  Amps_RMS = Amps_Peak_Peak*0.3536*0.06;     //Now we have the peak to peak value normally the formula requires only multiplying times 0.3536
                                             //but since the values will be very big you should multiply by 0.06, you can first not use it, 
                                             //do your calculations and compare them to real values measured by an Ammeter. eg: 0.06=Real value/Measured value
                                             
  Serial.print(Amps_RMS);                    //Here I show the RMS value and the peak to peak value, you can print what you want and add the "A" symbol...
  Serial.print("\t");
  Serial.println(Amps_Peak_Peak);
  delay(200);
}

void read_Amps()            //read_Amps function calculate the difference between the high peak and low peak 
{                           //get peak to peak value
  int cnt;            //Counter
  High_peak = 0;      //We first assume that our high peak is equal to 0 and low peak is 1024, yes inverted
  Low_peak = 1024;
  
      for(cnt=0 ; cnt<SAMPLES ; cnt++)          //everytime a sample (module value) is taken it will go through test
      {
        float ACS_Value = analogRead(ACS_Pin); //We read a single value from the module

        
        if(ACS_Value > High_peak)                //If that value is higher than the high peak (at first is 0)
            {
              High_peak = ACS_Value;            //The high peak will change from 0 to that value found
            }
        
        if(ACS_Value < Low_peak)                //If that value is lower than the low peak (at first is 1024)
            {
              Low_peak = ACS_Value;             //The low peak will change from 1024 to that value found
            }
      }                                        //We keep looping until we take all samples and at the end we will have the high/low peaks values
      
  Amps_Peak_Peak = High_peak - Low_peak;      //Calculate the difference
}

Code_3.ino

Arduino
This code uses statistics formulas to calculate the TRMS of a signal whatever the sape and displays it on the serial monitor
/* This code works with ACS712 current sensor, it permits the calculation of the signal TRMS
 * Visit www.surtrtech.com for more details
 */

#include <Filters.h>                      //This library does a massive work check it's .cpp file

#define ACS_Pin A0                        //Sensor data pin on A0 analog input

float ACS_Value;                              //Here we keep the raw data valuess
float testFrequency = 50;                    // test signal frequency (Hz)
float windowLength = 40.0/testFrequency;     // how long to average the signal, for statistist



float intercept = 0; // to be adjusted based on calibration testing
float slope = 0.0752; // to be adjusted based on calibration testing
                      //Please check the ACS712 Tutorial video by SurtrTech to see how to get them because it depends on your sensor, or look below


float Amps_TRMS; // estimated actual current in amps

unsigned long printPeriod = 1000; // in milliseconds
// Track time in milliseconds since last reading 
unsigned long previousMillis = 0;

void setup() {
  Serial.begin( 9600 );    // Start the serial port
  pinMode(ACS_Pin,INPUT);  //Define the pin mode
}

void loop() {
  RunningStatistics inputStats;                 // create statistics to look at the raw test signal
  inputStats.setWindowSecs( windowLength );     //Set the window length
   
  while( true ) {   
    ACS_Value = analogRead(ACS_Pin);  // read the analog in value:
    inputStats.input(ACS_Value);  // log to Stats function
        
    if((unsigned long)(millis() - previousMillis) >= printPeriod) { //every second we do the calculation
      previousMillis = millis();   // update time
      
      Amps_TRMS = intercept + slope * inputStats.sigma();

      Serial.print( "\t Amps: " ); 
      Serial.print( Amps_TRMS );

    }
  }
}

/* About the slope and intercept
 * First you need to know that all the TRMS calucations are done by functions from the library, it's the "inputStats.sigma()" value
 * At first you can display that "inputStats.sigma()" as your TRMS value, then try to measure using it when the input is 0.00A
 * If the measured value is 0 like I got you can keep the intercept as 0, otherwise you'll need to add or substract to make that value equal to 0
 * In other words " remove the offset"
 * Then turn on the power to a known value, for example use a bulb or a led that ou know its power and you already know your voltage, so a little math you'll get the theoritical amps
 * you divide that theory value by the measured value and here you got the slope, now place them or modify them
 */

Code_ACS712_LCD.ino

Arduino
This code uses the TRMS calculation method and displays it on the LCD i²c
/* This code works with ACS712 and LCD ic
 * It measure the TRMS of an Alternating Current and displays the value on the screen
 * Visit www.SurtrTech.com for more details
 */

#include <Filters.h>              //This library does a huge work check its .cpp file
#include <LiquidCrystal_I2C.h>    //LCD ic library


#define ACS_Pin A0              //ACS712 data pin

#define I2C_ADDR 0x27 //I2C adress, you should use the code to scan the adress first (0x27) here
#define BACKLIGHT_PIN 3 // Declaring LCD Pins
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7

LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); //Declaring the lcd


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

float intercept = 0; // to be adjusted based on calibration testing
float slope = 0.0752; // to be adjusted based on calibration testing
                      //Please check the ACS712 Tutorial video by SurtrTech to see how to get them because it depends on your sensor, or look below

float Amps_TRMS; 
float ACS_Value;

unsigned long printPeriod = 1000; 
unsigned long previousMillis = 0;



void setup() {
  digitalWrite(2,HIGH);
  lcd.begin (16,2);
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH); //Lighting backlight
  lcd.home ();
  

}

void loop() {
  RunningStatistics inputStats;                 // create statistics to look at the raw test signal
  inputStats.setWindowSecs( windowLength );
   
  while( true ) {   
    ACS_Value = analogRead(ACS_Pin);  // read the analog in value:
    inputStats.input(ACS_Value);  // log to Stats function
        
    if((unsigned long)(millis() - previousMillis) >= printPeriod) { //every second we do the calculation
      previousMillis = millis();   // update time
      
      Amps_TRMS = intercept + slope * inputStats.sigma();  //Calibrate the values
      lcd.clear();               //clear the lcd and print in a certain position
      lcd.setCursor(2,0);
      lcd.print(Amps_TRMS);
      lcd.print(" A");

    }
  }
}

/* About the slope and intercept
 * First you need to know that all the TRMS calucations are done by functions from the library, it's the "inputStats.sigma()" value
 * At first you can display that "inputStats.sigma()" as your TRMS value, then try to measure using it when the input is 0.00A
 * If the measured value is 0 like I got you can keep the intercept as 0, otherwise you'll need to add or substract to make that value equal to 0
 * In other words " remove the offset"
 * Then turn on the power to a known value, for example use a bulb or a led that ou know its power and you already know your voltage, so a little math you'll get the theoritical amps
 * you divide that theory value by the measured value and here you got the slope, now place them or modify them
 */

Code_ACS712_OLED.ino

Arduino
This code uses the TRMS calculation method and displays the value on the OLED.
/* This code works with ACS712 and OLED ic
 * It measure the TRMS of an Alternating Current and displays the value on the screen
 * Visit www.SurtrTech.com for more details
 */


#include <Filters.h>            //This library does a huge work check its .cpp file
#include <Adafruit_GFX.h>       //OLED libraries
#include <Adafruit_SSD1306.h>

#define ACS_Pin A0

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET    -1 // Reset pin # (or -1 if sharing Arduino reset pin)

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

float intercept = 0; // to be adjusted based on calibration testing
float slope = 0.0752; // to be adjusted based on calibration testing
                      //Please check the ACS712 Tutorial video by SurtrTech to see how to get them because it depends on your sensor, or look below

float Amps_TRMS; 
float ACS_Value;

unsigned long printPeriod = 1000; 
unsigned long previousMillis = 0;

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

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display
  display.clearDisplay();
  display.display();
}

void loop() {
  RunningStatistics inputStats;                 // create statistics to look at the raw test signal
  inputStats.setWindowSecs( windowLength );
   
  while( true ) {   
    ACS_Value = analogRead(ACS_Pin);  // read the analog in value:
    inputStats.input(ACS_Value);  // log to Stats function
        
    if((unsigned long)(millis() - previousMillis) >= printPeriod) { //Do the calculations every 1s
      previousMillis = millis();   // update time
      
      Amps_TRMS = intercept + slope * inputStats.sigma();
      display.clearDisplay();
      display.setTextSize(3);                    
      display.setTextColor(WHITE);             
      display.setCursor(15,10);                
      display.print(Amps_TRMS); 
      display.println(" A");
      display.display();
    }
  }
}

/* About the slope and intercept
 * First you need to know that all the TRMS calucations are done by functions from the library, it's the "inputStats.sigma()" value
 * At first you can display that "inputStats.sigma()" as your TRMS value, then try to measure using it when the input is 0.00A
 * If the measured value is 0 like I got you can keep the intercept as 0, otherwise you'll need to add or substract to make that value equal to 0
 * In other words " remove the offset"
 * Then turn on the power to a known value, for example use a bulb or a led that ou know its power and you already know your voltage, so a little math you'll get the theoritical amps
 * you divide that theory value by the measured value and here you got the slope, now place them or modify them
 */

Credits

SurtrTech

SurtrTech

9 projects • 207 followers
YT Channel bit.ly/35Ai76l, run by Automation and Electrical Engineer, Electronics amateur, no IT background so you may see wreckage in codes

Comments