Using a button to change display screen information

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);            
//}

As You did not provide schematics You get guesses.

  1. Disconnect the button and check it up using a DMM in resistance mode.
  2. Button connected to the pin matching the code?
  3. Other end of button connected to GND?
  4. Using interrupts often creates trouble. Not needed for a none blocking code.

Rotate the four legs of the button 90 degrees (or move the pins 90 degrees) to see if its orientation is the problem.

The project still on proteus program.

Then it's not a question for me.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.