Bool button_check function behaving oddly

Hey all,
My 1st post here so pardon me if not everything is up to spec.

My setup has two buttons, one that does 99% of the job (BUTTON_PIN 4 , aka Green Button) and another (REPEAT_PIN 5, aka Black Button).

Detecting button presses is handled by this function which is currently just capable of handling the Green one, as it just became clear to me now that I require a 2nd button to avoid repetitive tasks (basically to command one calculating function to run over and over again, adding a value to itself + the newly calculated one).

bool check_button_press(int PIN) {  

  buttonState = digitalRead(PIN);  // READ PIN

  // // -- DEBUG START -- //
  // Serial.print("Start Routine ButtonState: ");
  // Serial.println(buttonState);
  // delay(500);
  // // DEBUG END //

  // ASSUMPTIONS:
  // 1. WE ARE CONSTANTLY RUNNING THIS FUNCTION AS THE HOLDING STATEMENT FOR BOTH BUTTON PRESSES
  // 2. FUNCTION ONLY RUNS IF buttonState IS DIFFERENT THAN lastButtonState, WITH RETURN false IF THEY ARE THE SAME
  // 3. IF IT IS, WE UPDATE lastButtonState TO THE CURRENT buttonState
  // 4. IF IT UPDATED TO HIGH, IT MEANS IT WAS UNPRESSED BETWEEN LAST CPU CYCLE AND CURRENT ONE. RETURN false
  // 5. IF IT UPDATED TO LOW, IT MEANS IT WAS PRESSED BETWEEN LAST CPU CYCLE AND CURRENT. RETURN true, TRIGGERS ITS HOLDING EVENT

  if (buttonState != lastButtonState) {
    
    lastButtonState = buttonState;
    
    if (buttonState == HIGH) {
      Serial.print("Button ");
      Serial.print(PIN);
      Serial.println(" NOT pressed, just returned to HIGH!");
      delay(500);   
      return false;

    } else {
      Serial.print("Button ");
      Serial.print(PIN);
      Serial.println(" pressed!");
      delay(1500);
      return true;
    }

  }
    Serial.print(" Button ");
    Serial.print(PIN);
    Serial.println(" NOT pressed!");
    delay(500);
    return false;
}

All my steps along the program other than the last one are handled with the following while loop:

  while (!check_button_press(BUTTON_PIN)) {};  // HOLD STATEMENT. WAITS FOR BUTTON PRESS

As the last step before returning to the main loop where we wait for BUTTON_PIN to be pressed to re-initiate the calculation, users have two options: BUTTON_PIN for exit, REPEAT_PIN to repeat the calculation, adding the calculated value cumulatively to the previous one. (I am basically counting parts and it might be physically impossible to count the whole batch in one turn - but I don't want to have to calculate the weight per part again - a routine I am not showing here.

This is my condition:

bool running = true;
  while (running) {
    Serial.println("Entering main loop");
    total_weight_and_part_count();                                                  //this function runs once at the start of the loop and will re-run and accumulate the calculation result

    while (!check_button_press(BUTTON_PIN) && !check_button_press(REPEAT_PIN)) {

    }
    if (check_button_press(BUTTON_PIN)) {
    Serial.println("GREEN");
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("START WITH BUTTON.");
    running = false;
  } 
    else if (check_button_press(REPEAT_PIN)){
    Serial.println("BLACK");

  } 
};

My logic is:

  1. User enters the loop and part_count() function runs once, displays its crap on the LCD of the equipment, and waits for user to press BUTTON_PIN (exit) or REPEAT_PIN (re-run while(running) loop).
  2. Whenever ONE of those buttons is pressed, program unlocks and either sets running to false and exits to my void main() or repeats the part_count() function.

I have tried many adaptations of my check_button, so I simply reverted back to a more stable state so that we can build from here.

My question: can someone guide me to make the necessary changes to the check_button or the last if BUTTON/REPEAT_PIN ? I am usually not too stupid with this :sweat_smile: so I don't think it will take anyone too long to get me thinking the right way up.

Thanks in advance for your time.

You will need to post the complete sketch, then paste the sections you want to reference.

This will only remember one button state, not one for each button.

looks this over

// check multiple buttons and toggle LEDs

enum { Off = HIGH, On = LOW };

byte pinsLed [] = { 10, 11, 12 };
byte pinsBut [] = { A1, A2, A3 };
#define N_BUT   sizeof(pinsBut)

byte butState [N_BUT];

// -----------------------------------------------------------------------------
int
chkButtons ()
{
    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        byte but = digitalRead (pinsBut [n]);

        if (butState [n] != but)  {
            butState [n] = but;

            delay (10);     // debounce

            if (On == but)
                return n;
        }
    }
    return -1;
}

// -----------------------------------------------------------------------------
void
loop ()
{
    switch (chkButtons ())  {
    case 2:
        digitalWrite (pinsLed [2], ! digitalRead (pinsLed [2]));
        break;

    case 1:
        digitalWrite (pinsLed [1], ! digitalRead (pinsLed [1]));
        break;

    case 0:
        digitalWrite (pinsLed [0], ! digitalRead (pinsLed [0]));
        break;
    }
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        pinMode (pinsBut [n], INPUT_PULLUP);
        butState [n] = digitalRead (pinsBut [n]);
    }

    for (unsigned n = 0; n < sizeof(pinsLed); n++)  {
        digitalWrite (pinsLed [n], Off);
        pinMode      (pinsLed [n], OUTPUT);
    }
}
1 Like

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