Need help for my basic Buzzer Timer code

I'm working on a project using an Arduino with a keypad, an LCD, and a buzzer. The idea is to set a code, and once the code is set, a countdown starts. During this countdown, the buzzer is supposed to beep at different frequencies depending on the remaining time:

However, I've encountered a problem where, when the buzzer should beep more fast, the beeping frequency doesn't change as expected. It continues to beep with the same interval as before.

Here's my code:

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <Tone.h>

Tone tone1;

const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {5, 6, 7, 8}; // Connect row pins of the keypad to digital pins 5, 6, 7, 8
byte colPins[COLS] = {9, 10, 11, 12}; // Connect to the column pinouts of the keypad

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

int currentLength = 0;
char entered[4];
char password[4] = {'1', '2', '3', '4'};
bool settingCode = true; // Flag to indicate code setting mode
String newCode = ""; // Variable to store the new code

LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address and dimensions

unsigned long previousMillis = 0;
const long interval = 1000; // Interval of 1 second
int countdown = 61; // Initial countdown value in seconds

void setup() {
  tone1.begin(4); // Initialize the buzzer on pin 4
  lcd.init(); // Initialize the LCD
  lcd.backlight(); // Turn on backlight
  lcd.setCursor(0, 0);
  lcd.print("Set Code:");

  pinMode(4, OUTPUT); // Set pin 4 as the buzzer pin
}

void loop() {
  if (settingCode) {
    char key = keypad.getKey();
    if (key != NO_KEY && currentLength < 4) {
      if (key == '#') {
        currentLength = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Code:");
      } else if (key != '*' && key != '#') {
        lcd.setCursor(currentLength, 1);
        lcd.print('*');
        newCode += key;
        currentLength++;
        tone1.play(500); // Play a quieter tone when a key is pressed during code setting
        delay(100);
        tone1.stop(); // Stop the tone after the delay
      }
    }

    if (currentLength == 4) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Code Set!");
      tone1.play(600); // Play a slightly louder tone to indicate code setting completion
      delay(2000);
      tone1.stop(); // Stop the tone after the delay
      lcd.clear();
      lcd.print("Enter Code:");
      settingCode = false;
      currentLength = 0;

      // Start the timer
      previousMillis = millis();
    }
  } else {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      countdown--;

      lcd.setCursor(12, 0); // Set the cursor position for the timer display
      lcd.print("   "); // Clear previous timer value
      lcd.setCursor(12, 0);
      lcd.print(countdown);

      // Play beeping sound based on countdown value
      if (countdown <= 60 && countdown > 30) {
        tone1.play(2000); // Play the beep sound
        delay(500); // Beep every 0.5 seconds
        tone1.stop();
      } else if (countdown <= 30 && countdown > 10) {
        tone1.play(2000); // Play the beep sound
        delay(250); // Beep every 0.25 seconds
        tone1.stop();
      } else if (countdown <= 10 && countdown > 5) {
        tone1.play(2000); // Play the beep sound
        delay(125); // Beep every 0.125 seconds
        tone1.stop();
      } else if (countdown <= 5 && countdown > 0) {
        tone1.play(2000); // Play the beep sound
        delay(63); // Beep every 0.063 seconds
        tone1.stop();
      } else if (countdown == 0) {
        tone1.play(2000); // Continuous beeping
        delay(50); // Beep every 0.05 seconds
        tone1.stop();
      }
    }

    char key = keypad.getKey();
    if (key != NO_KEY && currentLength < 4) {
      if (key == '#') {
        currentLength = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Enter Code:");
      } else if (key != '*' && key != '#') {
        lcd.setCursor(currentLength, 1);
        lcd.print('*');
        entered[currentLength] = key;
        currentLength++;
        tone1.play(500); // Play a quieter tone when a key is pressed during code entry
        delay(100);
        tone1.stop(); // Stop the tone after the delay
      }
    }

    if (currentLength == 4) {
      if (entered[0] == newCode[0] && entered[1] == newCode[1] && entered[2] == newCode[2] && entered[3] == newCode[3]) {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Bomb Defused");
        tone1.play(700); // Play a slightly louder tone to indicate successful code entry
        delay(2500);
        tone1.stop(); // Stop the tone after the delay
        lcd.clear();
        settingCode = true;
        newCode = "";
        lcd.setCursor(0, 0);
        lcd.print("Set Code:");
        currentLength = 0;
        countdown = 30; // Reset the countdown timer
      } else {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Wrong Password!");
        tone1.play(400); // Play a slightly louder tone to indicate wrong password
        delay(1500);
        tone1.stop(); // Stop the tone after the delay
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Enter Code:");
        currentLength = 0;
        countdown -= 5; // Decrease the timer by 5 seconds for wrong password
        if (countdown < 0) {
          countdown = 0; // Ensure the countdown doesn't go negative
        }
        lcd.setCursor(12, 0); // Update the timer display on the LCD
        lcd.print("   "); // Clear previous timer value
        lcd.setCursor(12, 0);
        lcd.print(countdown);

        if (countdown <= 10) {
          lcd.setCursor(1, 7);
          lcd.print("Code: ");
          lcd.setCursor(1, 13);
          lcd.print(newCode);
        }
      }
    }
  }
}

