How to program push buttons using While loop

Hi guys, I am making a small project right now and I need your help. My project is all about counting people entering and exiting the room. First I need to input the maximum capacity allowed in the room using 4 push buttons (+, -, reset and okay buttons). After setting the capacity number if the Okay button is pressed it will now start the counting. My previous codes have multiple if else but only works on setting the capacity, now I've used while loop for reading push buttons but it is not working. Any help will be so much appreciated Thank you🧡

here is my code:


#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

#define buttonp 2

#define buttonm 3

#define buttonr 4

#define buttonk 7

#define ledp 5

#define ledm 6

#define IR1 8

#define IR2 9

int count = 0;

int capacity = 0;

int Pcount = 0;

int state = 0;

void setup() {

  // put your setup code here, to run once:

  pinMode(buttonp, INPUT_PULLUP);

  pinMode(buttonm, INPUT_PULLUP);

  pinMode(buttonr, INPUT_PULLUP);

  pinMode(buttonk, INPUT_PULLUP);

  pinMode(ledp, OUTPUT);

  pinMode(ledm, OUTPUT);

  pinMode(IR1, INPUT_PULLUP);

  pinMode(IR2, INPUT_PULLUP);

  lcd.init();

  lcd.backlight();

  lcd.clear();

  lcd.setCursor(0, 0);

  lcd.print("PROJECT GENESIS");

  delay(2000);

  lcd.clear();

  lcd.print("SET CAPACITY");

  lcd.setCursor(0, 1);

  lcd.print("CAPACITY = ");

  lcd.setCursor(12, 1);

  lcd.print(count);

}

void loop() {

  // put your main code here, to run repeatedly:

  int button_statep = digitalRead(buttonp);

  int button_statem = digitalRead(buttonm);

  int button_stater = digitalRead(buttonr);

  int button_statek = digitalRead(buttonk);

  int IR_state1 = digitalRead(IR1);

  int IR_state2 = digitalRead(IR2);

  

  while (true) {

    if (button_statep == HIGH)  //Plus button

    {

      PressP();

      lcd.setCursor(12, 1);

      lcd.print(count);

    }

    else if (button_statem == HIGH)  //Minus button

    {

      PressM();

      lcd.setCursor(12, 1);

      lcd.print(count);

    }

    else if (button_stater == HIGH) {

      PressR();  //Reset button

      lcd.setCursor(13, 1);

      lcd.print(" ");

      lcd.setCursor(12, 1);

      lcd.print(count);

    }

    else if (button_statek == HIGH)  //Okay button

    {

      capacity = count;

      lcd.clear();

      lcd.setCursor(0, 0);

      lcd.print("Counting active:");

      lcd.setCursor(0, 1);

      lcd.print("Passenger: ");

      lcd.setCursor(12, 1);

      lcd.print(Pcount);

      break;

    }

  }

  if(IR_state1 == HIGH)

  {

    delay(200);

    Pcount++;

    lcd.print(Pcount);

  }

  else if(IR_state2 == HIGH)

  {

    delay(200);

    Pcount--;

    lcd.print(Pcount);

  }

}

void PressP()

{

  digitalWrite(ledp, HIGH);

  delay(300);

  count = count + 1;

  delay(100);

  digitalWrite(ledp, LOW);

}

void PressM()

{

  digitalWrite(ledm, HIGH);

  delay(300);

  count = count - 1;

  if(count < 1)

  {

    count = 0;

  }

  else if(count >= 1 && count <10);

    {

      lcd.setCursor(13, 1);

      lcd.print(" ");

    }

  delay(100);

  digitalWrite(ledm, LOW);

}

void PressR()

{

  digitalWrite(ledm, HIGH);

  digitalWrite(ledp, HIGH);

  delay(300);

  count = 0;

  delay(100);

  digitalWrite(ledp, LOW);

  digitalWrite(ledm, LOW);

}

Scan your switches every 50ms.

When a switch changes state, then do an operation; don’t use switch levels, use switch change in state.

Avoid while( ) loops like the Covid plague.


BTW
In the Arduino IDE, use Ctrl T or CMD T to format your code then copy the complete sketch.
Use the </> icon from the ‘reply menu’ to attach the copied sketch.

1 Like

YMMD

Hi @LarryD thank you for your response, what loop will I be using for checking the switch every 50ms? and If I am avoiding while loop like my previous code, the void loop function will have a bunch of if else statements and it is confusing for me.

In the loop( ) function you monitor a 50ms TIMER.

When the TIMER expires, you call a scanSwitch function.

In the scanSwitch function you check each switch to see if they have changed state.

When a switch changes from released to pushed you can increment/decrement etc. your variables.

I am slightly confused about your explanation sir, could you provide me a simple code example? Thank you so much🧡

What part are you not following ?

