Saturday, January 18, 2014

Volt Amp Watt Hour Meter Shield

A while back I designed a watt hour meter for tracking power produced by solar or wind, power consumed by loads, and power contained in a battery bank. I have produced a new version built on the Sparkfun Protoshield. This one uses a ACS712 (5 amp) current sensor, and is designed to monitor up to 10vdc. Different current sensors and resistors can be installed for other current and voltage ranges. The next upgrade will be a 16 pin header for a LCD display. So stay tuned. Code and wiring schematics coming shortly.








Code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

const float referenceVolts = 5; // the default reference on a 5-volt board
//const float referenceVolts = 3.3; // use this for a 3.3-volt board

const float R1 = 10000; // value for a maximum voltage of 10 volts
const float R2 = 10000;
// determine by voltage divider resistors, see text
const float resistorFactor = 1023.0 / (R2/(R1 + R2));
const int batteryPin = 0; // +V from battery is connected to analog pin 0

int sensorPin3 = A3; // select the input pin for the potentiometer

int sensorValue0 = 0; // variable to store the value coming from the sensor
int sensorValue3 = 0; // variable to store the value coming from the sensor

void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
lcd.begin(20,4); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
}

void loop() {

int val = analogRead(batteryPin); // read the value from the sensor
float volts = (val / resistorFactor) * referenceVolts ; // calculate the ratio
Serial.print("Volts :");
Serial.println(volts); // print the value in volts

float average = 0;
for(int i = 0; i < 1000; i++) {
average = average + (.0264 * analogRead(A3) -13.51) / 1000;
delay(1);
}
Serial.print("Amps :");
Serial.println(average);

lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row)
lcd.print("Volts:"); // change this text to whatever you like. keep it clean.
lcd.setCursor(0,1); // set cursor to column 0, row 1
lcd.print(volts);

// if you have a 4 row LCD, uncomment these lines to write to the bottom rows
// and change the lcd.begin() statement above.
lcd.setCursor(0,2); // set cursor to column 0, row 2
lcd.print("Amps");
lcd.setCursor(0,3); // set cursor to column 0, row 3
lcd.print(average);

}