Hi folks,
Here is a shot at getting some battery information using only the voltage divider - which is all I have implemented so far.
Comments, criticism, hints, more than welcome.
Thanks in advance.
Andrew.
/*
** Andrew Scott Solar Monitor 11-Sept-2012
*/
// libraries
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
// Define LCD I2C address and pins
#define I2C_ADDR 0x3F
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
// For LCD healthcheck. LCD sometimes seems to freeze. This
// seems to be a problem after uploading code and rebooting
// when running from USB power only.
boolean lcdHealthCheck = false;
// Setup LCD
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
void setup()
{
// Initialize LCD
lcd.begin (20,4);
// Switch on LCD the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
// Static LCD characters
lcd.setCursor ( 0, 0 );
lcd.print("BATT: ");
lcd.setCursor ( 11, 0 );
lcd.print("V");
}
void loop(){
// ADC value from voltage divider
// R1 = 10K, R2 = 1K, resolution 0.05V
int battVRaw;
// Lazy division on the ADC value, matches DMM
float battDivideBy = 18.45;
// Actual voltage
float battVActual;
// Value for making battery charge bar
float chargeBar;
// Read A2 to get ADC value for battery voltage
battVRaw = analogRead(A2);
// Do lazy maths to calculate actual battery voltage
battVActual = (battVRaw / battDivideBy);
// Print actual battery voltage
lcd.setCursor ( 6, 0);
lcd.print(battVActual);
// Print ADC value for debugging - temporary
lcd.setCursor ( 13, 0 );
lcd.print("A2: ");
lcd.print(battVRaw);
// Print charge status, or battery level if not charging
// Position cursor at 3rd line, 5th char from left.
lcd.setCursor ( 4, 2 );
// If voltage < 13.19, probably not charging
// This should probably be verified by checking solar current
// sensor when installed.
//
// DMM shows 13V stable when full, and inverter auto shutdown
// happens at < 12V, so that can be minimum for now.
// A nice easy 10 segment bar graph.
if(battVActual < 13.19){
lcd.print("E");
chargeBar = 12.0;
while(chargeBar < battVActual){
lcd.print(char(255));
chargeBar = chargeBar + 0.1;
}
lcd.setCursor ( 14, 2);
lcd.print("F");
}
// Print charge status, cover all cases above 13.19V
// Measurement accuracy seems good enough to identify these states
// May require tweaking!
else if(battVActual > 13.19 & battVActual < 13.81){
lcd.print("FLOAT CHARGING");
}
else if(battVActual > 13.81 & battVActual < 14.39){
lcd.print("ABOVE FLOAT CHG.");
}
else if(battVActual > 14.39 & battVActual < 14.41){
lcd.print("BOOST CHARGING");
}
else if(battVActual > 14.41 & battVActual < 14.59){
lcd.print("ABOVE BOOST CHG.");
}
else if(battVActual > 14.59 & battVActual < 14.61){
lcd.print("EQUALIZE CHARGE");
}
else if(battVActual > 14.61){
lcd.print("CHG. OVER VOLT!");
}
// Blinking star in the bottom right corner
// for LCD health check
lcd.setCursor ( 19, 3 );
if(lcdHealthCheck == false){
lcdHealthCheck = true;
lcd.print("*");
}else{
lcdHealthCheck = false;
lcd.print(" ");
}
delay(2000);
}