Hello zgryx
I´ve made a low level flight about the sketch.
The recommendation is to study the IPO model and the basics of C++ coding. This basics will help you to get a structured sketch by using array, struct etc.
At least the following functions are needed:

  • Button handler
  • Time handler

What are the purposes of the inputs IR1 and IR2?

Have a nice day and enjoy coding in C++.

This part sir

[quote="paulpaulson, post: 8, topic: 951913"]
What are the purposes of the inputs IR1 and IR2?

[quote]

Hello sir @paulpaulson, thank you for your response. The inputs IR1 and IR2 are the 2 obstacle IR sensors. If they detect a person entering, it will increment the variable Pcount and vise versa. It is the live counting I am mentioning in my post sir after you click the Okay button then the device will start counting

Hello zgryx
I cannot see any processing on these inputs?
In short words - fitted for but not with - a function?
Have a nice day and enjoy coding in C++.

It's at this part sir

Hello zgryx
You are right. I´ve to clean my glasses and have another cup of coffee :nerd_face:
Have a nice day and enjoy coding in C++.

How are your switches wired ?

Sir @LarryD the resistor is 10Kohms

Here is a star to what was explained.

See if you can follow what is there.

#include <Wire.h>

//******************************************************************************
//remove comment marks for an I2C LCD
//#define hd44780serialLCDisBeingUsed  //uncomment if you have a serial LCD  <--------------<<<<<

//********************************************
#ifdef  hd44780serialLCDisBeingUsed

//Use I2C library:     https://github.com/duinoWitchery/hd44780
//LCD Reference:       https://www.arduino.cc/en/Reference/LiquidCrystal

//this LCD is I2C wired
#include <hd44780.h>   //main hd44780 header

//N O T E :
//hd44780_I2Cexp control LCD using I2C I/O expander backpack (PCF8574 or MCP23008)
//hd44780_I2Clcd control LCD with native I2C interface (PCF2116, PCF2119x, etc...)

#include <hd44780ioClass/hd44780_I2Cexp.h> //I2C expander i/o class header

//If you do not know what your I2C address is, first run the 'I2C_Scanner' sketch
//OR
//Run: I2CexpDiag.ino
//C:\Users\YourName\Documents\Arduino1.69\libraries\hd44780\examples\ioClass\hd44780_I2Cexp\I2CexpDiag

hd44780_I2Cexp lcd(0x3F);
//hd44780_I2Cexp lcd(0x27);

//********************************************
#else

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

#endif

//******************************************************************************
#define LEDon        HIGH
#define LEDoff       LOW

#define ENABLED      true
#define DISABLED     false

#define PUSHED       HIGH


#define buttonp      2
#define buttonm      3
#define buttonr      4
#define buttonk      7

#define ledp         5
#define ledm         6

#define IR1          8
#define IR2          9

#define heartbeatLED 13

int count;
int capacity;
int Pcount;
int state;

byte last_buttonp;
byte last_buttonm;
byte last_buttonr;
byte last_buttonk;

//Timning stuff
unsigned long heartbeatMillis;
unsigned long switchMillis;

//********************************************^************************************************
void setup()
{
  pinMode(heartbeatLED, OUTPUT);
  pinMode(ledp, OUTPUT);
  pinMode(ledm, OUTPUT);

  pinMode(buttonp, INPUT_PULLUP);
  pinMode(buttonm, INPUT_PULLUP);
  pinMode(buttonr, INPUT_PULLUP);
  pinMode(buttonk, INPUT_PULLUP);
  pinMode(IR1, INPUT_PULLUP);
  pinMode(IR2, INPUT_PULLUP);

  //********************************************
#ifdef  hd44780serialLCDisBeingUsed
  lcd.begin(16, 2);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("PROJECT GENESIS");

#else
  lcd.init();
  lcd.backlight();

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("PROJECT GENESIS");
#endif

  //********************************************
  delay(2000);
  lcd.clear();
  lcd.print("SET CAPACITY");
  lcd.setCursor(0, 1);
  lcd.print("CAPACITY = ");
  lcd.setCursor(12, 1);
  lcd.print(count);

} //END of   setup()


