need help to clear the code issue with alarm function of binary clock

Hello everyone. I'm Lucas, from lafabriquediy.com

I have already asked the person who wrote this code for assistance but he says he is busy. And I'm not sure if he will be helping me. So, I decided to ask it here too. The code length is over the allowed 9000 character limit. So, I will be pasting it in 3-4 pieces. And I will be attaching the arduino IDE ino file.

It is about a 24-hour, binary coded decimal clock with the alarm function. The clock is driven by Arduino Uno. It uses the DS3231 RTC module for timekeeping.

INTENDED CLOCK OPERATION:

The functions of the clock are controlled by 4 buttons:

  1. A push-button for setting Hours;
  2. A push-button for setting Minutes;
  3. A push-button for Alarm function;
  4. A normal button for Lights On/Off switch.

Clock behaviour:

  • Long pressing Alarm Button activates or deactivates the alarm. When alarm is activated, rows of LEDs light up in sequence from bottom to top and this is accompanied with rising piezo tones to indicate that alarm has just been activated/switched ON. The alarm deactivation effect is the opposite of this.

  • Long pressing hour and minute buttons together, switches the clock to Setting Mode. Within the setting mode, there are two modes:

  1. Alarm Time setting mode;
  2. Clock Time setting mode.

In Setting Mode, as you are setting time, the hours or minutes will blink depending on which one you have got selected.

You can move between Alarm Time Setting Mode and Clock Time Setting Mode by short pressing the Alarm Button. When you have finished setting alarm time and/or clock time, you long press hour and minute buttons again to store changes and exit to normal display mode.

Alarm sound: half-second beep followed by half-second pause, then 1 second beep followed by 1 second pause.

When the alarm goes off, all LEDs flash during the beeps and time is shown during the pauses. So, it creates a nice blinking effect that accompanies the alarm sound.

When the alarm is playing, pressing any of the push-buttons activates the Snooze Mode which lasts for 5 minutes after which the alarm is triggered again. You can Snooze as many times as you like. If you don't take any action, the alarm will switch itself OFF in 10 minutes.

When the Lights On/Off button is in Off position, all lights are turned OFF and all user inputs are disabled in order to keep the user from pressing buttons blindly. If alarm goes off, the light switch is ignored and time is shown for as long as alarm is active.

When the clock is powered off, the RTC module keeps track of time using the backup battery. Alarm time is stored in EEPROM, so the clock retains alarm time over power cycles.

THE PROBLEM:

-- When alarm starts playing, (goes off) it has been designed so that the owner can snooze it with pressing of any button. When snoozed, alarm should play again after 5 minutes. This is OK. Or the owner can switch alarm off by LongPressing Alarm button. Also is working fine.

But if alarm is let to run the scheduled 10 minutes without owner input, the alarm switches itself off automatically -- then, something happens in the system and if you make a new alarm time, and the alarm time is reached, alarm starts playing and switches itself OFF immediately within 2 seconds. Doesn't even allow the alarm to run. It is as if, it remembers to switch itself off immediately. Something is broken there. It only happens if alarm is let to run 10 minutes and switch itself off. Cycling the power to the clock, fixes that.

arduinoware_sketch.ino (27.2 KB)

Code Part 1.

// Store the alarm over power down.
#include <EEPROM.h>
#include <DS3231.h>

// Initiate the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

// Initiate a time-data structure
Time  t;

// Various settings.
#define BLINK_FREQUENCY 750    // in milliseconds, how fast the LEDs blink when setting hour/minute.
#define LONG_PRESS_TIME 500    // How long before a long press is deteceted, in milliseconds.
#define DEBOUNCE_DELAY 50      // How long to wait for debounce/rebound.
#define SNOOZE_TIME 300000     // How long to snooze - and start playing alarm again, unless switched off by long press on the alarm button.
#define BUTTON_REPEAT_TIME 200

//определим выводы светодиодов подключаемых к arduino
const byte leds[4][4] = {
  { -1, 11, -1,  3},
  { -1, 10,  6,  2},
  {13,  8,  5,  1},
  {12,  7,  4,  0}
};

