Need calibration for 220V main , for current and voltage meter

can i connect acs712 and zmpt101b dirctly to arduino and use emo code?

Have you looked at the data sheets? They should, in fact they do, tell you.

First, the ACS712.
Check the supply voltage: in the table COMMON OPERATING CHARACTERISTICS, it is 5 V typical, so that can connect to the same supply as the Arduino.
Check the output: In the same table it is Zero Current Output Voltage - VCC × 0.5. That means 2.5 V, which is exactly what you want to put it in the centre of the available range.
So the answer for this - yes you can connect it directly.

Second, the ZMPT101B. That is a current transformer, so you need a few more components. In fact, you can use our circuit for the SCT-013-000 current transformer but with just one extra resistor - R’ on the Interplus data sheet. That is necessary to convert the mains voltage to a current.
Look at the circuit diagram here Learn→Electricity Monitoring→CT Sensors→3. Interfacing with an Arduino→CT Sensors - Interfacing with an Arduino
The data sheet says “Primary current: 2 mA” You must calculate the value of the resistor to give 2 mA at your mains voltage - whatever that is - and connect it in series with the primary winding. If your voltage is more than 120 V, I recommend you use two resistors in series, each half the value you need, for safety. Be certain that you use a resistor or resistors rated to at least 350 V, and at least 0.5 W if your voltage is less than 250 V. If it is more, you must be sure that the voltage and power rating is adequate for the actual voltage.

Now the secondary side: The resistor on our diagram labelled “Burden - 33Ω” is resistor R on the data sheet. You want 1.6 V when 2 mA is flowing, therefore the value needs to be 800 Ω. If you can get a 750 Ω resistor, that is the best value to use, or failing that, 680 Ω.
The remaining components, R1, R2 & C1 are correct for what you want.

You should then be able to use the sketch on this page Learn→Electricity Monitoring→Current & Voltage→Basic: How to build an arduino energy monitor→How to build an Arduino energy monitor - measuring mains voltage and current BUT you will need to change the calibration factors to get the correct values.

I cannot calculate those for you because I do not know which ACS712 you have, nor do I know what the value for R’ with the ZMPT101B will be. You must set them using the calibration procedure that is in the same section of ‘Learn’.

Please format code with 3 backticks on a line before, and 3 backticks on a line after (BPO Mod)

#include <LiquidCrystal.h>
LiquidCrystal lcd(3, 5, 6, 7, 8, 9);
const int voltageSensor = A0;
const int currentSensor = A1;
const int numberOfSamples = 3000;
// Calibration constants
const float AC_WALL_VOLTAGE = 120.9;
const float AC_ADAPTER_VOLTAGE = 14.1;
const float AC_VOLTAGE_DIV_VOUT = 0.85;
const float CT_BURDEN_RESISTOR = 40.2;
const float CT_TURNS = 2280.0;
// Calibration coefficients
const float VCAL = 1.0;
const float ICAL = 1.0;
const float PHASECAL = 0.9;
// Calculated ratio constants, modified by VCAL/ICAL
const float AC_ADAPTER_RATIO = AC_WALL_VOLTAGE / AC_ADAPTER_VOLTAGE;
const float AC_VOLTAGE_DIV_RATIO = AC_ADAPTER_VOLTAGE / AC_VOLTAGE_DIV_VOUT;
const float V_RATIO = AC_ADAPTER_RATIO * AC_VOLTAGE_DIV_RATIO * 5 / 1024 * VCAL;
const float I_RATIO = CT_TURNS / CT_BURDEN_RESISTOR * 5 / 1024 * ICAL;
// Sample variables
int lastSampleV, lastSampleI, sampleV, sampleI;
// Filter variables
float lastFilteredV, lastFilteredI, filteredV, filteredI;
// Power sample totals
float sumI, sumV, sumP;
// Phase calibrated instantaneous voltage
float calibratedV;
// Calculated power variables
float realPower, apparentPower, powerFactor, voltageRMS, currentRMS;
unsigned long last_kWhTime, kWhTime;
float kilowattHour = 0.0;
void setup() {
lcd.begin(16,2);
}
void loop() {
   
calculatePower();
displayPower();

}
void calculatePower() {
for (int i = 0; i < numberOfSamples; i++) {
// Used for voltage offset removal
lastSampleV = sampleV;
lastSampleI = sampleI;
// Read voltage and current values
sampleV = analogRead(voltageSensor);
sampleI = analogRead(currentSensor);
// Used for voltage offset removal
lastFilteredV = filteredV;
lastFilteredI = filteredI;
// Digital high pass filters to remove 2.5V DC offset
filteredV = 0.996 * (lastFilteredV + sampleV - lastSampleV);
filteredI = 0.996 * (lastFilteredI + sampleI - lastSampleI);
// Phase calibration
calibratedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV);
// Root-mean-square voltage
sumV += calibratedV * calibratedV;
// Root-mean-square current
sumI += filteredI * filteredI;
// Instantaneous Power
sumP += abs(calibratedV * filteredI);
}
// Calculation of the root of the mean of the voltage and current squared (rms)
// Calibration coeficients applied
voltageRMS = V_RATIO * sqrt(sumV / numberOfSamples);
currentRMS = I_RATIO * sqrt(sumI / numberOfSamples);
// Calculate power values
realPower = V_RATIO * I_RATIO * sumP / numberOfSamples;
apparentPower = voltageRMS * currentRMS;
powerFactor = realPower / apparentPower;
Serial.print(voltageRMS);
 Serial.println(currentRMS);
 Serial.println( realPower);
 Serial.println( apparentPower);
 Serial.println (powerFactor);