I have deleted your other cross-post @veribot.

Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting can result in a suspension from the forum.

In the future, please only create one topic for each distinct subject matter. This is basic forum etiquette, as explained in the "How to get the best out of this forum" guide. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

alright, i just created my account so i didnt know that. Thank you!

1 Like

not solution, just litle info. you need not clear area before display new symbols, new line will anyway overwrite the existing

        lcd.setCursor(12, 0); // Update the timer display on the LCD
        lcd.print(countdown);
        lcd.print(' '); // to be sure, when new number is shorter
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>

const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {5, 6, 7, 8}; // Connect row pins of the keypad to digital pins 5, 6, 7, 8
byte colPins[COLS] = {9, 10, 11, 12}; // Connect to the column pinouts of the keypad

Keypad keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

int currentLength = 0;
char entered[4];
char password[4] = {'1', '2', '3', '4'};
bool settingCode = true; // Flag to indicate code setting mode
String newCode = ""; // Variable to store the new code

LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address and dimensions

unsigned long previousMillis = 0;
const long interval = 1000; // Interval of 1 second
int countdown = 61; // Initial countdown value in seconds

void setup() {
  lcd.init(); // Initialize the LCD
  lcd.backlight(); // Turn on backlight
  lcd.setCursor(0, 0);
  lcd.print("Set Code:");

  pinMode(4, OUTPUT); // Set pin 4 as the buzzer pin
}

