Hi, I have a project to measure battery capacity. I use bush button to change between screen. the button I use to enter the sub screen does not work can you help me please.
the code
#include <SPI.h>
#include <stdlib.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long previousMillis = 0;
unsigned long millisPassed = 0;
float Capacity = 0.0; // The calculated capacity of the battery, measured wile discharging
float mA=0;
float SetI = 0; // The setpoint for the discharging current. Remember you can adjust the discharging current using the 500K trimpot.
float BatLevel = 0; // The percentage of battery charge/level
float BatVoltCorrected = 0; // The voltage of the battery, measured based on the arduino internal reference
const float RES = 1; // Value of your resistor. Suggested Value is 1 Ohm. Change it if you youse a different resistor
#define clk 2
#define dt 3
#define sw 5
#define MOSFET_Discharge 9 // It is an N-MOSFET, so HIGH is ON and LOW is OFF
#define MOSFET_Charge 8 // It is a P-MOSFET, so HIGH is OFF and LOW is ON
char screen = 0;
char arrowpos = 0;
char charging = 0;
char discharging = 0;
char storage = 0;
char storagecharge = 0;
char storagedischarge = 0;
//char nointermediate = 0;
const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
volatile boolean TurnDetected = false;
volatile boolean up = false;
volatile boolean button = false;
byte customChar1[8] = {
0b10000,
0b11000,
0b11100,
0b11110,
0b11110,
0b11100,
0b11000,
0b10000
};
ISR(PCINT2_vect) {
if (digitalRead (sw) == LOW) {
button = true;
}
}
void isr0 () {
TurnDetected = true;
up = (digitalRead(clk) == digitalRead(dt));
}
void setup() {
lcd.begin(16,2);
lcd.setCursor(0, 0);
pinMode(MOSFET_Discharge, OUTPUT);
pinMode(MOSFET_Charge, OUTPUT);
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
pinMode(sw, INPUT_PULLUP);
pinMode(clk, INPUT);
pinMode(dt, INPUT);
PCICR |= 0b00000100;
PCMSK2 |= 0b00010000; // turn o PCINT20(D4)
attachInterrupt(0, isr0, RISING);
lcd.createChar(0, customChar1);
lcd.clear();
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
}
void loop() {
int in0 = analogRead(A0); //read the A0 pin value
int sensorValue1 = analogRead(A1); //read the A1 pin value
float val0 = in0 * 5.0 / 1024.0;
float supply = readVcc() / 1000.0;
SetI = sensorValue1 * (5.00 / 1024.00) / RES * 1000; // Calculate the discharge rate of the battery
BatVoltCorrected = supply / 5 * val0 * 4.3; //In case you use different voltage dividers, you need to change the number 4.3 accordingly.
millisPassed = millis() - previousMillis;
previousMillis = millis();
//------------------------------------------------------------------- battery percentage - linear calculation based on voltage (linear does NOT represent the REAL percentage)
if (BatVoltCorrected < 2.5) {
BatLevel = 0;
}
else if (BatVoltCorrected > 4.2)
{BatLevel = 100;
}
else {BatLevel = (BatVoltCorrected - 2.5 ) / 1.7 * 100 ;
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------
if (BatVoltCorrected <= 3.70 && BatVoltCorrected >= 3.65){ // For 3400mAh batteries sorage voltage is 3.6-3.7V, for batteries below 2600mAh it should be higher.
storagedischarge = 0;
storagecharge = 0;
}
if (BatVoltCorrected <= 3.75 && BatVoltCorrected > 3.7){ // Set these numbers +0.5V of your batteries storage voltage
storagedischarge = 1;
storage = 2;
storagecharge = 0;
}
if (BatVoltCorrected >= 3.6 && BatVoltCorrected < 3.65){ // Set these numbers -0.5V of your batteries storage voltage
storagecharge = 1;
storage = 2;
storagedischarge = 0;
}
if (BatVoltCorrected > 3.75 || BatVoltCorrected < 3.6){ // Set these numbers +0.5V and -0.5V of your batteries storage voltage
storage = 0;
storagedischarge = 0;
storagecharge = 0;
}
if (BatVoltCorrected <= 3.75 && BatVoltCorrected >= 3.6){ // Set these numbers +0.5V and -0.5V of your batteries storage voltage
storage = 1;
}
//----------------------------------------------------------------------------------------Capacity test mode-------------------------------------------------------
if (screen == 1) {
if (BatVoltCorrected <= 2.3){
Capacity = Capacity;
digitalWrite(MOSFET_Discharge, LOW);
// buz();
lcd.setCursor(0,0);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(8,0);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
lcd.setCursor(0,1);
lcd.print("Cap:");
lcd.print(Capacity,0);
lcd.print("mAh ");
lcd.setCursor(11,1);
lcd.print(" LowV");
delay(100);
}
else if (BatVoltCorrected > 2.3) {
Capacity = Capacity + (SetI * (millisPassed / 3600000.0));
digitalWrite(MOSFET_Discharge, HIGH);
lcd.setCursor(0,0);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(8,0);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
lcd.setCursor(0,1);
lcd.print("Cap:");
lcd.print(Capacity,0);
lcd.print("mAh ");
lcd.setCursor(11,1);
lcd.print(" ");
delay(500);
}
}
//----------------------------------------------------------------------------------------Charge mode-------------------------------------------------------
else if (screen == 2) {
if (BatVoltCorrected >= 4.2) {
lcd.setCursor(0,0);
lcd.print("Full Battery");
lcd.setCursor(12,0);
lcd.print(BatLevel,0);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Charge, HIGH);
delay(500);
}
else if (BatVoltCorrected < 4.2) {
lcd.setCursor(0,0);
lcd.print("Charging... ");
lcd.setCursor(12,0);
lcd.print(BatLevel,0);
lcd.print("% ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Charge, LOW);
delay(9000);
digitalWrite(MOSFET_Charge, HIGH);
delay(50);
}
}
//----------------------------------------------------------------------------------------Storage mode-----------------------------------------------------------------------------------------
// You need to adjust your voltages according to your batteries, for 3400mAh batteries sorage voltage (50% capacity) is 3.6-3.7V, for batteries below 2600mAh it should be higher.
// For more info visit this:https://lygte-info.dk/info/BatteryChargePercent%20UK.html
else if (screen == 3) {
delay(100);
if (BatVoltCorrected <= 1.5 ) {
lcd.setCursor(0,0);
lcd.print("No battery ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
charging = 0;
discharging = 0;
storage = 0;
storagecharge = 0;
storagedischarge = 0;
}
else if (BatVoltCorrected > 3.75 && charging == 0) { // Checks if the "quiescent voltage" of the battery is above 3.7V and Starts the discharge.
lcd.setCursor(0,0);
lcd.print("Discharging ");
lcd.setCursor(0,1);
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(9,1);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
digitalWrite(MOSFET_Charge, HIGH);
delay(100);
discharging = 1;
digitalWrite(MOSFET_Discharge, HIGH);
delay(9000);
digitalWrite(MOSFET_Discharge, LOW);
}
else if (storagedischarge == 1 && discharging == 1){ // Intermediate step before stopping the discharge
lcd.setCursor(0,0);
lcd.print("RDY for storage");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
discharging = 1;
digitalWrite(MOSFET_Charge, HIGH);
delay(100);
digitalWrite(MOSFET_Discharge, HIGH);
delay(9000);
digitalWrite(MOSFET_Discharge, LOW);
}
else if (BatVoltCorrected >= 1.5 && BatVoltCorrected < 3.6) { // Checks if the "quiescent voltage" of the battery is between 1.5V and 3.6V
if (discharging == 1 && BatVoltCorrected < 3.0){ // Stops discharging if the "discharge voltage" of the battery is below 3.0V
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(9,1);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
digitalWrite(MOSFET_Discharge, LOW);
}
if (discharging == 1 && BatVoltCorrected > 2){ // Prevents from charging (continues discharging) even if the "quiescent voltage" is below 3.6V
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
lcd.setCursor(9,1);
lcd.print("I:");
lcd.print(SetI,0);
lcd.print("mA ");
}
else if (discharging == 0 && BatVoltCorrected < 3.6){ // Starts to charge the battery
lcd.setCursor(0,0);
lcd.print("Charging ");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Discharge, LOW);
delay(100);
digitalWrite(MOSFET_Charge, LOW);
charging = 1;
delay(1000);
}
else { // used for debugging
lcd.setCursor(0,0);
lcd.print("error? ");
}
}
else if (storagecharge == 1 && charging == 1){ // Intermediate step before stopping the charge. (not actually stopping the charge)
lcd.setCursor(0,0);
lcd.print("RDY for storage");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
charging = 1;
//nointermediate = 1;
digitalWrite(MOSFET_Discharge, LOW);
delay(100);
digitalWrite(MOSFET_Charge, LOW);
delay(1000);
}
else if (charging == 1 && BatVoltCorrected > 3.65 ){ // Stops charge . This step is used if the Intermediate stop of charge was used.
lcd.setCursor(0,0);
lcd.print("RDY for storage");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
delay(1000);
}
else if (storage == 1 && charging == 0){ // For 3400mAh batteries sorage voltage is 3.6-3.7V, for batteries below 2600mAh it should be higher.
lcd.setCursor(0,0); // This step is used if the Intermediate stop of charge was NOT used. Or after intermadiate stop of discharge.
lcd.print("RDY for storage");
lcd.setCursor(0,1);
lcd.print("V:");
lcd.print(BatVoltCorrected);
lcd.print("V ");
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
delay(1000);
}
}
//-------------------------------------------------------------------------------- TURN -------------------------------------------------------------------------------------------------------
if (TurnDetected) {
delay(200);
switch (screen) {
case 0:
switch (arrowpos) {
case 0:
if (!up) {
screen0();
lcd.setCursor(0, 1);
lcd.write((uint8_t)0);
arrowpos = 1;
}
else {
screen0();
lcd.setCursor(8, 1);
lcd.write((uint8_t)0);
arrowpos = 2;
}
break;
case 1:
if (up) {
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
arrowpos = 0;
}
else {
screen0();
lcd.setCursor(8, 1);
lcd.write((uint8_t)0);
arrowpos = 2;
}
break;
case 2:
if (up) {
screen0();
lcd.setCursor(0, 1);
lcd.write((uint8_t)0);
arrowpos = 1;
}
else {
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
arrowpos = 0;
}
break;
}
break;
}
TurnDetected = false;
}
//-------------------------------------------------------------------------------------------- BUTTON PRESS --------------------------------------------------------------------------------------------
if (button) {
delay(200);
switch (screen) {
case 0:
if (arrowpos == 0) {
screen = 1;
screen1();
}
else if (arrowpos == 1){
screen = 2;
screen2();
}
else {
screen = 3;
screen3();
}
break;
case 1:
screen = 0;
screen0();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
break;
case 2:
screen = 1;
screen1();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
break;
case 3:
screen = 2;
screen2();
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
break;
}
arrowpos = 0;
button = false;
}
}
//-----------------------------------------------------------------------------------------------------SCREENS-------------------------------------------------------------------------------------
void screen0() {
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Capacity test");
lcd.setCursor(1, 1);
lcd.print("Charge");
lcd.setCursor(9, 1);
lcd.print("Store");
digitalWrite(MOSFET_Discharge, LOW);
digitalWrite(MOSFET_Charge, HIGH);
charging = 0;
discharging = 0;
storage = 0;
storagecharge = 0;
storagedischarge = 0;
}
void screen1() {
lcd.clear();
}
void screen2() {
lcd.clear();
}
void screen3() {
lcd.clear();
}
//-------------------------------------------------------------------voltage based on internal reference-------------------------------------------------------------
long readVcc() {
long result;
// Read 1.1V reference against AVcc
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA, ADSC));
result = ADCL;
result |= ADCH << 8;
result = 1126400L / result; // Calculate Vcc (in mV); 1126400 = 1.1*1024*1000
return result;
}
//void buz()
// {
// digitalWrite(9, HIGH);
// delay(100);
// digitalWrite(9, LOW);
// delay(10);
//}