Editorial Solution

  • From the task, we will be using the two buttons for incrementing and decrementing the count.
  • We will also store the value in the EEPROM so that the value is retained over power off/reset.
  • We will also implement a proper debounce logic on both buttons to correctly read one press instead of dangling presses.
  • We will increase and decrease the count value based on the corresponding button press.

System Setup 

 

Code

#include <EEPROM.h>

// Pin Definitions
#define INC_BUTTON_PIN 2  // Button to increment count
#define DEC_BUTTON_PIN 3  // Button to decrement count

// Variables
int humanCount;               // Current human count
const int eepromAddress = 0;  // EEPROM address to store the count

void setup() {
  Serial.begin(9600);
  initiateCount();

  // Configure button pins
  pinMode(INC_BUTTON_PIN, INPUT_PULLUP);
  pinMode(DEC_BUTTON_PIN, INPUT_PULLUP);

  Serial.println("Human Counter System Started!");
  Serial.print("Initial Count: ");
  Serial.println(humanCount);
}


void loop() {
  static bool incButtonState = HIGH;
  static bool decButtonState = HIGH;


  // Read button states with debounce
  bool incButtonPressed = debounceButton(INC_BUTTON_PIN, incButtonState);
  bool decButtonPressed = debounceButton(DEC_BUTTON_PIN, decButtonState);


  // Increment count
  if (incButtonPressed) {
    humanCount++;
    updateEEPROM();
    Serial.print("Count Incremented: ");
    Serial.println(humanCount);
  }

  // Decrement count
  if (decButtonPressed && humanCount > 0) {
    humanCount--;
    updateEEPROM();
    Serial.print("Count Decremented: ");
    Serial.println(humanCount);
  }
}


bool debounceButton(int pin, bool &lastState) {
  bool currentState = digitalRead(pin);
  if (lastState != currentState) {
    delay(50);  // Debounce delay
    if (digitalRead(pin) == currentState) {
      lastState = currentState;
      return currentState == LOW;  // Return true if button is pressed
    }
  }
  return false;
}


void updateEEPROM() {
  EEPROM.write(eepromAddress, humanCount);
}

void initiateCount() {
  humanCount = EEPROM.read(eepromAddress);
  if (humanCount == 255) {
    humanCount = 0;
    updateEEPROM();
  }
}

Code Explanation

Debouncing Logic:

  • Prevent multiple triggers by introducing a delay (50ms) after detecting a button state change:
    • The condition if (lastState != currentState) checks whether the button's state has changed (e.g., from HIGH to LOW or vice versa). This ensures that further checks only occur when a button press or release is detected.
    • The delay(50) introduces a 50ms delay to filter out noise and stabilize the input signal. Mechanical buttons often "bounce" rapidly between states when pressed, causing false triggers if read immediately.
    • After the delay, the logic re-checks the pin state with if (digitalRead(pin) == currentState). If the state remains the same as currentState, it confirms that the button input is stable.
    • lastState = currentState updates the last recorded state to the current stable state. The line return currentState == LOW checks if the button is pressed (LOW logic) and returns true if so.
if (lastState != currentState) {
  delay(50); // Debounce delay
  if (digitalRead(pin) == currentState) {
    lastState = currentState;
    return currentState == LOW;  // Return true if button is pressed
  }
}

 

Output Video

 

Submit Your Solution