//********************************************^************************************************
void loop()
{
  //****************************************               h e a r t b e a t L E D   T I M E R
  //is it time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500)
  {
    //restart this TIMER
    heartbeatMillis = millis();

    //Toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //****************************************               c h e c k S w i t c h e s    T I M E R
  //is it time to check the switches ?
  if (millis() - switchMillis >= 50)
  {
    //restart this TIMER
    switchMillis = millis();

    checkSwitches();
  }


  //  if (IR_state1 == HIGH)
  //  {
  //    delay(200);
  //    Pcount++;
  //    lcd.print(Pcount);
  //  }
  //
  //  else if (IR_state2 == HIGH)
  //  {
  //    delay(200);
  //    Pcount--;
  //    lcd.print(Pcount);
  //  }

} //END of   loop()


//********************************************^************************************************
void checkSwitches()
{
  //****************************************  //Plus button
  byte state = digitalRead(buttonp);

  //Has the switch changed state ?
  if (last_buttonp != state)
  {
    //update to the new state
    last_buttonp = state;

    if (state == PUSHED)
    {
      PressP();
      lcd.setCursor(12, 1);
      lcd.print(count);
    }
  }

  //****************************************  //Minus button
  state = digitalRead(buttonm);

  //Has the switch changed state ?
  if (last_buttonm != state)
  {
    //update to the new state
    last_buttonm = state;

    if (state == PUSHED)
    {
      PressM();
      lcd.setCursor(12, 1);
      lcd.print(count);
    }
  }

  //****************************************  //Reset button
  state = digitalRead(buttonr);

  //Has the switch changed state ?
  if (last_buttonr != state)
  {
    //update to the new state
    last_buttonr = state;

    if (state == PUSHED)
    {
      PressR();  //Reset button
      lcd.setCursor(13, 1);
      lcd.print(" ");
      lcd.setCursor(12, 1);
      lcd.print(count);
    }
  }

  //****************************************  //Okay button
  state = digitalRead(buttonk);

  //Has the switch changed state ?
  if (last_buttonk != state)
  {
    //update to the new state
    last_buttonk = state;

    if (state == PUSHED)
    {
      capacity = count;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Counting active:");
      lcd.setCursor(0, 1);
      lcd.print("Passenger: ");
      lcd.setCursor(12, 1);
      lcd.print(Pcount);
    }
  }

} //END of    checkSwitches()


//********************************************^************************************************
void PressP()
{
  digitalWrite(ledp, HIGH);
  delay(300);
  count = count + 1;
  delay(100);
  digitalWrite(ledp, LOW);

}


//********************************************^************************************************
void PressM()
{
  digitalWrite(ledm, HIGH);
  delay(300);
  count = count - 1;
  if (count < 1)
  {
    count = 0;
  }
  else if (count >= 1 && count < 10);
  {
    lcd.setCursor(13, 1);
    lcd.print(" ");
  }
  delay(100);
  digitalWrite(ledm, LOW);

}


//********************************************^************************************************
void PressR()
{
  digitalWrite(ledm, HIGH);
  digitalWrite(ledp, HIGH);
  delay(300);
  count = 0;
  delay(100);
  digitalWrite(ledp, LOW);
  digitalWrite(ledm, LOW);

}

Thank you so much @LarryD I'll definitely study your code🧡 I'll give feedback ASAP

With IR sensors:

#include <Wire.h>

//******************************************************************************
//#define hd44780serialLCDisBeingUsed  

//********************************************
#ifdef  hd44780serialLCDisBeingUsed

//Use I2C library:     https://github.com/duinoWitchery/hd44780
//LCD Reference:       https://www.arduino.cc/en/Reference/LiquidCrystal

//this LCD is I2C wired
#include <hd44780.h>   //main hd44780 header

//N O T E :
//hd44780_I2Cexp control LCD using I2C I/O expander backpack (PCF8574 or MCP23008)
//hd44780_I2Clcd control LCD with native I2C interface (PCF2116, PCF2119x, etc...)

#include <hd44780ioClass/hd44780_I2Cexp.h> //I2C expander i/o class header

//If you do not know what your I2C address is, first run the 'I2C_Scanner' sketch
//OR
//Run: I2CexpDiag.ino
//C:\Users\YourName\Documents\Arduino1.69\libraries\hd44780\examples\ioClass\hd44780_I2Cexp\I2CexpDiag

hd44780_I2Cexp lcd(0x3F);
//hd44780_I2Cexp lcd(0x27);

//********************************************
#else

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

#endif

//******************************************************************************
#define LEDon        HIGH
#define LEDoff       LOW
#define ENABLED      true
#define DISABLED     false
#define PUSHED       HIGH

#define buttonp      2
#define buttonm      3
#define buttonr      4
#define buttonk      7

#define ledp         5
#define ledm         6

#define IR1          8
#define IR2          9

#define heartbeatLED 13

int count;
int capacity;
int Pcount;
int state;

byte last_buttonp;
byte last_buttonm;
byte last_buttonr;
byte last_buttonk;
byte last_IR1;
byte last_IR2;


//Timning stuff
unsigned long heartbeatMillis;
unsigned long switchMillis;

//********************************************^************************************************
void setup()
{
  pinMode(heartbeatLED, OUTPUT);
  pinMode(ledp, OUTPUT);
  pinMode(ledm, OUTPUT);

  pinMode(buttonp, INPUT_PULLUP);
  pinMode(buttonm, INPUT_PULLUP);
  pinMode(buttonr, INPUT_PULLUP);
  pinMode(buttonk, INPUT_PULLUP);
  
  pinMode(IR1, INPUT_PULLUP);
  pinMode(IR2, INPUT_PULLUP);

  //********************************************
#ifdef  hd44780serialLCDisBeingUsed
  lcd.begin(16, 2);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("PROJECT GENESIS");

#else
  lcd.init();
  lcd.backlight();

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("PROJECT GENESIS");
#endif

  //********************************************
  delay(2000);
  
  lcd.clear();
  lcd.print("SET CAPACITY");
  lcd.setCursor(0, 1);
  lcd.print("CAPACITY = ");
  lcd.setCursor(12, 1);
  lcd.print(count);

} //END of   setup()


//********************************************^************************************************
void loop()
{
  //****************************************               h e a r t b e a t L E D   T I M E R
  //is it time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500)
  {
    //restart this TIMER
    heartbeatMillis = millis();

    //Toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //****************************************               c h e c k S w i t c h e s    T I M E R
  //is it time to check the switches ?
  if (millis() - switchMillis >= 50)
  {
    //restart this TIMER
    switchMillis = millis();

    checkSwitches();
  }

} //END of   loop()


//********************************************^************************************************
void checkSwitches()
{
  //****************************************  //Plus button
  byte state = digitalRead(buttonp);

  //Has the switch changed state ?
  if (last_buttonp != state)
  {
    //update to the new state
    last_buttonp = state;

    if (state == PUSHED)
    {
      PressP();
      lcd.setCursor(12, 1);
      lcd.print(count);
    }
  }

  //****************************************  //Minus button
  state = digitalRead(buttonm);

  //Has the switch changed state ?
  if (last_buttonm != state)
  {
    //update to the new state
    last_buttonm = state;

    if (state == PUSHED)
    {
      PressM();
      lcd.setCursor(12, 1);
      lcd.print(count);
    }
  }

  //****************************************  //Reset button
  state = digitalRead(buttonr);

  //Has the switch changed state ?
  if (last_buttonr != state)
  {
    //update to the new state
    last_buttonr = state;

    if (state == PUSHED)
    {
      PressR();  //Reset button
      lcd.setCursor(13, 1);
      lcd.print(" ");
      lcd.setCursor(12, 1);
      lcd.print(count);
    }
  }

  //****************************************  //Okay button
  state = digitalRead(buttonk);

  //Has the switch changed state ?
  if (last_buttonk != state)
  {
    //update to the new state
    last_buttonk = state;

    if (state == PUSHED)
    {
      capacity = count;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Counting active:");
      lcd.setCursor(0, 1);
      lcd.print("Passenger: ");
      lcd.setCursor(12, 1);
      lcd.print(Pcount);
    }
  }

  //****************************************  //IR1 sensor
  state = digitalRead(IR1);

  //Has the IR sensor changed state ?
  if (last_IR1 != state)
  {
    //update to the new state
    last_IR1 = state;

    if (state == HIGH)
    {
      Pcount++;

      lcd.setCursor(13, 1);
      lcd.print(" ");
      lcd.setCursor(12, 1);
      lcd.print(Pcount);

      delay(200);
    }
  }

  //****************************************  //IR2 sensor
  state = digitalRead(IR2);

  //Has the IR sensor changed state ?
  if (last_IR2 != state)
  {
    //update to the new state
    last_IR2 = state;

    if (state == HIGH)
    {
      Pcount--;
      if (Pcount < 0)
      {
        Pcount = 0;
      }

      lcd.setCursor(13, 1);
      lcd.print(" ");
      lcd.setCursor(12, 1);
      lcd.print(Pcount);

      delay(200);
    }
  }

} //END of    checkSwitches()


//********************************************^************************************************
void PressP()
{
  digitalWrite(ledp, HIGH);
  delay(300);
  
  count = count + 1;
  
  delay(100);
  
  digitalWrite(ledp, LOW);

}


//********************************************^************************************************
void PressM()
{
  digitalWrite(ledm, HIGH);
  delay(300);
  
  count = count - 1;
  if (count < 1)
  {
    count = 0;
  }
  
  else if (count >= 1 && count < 10);
  {
    lcd.setCursor(13, 1);
    lcd.print(" ");
  }
  
  delay(100);
  
  digitalWrite(ledm, LOW);

}


//********************************************^************************************************
void PressR()
{
  digitalWrite(ledm, HIGH);
  digitalWrite(ledp, HIGH);
  
  delay(300);
  
  count = 0;
  
  delay(100);
  
  digitalWrite(ledp, LOW);
  digitalWrite(ledm, LOW);

}

You need to now get rid of calls to delay( ) and replace them with non blocking delay code or possibly remove them.

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