Single channel relay not turning off

First thanks for taking time to take a look.

I have made this to work with a single channel relay so that a buzzer with 12V battery is linked.
The battery links to the COM pin and the positive for the buzzer to the NO pin on the relay.
However I set it to turn off 5 seconds after deactivation, but it will not turn off.
See attached code and diagram
(For simulation only, the COM and negative for the relay are attached to the board)

Any ideas what is wrong?

// TM1637 - Version: Latest
#include <TM1637Display.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define BUTTON_START_PIN 2
#define BUTTON_SET_UP_PIN 3
#define BUTTON_SET_DOWN_PIN 4
#define BUZZER_PIN 7
#define RELAY_PIN 6 // Assuming the relay is connected to pin 6

// Initialize TM1637 module
#define CLK 9
#define DIO 8
const uint8_t SEG_COLON[] = { 0x00, 0x00, 0x2, 0x00 }; // The third element (0x2) represents the colon
TM1637Display display(CLK, DIO);

LiquidCrystal_I2C lcd(0x27, 16, 2);

unsigned long previousMillis = 0;
const long interval = 1000; // 1 second interval in milliseconds
unsigned long debounceDelay = 200; // Debounce delay in milliseconds

unsigned long lastDebounceTime = 0; // Initialize the last debounce time

int prepCountdownTimer = 0;
int settingPrepTime = 0; // initial setting time in seconds for prep timer
int gameCountdownTimer = 0;
int settingGameTime = 0; // initial setting time in seconds for game timer
bool settingPrep = false;
bool settingGame = false;
bool prepTimeFinished = false;
bool gameStarted = false;

void setup() {
  pinMode(BUTTON_START_PIN, INPUT_PULLUP);
  pinMode(BUTTON_SET_UP_PIN, INPUT_PULLUP);
  pinMode(BUTTON_SET_DOWN_PIN, INPUT_PULLUP);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW); // Ensure the relay is initially off

  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Prep Time: 0:00");

  // Setup TM1637 module
  display.setBrightness(0x0f);  // Set the brightness of the display
  display.showNumberDecEx(0, 0b1000000, true); // Clear the display
}

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

  if (!settingPrep && !settingGame) {
    handleSettingTime(settingPrepTime, prepCountdownTimer, "Prep Time: ", currentMillis);
  } else if (settingPrep && !settingGame) {
    handleSettingTime(settingGameTime, gameCountdownTimer, "Game Time: ", currentMillis);
  } else if (settingPrep && settingGame) {
    if (!prepTimeFinished) {
      handlePrepCountdown(currentMillis);
    } else {
      handleGameCountdown(currentMillis);
    }
  }
}

void handleSettingTime(int &settingTime, int &countdown, String title, unsigned long currentMillis) {
  if (digitalRead(BUTTON_SET_UP_PIN) == LOW && (currentMillis - lastDebounceTime) > debounceDelay) {
    lastDebounceTime = currentMillis;
    settingTime += 60; // Increase the time by one minute
    if (!settingGame) {
      displaySettingTime(settingTime, 0, title);
    } else {
      displaySettingTime(settingTime, 1, title);
    }
  }

  if (digitalRead(BUTTON_SET_DOWN_PIN) == LOW && settingTime >= 60 && (currentMillis - lastDebounceTime) > debounceDelay) {
    lastDebounceTime = currentMillis;
    settingTime -= 60; // Decrease the time by one minute
    if (!settingGame) {
      displaySettingTime(settingTime, 0, title);
    } else {
      displaySettingTime(settingTime, 1, title);
    }
  }

  if (digitalRead(BUTTON_START_PIN) == LOW && settingTime > 0) {
    if (!settingPrep) {
      settingPrep = true;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Prep Time: ");
      displaySettingTime(settingGameTime, 0, "Game Time: ");
    } else {
      settingGame = true;
      lcd.clear();
      lcd.print("Starting");
      delay(2000); // Delay in milliseconds
      lcd.clear();
      prepCountdownTimer = settingPrepTime;
    }
  }
}

void handlePrepCountdown(unsigned long currentMillis) {
  handleCountdownHelper(prepCountdownTimer, "Prep Time: ", currentMillis);

  if (prepCountdownTimer == 0) {
    prepTimeFinished = true;
    activateRelay(); // Activate the relay for the game buzzer
    lcd.clear();
    lcd.print("Game Started!");
    delay(2000); // Delay in milliseconds
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Game Time: ");
    displaySettingTime(settingGameTime, 1, "Game Time: ");
    gameCountdownTimer = settingGameTime;
  }
}

void handleGameCountdown(unsigned long currentMillis) {
  handleCountdownHelper(gameCountdownTimer, "Game Time: ", currentMillis);

  if (gameCountdownTimer == 0) {
    activateRelay(); // Activate the relay for the long buzzer
    lcd.clear();
    lcd.print("GAME OVER");
    while (true) {
      // Game over, do nothing
    }
  }
}

void handleCountdownHelper(int &countdown, String title, unsigned long currentMillis) {
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (countdown > 0) {
      if (countdown <= 10) {
        lastDebounceTime = true;
        digitalWrite(BUZZER_PIN, HIGH);
        delay(200); // Delay in milliseconds
        digitalWrite(BUZZER_PIN, LOW);
      } else {
        lastDebounceTime = false;
      }
      countdown--;
    }
    if (!settingGame) {
      displaySettingTime(countdown, 0, title);
    } else {
      displaySettingTime(countdown, 1, title);
    }
  }
}

void displaySettingTime(int time, int row, String title) {
  lcd.setCursor(0, row);
  lcd.print(title);
  lcd.print(time / 60);
  lcd.print(":");
  if ((time % 60) < 10) {
    lcd.print("0");
  }
  lcd.print(time % 60);

  // Display the time on the TM1637 module
  int displayTime = (time / 60) * 100 + (time % 60); // Convert time to a format supported by TM1637
  int colonPosition = 2; // Adjust this based on the position of the colon on your display
  display.setSegments(SEG_COLON, 1, colonPosition); // Display the colon at the specified position
  display.showNumberDecEx(displayTime, 0b11100000, false, 4, 0); // Show the time on the TM1637 display without the colon
}

void activateRelay() {
  digitalWrite(RELAY_PIN, HIGH); // Turn on the relay
}

void deactivateRelay() {
  digitalWrite(RELAY_PIN, LOW); // Turn off the relay
}

void longBuzzer() {
  activateRelay(); // Activate the relay for the long buzzer
  unsigned long buzzerStartTime = millis(); // Record the time when the buzzer starts
  while (millis() - buzzerStartTime < 5000) {
    // Wait for 5000 milliseconds
  }
  deactivateRelay(); // Deactivate the relay after buzzing
}

void startBuzzer() {
  activateRelay(); // Activate the relay for the start buzzer
  unsigned long buzzerStartTime = millis(); // Record the time when the buzzer starts
  while (millis() - buzzerStartTime < 3000) {
    // Wait for 3000 milliseconds
  }
  deactivateRelay(); // Deactivate the relay after buzzing
}

Use Serial.println on key variabels, and serial monitor, to show the status inside the code.

That is a bit beyond my ability.

What?

Instead of :-

void setup() {
  pinMode(BUTTON_START_PIN, INPUT_PULLUP);

Replace with

void setup() {
  Serial.begin(9600);
  delay(3000);

Then instead of:-

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

Use:-

void loop() {
 Serial.println("start of the loop function");
  unsigned long currentMillis = millis();

Repeat this for all the functions you want to track.

If this is truly beyond you, then so is your project.

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