void loop() {
  if (settingCode) {
    char key = keypad.getKey();
    if (key != NO_KEY && currentLength < 4) {
      if (key == '#') {
        currentLength = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Code:");
      } else if (key != '*' && key != '#') {
        lcd.setCursor(currentLength, 1);
        lcd.print('*');
        newCode += key;
        currentLength++;
        tone(4, 500); // Play a quieter tone when a key is pressed during code setting
        delay(100);
        noTone(4); // Stop the tone after the delay
      }
    }

    if (currentLength == 4) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Code Set!");
      tone(4, 600); // Play a slightly louder tone to indicate code setting completion
      delay(2000);
      noTone(4); // Stop the tone after the delay
      lcd.clear();
      lcd.print("Enter Code:");
      settingCode = false;
      currentLength = 0;

      // Start the timer
      previousMillis = millis();
    }
  } else {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      countdown--;

      lcd.setCursor(12, 0); // Set the cursor position for the timer display
      lcd.print("   "); // Clear previous timer value
      lcd.setCursor(12, 0);
      lcd.print(countdown);

      // Play beeping sound based on countdown value
      if (countdown <= 60 && countdown > 30) {
        tone(4, 500); // Play the beep sound
        delay(500); // Beep every 0.5 seconds
        noTone(4);
      } else if ( countdown > 10) {
        tone(4, 700); // Play the beep sound
        delay(250); // Beep every 0.25 seconds
        noTone(4);
      } else if (countdown > 5) {
        tone(4, 1000); // Play the beep sound
        delay(125); // Beep every 0.125 seconds
        noTone(4);
      } else if ( countdown > 0) {
        tone(4, 1500); // Play the beep sound
        delay(63); // Beep every 0.063 seconds
        noTone(4);
      } else if (countdown == 0)tone(4, 50, 50); // Beep every 0.05 seconds
    }

    char key = keypad.getKey();
    if (key != NO_KEY && currentLength < 4) {
      if (key == '#') {
        currentLength = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Enter Code:");
      } else if (key != '*' && key != '#') {
        lcd.setCursor(currentLength, 1);
        lcd.print('*');
        entered[currentLength] = key;
        currentLength++;
        tone(4, 500); // Play a quieter tone when a key is pressed during code entry
        delay(100);
        noTone(4); // Stop the tone after the delay
      }
    }

    if (currentLength == 4) {
      if (entered[0] == newCode[0] && entered[1] == newCode[1] && entered[2] == newCode[2] && entered[3] == newCode[3]) {
        lcd.clear();
        lcd.print("Bomb Defused");
        tone(4, 700); // Play a slightly louder tone to indicate successful code entry
        delay(2500);
        noTone(4); // Stop the tone after the delay
        lcd.clear();
        settingCode = true;
        newCode = "";
        lcd.print("Set Code:");
        currentLength = 0;
        countdown = 30; // Reset the countdown timer
      } else {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Wrong Password!");
        tone(4, 400); // Play a slightly louder tone to indicate wrong password
        delay(1500);
        noTone(4); // Stop the tone after the delay
        lcd.clear();
        lcd.print("Enter Code:");
        currentLength = 0;
        countdown -= 5; // Decrease the timer by 5 seconds for wrong password
        if (countdown < 0)countdown = 0; // Ensure the countdown doesn't go negative
        
        lcd.setCursor(12, 0); // Update the timer display on the LCD
        lcd.print(countdown); lcd.print(" "); 

        if (countdown <= 10) {
          lcd.setCursor(1, 7);
          lcd.print("Code: ");
          lcd.print(newCode);
        }
      }
    }
  }
}

Okay, thank you about that

i have updated the code but now the countdown goes 2x faster when the buzzer beeps 2 times every second.

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>

const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {5, 6, 7, 8}; // Connect row pins of the keypad to digital pins 5, 6, 7, 8
byte colPins[COLS] = {9, 10, 11, 12}; // Connect to the column pinouts of the keypad

Keypad keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

int currentLength = 0;
char entered[4];
char password[4] = {'1',  '2', '3', '4'};
bool settingCode = true; // Flag to indicate code setting mode
String newCode = ""; // Variable to store the new code

LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address and dimensions

unsigned long previousMillis = 0;
unsigned long beepMillis = 0;
unsigned long beepDuration = 100; // Beep duration
unsigned long beepInterval = 1000; // Initial beep interval
int countdown = 61; // Initial countdown value in seconds

bool beeping = false; // To track whether the buzzer is currently on

void setup() {
  lcd.init(); // Initialize the LCD
  lcd.backlight(); // Turn on backlight
  lcd.setCursor(0, 0);
  lcd.print("Set Code:");

  pinMode(4, OUTPUT); // Set pin 4 as the buzzer pin
}