//выводы кнопок
const byte buttonHourPin = A0;
const byte buttonMinutePin = A1;
const byte buttonAlarmPin = A2;
const byte buttonOnOffPin = A3;

byte buttons[3];
#define BUTTON_HOUR 0
#define BUTTON_MINUTE 1
#define BUTTON_ALARM 2

//вывод динамика
const byte speakerPin = 9;

// Default values for the alarm.
byte minuteAlarm = 0;
byte hourAlarm = 0;

// The various modes we can be in.
#define MODE_CLOCK 0
#define MODE_SET_ALARM 1
#define MODE_SET_CLOCK 2
#define MODE_ALARM 3
byte clockMode = MODE_CLOCK;

// The various status flags we have.
bool lightsOn = true;
bool alarmOn = false;
bool alarmSnoozed = false;
bool selectingMinute = false;
bool selectingHour = false;
bool blinkStatus = false;

// Button handling.
unsigned long buttonPressedTime[3];
byte buttonState[3];

#define BUTTON_UNPRESSED 0
#define BUTTON_DEBOUNCING 1
#define BUTTON_PRESSED 2
#define BUTTON_SHORTPRESSED 3
#define BUTTON_LONGPRESSED 4
#define BUTTON_HANDLED 5
#define BUTTON_LONGPRESS_REPEAT 6

// Various variables.
unsigned long blinkTime;
unsigned long alarmStartedTime;
unsigned long snoozedTime;
byte selectedHour;
byte selectedMinute;

// The special effects playing state.
byte effectsStage;
bool effectsPlaying = false;
bool playButtonPressEffects = false;
bool buttonPressEffectsPlaying = false;
bool playAlarmSwitchedOffEffects = false;
bool alarmSwitchedOffEffectsPlaying = false;
bool playAlarmSwitchedOnEffects = false;
bool alarmSwitchedOnEffectsPlaying = false;
bool playModeSetClockEffects = false;
bool modeSetClockEffectsPlaying = false;
bool playModeSetAlarmEffects = false;
bool modeSetAlarmEffectsPlaying = false;
bool playSnoozeOffEffects = false;
bool snoozeOffEffectsPlaying = false;
bool playFinishTimeSettingEffects = false;
bool finishTimeSettingEffectsPlaying = false;
bool playAlarm = false;
bool alarmPlaying = false;
unsigned int alarmRepeats = 0;
bool effectDisplayClock = false;
bool alarmJustSet = false;
uint32_t nextEffectMillis;

void setup()
{
  rtc.begin();

  //set outputs
  for (byte i = 0; i < 4; i++) {
    for (byte j = 0; j < 4; j++) {
      pinMode(leds[i][j], OUTPUT);
    }
  }

  pinMode(speakerPin, OUTPUT);
  allOn();
  delay(400);
  allOff();

  // Set buttons.
  buttons[BUTTON_HOUR] = buttonHourPin;
  buttons[BUTTON_MINUTE] = buttonMinutePin;
  buttons[BUTTON_ALARM] = buttonAlarmPin;
  for (byte i = 0; i < 3; i++) {
    pinMode(buttons[i], INPUT_PULLUP);
  }

  pinMode(buttonOnOffPin, INPUT_PULLUP);

  // Read the alarm from EEPROM.
  minuteAlarm = EEPROM.read(0);
  hourAlarm = EEPROM.read(1);
  if (minuteAlarm > 59) minuteAlarm = 0;
  if (hourAlarm > 23) hourAlarm = 0;

}

