Академический Документы
Профессиональный Документы
Культура Документы
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)
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.
For better understanding I have attached the real time simulation by 123D.circuit for voltage
measurement
Calibration:
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;
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
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;
The millis() function returns the no of milliseconds since the Arduino board began running the
current program.
ARDUINO CODE:
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 :
ARDUINO CODE:
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");
}
Refer the above screenshots for better under standing.
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
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)
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)
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();
https://cdn.instructables.com/ORIG/F48/C0DB/HQMN5RW3/F48C0DBHQMN5RW3.txt
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.
https://cdn.instructables.com/ORIG/FLX/38JT/HQIMACP5/FLX38JTHQIMACP5.txt
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
* SD card attached to SPI bus as follows:
** UNO: MOSI - pin 11, MISO - pin 12, CLK - pin 13, CS - pin 4 (CS pin can
be changed)
and pin #10 (SS) must be an output
** Mega: MOSI - pin 51, MISO - pin 50, CLK - pin 52, CS - pin 4 (CS pin can
be changed)
and pin #52 (SS) must be an output
** Leonardo: Connect to hardware SPI via the ICSP header
Pin 4 used here for consistency with other Arduino examples
original code was created on 24 Nov 2010 and modified 9 Apr 2012 by Tom Igoe
I (Debasish Dutta) was again modified for my energy monitoring requirement on
14/01/14
*/
#include <SD.h>
File dataFile;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(SS, OUTPUT);
void loop()
/////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/// taking 150 samples from sensors with a inerval of
2sec and then average the samples data collected
for(int i=0;i<150;i++)
{
sample1+=analogRead(A2); //read the voltage from the sensor
sample2+=analogRead(A3); //read the current from sensor
delay(2);
}
sample1=sample1/150;
sample2=sample2/150;
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
////
/////voltage
calculation//////////////////////
////////////////////////////////////////////////////////
// make a string for assembling the data to log:
String dataString = "";
int parameter[4]={voltage,amps,watt,energy}; // here parameters are
power,energy,watt-hour and current
// read 4 parameters and append to the string:
for (int i = 0; i < 4; i++)
{
int sensor = parameter[i];
dataString += String(sensor);
if (i < 4)
{
dataString += ",";
}
}
dataFile.println(dataString);
// The following line will 'save' the file to the SD card after every
// line of data - this will use more power and slow down how much data
// you can read but it's safer!
// If you want to speed up the system, remove the call to flush() and it
// will save the file only every 512 bytes - every time a sector on the
// SD card is filled with data.
dataFile.flush();
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>
#include <LiquidCrystal.h>
// Analog pin which we're monitoring (0 and 1 are used by the Ethernet
shield)
int sensorPin = 2;
XivelyDatastream datastreams[] =
{
XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
XivelyDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
};
void setup() {
Serial.begin(9600);
pinMode(backLight, OUTPUT); //set pin 13 as output
analogWrite(backLight, 150); //controls the backlight intensity 0-
254
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() {
/////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/// taking 150 samples from sensors with a inerval of
2sec and then average the samples data collected
for(int i=0;i<150;i++)
{
sample1+=analogRead(A2); //read the voltage from the sensor
sample2+=analogRead(A3); //read the current from sensor
delay(2);
}
sample1=sample1/150;
sample2=sample2/150;
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
////
/////voltage calculation//////////////////////
voltage=4.669*2*sample1/1000; // callibration // 3.25v from voltage div
is eqv 696 in A2 reading // multiply 2 to get actual voltage
/// current calculation //////////////////////
val =(5.0*sample2)/1024.0;
actualval =val-2.5; // offset voltage is 2.5v
amps =actualval*10; // 100mv/A from data sheet
totamps=totamps+amps; // total amps
avgamps=totamps/time; // average amps
amphr=(avgamps*time)/3600; // amphour
watt =voltage*amps; // power=voltage*current
energy=(watt*time)/3600; //energy in watt hour
// energy=(watt*time)/(1000*3600); // energy in kWh
////////////////////////////////////DISPLAY IN 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);
*/
///////////////////////////////////DISPLAY IN
LCD//////////////////////////////////////////////////////////////////
//////////////////////////////////////////XIVELY
UPLOAD///////////////////////////////////////////////////////
float sensor1 = watt;
float sensor2 = energy;
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");
if (ret > 0) {
Serial.print("Datastream is: ");
Serial.println(feed[0]);
Serial.print("Power value is: ");
Serial.println(feed[0].getFloat());
Serial.println();
}