void loop() {
  unsigned long currentMillis = millis();

  if (settingCode) {
    char key = keypad.getKey();
    if (key != NO_KEY && currentLength < 4) {
      if (key == '#') {
        currentLength = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Code:");
      } else if (key != '*' && key != '#') {
        lcd.setCursor(currentLength, 1);
        lcd.print('*');
        newCode += key;
        currentLength++;
        tone(4, 500); // Play a quieter tone when a key is pressed during code setting
        delay(100);
        noTone(4); // Stop the tone after the delay
      }
    }

    if (currentLength == 4) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Code Set!");
      tone(4, 600); // Play a slightly louder tone to indicate code setting completion
      delay(500);
      noTone(4); // Stop the tone after the delay
      lcd.clear();
      lcd.print("Enter Code:");
      settingCode = false;
      currentLength = 0;

      // Start the timer
      previousMillis = millis();
    }
  } else {
    // Countdown Logic
    if (currentMillis - previousMillis >= 1000) {
      previousMillis = currentMillis;
      countdown--;

      lcd.setCursor(12, 0); // Set the cursor position for the timer display
      lcd.print("   "); // Clear previous timer value
      lcd.setCursor(12, 0);
      lcd.print(countdown);

      if (countdown == 0) {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Bomb Exploded");
        tone(4, 500);
        delay(2000);
        noTone(4);
      }

      // Adjust beep interval based on the countdown value
      if (countdown > 30) {
        beepInterval = 1000; // 1 beep per second
      } else if (countdown > 10) {
        beepInterval = 500;  // 2 beeps per second
      } else if (countdown > 5) {
        beepInterval = 250;  // 4 beeps per second
      } else if (countdown > 0) {
        beepInterval = 125;  // 8 beeps per second
      }
    }

    // Beeping Logic
    if (!beeping && currentMillis - beepMillis >= beepInterval) {
      beepMillis = currentMillis;
      tone(4, 500); // Start the beep
      beeping = true; // Set the beeping flag
    }

    if (beeping && currentMillis - beepMillis >= beepDuration) {
      noTone(4); // Stop the beep after the beep duration
      beeping = false; // Reset the beeping flag
    }

    // Code Entry Logic
    char key = keypad.getKey();
    if (key != NO_KEY && currentLength < 4) {
      if (key == '#') {
        currentLength = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Enter Code:");
      } else if (key != '*' && key != '#') {
        lcd.setCursor(currentLength, 1);
        lcd.print('*');
        entered[currentLength] = key;
        currentLength++;
        tone(4, 500); // Play a quieter tone when a key is pressed during code entry
        delay(100);
        noTone(4); // Stop the tone after the delay
      }
    }

    if (currentLength == 4) {
      if (entered[0] == newCode[0] && entered[1] == newCode[1] && entered[2] == newCode[2] && entered[3] == newCode[3]) {
        lcd.clear();
        lcd.print("Bomb Defused");
        tone(4, 700); // Play a slightly louder tone to indicate successful code entry
        delay(2500);
        noTone(4); // Stop the tone after the delay
        lcd.clear();
        settingCode = true;
        newCode = "";
        lcd.print("Set Code:");
        currentLength = 0;
        countdown = 61; // Reset the countdown timer
        beepInterval = 1000; // Reset the beep interval
      } else {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Wrong Password!");
        tone(4, 400); // Play a slightly louder tone to indicate wrong password
        delay(1500);
        noTone(4); // Stop the tone after the delay
        lcd.clear();
        lcd.print("Enter Code:");
        currentLength = 0;
        countdown -= 5; // Decrease the timer by 5 seconds for wrong password
        if (countdown < 0) countdown = 0; // Ensure the countdown doesn't go negative
        
        lcd.setCursor(12, 0); // Update the timer display on the LCD
        lcd.print(countdown); 
        lcd.print(" "); 

        if (countdown <= 10) {
          lcd.setCursor(1, 7);
          lcd.print("Code: ");
          lcd.print(newCode);
        }
      }
    }
  }
}

Here's the fully fixed code, anyone can use it for free :slight_smile:

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>

const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {5, 6, 7, 8}; // Connect row pins of the keypad to digital pins 5, 6, 7, 8
byte colPins[COLS] = {9, 10, 11, 12}; // Connect to the column pinouts of the keypad

Keypad keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

int currentLength = 0;
char entered[4];
String newCode = ""; // Variable to store the new code
bool settingCode = true; // Flag to indicate code setting mode

LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address and dimensions

unsigned long previousMillis = 0;
unsigned long beepMillis = 0;
const long interval = 1000; // Interval of 1 second
int countdown = 61; // Initial countdown value in seconds
int beepInterval = 1000; // Initial beep interval
const int beepDuration = 100; // Beep duration in milliseconds
bool beeping = false;

void setup() {
  lcd.init(); // Initialize the LCD
  lcd.backlight(); // Turn on backlight
  lcd.setCursor(0, 0);
  lcd.print("Set Code:");

  pinMode(4, OUTPUT); // Set pin 4 as the buzzer pin
}