void displayClock()
{

  // Clock is displayed when:
  // - lightsOn and no special effects playing, or:
  // - while alarm is snoozed, or:
  // - when the special effects explicitly ask for it.
  //
  // Otherwise, the LEDs are switched off when:
  // - no special effects playing.

  t = rtc.getTime();
  byte hourClock = t.hour;
  byte minuteClock = t.min;
  byte secondClock = t.sec;

  // When it's time and alarms are switched on, start playing the alarm.
  if (alarmJustSet == false &&
      clockMode == MODE_CLOCK &&
      ((alarmPlaying == false && secondClock == 0 && minuteClock == minuteAlarm && hourClock == hourAlarm && alarmOn) ||
       (alarmSnoozed && millis() - snoozedTime > SNOOZE_TIME))) {
    playAlarm = true;  // Will be handled after all other effects have been switched off.
    alarmSnoozed = false;
    effectsPlaying = false;  // Make sure no other effects are playing.
    clockMode = MODE_ALARM;
  }

  if (secondClock > 0 && alarmJustSet) {
    alarmJustSet = false;
  }

  if ((lightsOn && effectsPlaying == false) ||
      alarmSnoozed ||
      effectDisplayClock) {

    int hourUnit, minuteUnit, hourTens, minuteTens;
    switch (clockMode) {
      case MODE_CLOCK:
      case MODE_ALARM:
        hourUnit = hourClock % 10;
        minuteUnit = minuteClock % 10;
        hourTens = int(hourClock / 10);
        minuteTens = int(minuteClock / 10);
        break;

      case MODE_SET_ALARM:
        hourUnit = hourAlarm % 10;
        minuteUnit = minuteAlarm % 10;
        hourTens = int(hourAlarm / 10);
        minuteTens = int(minuteAlarm / 10);
        break;

      case MODE_SET_CLOCK:
        hourUnit = selectedHour % 10;
        minuteUnit = selectedMinute % 10;
        hourTens = int(selectedHour / 10);
        minuteTens = int(selectedMinute / 10);
        break;
    }

    for (byte i = 0; i < 4; i++) {
      if (selectingMinute && (blinkStatus == false)) { // If we're selecting the minute, and blinkStatus is false, don't display the minutes.
        digitalWrite(leds[3 - i][3], 0);
        digitalWrite(leds[3 - i][2], 0);
      }
      else {
        digitalWrite(leds[3 - i][3], minuteUnit & (1 << i));
        digitalWrite(leds[3 - i][2], minuteTens & (1 << i));
      }
      if (selectingHour && (blinkStatus == false)) { // If we're selecting the hour, and blinkStatus is false, don't display the hours.
        digitalWrite(leds[3 - i][1], 0);
        digitalWrite(leds[3 - i][0], 0);
      }
      else {
        digitalWrite(leds[3 - i][1], hourUnit & (1 << i));
        digitalWrite(leds[3 - i][0], hourTens & (1 << i));
      }
    }
  }
  else if (effectsPlaying == false) {
    ledsOff();
  }
}

