ESP32 counter getting stuck

I've written the code below to count down on a seven segment counter when a button is pressed (button1). Another button (button2) resets the counter back to 9.

What im trying to do in the last if statement is make an LED blink when the counter reaches 1. When i get to one sure enough the LED blinks but the counter stops responding. None of the buttons work and I'm now stuck with a counter showing 1 and a blinking LED.

Whats the issue with the IF statement? i feel like instead of reading my count variable, I'm eternally defining it and getting stuck...

#include "SevSeg.h"  /*Include seven segment library*/
SevSeg sevseg;       /*Seven Segment Variable*/  
int state1;          /*Variable to store pushbutton state*/
int state2;          /*Variable to store pushbutton state*/
int state3; 
int count=0;         /*Variable that will store counter value*/
const int ledPin = 13;
#define button1 23   /*ESP32 pin for pushbutton */
#define button2 22   /*ESP32 pin for pushbutton */
 void setup()  {
pinMode(button1,INPUT_PULLUP);  /*Assign button as input*/
  byte sevenSegments = 1;   /*Number of seven segments we are using*/
  byte CommonPins[] = {};   /*Define common pins*/
  byte LEDsegmentPins[] = {15, 2, 4, 5, 18, 19, 21};  /*ESP32 digital pins defined for seven segment sequence pin a to g*/
  bool resistorsOnSegments = true;
sevseg.begin(COMMON_ANODE, sevenSegments, CommonPins, LEDsegmentPins, resistorsOnSegments);/*configuration of the seven-segment */
sevseg.setBrightness(80);  /*Brightness of seven segment*/
pinMode(button2,INPUT_PULLUP);  /*Assign button as input*/
pinMode(ledPin, OUTPUT);
}
void loop()  {
state1=digitalRead(button1);  /*Read pushbutton state*/
   if (state1== LOW){         /*LOW state when pushup button is pressed*/
        count--;              /*Increase display value by 1*/
sevseg.setNumber(count);      /*display the count value*/
sevseg.refreshDisplay();      /*refresh 7-segment */
delay(200);
  }
  sevseg.setNumber(count);/*display the count value*/
sevseg.refreshDisplay();/* refresh 7-segment*/
state2=digitalRead(button2);  /*Read pushbutton state*/
   if (state2== LOW){         /*LOW state when pushup button is pressed*/
        count = 9;   }         /*Increase display value by 1*/

if (count == 1) {
  digitalWrite(ledPin, HIGH); // Turn on the LED
  delay(500); // Wait for 500 milliseconds
  digitalWrite(ledPin, LOW); // Turn off the LED
  delay(500); // Wait for another 500 milliseconds
}

}

Welcome to the forum.

When you have the sketch in the Arduino IDE 2.1.0, could you right-click on the sketch and select "Format Document" ?

To do multiple things at the same time, you could use tasks. The ESP32 is already running FreeRTOS.
An other way to do multiple things at the same time is to use millis(). This is the starting page: https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay
When a Arduino board has only little SRAM memory (such as the Arduino Uno), then using millis() does not need an extra stack for each task.

I made a Wokwi simulation of your project:

1 Like

HI @blenks9,

welcome to the arduino-forum.

The examples delivered with the arduino-IDE has IMHO a big flaw.
It shows the function delay()

Showing this puts newcomers on an easy to understand track that - a little but further down the road - makes it hard to understand how to go on with coding.

The standard blink without delay-example in my opinion sucks for two reasons:

  1. it does not explain the fundamental difference between delay() and non-blocking timing
  2. it does not use an everyday example with easy to follow numbers to understand how non-blocking timing works

The link from user @Koepel has this poor explanation
quoting:
"The code below uses the millis() function, a command that returns the number of milliseconds since the board started running its current sketch, to blink an LED."

The sentence is true. But leads to misunderstandings:
This misunderstanding is: you can't simply replace function delay() with function millis().
It is a little bit more work.

I recommend to read through this tutorial because:

  1. it does explain the fundamental difference between delay() and non-blocking timing
  2. it does [/color] use an everyday example (baking a frosted pizza) with easy to follow numbers to understand how non-blocking timing works

best regards Stefan

2 Likes

That is a 1 second process during which nothing else can happen.
Now when the if loop finishes, UNLESS another count is detected in that tiny space of time, the count is still 1 - so it goes around again ... and again ...

You need to
restructure your program to use millis() to do the timing
That will allow counts to be detected, so the next time the program reaches that test the count will be able to have changed..

1 Like

without checking for a change in button state, just checking for LOW causes the condition to be executed repeatedly while the button is held down. in this case the count get decremented each time instead of the value decrementing once each button pressed.

a short delay handles the bounce. your 200 msec delay limited the decrementing to 5 times a second

also there's no need to update the 7seg display both when the button is pressed as well as outside the condition

look this over

void loop ()
{
    byte but = digitalRead (button1);
    if (state1 != but)  {   // check for state change
        state1 = but;
        delay (20);         // debounce

        if (but == LOW)  {  // button pressed (not held down)
            count--;
            Serial.println (count);
        }
    }

    but = digitalRead (button2);
    if (state2 != but)  {
        state2 = but;
        delay (20);         // debounce

        if (LOW == but)  {
            count = 9;      // reset count;
            Serial.println (count);
        }
    }

    sevseg.setNumber (count);
    sevseg.refreshDisplay ();

    if (count == 1) {
        digitalWrite (ledPin, HIGH);
        delay (500);
        digitalWrite (ledPin, LOW);
        delay (500);
    }
}
1 Like

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