void loop() {
  unsigned long currentMillis = millis();

  // Code Setting Logic
  if (settingCode) {
    char key = keypad.getKey();
    if (key != NO_KEY && currentLength < 4) {
      if (key == '#') {
        currentLength = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Code:");
      } else if (key != '*' && key != '#') {
        lcd.setCursor(currentLength, 1);
        lcd.print('*');
        newCode += key;
        currentLength++;
        tone(4, 500); // Play a quieter tone when a key is pressed during code setting
        delay(100);
        noTone(4); // Stop the tone after the delay
      }
    }

    if (currentLength == 4) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Code Set!");
      tone(4, 600); // Play a slightly louder tone to indicate code setting completion
      delay(500);
      noTone(4); // Stop the tone after the delay
      lcd.clear();
      lcd.print("Enter Code:");
      settingCode = false;
      currentLength = 0;

      // Start the timer
      previousMillis = millis();
    }
  } else {
    // Countdown Logic
    if (currentMillis - previousMillis >= 1000) {
      previousMillis = currentMillis;
      countdown--;

      lcd.setCursor(12, 0); // Set the cursor position for the timer display
      lcd.print("   "); // Clear previous timer value
      lcd.setCursor(12, 0);
      lcd.print(countdown);

      // Adjust beep interval based on the countdown value
      if (countdown > 45) {
        beepInterval = 1000; // 1 beep per second
      } else if (countdown > 30) {
        beepInterval = 500;  // 2 beeps per second
      } else if (countdown > 15) {
        beepInterval = 300;  // 4 beeps per second
      } else if (countdown > 5) {
        beepInterval = 150;  // 4 beeps per second
      } else if (countdown > 0) {
        beepInterval = 50;  // 8 beeps per second
      }
    }

    // Beeping Logic
    if (!beeping && currentMillis - beepMillis >= beepInterval) {
      beepMillis = currentMillis;
      tone(4, 500); // Start the beep
      beeping = true; // Set the beeping flag
    }

    if (beeping && currentMillis - beepMillis >= beepDuration) {
      noTone(4); // Stop the beep after the beep duration
      beeping = false; // Reset the beeping flag
    }

    // Code Entry Logic
    char key = keypad.getKey();
    if (key != NO_KEY && currentLength < 4) {
      if (key == '#') {
        currentLength = 0;
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Enter Code:");
      } else if (key != '*' && key != '#') {
        lcd.setCursor(currentLength, 1);
        lcd.print('*');
        entered[currentLength] = key;
        currentLength++;
        tone(4, 500); // Play a quieter tone when a key is pressed during code entry
        delay(100);
        noTone(4); // Stop the tone after the delay
      }
    }

    if (currentLength == 4) {
      if (entered[0] == newCode[0] && entered[1] == newCode[1] && entered[2] == newCode[2] && entered[3] == newCode[3]) {
        lcd.clear();
        lcd.print("Bomb Defused");
        tone(4, 700); // Play a slightly louder tone to indicate successful code entry
        delay(2500);
        noTone(4); // Stop the tone after the delay
        lcd.clear();
        settingCode = true;
        newCode = "";
        lcd.print("Set Code:");
        currentLength = 0;
        countdown = 61; // Reset the countdown timer
        beepInterval = 1000; // Reset the beep interval
      } else {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Wrong Password!");
        tone(4, 400); // Play a slightly louder tone to indicate wrong password
        delay(1500);
        noTone(4); // Stop the tone after the delay
        lcd.clear();
        lcd.print("Enter Code:");
        currentLength = 0;
        countdown -= 5; // Decrease the timer by 5 seconds for wrong password
        if (countdown < 0) countdown = 0; // Ensure the countdown doesn't go negative
        
        lcd.setCursor(12, 0); // Update the timer display on the LCD
        lcd.print(countdown); 
        lcd.print(" "); 

        if (countdown <= 10) {
          lcd.setCursor(1, 7);
          lcd.print("Code: ");
          lcd.print(newCode);
        if (countdown == 0) {
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Bomb Exploded");
          tone(4, 500);
          delay(2000);
          noTone(4);

          // Reset to "Set Code" state
          settingCode = true;
          newCode = ""; // Clear the previous code
          currentLength = 0;
          countdown = 61; // Reset the countdown timer
          beepInterval = 1000; // Reset the beep interval
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Set Code:");
        }
        }
      }
    }
  }
}

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