# DIY Amp / Watt Hour Volt Meter - Arduino

## Step 6: Source Code

All the code, schematics, and photo's along with discussion is available at http://tech.groups.yahoo.com/group/arduinohome/files/volt%20amp%20watt%20hour%20meter/ and http://forum.pololu.com/viewtopic.php?f=3&t=5415

#include <LiquidCrystal.h>

/* This sketch describes how to connect a ACS715 Current Sense Carrier
(http://www.pololu.com/catalog/product/1186) to the Arduino,
and read current flowing through the sensor.

*/

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

/*

Vcc on carrier board to Arduino +5v
GND on carrier board to Arduino GND
OUT on carrier board to Arduino A0

arrow on carrier board points to load, other lug connects to
power supply positive

Voltage Divider

11.66 from + to A4
4.62k from A4 to Gnd
Ratio 2.5238

*/
int batMonPin = A4;    // input pin for the voltage divider
int batVal = 0;       // variable for the A/D value
float pinVoltage = 0; // variable to hold the calculated voltage
float batteryVoltage = 0;

int sensorValue = 0;        // value read from the carrier board
int outputValue = 0;        // output in milliamps
unsigned long msec = 0;
float time = 0.0;
int sample = 0;
float totalCharge = 0.0;
float averageAmps = 0.0;
float ampSeconds = 0.0;
float ampHours = 0.0;
float wattHours = 0.0;
float amps = 0.0;

int R1 = 11660; // Resistance of R1 in ohms
int R2 = 4620; // Resistance of R2 in ohms

float ratio = 0;  // Calculated from R1 / R2

void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
lcd.begin(20, 4);
}

void loop() {

int sampleBVal = 0;
int avgBVal = 0;
int sampleAmpVal = 0;
int avgSAV = 0;

for (int x = 0; x < 10; x++){ // run through loop 10x

sampleAmpVal = sampleAmpVal + sensorValue; // add samples together

sampleBVal = sampleBVal + batVal; // add samples together

delay (10); // let ADC settle before next sample

}

avgSAV = sampleAmpVal / 10;

// convert to milli amps
outputValue = (((long)avgSAV * 5000 / 1024) - 500 ) * 1000 / 133;

/* sensor outputs about 100 at rest.
Analog read produces a value of 0-1023, equating to 0v to 5v.
"((long)sensorValue * 5000 / 1024)" is the voltage on the sensor's output in millivolts.
There's a 500mv offset to subtract.
The unit produces 133mv per amp of current, so
divide by 0.133 to convert mv to ma

*/

avgBVal = sampleBVal / 10; //divide by 10 (number of samples) to get a steady reading

pinVoltage = avgBVal * 0.00610;       //  Calculate the voltage on the A/D pin
/*  A reading of 1 for the A/D = 0.0048mV
if we multiply the A/D reading by 0.00488 then
we get the voltage on the pin.

to .00610 to match fluke meter.

Also, depending on wiring and
where voltage is being read, under
heavy loads voltage displayed can be
well under voltage at supply. monitor
at load or supply and decide.
*/

ratio = (float)R1 / (float)R2;
batteryVoltage = pinVoltage * ratio;    //  Use the ratio calculated for the voltage divider
//  to calculate the battery voltage

amps = (float) outputValue / 1000;
float watts = amps * batteryVoltage;

Serial.print("Volts = " );
Serial.print(batteryVoltage);
Serial.print("\t Current (amps) = ");
Serial.print(amps);
Serial.print("\t Power (Watts) = ");
Serial.print(watts);

sample = sample + 1;

msec = millis();

time = (float) msec / 1000.0;

totalCharge = totalCharge + amps;

averageAmps = totalCharge / sample;

ampSeconds = averageAmps*time;

ampHours = ampSeconds/3600;

wattHours = batteryVoltage * ampHours;

Serial.print("\t Time (hours) = ");
Serial.print(time/3600);

Serial.print("\t Amp Hours (ah) = ");
Serial.print(ampHours);
Serial.print("\t Watt Hours (wh) = ");
Serial.println(wattHours);

lcd.setCursor(0,0);
lcd.print(batteryVoltage);
lcd.print(" V ");
lcd.print(amps);
lcd.print(" A ");

lcd.setCursor(0,1);
lcd.print(watts);
lcd.print(" W ");
lcd.print(time/3600);
lcd.print(" H ");

lcd.setCursor(0,2);
lcd.print(ampHours);
lcd.print(" Ah ");
lcd.print(wattHours);
lcd.print(" Wh ");

lcd.setCursor(0,3);
lcd.print(ratio, 5);
lcd.print("   ");
lcd.print(avgBVal);

// wait 10 milliseconds before the next loop
// for the analog-to-digital converter to settle