ARDUINO ENERGY METER

495,887

876

157

Introduction: ARDUINO ENERGY METER

I am an Electrical Engineer. I love to harvest Solar Energy and make things by recycling old stuf...


[ Play Video ]

I belong to a village of Odisha, India where frequent power cut is very common. It hampers the life of every one. During my childhood days continuing studies after dusk was a real challenge. Due to this problem I designed a solar system for my home on a experimental basis. I used a solar panel of 10 Watt ,6V for lighting few bright LEDs. After facing lot of hardships the project was successful. Then I decided to monitor the voltage, current, power & energy involved in the system. This brought the idea of designing an ENERGY METER.I used ARDUINO as the heart of this project because it is very easy to write code in its IDE and there are huge numbers of open source library available in the internet which can be used according to the requirement.I have experimented the project for very small rated (10Watt) solar system but this can be easily modified to use for higher rating system.

You can find all of my projects on : https://www.opengreenenergy.com/

Feature:
Energy monitoring by
1.LCD display
2. via internet (Xively upload)
3. Data logging in a SD card

You can see my new instructable ARDUINO MPPT SOLAR CHARGE CONTROLLER ( Version-3.0)

You can also see my other instructables on

ARDUINO SOLAR CHARGE CONTROLLER ( Version 2.0)

ARDUINO SOLAR CHARGE CONTROLLER (Version-1)

Step 1: Parts Required :

1. ARDUINO UNO ( Amazon)
2. ARDUINO ETHERNET SHIELD ( Amazon )

3. 16x2 CHARACTER LCD ( Amazon )

4. ACS 712 CURRENT SENSOR ( Amazon )
4. RESISTORS (10k ,330ohm) ( Amazon )
5. 10K POTENTIOMETER ( Amazon )
6. JUMPER WIRES ( Amazon )
7. ETHERNET CABLE (Amazon)
8. BREAD BOARD ( Amazon )

Step 2: Power and Energy

Power :
Power is product of voltage (volt) and current (Amp)
P=VxI
Unit of power is Watt or KW

Energy:
Energy is product of power (watt) and time (Hour)
E= Pxt
Unit of Energy is Watt Hour or Kilowatt Hour (kWh)

From the above formula it is clear that to measure Energy we need three parameters
1. Voltage
2. Current
3. Time

Step 3: Voltage Measurement

Voltage is measured by the help of a voltage divider circuit.As the ARDUINO analog pin input voltage is
restricted to 5V I designed the voltage divider in such a way that the output voltage from it should be less than 5V.My battery used for storing the power from the solar panel is rated 6v, 5.5Ah.So I have to step down this 6.5v to a voltage lower than 5V.
I used R1=10k and R2 =10K. The value of R1 and R2 can be lower one but the problem is that when resistance is low higher current flow through it as a result large amount of power (P = I^2R) dissipated in the form of heat. So different resistance value can be chosen but care should be taken to minimize the power loss across the resistance.

Vout=R2/(R1+R2)*Vbat
Vbat=6.5 when fully charged
R1=10k and R2=10k
Vout=10/(10+10)*6.5=3.25v which is lower than 5v and suitable for ARDUINO analog pin

NOTE
I have shown 9 Volt battery in bared board circuit is just for example to connect the wires.But the actual battery I used is a 6 Volt, 5.5Ah lead acid battery.

Voltage Calibration:
When battery is fully charged (6.5v) we will get a Vout=3.25v and lower value for other lower battery voltage.

AEDUINO ADC convert Analog signal to corresponding digital approximation .
When the battery voltage is 6.5v I got 3.25v from the voltage divider and sample1 = 696 in serial monitor ,where sample1 is ADC value corresponds to 3.25v

For better understanding I have attached the real time simulation by 123D.circuit for voltage measurement

Calibration:

3.25v equivalent to 696
1 is equivalent to 3.25/696=4.669mv
Vout = (4.669*sample1)/1000 volt
Actual battery voltage = (2*Vout) volt

ARDUINO CODE:

// taking 150 samples from voltage divider with a interval of 2sec and then average the samples data collected for(int i=0;i<150;i++)
{
sample1=sample1+analogRead(A2); //read the voltage from the divider circuit
delay (2);
}
sample1=sample1/150;
voltage=4.669*2*sample1/1000;

Step 4: Current Measurement

For current measurement I used a Hall Effect current sensor ACS 712 (20 A).There are different current range ACS712 sensor available in the market, so choose according to your requirement. In bread board diagram I have shown LED as a load but the actual load is different.
WORKING PRINCIPLE :