// Calculate running total kilowatt hours
// This value will reset in 50 days
last_kWhTime = kWhTime;
kWhTime = millis();
// Convert watts into kilowatts and multiply by the time since the last reading in ms
kilowattHour += (realPower / 1000) * ((kWhTime - last_kWhTime) / 3600000.0);
// Reset sample totals
sumV = 0;
sumI = 0;
sumP = 0;
}
void displayPower() {
lcd.clear();
lcd.print(realPower, 0);
lcd.print("w ");
lcd.print(apparentPower, 0);
lcd.print("va ");
lcd.print(powerFactor * 100, 0);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print(voltageRMS, 0);
lcd.print("v ");
lcd.print(currentRMS, 1);
lcd.print("a ");
lcd.print(kilowattHour, 4);
}

why it dosnt give value in serial monitor

I’m not going to tell you, but I will tell you where to look and how to find your mistake. :wink:

There’s an important statement missing from setup( ). Go back to the Arduino documentation where it tells you about printing to the Serial port, and carefully compare their setup( ) with yours.

Serial.begin(9600)?

:+1: That’s it, well done. Now you have printing?

no :rofl: but i try anathor code and it work 
 but there is some problem when i try more than one load can you help

I cannot read that. Please either provide a link to the source code, or copy and paste your sketch.

You will also need to say what the problem is.

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

#include "EmonLib.h"             // Include Emon LibrarEnergyMonitor emon1// Create an instance
EnergyMonitor emon1;
const int RELAY_PIN = 3;


void setup()
{  
  Serial.begin(9600);
  pinMode(RELAY_PIN, OUTPUT);
  
  emon1.voltage(A0, 650,1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(A1,70);       // Current: input pin, calibration.
  emon1.current(A2,70);       // Current: input pin, calibration.
  
  emon1.current(A3,70);  
}

void loop()
{
  digitalWrite(RELAY_PIN, LOW);
  emon1.calcVI(20,2000);        // Calculate all. No.of half wavelengths (crossings), time-out
  Serial.println();// Calculate all. No.of half wavelengths (crossings), time-out
  emon1.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)
  Serial.println(); 
  
  float realPower       = emon1.realPower;        //extract Real Power into variable
  float apparentPower   = emon1.apparentPower;    //extract Apparent Power into variable
  float powerFActor     = emon1.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage   = emon1.Vrms;             //extract Vrms into Variable
  float Irms            = emon1.Irms;             //extract Irms into Variable
  float realPower1      =emon1.realPower;
  float apparentPower1   = emon1.apparentPower;
  float powerFActor1     = emon1.powerFactor;
   float supplyVoltage1   = emon1.Vrms;
  float Irms1            = emon1.Irms;   
    if(Irms <= 0.1)
    
        {
          digitalWrite(RELAY_PIN,HIGH);
          delay(1000);
        }
  
}

is it correct to calculate the second lode?

No. What you must do is create a second and third “instance” of EnergyMonitor, like this:
EnergyMonitor emon1, emon2, emon3;
(just the same way as you might create integers, say: int integer1, integer2;)