void readButtons()
{
  for (uint8_t i = 0; i < 3; i++) {                 // Handle the buttons.
    if (digitalRead(buttons[i]) == LOW) {
      switch (buttonState[i]) {
        case BUTTON_UNPRESSED:                      // Not debouncing or recorded press: start debounce delay.
          buttonState[i] = BUTTON_DEBOUNCING;
          buttonPressedTime[i] = millis();
          if (lightsOn) {
            playButtonPressEffects = true;
          }
          break;

Code Part 2.

case BUTTON_DEBOUNCING:                     // We're debouncing the button.
          if (millis() - buttonPressedTime[i] > DEBOUNCE_DELAY) {
            buttonState[i] = BUTTON_PRESSED;        // Debounce done: record actual press.
          }
          break;

        case BUTTON_PRESSED:                        // Button is pressed.
          // Check for a long press of this button.
          if (millis() - buttonPressedTime[i] > LONG_PRESS_TIME) {
            buttonState[i] = BUTTON_LONGPRESSED;
            buttonPressedTime[i] += LONG_PRESS_TIME;
          }
          break;

        case BUTTON_LONGPRESS_REPEAT:
          if (millis() - buttonPressedTime[i] > BUTTON_REPEAT_TIME) {
            buttonState[i] = BUTTON_LONGPRESSED;
            buttonPressedTime[i] += BUTTON_REPEAT_TIME;
          }
          break;
      }
    }
    else {  // Button not pressed.
      switch (buttonState[i]) {
        case BUTTON_PRESSED:
          buttonState[i] = BUTTON_SHORTPRESSED;
          break;

        default:
          buttonState[i] = BUTTON_UNPRESSED;
          break;
      }
    }

    // Do something useful with these button presses.
    switch (buttonState[i]) {
      case BUTTON_SHORTPRESSED:
        buttonState[i] = BUTTON_HANDLED; // Make sure the button press is handled once and once only.
        switch (clockMode) {
          case MODE_CLOCK:
            switch (i) {
              case BUTTON_MINUTE:
                break;

              case BUTTON_HOUR:
                break;

              case BUTTON_ALARM:
                break;
            }
            break;

          case MODE_SET_ALARM:
            switch (i) {
              case BUTTON_MINUTE:
                if (selectingMinute) {
                  minuteAlarm++;
                  if (minuteAlarm > 59) minuteAlarm = 0;
                }
                else {
                  selectingMinute = true;
                  selectingHour = false;
                }
                break;

              case BUTTON_HOUR:
                if (selectingHour) {
                  hourAlarm++;
                  if (hourAlarm > 23) hourAlarm = 0;
                }
                else {
                  selectingMinute = false;
                  selectingHour = true;
                }
                break;

              case BUTTON_ALARM:
                EEPROM.write(0, minuteAlarm);
                EEPROM.write(1, hourAlarm);
                clockMode = MODE_SET_CLOCK;
                playModeSetClockEffects = true;
                t = rtc.getTime();
                selectedHour = t.hour;
                selectedMinute = t.min;
                selectingHour = false;
                selectingMinute = true;
                break;
            }
            break;

          case MODE_SET_CLOCK:
            switch (i) {
              case BUTTON_MINUTE:
                if (selectingMinute) {
                  selectedMinute++;
                  if (selectedMinute > 59) selectedMinute = 0;
                }
                else {
                  selectingMinute = true;
                  selectingHour = false;
                }
                break;

              case BUTTON_HOUR:
                if (selectingHour) {
                  selectedHour++;
                  if (selectedHour > 23) selectedHour = 0;
                }
                else {
                  selectingMinute = false;
                  selectingHour = true;
                }
                break;

              case BUTTON_ALARM:
                rtc.setTime(selectedHour, selectedMinute, 0);
                clockMode = MODE_SET_ALARM;
                selectingHour = false;
                selectingMinute = true;
                playModeSetAlarmEffects = true;
                break;
            }
            break;

          case MODE_ALARM:
            switch (i) {
              case BUTTON_MINUTE:
                break;

              case BUTTON_HOUR:
                break;

              case BUTTON_ALARM:
                break;
            }
            break;
        }
        break;

      case BUTTON_LONGPRESSED:
        switch (clockMode) {
          case MODE_CLOCK:
            blinkTime = millis();
            blinkStatus = true;
            switch (i) {
              case BUTTON_MINUTE:   // Minute button long pressed in clock mode: if hour button also pressed, switch to alarm mode.
              case BUTTON_HOUR:   // Hour button long pressed in clock mode: if hour button also pressed, switch to alarm mode.
                if (lightsOn &&   // Ignore these buttons if lights are off.
                    (buttonState[BUTTON_HOUR] ==  BUTTON_DEBOUNCING ||
                     buttonState[BUTTON_HOUR] ==  BUTTON_PRESSED ||
                     buttonState[BUTTON_HOUR] ==  BUTTON_LONGPRESSED) &&
                    (buttonState[BUTTON_MINUTE] ==  BUTTON_DEBOUNCING ||
                     buttonState[BUTTON_MINUTE] ==  BUTTON_PRESSED ||
                     buttonState[BUTTON_MINUTE] ==  BUTTON_LONGPRESSED)) {

                  clockMode = MODE_SET_ALARM;
                  buttonState[BUTTON_MINUTE] = BUTTON_HANDLED;
                  buttonState[BUTTON_HOUR] = BUTTON_HANDLED;
                  playModeSetAlarmEffects = true;
                  selectingMinute = true;
                  selectingHour = false;
                  t = rtc.getTime();
                  selectedHour = t.hour;
                  selectedMinute = t.min;
                }
                break;

              case BUTTON_ALARM:  // Alarm button long pressed in clock mode: if snoozed, cancel snooze; otherwise toggle alarm on/off.
                if (alarmSnoozed) {
                  alarmSnoozed = false;
                  playSnoozeOffEffects = true;
                }
                else {
                  if (alarmOn) {
                    alarmOn = false;
                    playAlarmSwitchedOffEffects = true;
                  }
                  else {
                    alarmOn = true;
                    playAlarmSwitchedOnEffects = true;
                  }
                }
                buttonState[BUTTON_ALARM] = BUTTON_HANDLED;
                break;
            }
            break;

          case MODE_SET_ALARM:  // Long press of buttons in alarm mode.
            blinkTime = millis();
            blinkStatus = true;
            {
              bool finish = false;
              switch (i) {
                case BUTTON_MINUTE:  // Minute button long pressed in setting alarm mode: advance alarm minute; rate repeat.
                  if (buttonState[BUTTON_HOUR] ==  BUTTON_DEBOUNCING ||
                      buttonState[BUTTON_HOUR] ==  BUTTON_PRESSED ||
                      buttonState[BUTTON_HOUR] ==  BUTTON_LONGPRESSED) {
                    finish = true;
                  }
                  else if (selectingMinute) {
                    minuteAlarm++;
                    if (minuteAlarm > 59) minuteAlarm = 0;
                    buttonState[BUTTON_MINUTE] = BUTTON_LONGPRESS_REPEAT;
                  }
                  else {
                    selectingMinute = true;
                    selectingHour = false;
                    buttonState[BUTTON_MINUTE] = BUTTON_HANDLED;
                  }
                  break;

                case BUTTON_HOUR:  // Hour button long pressed in setting alarm mode: advance alarm hour; rate repeat.
                  if (buttonState[BUTTON_MINUTE] ==  BUTTON_DEBOUNCING ||
                      buttonState[BUTTON_MINUTE] ==  BUTTON_PRESSED ||
                      buttonState[BUTTON_MINUTE] ==  BUTTON_LONGPRESSED) {
                    finish = true;
                  }
                  else if (selectingHour) {
                    hourAlarm++;
                    if (hourAlarm > 23) hourAlarm = 0;
                    buttonState[BUTTON_HOUR] = BUTTON_LONGPRESS_REPEAT;
                  }
                  else {
                    selectingMinute = false;
                    selectingHour = true;
                    buttonState[BUTTON_HOUR] = BUTTON_HANDLED;
                  }
                  break;
              }

              if (finish) {
                doFinish();
              }
            }
            break;

Code Part 3.

case MODE_SET_CLOCK:
            {
              bool finish = false;
              switch (i) {
                case BUTTON_MINUTE:  // Minute button long pressed in setting alarm mode: advance alarm minute; rate repeat.
                  if (buttonState[BUTTON_HOUR] ==  BUTTON_DEBOUNCING ||
                      buttonState[BUTTON_HOUR] ==  BUTTON_PRESSED ||
                      buttonState[BUTTON_HOUR] ==  BUTTON_LONGPRESSED) {
                    finish = true;
                  }
                  else if (selectingMinute) {
                    selectedMinute++;
                    if (selectedMinute > 59) selectedMinute = 0;
                    buttonState[BUTTON_MINUTE] = BUTTON_LONGPRESS_REPEAT;
                  }
                  else {
                    selectingMinute = true;
                    selectingHour = false;
                    buttonState[BUTTON_MINUTE] = BUTTON_HANDLED;
                  }
                  break;

                case BUTTON_HOUR:  // Hour button long pressed in setting alarm mode: advance alarm hour; rate repeat.
                  if (buttonState[BUTTON_MINUTE] ==  BUTTON_DEBOUNCING ||
                      buttonState[BUTTON_MINUTE] ==  BUTTON_PRESSED ||
                      buttonState[BUTTON_MINUTE] ==  BUTTON_LONGPRESSED) {
                    finish = true;
                  }
                  else if (selectingHour) {
                    selectedHour++;
                    if (selectedHour > 23) selectedHour = 0;
                    buttonState[BUTTON_HOUR] = BUTTON_LONGPRESS_REPEAT;
                  }
                  else {
                    selectingMinute = false;
                    selectingHour = true;
                    buttonState[BUTTON_HOUR] = BUTTON_HANDLED;
                  }
                  break;
              }
              if (finish) {
                doFinish();
              }
            }
            break;
        }

      case BUTTON_PRESSED:
        switch (clockMode) {
          case MODE_SET_ALARM:
          case MODE_SET_CLOCK:
            blinkTime = millis();
            blinkStatus = true;
            break;

          case MODE_ALARM:
            effectsPlaying = false;
            alarmSnoozed = true;
            snoozedTime = millis();
            clockMode = MODE_CLOCK;
            break;
        }
        break;
    }
  }

  // Special case: this is a toggle button, not a push button. So it's simply on or off.
  if (digitalRead(buttonOnOffPin) == LOW) {
    lightsOn = true;
  }
  else {
    lightsOn = false;
  }
}