The Hall Effect is the production of a voltage difference (the Hall voltage) across an electrical conductor, transverse to an electric current in the conductor and a magnetic field perpendicular to the current.
To know more about Hall Effect sensor click here
The data sheet of ACS 712 sensor is found here

From Data Sheet
1. ACS 712 measure positive and negative 20Amps, corresponding to the analog output 100mV/A
2. No test current through the output voltage is VCC / 2 =5v/2=2.5V

Calibration:
Analog read produces a value of 0-1023, equating to 0v to 5v
So Analog read 1 = (5/1024) V =4.89mv
Value = (4.89*Analog Read value)/1000 V
But as per data sheets offset is 2.5V (When current zero you will get 2.5V from the sensor's output)
Actual value = (value-2.5) V
Current in amp =actual value*10

ARDUINO CODE:

// taking 150 samples from sensors with a interval of 2sec and then average the samples data collected
for(int i=0;i<150;i++)
{
sample2+=analogRead(A3); //read the current from sensor
delay(2);
}
sample2=sample2/150;
val =(5.0*sample2)/1024.0;
actualval =val-2.5; // offset voltage is 2.5v
amps =actualval*10;

Step 5: Time Measurement

For time measurement there is no need of any external hardware, as ARDUINO itself has inbuilt timer.

The millis() function returns the no of milliseconds since the Arduino board began running the current program.

ARDUINO CODE:

long milisec = millis(); // calculate time in milliseconds
long time=milisec/1000; // convert milliseconds to seconds


Step 6: How ARDUINO Calculate Power and Energy


totamps=totamps+amps; // calculate total amps
avgamps=totamps/time; // average amps
amphr=(avgamps*time)/3600; // amp-hour
watt =voltage*amps; // power=voltage*current
energy=(watt*time)/3600; Watt-sec is again convert to Watt-Hr by dividing 1hr(3600sec)
// energy=(watt*time)/(1000*3600); for reading in kWh

Step 7: Visual Output

All the results can be visualized in the serial monitor or by using a LCD.
I used a 16x2 character LCD to display all the results obtained in the previous steps.For schematics see the bread board circuit shown above.

Connect LCD with ARDUINO as given bellow :

LCD -> Arduino
1. VSS -> Arduino GND
2. VDD -> Arduino +5v
3. VO -> Arduino GND pin + Resistor or Potentiometer
4. RS -> Arduino pin 8
5. RW -> Arduino pin 7
6. E -> Arduino pin 6
7. D0 -> Arduino - Not Connected
8. D1 -> Arduino - Not Connected
9. D2 -> Arduino - Not Connected
10. D3 -> Arduino - Not Connected
11. D4 -> Arduino pin 5
12. D5 -> Arduino pin 4
13. D6 -> Arduino pin 3
14. D7 -> Arduino pin 2
15. A -> Arduino Pin 13 + Resistor (Backlight power)
16. K -> Arduino GND (Backlight ground)

ARDUINO CODE:

For Serial Monitor:


Serial.print("VOLTAGE : ");
Serial.print(voltage);
Serial.println("Volt");
Serial.print("CURRENT :");
Serial.print(amps);
Serial.println("Amps");
Serial.print("POWER :");
Serial.print(watt);
Serial.println("Watt");
Serial.print("ENERGY CONSUMED :");
Serial.print(energy);
Serial.println("Watt-Hour");
Serial.println(""); // print the next sets of parameter after a blank line
delay(2000);

For LCD :

For LCD display you have to first import the "LiquidCrystal" library in the code.
To know more about the LequidCrystal library click here
For LCD tutorial clickhere

The following code is a format to display in LCD all the calculation for power and energy

#include <LiquidCrystal.h>
lcd(8, 7, 6, 5, 4, 3, 2);
int backLight = 9;
void setup()
{
pinMode(backLight, OUTPUT); //set pin 9 as output
analogWrite(backLight, 150); //controls the backlight intensity 0-254
lcd.begin(16,2); // columns, rows. size of display
lcd.clear(); // clear the screen
}
void loop()
{
lcd.setCursor(16,1); // set the cursor outside the display count
lcd.print(" "); // print empty character
delay(600);
//////////////////////////////////////////print power and energy to a LCD////////////////////////////////////////////////
lcd.setCursor(1,0); // set the cursor at 1st col and 1st row
lcd.print(watt);
lcd.print("W ");
lcd.print(voltage);
lcd.print("V");
lcd.setCursor(1,1); // set the cursor at 1st col and 2nd row
lcd.print(energy);
lcd.print("WH ");
lcd.print(amps);
lcd.print("A");
}

Step 8: Data Uploading to Xively.com

Refer the above screenshots for better under standing.

For data uploading to xively.com the following library to be downloaded first

HttpClient
: click here
Xively : click here
SPI : Import from arduino IDE (sketch -> Import library.....)
Ethernet : Import from arduino IDE ((sketch -> Import library.....)
Open an account with http://xively.com (formerly pachube.com and cosm.com)

Sign up for a free developer account at http://xively.com

  • Choose a username, password, set your address
    and time zone etc.
    You will receive a confirmation email;
then click
the activation link to activate your
account.
After successfully opening the account you will
be diverted to Development devices
page


  • Click on +Add Device box

  • Give a name to your device and description (e.g
    ENERGY MONITORING)


    ·

  • Choose private or public data (I choose private)


    ·

  • Click on Add Device
After adding the device you are diverted to a new
page where many important information are there


  • Product ID,
    Product Secret, Serial Number, Activation Code


    ·

  • Feed ID, Feed
    URL,API End Point (Feed ID is used in ARDUINO code)

  • Add Channels (I
    Choose ENERGY and POWER, but you can choose according to your choice)


    Give unit and symbol for the parameter


    ·

  • Add your
    location


    ·

  • API keys (used
    in ARDUINO code ,avoid to share this number)


    ·

  • Triggers (ping a
    web page when an event happened, like when energy consumption exceed a certain
    limit)



Step 9: Xively and ARDUINO Code


Here I attached the complete code(beta version) for energy meter excluding SD card data logging which is attached separately in the next step.


/**
Energy monitoring data upload to xively **/ #include #include #include #include
#define API_KEY "xxxxxxxx" // Enter your Xively API key
#define FEED_ID xxxxxxxxx // Enter your Xively feed ID
// MAC address for your Ethernet shield
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// Analog pin which we're monitoring (0 and 1 are used by the Ethernet shield) int sensorPin = 2;
unsigned long lastConnectionTime = 0; // last time we connected to Cosm
const unsigned long connectionInterval = 15000; // delay between connecting to Cosm in milliseconds
// Initialize the Cosm library
// Define the string for our datastream ID
char sensorId[] = "POWER";
char sensorId2[] = "ENERGY";
XivelyDatastream datastreams[] = {
XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
XivelyDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
DATASTREAM_FLOAT), };
// Wrap the datastream into a feed
XivelyFeed feed(FEED_ID, datastreams, 2 /* number of datastreams */);
EthernetClient client;
XivelyClient xivelyclient(client);
void setup()
{
Serial.begin(9600);
Serial.println("Initializing network");
while (Ethernet.begin(mac) != 1)
{
Serial.println("Error getting IP address via DHCP, trying again...");
delay(15000);
}
Serial.println("Network initialized");
Serial.println();
}
void loop()
{
if (millis() - lastConnectionTime > connectionInterval)
{
sendData(); // send data to xively
getData(); // read the datastream back from xively
lastConnectionTime = millis(); // update connection time so we wait before connecting again
}
}
void sendData()
{
int sensor1 = watt;
int sensor2 = energy;
datastreams[0].setFloat(sensor1); // power value
datastreams[1].setFloat(sensor2); // energy value
Serial.print("Read power ");
Serial.println(datastreams[0].getFloat());
Serial.print("Read energy ");
Serial.println(datastreams[1].getFloat());
Serial.println("Uploading to Xively");
int ret = xivelyclient.put(feed, API_KEY);
Serial.print("PUT return code: ");
Serial.println(ret);
Serial.println();
}
// get the value of the datastream from xively, printing out the value we received
void getData()
{
Serial.println("Reading data from Xively");
int ret = xivelyclient.get(feed, API_KEY);
Serial.print("GET return code: ");
Serial.println(ret);
if (ret > 0)
{
Serial.print("Datastream is: ");
Serial.println(feed[0]);
Serial.print("Power value is: ");
Serial.println(feed[0].getFloat());
Serial.print("Datastream is: ");
Serial.println(feed[1]);
Serial.print("Energy value is: ");
Serial.println(feed[1].getFloat());
}
Serial.println();

Step 10: Data Logging in a SD Card

For data storing in a SD card you have to import the SD library

For tutorial click here
To know more about the SD library click here


The code for storing data in to a SD card is written separately as I don't have sufficient memory in my ARDUINO UNO after writing code for LCD display and data uploading xively.com. But I am trying to improve the beta version code so that a single code can contain all the features(LCD display,Xively data uploading and data storing in a SD card).
The code for data logging is attached bellow.

If any one write a better code by modifying my code please share with me.

This is my first technical instructable ,If anyone find any mistake in it , feel free to comments.. so that I can improve myself.
If you find areas of improvement in this project please comments or message me,So the project will be more powerful.I think it will be helpful for others as well as for me.

123D Circuits Contest

Third Prize in the
123D Circuits Contest

4 People Made This Project!

Recommendations

  • Creative Misuse Contest

    Creative Misuse Contest
  • Fix It! Contest

    Fix It! Contest
  • Tiny Home Contest

    Tiny Home Contest

157 Discussions

Hi,

I wish to made this, but I have some questions about this project.

aim going to use it for my Solar charging control ( it is 12V 200W panel with 12V 100A battery)

1: 12V 100A battery can be messier on this? and it can be use it with 200W solar panel.

2: this project can be use Arduino Nano instead of Uno. if yes I may need to change the codes?

3: it is possible to use this project without Ethernet shield?

Regards.

Hye can i get a full program code without the xively? Thank you.

Hi. I am trying to apply this deba168 energy meter to my simple off grid PV system. The system is build of 7 panels connected in series. The load is heater for heating 300l of water. The load is regulated by the mppt driver and it works perfect. Can you help me to build a voltage divider for 230DC and a 10A peak current, which can I connect to arduino (so it must be reduced to 5V). Main problem is choosing the right resistors to withstand 10A current flowing in the circuit.

Can we see the output graph on processing ide without ethernet shield? And how much watt panel can be used.

I dont have an arduino shield at the moment, but i have a rapsberry-pi 3B. can i connect arduino to rapsberry-pi and send the data to it, and makes rapsberry-pi do the data logging and data uploading to Xively.com?

i want to a code on calcutating fares of used power like petrol bunks. i doing solar charing station prototype for my final year project.
please help me

its good sir!

can anyone help with energy consumption code using ACS712 current sensor reading AC current .

1 reply

Your best starting point is the datasheet. ( try https://www.google.com/url?sa=t&rct=j&q=&esrc=s&so...

The output of the sensor is fairly linear but the zero point has to be checked for each sensor (i.e. you calibrate the output to the microcontroller by letting the microcontroller know what ACS712 voltage equals zero current). After that, equating the output voltage of the ACS712 sensor to current is just a matter of simple algebra.

Measuring the voltage is straight forward. Measuring voltage and current at the same time - tricky, but doable if you want to work with interrupts and a triggered > 4kHz sampling rate, switching back and fourth between voltage and current measurements. Hard to say without more info.

You did not mention what you are measuring. Will the voltage be AC or DC? Will the AC waveform be known or not? Based on your needs you might have to add some additional circuitry (voltage bridges, differential op amps, Schmitt trigger, etc).

This could be an easy project or a complex one depending on what you are really trying to do. Can you provide more info?

I appreciate the detailed descriptions of the methodology behind every design step.
I did not make one yet but I did notice that the math for calculating power assumes that there is no AC component in the measured circuit and no phase differences. Multiplying instantaneous voltage and current, calculating instantaneous power and then averaging all the power measurements would be more in line with a real power meter. Of course, to start to approach being a real power meter the measurement cycle would have be increased to at least 1800Hz for 50-60Hz power being measured. Nonetheless, a great starting point with lots of pointers. Thanks.

please help me

ii need full program

Whether it is for ac r dc

sorry
Am using arduino to build a smart meter and the arduino will be powered from the rectified 230v AC from the mains
what circuit will be best for this kind of system and how do i read to my lcd and see it on my mobile app too

Active power is calculated by V*I*power factor. you didn't tell anything about power factor. V*I will give apparent power not active power

Is there a way to do this with a WiFi sheild rather than ethernet?

Hi

I have a pressure meter which is giving 4-20 mA current for
presenting the pressure value. Is it possble to use ACS712 to read the
amp value or it can not detect this low amps?

Your help would be appriciated.

this measure the power generated by the solar panel or used by the load?

2 replies

do you have idea how to design a power meter to measure the power generated by solar panel?

WILL APPRECIATE VERY MUCH