Then everything you have done for emon1, you repeat for emon2 and emon3, but using the different pin numbers for the different inputs.

So:

  emon1.voltage(A0, 650,1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(A1,70);       // Current: input pin, calibration.

  emon2.voltage(A0, 650,1.7);  // Voltage: input pin, calibration, phase_shift
  emon2.current(A2,70);       // Current: input pin, calibration.
  
  emon3.voltage(A0, 650,1.7);  // Voltage: input pin, calibration, phase_shift
  emon3.current(A3,70);  

(That is if you are using the same voltage throughout.)

Then to calculate and print Input 2 power, etc, add:

  emon2.calcVI(20,2000);
  emon2.serialprint();

and so on. Therefore, the current measured by Input 2 will be emon2.Irms.

you are the best 
 thaaanksss

can you help 
when i use the same loads i have different current and power why?
and how i can save the value of relay in (if stetment)
this is the code

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

#include "EmonLib.h"             // Include Emon LibrarEnergyMonitor emon1// Create an instance
EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;
const int RELAY1_PIN = 3;
const int RELAY2_PIN = 4;
const int RELAY3_PIN = 5;

void setup()
{  
  Serial.begin(9600);
  pinMode(RELAY1_PIN, OUTPUT);
  pinMode(RELAY2_PIN, OUTPUT);
  pinMode(RELAY3_PIN, OUTPUT);
 emon1.voltage(A0, 650,1.7);  // Voltage: input pin, calibration, phase_shift
  emon1.current(A1,60);       // Current: input pin, calibration.

  emon2.voltage(A0, 650,1.7);  // Voltage: input pin, calibration, phase_shift
  emon2.current(A2,60);       // Current: input pin, calibration.
  
  emon3.voltage(A0, 650,1.7);  // Voltage: input pin, calibration, phase_shift
  emon3.current(A3,60); 
}

void loop()
{
  digitalWrite(RELAY1_PIN, HIGH);
  digitalWrite(RELAY2_PIN, HIGH);
  digitalWrite(RELAY3_PIN, HIGH);
  emon1.calcVI(20,2000);        // Calculate all. No.of half wavelengths (crossings), time-out
  emon2.calcVI(20,2000);        // Calculate all. No.of half wavelengths (crossings), time-out
  emon3.calcVI(20,2000);        // Calculate all. No.of half wavelengths (crossings), time-out
  Serial.println("first load");// Calculate all. No.of half wavelengths (crossings), time-out
  emon1.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)
  Serial.println("second load ");// Calculate all. No.of half wavelengths (crossings), time-out
  emon2.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)
  Serial.println("third load");// Calculate all. No.of half wavelengths (crossings), time-out
  emon3.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)

  //Serial.println(); 
  float realPower       = emon1.realPower;        //extract Real Power into variable
  float apparentPower   = emon1.apparentPower;    //extract Apparent Power into variable
  float powerFActor     = emon1.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage   = emon1.Vrms;             //extract Vrms into Variable
  float Irms            = emon1.Irms;             //extract Irms into Variable
  float realPower1       = emon2.realPower;        //extract Real Power into variable
  float apparentPower1   = emon2.apparentPower;    //extract Apparent Power into variable
  float powerFActor1     = emon2.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage1   = emon2.Vrms;             //extract Vrms into Variable
  float Irms1            = emon2.Irms;             //extract Irms into Variable
  float realPower2       = emon3.realPower;        //extract Real Power into variable
  float apparentPower2   = emon3.apparentPower;    //extract Apparent Power into variable
  float powerFActor2     = emon3.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage2   = emon3.Vrms;             //extract Vrms into Variable
  float Irms2            = emon3.Irms;             //extract Irms into Variable
  delay(5000);
  if(Irms <2.0)       
  {
      digitalWrite(RELAY1_PIN,LOW);
      delay(500);
  }
  if(Irms1<0.5)
  {
     digitalWrite(RELAY2_PIN,LOW);
     delay(500);
  }
  if(Irms2>100  )
  {
     digitalWrite(RELAY3_PIN,LOW);
     delay(500);
  }    
     
}

[Edited for presentation - RW]

This is what the relays do at the moment:

When the sketch starts, the relay pins are ‘low’. This happens automatically.