void doFinish() {
  rtc.setTime(selectedHour, selectedMinute, 0);
  EEPROM.write(0, minuteAlarm);
  EEPROM.write(1, hourAlarm);
  alarmJustSet = true;
  selectingMinute = false;
  selectingHour = false;
  clockMode = MODE_CLOCK;
  buttonState[BUTTON_MINUTE] = BUTTON_HANDLED;
  buttonState[BUTTON_HOUR] = BUTTON_HANDLED;
  playFinishTimeSettingEffects = true;
}

void setPattern(byte pattern[4]) {
  for (byte i = 0; i < 4; i++) {
    byte p = pattern[i];
    for (byte j = 0; j < 4; j++) {
      digitalWrite(leds[i][3 - j], p & (1 << j));
    }
  }
}

void ledsOff() {
  for (byte i = 0; i < 4; i++) {
    for (byte j = 0; j < 4; j++) {
      digitalWrite(leds[i][j], LOW);
    }
  }
}

void allOff() {
  ledsOff();
  noTone(speakerPin);
}

void ledsOn() {
  for (byte i = 0; i < 4; i++) {
    for (byte j = 0; j < 4; j++) {
      digitalWrite(leds[i][j], HIGH);
    }
  }
}

void allOn() {
  ledsOn();
  tone(speakerPin, 1865);
}

