/* J. Paewai 2024 - A battery level indercator for LCD displays.
I've used it on many projects were having a battery level indicator is needed.
This project simply reads an analog value which is assumed that you will be connecting to a voltage divider.
The circuit does not calculate a voltage divider circuit you will have to build that yourself and work out the battery level is that you wish to display.
The circuit makes that easy and displays a battery indicator in the top right-hand corner of an LCD display.
It will indicate 100%, 75%, 25% and flashes the battery indicator when the level is below that.
If You're connected to a computer where the analogue to digital value would normally be too low for the microprocessor to run
the unit will display a series of letters indicating that you're on USB power rather than a battery.
This is a great add-on to other projects.
Simply connect whatever analogue port you wish to use calculate your voltage divider for the battery you wish to monitor.
Then adjust the values in the function getbatt() four the levels that you wish to indicate.
*/
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
// Battery Measurement
#define BatCheckTime 1000 // Check Battery every 1 second
unsigned long BatTime = 0; // current time of bettery check
unsigned char Blink_S = 0; // Battery blink status
#define batteryPin A0 // Where the voltage divider is located
// Timmers
unsigned long msNow = 0; // current processor time
// Create a battery full/empty characters
byte EmptyEnd[] = { B11111, B10000, B10000, B10000, B10000, B10000, B10000, B11111 };
byte EmptyMiddle[] = { B11111, B00000, B00000, B00000, B00000, B00000, B00000, B11111 };
byte EmptyCap[] = { B11110, B00010, B00010, B00001, B00001, B00010, B00010, B11110 };
byte FullBody[] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 };
byte FullCap[] = { B11110, B11110, B11111, B11111, B11111, B11111, B11110, B11110 };
void getbatt(void) // Reads analogue which your voltage divider is on and updates the LCD battery graphics
{
int U = analogRead(batteryPin);
if (U >= 700){ // Battery 100%
lcd.setCursor(11, 0);
lcd.write(byte(3));
lcd.write(byte(3));
lcd.write(byte(3));
lcd.write(byte(4));
}
else if (U >= 642){ // Battery 75%
lcd.setCursor(11, 0);
lcd.write(byte(3));
lcd.write(byte(3));
lcd.write(byte(3));
lcd.write(byte(2));
}
else if (U >= 560){ // Battery 50%
lcd.setCursor(11, 0);
lcd.write(byte(3));
lcd.write(byte(3));
lcd.write(byte(1));
lcd.write(byte(2));
}
else if (U >=528){ // Battery 25%
lcd.setCursor(11, 0);
lcd.write(byte(3));
lcd.write(byte(1));
lcd.write(byte(1));
lcd.write(byte(2));
}
else if (U < 397){ // Less Than 10%
lcd.setCursor(11, 0);
lcd.print ("USBpw");
}
else {
if (Blink_S ==1){ // Flashes the battery indercator for very low capacity
lcd.setCursor(11, 0);
lcd.write(byte(0));
lcd.write(byte(1));
lcd.write(byte(1));
lcd.write(byte(2));
Blink_S = 0;
}
else{
if (Blink_S ==0) {
lcd.setCursor(11, 0);
lcd.print(" ");
Blink_S =1 ;
}
}
}
}
void setup() {
lcd.init(); // init the display
lcd.backlight(); // Back light on
// Create the special battery characters
lcd.createChar(0, EmptyEnd);
lcd.createChar(1, EmptyMiddle);
lcd.createChar(2, EmptyCap);
lcd.createChar(3, FullBody);
lcd.createChar(4, FullCap);
pinMode(batteryPin,INPUT); // MCU voltage divider pin to INPUT
}
void loop() {
msNow=millis(); // get micro time
if(BatTime < msNow) { // good place to check the battery - update every second
getbatt();
BatTime = millis()+ BatCheckTime;
}
// add own project code
// Displays the analogue value on the battery port
lcd.setCursor(0,1);
lcd.print("Value: ");
lcd.setCursor(7,1);lcd.print(analogRead(batteryPin),DEC);lcd.print(" ");
}