At the start of the loop, all the relay pins are set ‘high’.
A little over 5 s later (the delay 5000 ms + 30 mains cycles + the time to do the 3 print statements), you test the first relay. I Irms is small (< 2.0) the relay pin goes low. Otherwise, it remains high.
0.5 s later if relay 1 was set low, otherwise immediately, you test Irms1 and likewise, set the pin low and delay, or immediately test Irms2. In exactly the same way, you wait for 0.5 s if you set the relay low, otherwise you return to the top of the loop and set all relay pins high again.

Now I do not know what you want, but it seems peculiar that you repeat the loop once every (approximately) 5œ s, 6 s, 6œ s or 7 s depending on how many relays changed from high to low. And of course it means that if the current satisfies the condition, the relay pin is low for œ s every 5 s, otherwise it remains high.

I think you need to explain what you want the relay to do.

For future reference, when posting code or output, put in 3 ‘backticks’ (found at the top left of the keyboard normally) on a line on their own, then the code, then 3 more backticks on a line following the code.

```
code
```

i will delete the delay in if stetmant because its not important 
but can you tell me how can i save the relay state if condetion is satisfied?

I do not understand what you want. You need to explain what you want the relay to do.

Let me try a different way:

Under what condition do you want the relay pin ‘high’?
Under what condition do you want the relay pin ‘low’?

when Irms exceed spesific value relay open and never close

I think - I am not certain - that what you want is this:

void loop()
{
  emon1.calcVI(20,2000);        // Calculate all. No.of half wavelengths (crossings), time-out
  emon2.calcVI(20,2000);        // Calculate all. No.of half wavelengths (crossings), time-out
  emon3.calcVI(20,2000);        // Calculate all. No.of half wavelengths (crossings), time-out
  Serial.println("first load");// Calculate all. No.of half wavelengths (crossings), time-out
  emon1.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)
  Serial.println("second load ");// Calculate all. No.of half wavelengths (crossings), time-out
  emon2.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)
  Serial.println("third load");// Calculate all. No.of half wavelengths (crossings), time-out
  emon3.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)

  //Serial.println(); 
  float realPower       = emon1.realPower;        //extract Real Power into variable
  float apparentPower   = emon1.apparentPower;    //extract Apparent Power into variable
  float powerFActor     = emon1.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage   = emon1.Vrms;             //extract Vrms into Variable
  float Irms            = emon1.Irms;             //extract Irms into Variable
  float realPower1       = emon2.realPower;        //extract Real Power into variable
  float apparentPower1   = emon2.apparentPower;    //extract Apparent Power into variable
  float powerFActor1     = emon2.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage1   = emon2.Vrms;             //extract Vrms into Variable
  float Irms1            = emon2.Irms;             //extract Irms into Variable
  float realPower2       = emon3.realPower;        //extract Real Power into variable
  float apparentPower2   = emon3.apparentPower;    //extract Apparent Power into variable
  float powerFActor2     = emon3.powerFactor;      //extract Power Factor into Variable
  float supplyVoltage2   = emon3.Vrms;             //extract Vrms into Variable
  float Irms2            = emon3.Irms;             //extract Irms into Variable

  delay(5000);
  if (Irms <2.0)       
    digitalWrite(RELAY1_PIN,LOW);
  else if (Irms > 2.05)
    digitalWrite(RELAY1_PIN,HIGH);
  
  if (Irms1<0.5)
    digitalWrite(RELAY2_PIN,LOW);
  else if (Irms1 > 0.55)
    digitalWrite(RELAY2_PIN,HIGH);
  
  if (Irms2>100  )
    digitalWrite(RELAY3_PIN,LOW);
  else if (Irms < 99.9)
    digitalWrite(RELAY3_PIN,HIGH);
    
}

Look at Irms and RELAY1:

  if (Irms <2.0)       
    digitalWrite(RELAY1_PIN,LOW);

If Irms is less than 2.0, that will make the pin LOW.
If Irms is not less than 2.0, it tests this:

  else if (Irms > 2.05)
    digitalWrite(RELAY1_PIN,HIGH);

and if Irms is greater than 2.05, it makes the pin HIGH.
If Irms is greater than 2.0 but less than 2.05, nothing happens - the relay remains in the state it was before. You should always do this when switching something, because if Irms changes a very small amount each time to take it the other side of 2.0, the relay might switch on or off every 5 s.