//главный цикл, вызов всех процедур
void loop() {
  displayClock();
  readButtons();
  specialEffects();
  if (millis() - blinkTime > BLINK_FREQUENCY) {
    blinkStatus = !blinkStatus;
    blinkTime = millis();
  }
  if (lightsOn == false &&
      (clockMode == MODE_SET_CLOCK || clockMode == MODE_SET_ALARM)) {
    clockMode = MODE_CLOCK;
    selectingMinute = false;
    selectingHour = false;
  }
}

void specialEffects() {

  // If we're not supposed to play any effects now - switch them all off.
  if (effectsPlaying == false) {
    alarmSwitchedOnEffectsPlaying = false;
    alarmSwitchedOffEffectsPlaying = false;
    modeSetClockEffectsPlaying = false;
    modeSetAlarmEffectsPlaying = false;
    snoozeOffEffectsPlaying = false;
    buttonPressEffectsPlaying = false;
    finishTimeSettingEffectsPlaying = false;
    effectDisplayClock = false;
    alarmPlaying = false;
    noTone(speakerPin);
  }

  if (playAlarmSwitchedOnEffects && effectsPlaying == false) {
    alarmSwitchedOnEffectsPlaying = true;
    effectsPlaying = true;
    effectsStage = 0;
    nextEffectMillis = millis();
    playAlarmSwitchedOnEffects = false;
  }

  if (alarmSwitchedOnEffectsPlaying && effectsPlaying) {
    if (millis() > nextEffectMillis) {
      effectsStage++;
      switch (effectsStage) {
        case 1:
          setPattern((const byte[4]) {
            0b0000,
            0b0000,
            0b0000,
            0b1111
          });
          tone(speakerPin, 1568);
          nextEffectMillis += 200;
          break;

        case 2:
          setPattern((const byte[4]) {
            0b0000,
            0b0000,
            0b1111,
            0b1111
          });
          tone(speakerPin, 1661);
          nextEffectMillis += 200;
          break;

        case 3:
          setPattern((const byte[4]) {
            0b0000,
            0b1111,
            0b1111,
            0b1111
          });
          tone(speakerPin, 1760);
          nextEffectMillis += 200;
          break;

        case 4:
          ledsOn();
          tone(speakerPin, 1865);
          nextEffectMillis += 500;
          break;

        case 5:
          allOff();
          nextEffectMillis += 100;
          break;

        default:
          alarmSwitchedOnEffectsPlaying = false;
          effectsPlaying = false;
      }
    }
  }

  if (playAlarmSwitchedOffEffects && effectsPlaying == false) {
    alarmSwitchedOffEffectsPlaying = true;
    effectsPlaying = true;
    effectsStage = 0;
    nextEffectMillis = millis();
    playAlarmSwitchedOffEffects = false;
  }

  if (alarmSwitchedOffEffectsPlaying && effectsPlaying) {
    if (millis() > nextEffectMillis) {
      effectsStage++;
      switch (effectsStage) {
        case 1:
          ledsOn();
          tone(speakerPin, 1865);
          nextEffectMillis += 200;
          break;

        case 2:
          setPattern((const byte[4]) {
            0b0000,
            0b1111,
            0b1111,
            0b1111
          });
          tone(speakerPin, 1760);
          nextEffectMillis += 200;
          break;

        case 3:
          setPattern((const byte[4]) {
            0b0000,
            0b0000,
            0b1111,
            0b1111
          });
          tone(speakerPin, 1661);
          nextEffectMillis += 200;
          break;

        case 4:
          setPattern((const byte[4]) {
            0b0000,
            0b0000,
            0b0000,
            0b1111
          });
          tone(speakerPin, 1568);
          nextEffectMillis += 200;
          break;

        case 5:
          allOff();
          nextEffectMillis += 100;
          break;

        default:
          alarmSwitchedOffEffectsPlaying = false;
          effectsPlaying = false;
      }
    }
  }

  if (playModeSetClockEffects && effectsPlaying == false) {
    modeSetClockEffectsPlaying = true;
    effectsPlaying = true;
    effectsStage = 0;
    nextEffectMillis = millis();
    playModeSetClockEffects = false;
  }

  if (modeSetClockEffectsPlaying && effectsPlaying) {
    if (millis() > nextEffectMillis) {
      effectsStage++;
      switch (effectsStage) {
        case 1:
          ledsOff();
          nextEffectMillis += 100;
          break;

        default:
          modeSetClockEffectsPlaying = false;
          effectsPlaying = false;
      }
    }
  }

Code Part 4.

if (playModeSetAlarmEffects && effectsPlaying == false) {
    modeSetAlarmEffectsPlaying = true;
    effectsPlaying = true;
    effectsStage = 0;
    nextEffectMillis = millis();
    playModeSetAlarmEffects = false;
  }

  if (modeSetAlarmEffectsPlaying && effectsPlaying) {
    if (millis() > nextEffectMillis) {
      effectsStage++;
      switch (effectsStage) {
        case 1:
          ledsOff();
          nextEffectMillis += 100;
          tone(speakerPin, 1865);
          break;

        case 2:
          effectDisplayClock = true;
          nextEffectMillis += 100;
          tone(speakerPin, 1865);
          break;

        default:
          noTone(speakerPin);
          effectDisplayClock = false;
          modeSetAlarmEffectsPlaying = false;
          effectsPlaying = false;
      }
    }
  }

  if (playAlarm) {
    alarmPlaying = true;
    effectsPlaying = true;
    effectsStage = 0;
    nextEffectMillis = millis();
    playAlarm = false;
  }

  if (alarmPlaying && effectsPlaying) {
    if (millis() > nextEffectMillis) {
      effectsStage++;
      switch (effectsStage) {
        case 1:
          effectDisplayClock = false;
          ledsOn();
          tone(speakerPin, 1865);
          nextEffectMillis += 500;
          break;

        case 2:
          effectDisplayClock = true;
          noTone(speakerPin);
          nextEffectMillis += 500;
          break;

        case 3:
          effectDisplayClock = false;
          ledsOn();
          tone(speakerPin, 1865);
          nextEffectMillis += 1000;
          break;

        case 4:
          noTone(speakerPin);
          effectDisplayClock = true;
          nextEffectMillis += 1000;
          alarmRepeats++;
          if (alarmRepeats < 200) {   // 3 seconds per sequence; 200x2 = 600 seconds = 10 minutes.
            effectsStage = 0;
          }
          break;

        default:
          alarmPlaying = false;
          effectDisplayClock = false;
          effectsPlaying = false;
          clockMode = MODE_CLOCK;
      }
    }
  }
  //
  //  if (playButtonPressEffects && effectsPlaying == false) {
  //    buttonPressEffectsPlaying = true;
  //    effectsPlaying = true;
  //    effectsStage = 0;
  //    nextEffectMillis = millis();
  //    playButtonPressEffects = false;
  //  }
  //
  //  if (buttonPressEffectsPlaying && effectsPlaying) {
  //    if (millis() > nextEffectMillis) {
  //      effectsStage++;
  //      switch (effectsStage) {
  //        case 1:
  //          break;
  //
  //        default:
  //          buttonPressEffectsPlaying = false;
  //          effectsPlaying = false;
  //      }
  //    }
  //  }

  if (playSnoozeOffEffects && effectsPlaying == false) {
    snoozeOffEffectsPlaying = true;
    effectsPlaying = true;
    effectsStage = 0;
    nextEffectMillis = millis();
    playSnoozeOffEffects = false;
  }

  if (snoozeOffEffectsPlaying && effectsPlaying) {
    if (millis() > nextEffectMillis) {
      effectsStage++;
      switch (effectsStage) {
        case 1:
          ledsOff();
          nextEffectMillis += 50;
          break;

        case 2:
          ledsOn();
          nextEffectMillis += 200;
          break;

        case 3:
          ledsOff();
          nextEffectMillis += 50;
          break;

        default:
          snoozeOffEffectsPlaying = false;
          effectsPlaying = false;
      }
    }
  }

  if (playFinishTimeSettingEffects && effectsPlaying == false) {
    finishTimeSettingEffectsPlaying = true;
    effectsPlaying = true;
    effectsStage = 0;
    nextEffectMillis = millis();
    playFinishTimeSettingEffects = false;
  }

  if (finishTimeSettingEffectsPlaying && effectsPlaying) {
    if (millis() > nextEffectMillis) {
      effectsStage++;
      byte pattern[4];
      switch (effectsStage) {
        case 1:
          ledsOn();
          nextEffectMillis += 500;
          break;

        case 2:
          pattern[0] = displayRow(3);
          pattern[1] = 0b1111;
          pattern[2] = 0b1111;
          pattern[3] = 0b1111;
          setPattern(pattern);
          nextEffectMillis += 200;
          break;

        case 3:
          pattern[0] = displayRow(3);
          pattern[1] = displayRow(2);
          pattern[2] = 0b1111;
          pattern[3] = 0b1111;
          setPattern(pattern);
          nextEffectMillis += 200;
          break;

        case 4:
          pattern[0] = displayRow(3);
          pattern[1] = displayRow(2);
          pattern[2] = displayRow(1);
          pattern[3] = 0b1111;
          setPattern(pattern);
          nextEffectMillis += 200;
          break;

        default:
          finishTimeSettingEffectsPlaying = false;
          effectsPlaying = false;
      }
    }
  }
}

byte displayRow(byte n) {
  byte hourUnit = selectedHour % 10;
  byte minuteUnit = selectedMinute % 10;
  byte hourTens = int(selectedHour / 10);
  byte minuteTens = int(selectedMinute / 10);
  byte row = 0;
  row |= (minuteUnit >> n) & 1;
  row |= ((minuteTens >> n) & 1) << 1;
  row |= ((hourUnit >> n) & 1) << 2;
  row |= ((hourTens >> n) & 1) << 3;
  return row;
}