60 LED WS2812 Clock using standalone ATMega328P

Hi all,
Looking for some help, pease.
I have recently built 4 of the 60 LED Neopixel clocks detailed in the following Youtube video -
[https://www.youtube.com/watch?v=hyZMtKf4GrI]
The clocks work fine, but I would like to add automatic nightime dimming of the clocks, using software. The guy in the video has manual dimming using a couple of diodes to reduce the supply voltage. I have not included the diodes in my build and have used a standalone ATMega328p chip, rather than a Nano, and changed the RTC to a DS1307 module, rather than a DS3231 module, as it has a smaller footprint.
My schematic is as follows: -
WS2812b analogue clock schematic.pdf (82.3 KB)
And the code used is this: -

// Add options for background settings
// TO DO: Clean up and comment code...
// BUG: demo state should start as mode 0 after intro
// NICE TO HAVE: When alarm is cancelled, the alarm still remains set for next day.

//Add the following libraries to the respective folder for you operating system. See http://arduino.cc/en/Guide/Environment
#include <FastLED.h>  // FastSPI Library from http://code.google.com/p/fastspi/
#include <Wire.h>     //This is to communicate via I2C. On arduino Uno & Nano use pins A4 for SDA (yellow/orange) and A5 for SCL (green). For other boards see http://arduino.cc/en/Reference/Wire
#include <RTClib.h>   // Include the RTClib library to enable communication with the real time clock.
#include <EEPROM.h>   // Include the EEPROM library to enable the storing and retrevel of settings.
#include <Bounce.h>   // Include the Bounce library for de-bouncing issues with push buttons.
#include <Encoder.h>  // Include the Encoder library to read the out puts of the rotary encoders

RTC_DS1307 RTC;  // Establishes the chipset of the Real Time Clock

#define LEDStripPin A0  // Pin used for the data to the LED strip
#define menuPin A3      // Pin used for the menu button (green stripe)
#define numLEDs 60      // Number of LEDs in strip

// Setting up the LED strip
struct CRGB leds[numLEDs];
Encoder rotary1(2, 3);  // Setting up the Rotary Encoder

DateTime old;  // Variable to compare new and old time, to see if it has moved on.
int rotary1Pos = 0;
int subSeconds;  // 60th's of a second
int secondBrightness;
int secondBrightness2;
int breathBrightness;
long newSecTime;  // Variable to record when a new second starts, allowing to create milli seconds
long oldSecTime;
long flashTime;  //
long breathCycleTime;
#define holdTime 1500
int cyclesPerSec;
float cyclesPerSecFloat;  // So can be used as a float in calcs
float fracOfSec;
float breathFracOfSec;
boolean demo;
#define demoTime 12  // seconds
long previousDemoTime;
long currentDemoTime;
boolean swingBack = false;

int timeHour;
int timeMin;
int timeSec;
int alarmMin;               // The minute of the alarm
int alarmHour;              // The hour of the alarm 0-23
int alarmDay = 0;           // The day of the alarm
boolean alarmSet;           // Whether the alarm is set or not
int modeAddress = 0;        // Address of where mode is stored in the EEPROM
int alarmMinAddress = 1;    // Address of where alarm minute is stored in the EEPROM
int alarmHourAddress = 2;   // Address of where alarm hour is stored in the EEPROM
int alarmSetAddress = 3;    // Address of where alarm state is stored in the EEPROM
int alarmModeAddress = 4;   // Address of where the alarm mode is stored in the EEPROM
boolean alarmTrig = false;  // Whether the alarm has been triggered or not
long alarmTrigTime;         // Milli seconds since the alarm was triggered
boolean countDown = false;
long countDownTime = 0;
long currentCountDown = 0;
long startCountDown;
int countDownMin;
int countDownSec;
int countDownFlash;
int demoIntro = 0;
int j = 0;
long timeInterval = 5;
long currentMillis;
long previousMillis = 0;
float LEDBrightness = 0;
float fadeTime;
float brightFadeRad;

int state = 0;  // Variable of the state of the clock, with the following defined states
#define clockState 0
#define alarmState 1
#define setAlarmHourState 2
#define setAlarmMinState 3
#define setClockHourState 4
#define setClockMinState 5
#define setClockSecState 6
#define countDownState 7
#define demoState 8
int mode;         // Variable of the display mode of the clock
int modeMax = 6;  // Change this when new modes are added. This is so selecting modes can go back beyond.
int alarmMode;    // Variable of the alarm display mode
int alarmModeMax = 3;

Bounce menuBouncer = Bounce(menuPin, 20);  // Instantiate a Bounce object with a 50 millisecond debounce time for the menu button
boolean menuButton = false;
boolean menuPressed = false;
boolean menuReleased = false;
int advanceMove = 0;
boolean countTime = false;
long menuTimePressed;
long lastRotary;
int rotaryTime = 1000;

int LEDPosition;
int reverseLEDPosition;
int pendulumPos;
int fiveMins;
int odd;
int LEDOffset = 30;

void setup() {
  // Set up all pins
  pinMode(menuPin, INPUT_PULLUP);  // Uses the internal 20k pull up resistor. Pre Arduino_v.1.0.1 need to be "digitalWrite(menuPin,HIGH);pinMode(menuPin,INPUT);"

  // Start LEDs
  LEDS.addLeds<WS2812, LEDStripPin, GRB>(leds, numLEDs);  // Structure of the LED data. I have changed to from rgb to grb, as using an alternative LED strip. Test & change these if you're getting different colours.

  // Start RTC
  Wire.begin();  // Starts the Wire library allows I2C communication to the Real Time Clock
  RTC.begin();   // Starts communications to the RTC

  Serial.begin(9600);  // Starts the serial communications

  // Uncomment to reset all the EEPROM addresses. You will have to comment again and reload, otherwise it will not save anything each time power is cycled
  // write a 0 to all 512 bytes of the EEPROM
  //  for (int i = 0; i < 512; i++)
  //  {EEPROM.write(i, 0);}

  // Load any saved setting since power off, such as mode & alarm time
  mode = EEPROM.read(modeAddress);            // The mode will be stored in the address "0" of the EEPROM
  alarmMin = EEPROM.read(alarmMinAddress);    // The mode will be stored in the address "1" of the EEPROM
  alarmHour = EEPROM.read(alarmHourAddress);  // The mode will be stored in the address "2" of the EEPROM
  alarmSet = EEPROM.read(alarmSetAddress);    // The mode will be stored in the address "2" of the EEPROM
  alarmMode = EEPROM.read(alarmModeAddress);
  // Prints all the saved EEPROM data to Serial
  Serial.print("Mode is ");
  Serial.println(mode);
  Serial.print("Alarm Hour is ");
  Serial.println(alarmHour);
  Serial.print("Alarm Min is ");
  Serial.println(alarmMin);
  Serial.print("Alarm is set ");
  Serial.println(alarmSet);
  Serial.print("Alarm Mode is ");
  Serial.println(alarmMode);

  // create a loop that calcuated the number of counted milliseconds between each second.
  DateTime now = RTC.now();
  //  startTime = millis();
  //  while (RTC.old() = RTC.new())

  //  if (now.month() == 1 && now.day() == 1 && now.hour() == 0 && now.minute() == 0 && now.minute() == 0)
  //    {}

  Serial.print("Hour time is... ");
  Serial.println(now.hour());
  Serial.print("Min time is... ");
  Serial.println(now.minute());
  Serial.print("Sec time is... ");
  Serial.println(now.second());

  Serial.print("Year is... ");
  Serial.println(now.year());
  Serial.print("Month is... ");
  Serial.println(now.month());
  Serial.print("Day is... ");
  Serial.println(now.day());
}


void loop() {
  DateTime now = RTC.now();  // Fetches the time from RTC

  // Check for any button presses and action accordingley
  menuButton = menuBouncer.update();  // Update the debouncer for the menu button and saves state to menuButton
  rotary1Pos = rotary1.read();        // Checks the rotary position
  if (rotary1Pos <= -2 && lastRotary - millis() >= rotaryTime) {
    advanceMove = -1;
    rotary1.write(0);
    lastRotary = millis();
  }
  if (rotary1Pos >= 2 && lastRotary - millis() >= rotaryTime) {
    advanceMove = 1;
    rotary1.write(0);
    lastRotary = millis();
  }
  if (menuButton == true || advanceMove != 0 || countTime == true) { buttonCheck(menuBouncer, now); }

  // clear LED array
  memset(leds, 0, numLEDs * 3);

  // Check alarm and trigger if the time matches
  if (alarmSet == true && alarmDay != now.day())  // The alarmDay statement ensures it is a newly set alarm or repeat from previous day, not within the minute of an alarm cancel.
  {
    if (alarmTrig == false) {
      alarm(now);
    } else {
      alarmDisplay();
    }
  }
  // Check the Countdown Timer
  if (countDown == true) {
    currentCountDown = countDownTime + startCountDown - now.unixtime();
    if (currentCountDown <= 0) {
      state = countDownState;
    }
  }
  // Set the time LED's
  if (state == setClockHourState || state == setClockMinState || state == setClockSecState) {
    setClockDisplay(now);
  } else if (state == alarmState || state == setAlarmHourState || state == setAlarmMinState) {
    setAlarmDisplay();
  } else if (state == countDownState) {
    countDownDisplay(now);
  } else if (state == demoState) {
    runDemo(now);
  } else {
    timeDisplay(now);
  }

  // Update LEDs
  LEDS.show();
}

void buttonCheck(Bounce menuBouncer, DateTime now) {
  if (menuBouncer.fallingEdge())  // Checks if a button is pressed, if so sets countTime to true
  {
    countTime = true;
    Serial.println("rising edge");
  }
  if (menuBouncer.risingEdge())  // Checks if a button is released,
  {
    countTime = false;
    Serial.println("rising edge");
  }               // if so sets countTime to false. Now the ...TimePressed will not be updated when enters the buttonCheck,
  if (countTime)  // otherwise will menuBouncer.duration will
  {
    menuTimePressed = menuBouncer.duration();
    if (menuTimePressed >= (holdTime - 100) && menuTimePressed <= holdTime) {
      clearLEDs();
      LEDS.show();
      delay(100);
    }
  }
  menuReleased = menuBouncer.risingEdge();
  if (menuPressed == true) { Serial.println("Menu Button Pressed"); }
  if (menuReleased == true) { Serial.println("Menu Button Released"); }
  Serial.print("Menu Bounce Duration ");
  Serial.println(menuTimePressed);
  if (alarmTrig == true) {
    alarmTrig = false;
    alarmDay = now.day();  // When the alarm is cancelled it will not display until next day. As without it, it would start again if within a minute, or completely turn off the alarm.
    delay(300);            // I added this 300ms delay, so there is time for the button to be released
    return;                // This return exits the buttonCheck function, so no actions are performs
  }
  switch (state) {
    case clockState:  // State 0
      if (advanceMove == -1 && mode == 0) {
        mode = modeMax;
        advanceMove = 0;
      } else if (advanceMove != 0)  //if displaying the clock, advance button is pressed & released, then mode will change
      {
        mode = mode + advanceMove;
        EEPROM.write(modeAddress, mode);
        advanceMove = 0;
      } else if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          state = alarmState;
          newSecTime = millis();
        }                                    // if displaying the clock, menu button is pressed & released, then Alarm is displayed
        else { state = setClockHourState; }  // if displaying the clock, menu button is held & released, then clock hour can be set
      }
      break;
    case alarmState:  // State 1
      if (advanceMove == -1 && alarmMode <= 0) {
        alarmMode = alarmModeMax;
        alarmSet = 1;
      } else if (advanceMove == 1 && alarmMode >= alarmModeMax) {
        alarmMode = 0;
        alarmSet = 0;
      } else if (advanceMove != 0) {
        alarmMode = alarmMode + advanceMove;
        if (alarmMode == 0) {
          alarmSet = 0;
        } else {
          alarmSet = 1;
        }
      }
      Serial.print("alarmState is ");
      Serial.println(alarmState);
      Serial.print("alarmMode is ");
      Serial.println(alarmMode);
      EEPROM.write(alarmSetAddress, alarmSet);
      EEPROM.write(alarmModeAddress, alarmMode);
      advanceMove = 0;
      alarmTrig = false;
      if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          state = countDownState;
          j = 0;
        }                                    // if displaying the alarm time, menu button is pressed & released, then clock is displayed
        else { state = setAlarmHourState; }  // if displaying the alarm time, menu button is held & released, then alarm hour can be set
      }
      break;
    case setAlarmHourState:  // State 2
      if (menuReleased == true) {
        state = setAlarmMinState;
      } else if (advanceMove == 1 && alarmHour >= 23) {
        alarmHour = 0;
      } else if (advanceMove == -1 && alarmHour <= 0) {
        alarmHour = 23;
      } else if (advanceMove != 0) {
        alarmHour = alarmHour + advanceMove;
      }
      EEPROM.write(alarmHourAddress, alarmHour);
      advanceMove = 0;
      break;
    case setAlarmMinState:  // State 3
      if (menuReleased == true) {
        state = alarmState;
        alarmDay = 0;
        newSecTime = millis();
      } else if (advanceMove == 1 && alarmMin >= 59) {
        alarmMin = 0;
      } else if (advanceMove == -1 && alarmMin <= 0) {
        alarmMin = 59;
      } else if (advanceMove != 0) {
        alarmMin = alarmMin + advanceMove;
      }
      EEPROM.write(alarmMinAddress, alarmMin);
      advanceMove = 0;
      break;
    case setClockHourState:  // State 4
      if (menuReleased == true) {
        state = setClockMinState;
      } else if (advanceMove == 1 && now.hour() == 23) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), 0, now.minute(), now.second()));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.hour() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), 23, now.minute(), now.second()));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), (now.hour() + advanceMove), now.minute(), now.second()));
        advanceMove = 0;
      }
      break;
    case setClockMinState:  // State 5
      if (menuReleased == true) {
        state = setClockSecState;
      } else if (advanceMove == 1 && now.minute() == 59) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 0, now.second()));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.minute() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 59, now.second()));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), (now.minute() + advanceMove), now.second()));
        advanceMove = 0;
      }
      break;
    case setClockSecState:  // State 6
      if (menuReleased == true) {
        state = clockState;
      } else if (advanceMove == 1 && now.second() == 59) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 0));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.second() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 59));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), (now.second() + advanceMove)));
        advanceMove = 0;
      }
      break;
    case countDownState:  // State 7
      if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          if (countDown == true && countDownTime <= 0) {
            countDown = false;
            countDownTime = 0;
            currentCountDown = 0;
          } else if (countDown == false && countDownTime > 0) {
            countDown = true;
            startCountDown = now.unixtime();
          } else {
            state = demoState;
            demoIntro = 1;
            j = 0;
          }  // if displaying the count down, menu button is pressed & released, then demo State is displayed
        } else {
          countDown = false;
          countDownTime = 0;
          currentCountDown = 0;
          j = 0;
        }  // if displaying the clock, menu button is held & released, then the count down is reset
      } else if (advanceMove == -1 && currentCountDown <= 0) {
        countDown = false;
        countDownTime = 0;
        currentCountDown = 0;
        demoIntro = 0;
      } else if (advanceMove == 1 && currentCountDown >= 3600) {
        countDown = false;
        countDownTime = 3600;
      } else if (advanceMove != 0)  //if displaying the count down, rotary encoder is turned then will change accordingley
      {
        countDown = false;
        countDownTime = currentCountDown - currentCountDown % 60 + advanceMove * 60;  // This rounds the count down minute up to the next minute
      }
      advanceMove = 0;
      break;
    case demoState:  // State 8
      if (menuReleased == true) {
        state = clockState;
        mode = EEPROM.read(modeAddress);
      }  // if displaying the demo, menu button pressed then the clock will display and restore to the mode before demo started
      break;
  }
  if (menuReleased || advanceMove != 0) { countTime = false; }
  Serial.print("Mode is ");
  Serial.println(mode);
  Serial.print("State is ");
  Serial.println(state);
}

void setAlarmDisplay() {

  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 100;
      leds[i].g = 100;
      leds[i].b = 100;
    }
  }

  if (alarmSet == 0) {
    for (int i = 0; i < numLEDs; i++)  // Sets background to red, to state that alarm IS NOT set
    {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = 20;
        leds[i].g = 0;
        leds[i].b = 0;
      }
    }
  } else {
    for (int i = 0; i < numLEDs; i++)  // Sets background to green, to state that alarm IS set
    {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = 0;
        leds[i].g = 20;
        leds[i].b = 0;
      }
    }
  }
  if (alarmHour <= 11) {
    leds[(alarmHour * 5 + LEDOffset) % 60].r = 255;
  } else {
    leds[((alarmHour - 12) * 5 + LEDOffset + 59) % 60].r = 25;
    leds[((alarmHour - 12) * 5 + LEDOffset) % 60].r = 255;
    leds[((alarmHour - 12) * 5 + LEDOffset + 1) % 60].r = 25;
  }
  leds[(alarmMin + LEDOffset) % 60].g = 100;
  flashTime = millis();
  if (state == setAlarmHourState && flashTime % 300 >= 150) {
    leds[(((alarmHour % 12) * 5) + LEDOffset + 59) % 60].r = 0;
    leds[(((alarmHour % 12) * 5) + LEDOffset) % 60].r = 0;
    leds[(((alarmHour % 12) * 5) + LEDOffset + 1) % 60].r = 0;
  }
  if (state == setAlarmMinState && flashTime % 300 >= 150) {
    leds[(alarmMin + LEDOffset) % 60].g = 0;
  }
  leds[(alarmMode + LEDOffset) % 60].b = 255;
}

void setClockDisplay(DateTime now) {
  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 10;
      leds[i].g = 10;
      leds[i].b = 10;
    }
  }
  if (now.hour() <= 11) {
    leds[(now.hour() * 5 + LEDOffset) % 60].r = 255;
  } else {
    leds[((now.hour() - 12) * 5 + LEDOffset + 59) % 60].r = 255;
    leds[((now.hour() - 12) * 5 + LEDOffset) % 60].r = 255;
    leds[((now.hour() - 12) * 5 + LEDOffset + 1) % 60].r = 255;
  }
  flashTime = millis();
  if (state == setClockHourState && flashTime % 300 >= 150) {
    leds[(((now.hour() % 12) * 5) + LEDOffset + 59) % 60].r = 0;
    leds[((now.hour() % 12) * 5 + LEDOffset) % 60].r = 0;
    leds[(((now.hour() % 12) * 5) + LEDOffset + 1) % 60].r = 0;
  }
  if (state == setClockMinState && flashTime % 300 >= 150) {
    leds[(now.minute() + LEDOffset) % 60].g = 0;
  } else {
    leds[(now.minute() + LEDOffset) % 60].g = 255;
  }
  if (state == setClockSecState && flashTime % 300 >= 150) {
    leds[(now.second() + LEDOffset) % 60].b = 0;
  } else {
    leds[(now.second() + LEDOffset) % 60].b = 255;
  }
}

// Check if alarm is active and if is it time for the alarm to trigger
void alarm(DateTime now) {
  if ((alarmMin == now.minute() % 60) && (alarmHour == now.hour() % 24))  //check if the time is the same to trigger alarm
  {
    alarmTrig = true;
    alarmTrigTime = millis();
  }
}

void alarmDisplay()  // Displays the alarm
{
  switch (alarmMode) {
    case 1:
      // set all LEDs to a dim white
      for (int i = 0; i < numLEDs; i++) {
        leds[i].r = 100;
        leds[i].g = 100;
        leds[i].b = 100;
      }
      break;
    case 2:
      LEDPosition = ((millis() - alarmTrigTime) / 300);
      reverseLEDPosition = 60 - LEDPosition;
      if (LEDPosition >= 0 && LEDPosition <= 29) {
        for (int i = 0; i < LEDPosition; i++) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31) {
        for (int i = 59; i > reverseLEDPosition; i--) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      if (LEDPosition >= 30) {
        for (int i = 0; i < numLEDs; i++) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      break;
    case 3:
      fadeTime = 60000;
      brightFadeRad = (millis() - alarmTrigTime) / fadeTime;  // Divided by the time period of the fade up.
      if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255;
      else LEDBrightness = 255.0 * (1.0 + sin((1.57 * brightFadeRad) - 1.57));
      Serial.println(brightFadeRad);
      Serial.println(LEDBrightness);
      for (int i = 0; i < numLEDs; i++) {
        leds[i].r = LEDBrightness;
        leds[i].g = LEDBrightness;
        leds[i].b = LEDBrightness;
      }
      break;

      // Currently not working
      //      case 4:
      //        fadeTime = 60000;
      //        brightFadeRad = (millis() - alarmTrigTime)/fadeTime; // Divided by the time period of the fade up.
      //        LEDPosition = ((millis() - alarmTrigTime)/(fadeTime/30));
      ////        if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255; // If the fade time is complete, then the LED brightness will be set to full.
      //        if (brightFadeRad <= 0) LEDBrightness = 0;
      //        else if (brightFadeRad >= 0) LEDBrightness = 1;
      //        else LEDBrightness = 255.0*(1.0+sin((1.57*brightFadeRad)-1.57));
      //
      ////        Serial.println(brightFadeRad);
      ////        Serial.println(LEDBrightness);
      //        reverseLEDPosition = 60 - LEDPosition;
      //        if (LEDPosition >= 0 && LEDPosition <= 29)
      //          {
      //            for (int i = 0; i < LEDPosition; i++)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31)
      //          {
      //            for (int i = 59; i > reverseLEDPosition; i--)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        if (LEDPosition >= 30)
      //          {
      //            for (int i = 0; i < numLEDs; i++)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        break;
  }
}

//
void countDownDisplay(DateTime now) {
  flashTime = millis();
  if (countDown == true) {
    currentCountDown = countDownTime + startCountDown - now.unixtime();
    if (currentCountDown > 0) {
      countDownMin = currentCountDown / 60;
      countDownSec = currentCountDown % 60 * 4;                                           // have multiplied by 4 to create brightness
      for (int i = 0; i < countDownMin; i++) { leds[(i + LEDOffset + 1) % 60].b = 240; }  // Set a blue LED for each complete minute that is remaining
      leds[(countDownMin + LEDOffset + 1) % 60].b = countDownSec;                         // Display the remaining secconds of the current minute as its brightness
    } else {
      countDownFlash = now.unixtime() % 2;
      if (countDownFlash == 0) {
        for (int i = 0; i < numLEDs; i++)  // Set the background as all off
        {
          leds[i].r = 0;
          leds[i].g = 0;
          leds[i].b = 0;
        }
      } else {
        for (int i = 0; i < numLEDs; i++)  // Set the background as all blue
        {
          leds[i].r = 0;
          leds[i].g = 0;
          leds[i].b = 255;
        }
      }
    }
  } else {
    currentCountDown = countDownTime;
    if (countDownTime == 0) {
      currentMillis = millis();
      clearLEDs();
      switch (demoIntro) {
        case 0:
          for (int i = 0; i < j; i++) { leds[(i + LEDOffset + 1) % 60].b = 20; }
          if (currentMillis - previousMillis > timeInterval) {
            j++;
            previousMillis = currentMillis;
          }
          if (j == numLEDs) { demoIntro = 1; }
          break;
        case 1:
          for (int i = 0; i < j; i++) { leds[(i + LEDOffset + 1) % 60].b = 20; }
          if (currentMillis - previousMillis > timeInterval) {
            j--;
            previousMillis = currentMillis;
          }
          if (j < 0) { demoIntro = 0; }
          break;
      }
    } else if (countDownTime > 0 && flashTime % 300 >= 150) {
      countDownMin = currentCountDown / 60;                                               //
      for (int i = 0; i < countDownMin; i++) { leds[(i + LEDOffset + 1) % 60].b = 255; }  // Set a blue LED for each complete minute that is remaining
    }
  }
}

void runDemo(DateTime now) {
  currentDemoTime = now.unixtime();
  currentMillis = millis();
  clearLEDs();
  switch (demoIntro) {
    case 0:
      timeDisplay(now);
      if (currentDemoTime - previousDemoTime > demoTime) {
        previousDemoTime = currentDemoTime;
        mode++;
      }
      break;
    case 1:
      for (int i = 0; i < j; i++) { leds[i].r = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 2:
      for (int i = j; i < numLEDs; i++) { leds[i].r = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 3:
      for (int i = 0; i < j; i++) { leds[i].g = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 4:
      for (int i = j; i < numLEDs; i++) { leds[i].g = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 5:
      for (int i = 0; i < j; i++) { leds[i].b = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 6:
      for (int i = j; i < numLEDs; i++) { leds[i].b = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 7:
      for (int i = 0; i < j; i++) {
        leds[i].r = 255;
        leds[i].g = 255;
        leds[i].b = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 8:
      for (int i = j; i < numLEDs; i++) {
        leds[i].r = 255;
        leds[i].g = 255;
        leds[i].b = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        demoIntro = 0;
        mode = 0;
        Serial.print("Mode is ");
        Serial.println(mode);
        Serial.print("State is ");
        Serial.println(state);
      }
      break;
  }
}

void clearLEDs() {
  for (int i = 0; i < numLEDs; i++)  // Set all the LEDs to off
  {
    leds[i].r = 0;
    leds[i].g = 0;
    leds[i].b = 0;
  }
}

void timeDisplay(DateTime now) {
  switch (mode) {
    case 0:
      minimalClock(now);
      break;
    case 1:
      basicClock(now);
      break;
    case 2:
      smoothSecond(now);
      break;
    case 3:
      outlineClock(now);
      break;
    case 4:
      minimalMilliSec(now);
      break;
    case 5:
      simplePendulum(now);
      break;
    case 6:
      breathingClock(now);
      break;
    default:  // Keep this here and add more timeDisplay modes as defined cases.
      {
        mode = 0;
      }
  }
}

////////////////////////////////////////////////////////////////////////////////////////////
//   CLOCK DISPLAY MODES
// Add any new display mode functions here. Then add to the "void timeDisplay(DateTime now)" function.
// Add each of the new display mode functions as a new "case", leaving default last.
////////////////////////////////////////////////////////////////////////////////////////////

//
void minimalClock(DateTime now) {
  unsigned char hourPos = (now.hour() % 12) * 5;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

//
void basicClock(DateTime now) {
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset + 59) % 60].g = 0;
  leds[(hourPos + LEDOffset + 59) % 60].b = 0;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].g = 0;
  leds[(hourPos + LEDOffset) % 60].b = 0;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].g = 0;
  leds[(hourPos + LEDOffset + 1) % 60].b = 0;
  leds[(now.minute() + LEDOffset) % 60].r = 0;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.minute() + LEDOffset) % 60].b = 0;
  leds[(now.second() + LEDOffset) % 60].r = 0;
  leds[(now.second() + LEDOffset) % 60].g = 0;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

//
void smoothSecond(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = millis() - newSecTime;
    cyclesPerSecFloat = (float)cyclesPerSec;
    newSecTime = millis();
  }
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime) / cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec) { secondBrightness = 50.0 * (1.0 + sin((3.14 * fracOfSec) - 1.57)); }
  if (subSeconds < cyclesPerSec) { secondBrightness2 = 50.0 * (1.0 + sin((3.14 * fracOfSec) + 1.57)); }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = secondBrightness;
  leds[(now.second() + LEDOffset + 59) % 60].b = secondBrightness2;
}

//
void outlineClock(DateTime now) {
  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 100;
      leds[i].g = 100;
      leds[i].b = 100;
    }
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}
//
void minimalMilliSec(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = (millis() - newSecTime);
    newSecTime = millis();
  }
  // set hour, min & sec LEDs
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  subSeconds = (((millis() - newSecTime) * 60) / cyclesPerSec) % 60;  // This divides by 733, but should be 1000 and not sure why???
  // Millisec lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(subSeconds + LEDOffset) % 60].r = 50;
  leds[(subSeconds + LEDOffset) % 60].g = 50;
  leds[(subSeconds + LEDOffset) % 60].b = 50;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

// Pendulum will be at the bottom and left for one second and right for one second
void simplePendulum(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = millis() - newSecTime;
    cyclesPerSecFloat = (float)cyclesPerSec;
    newSecTime = millis();
    if (swingBack == true) {
      swingBack = false;
    } else {
      swingBack = true;
    }
  }
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime) / cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec && swingBack == true) { pendulumPos = 27.0 + 3.4 * (1.0 + sin((3.14 * fracOfSec) - 1.57)); }
  if (subSeconds < cyclesPerSec && swingBack == false) { pendulumPos = 27.0 + 3.4 * (1.0 + sin((3.14 * fracOfSec) + 1.57)); }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  // Pendulum lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(pendulumPos + LEDOffset) % 60].r = 100;
  leds[(pendulumPos + LEDOffset) % 60].g = 100;
  leds[(pendulumPos + LEDOffset) % 60].b = 100;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

void breathingClock(DateTime now) {
  if (alarmTrig == false) {
    breathBrightness = 15.0 * (1.0 + sin((3.14 * millis() / 2000.0) - 1.57));
    for (int i = 0; i < numLEDs; i++) {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = breathBrightness + 5;
        leds[i].g = breathBrightness + 5;
        leds[i].b = breathBrightness + 5;
      } else {
        leds[i].r = 0;
        leds[i].g = 0;
        leds[i].b = 0;
      }
    }
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}


/*
// Cycle through the color wheel, equally spaced around the belt
void rainbowCycle(uint8_t wait)
{
  uint16_t i, j;
  for (j=0; j < 384 * 5; j++)
    {     // 5 cycles of all 384 colors in the wheel
      for (i=0; i < numLEDs; i++)
        {
          // tricky math! we use each pixel as a fraction of the full 384-color
          // wheel (thats the i / strip.numPixels() part)
          // Then add in j which makes the colors go around per pixel
          // the % 384 is to make the wheel cycle around
          strip.setPixelColor(i, Wheel(((i * 384 / numLEDs) + j) % 384));
        }
      delay(wait);
    }
}

//Input a value 0 to 384 to get a color value.
//The colours are a transition r - g - b - back to r

uint32_t Wheel(uint16_t WheelPos)
{
  byte r, g, b;
  switch(WheelPos / 128)
  {
    case 0:
      r = 127 - WheelPos % 128; // red down
      g = WheelPos % 128;       // green up
      b = 0;                    // blue off
      break;
    case 1:
      g = 127 - WheelPos % 128; // green down
      b = WheelPos % 128;       // blue up
      r = 0;                    // red off
      break;
    case 2:
      b = 127 - WheelPos % 128; // blue down
      r = WheelPos % 128;       // red up
      g = 0;                    // green off
      break;
  }
  return(strip.Color(r,g,b));
}
*/

I have found another version of the clock which does have automatic nightime dimming, but I don't like the clock faces and display as much as the original one.
The code for the one with automatic dimming is as follows: -

// Add options for background settings
// TO DO: Clean up and comment code...
// BUG: demo state should start as mode 0 after intro
// NICE TO HAVE: When alarm is cancelled, the alarm still remains set for next day.

//Add the following libraries to the respective folder for you operating system. See http://arduino.cc/en/Guide/Environment
#include <FastLED.h>  // FastSPI Library from http://code.google.com/p/fastspi/
#include <Wire.h>     //This is to communicate via I2C. On arduino Uno & Nano use pins A4 for SDA (yellow/orange) and A5 for SCL (green). For other boards see http://arduino.cc/en/Reference/Wire
#include <RTClib.h>   // Include the RTClib library to enable communication with the real time clock.
#include <EEPROM.h>   // Include the EEPROM library to enable the storing and retrevel of settings.
#include <Bounce.h>   // Include the Bounce library for de-bouncing issues with push buttons.
#include <Encoder.h>  // Include the Encoder library to read the out puts of the rotary encoders

RTC_DS1307 RTC;  // Establishes the chipset of the Real Time Clock

#define LEDStripPin A0  // Pin used for the data to the LED strip
#define menuPin A3      // Pin used for the menu button (green stripe)
#define numLEDs 60      // Number of LEDs in strip

// Setting up the LED strip
struct CRGB leds[numLEDs];
Encoder rotary1(2, 3);  // Setting up the Rotary Encoder

DateTime old;  // Variable to compare new and old time, to see if it has moved on.
int rotary1Pos = 0;
int subSeconds;  // 60th's of a second
int secondBrightness;
int secondBrightness2;
int breathBrightness;
long newSecTime;  // Variable to record when a new second starts, allowing to create milli seconds
long oldSecTime;
long flashTime;  //
long breathCycleTime;
#define holdTime 1500
int cyclesPerSec;
float cyclesPerSecFloat;  // So can be used as a float in calcs
float fracOfSec;
float breathFracOfSec;
boolean demo;
#define demoTime 12  // seconds
long previousDemoTime;
long currentDemoTime;
boolean swingBack = false;

int timeHour;
int timeMin;
int timeSec;
int alarmMin;               // The minute of the alarm
int alarmHour;              // The hour of the alarm 0-23
int alarmDay = 0;           // The day of the alarm
boolean alarmSet;           // Whether the alarm is set or not
int modeAddress = 0;        // Address of where mode is stored in the EEPROM
int alarmMinAddress = 1;    // Address of where alarm minute is stored in the EEPROM
int alarmHourAddress = 2;   // Address of where alarm hour is stored in the EEPROM
int alarmSetAddress = 3;    // Address of where alarm state is stored in the EEPROM
int alarmModeAddress = 4;   // Address of where the alarm mode is stored in the EEPROM
boolean alarmTrig = false;  // Whether the alarm has been triggered or not
long alarmTrigTime;         // Milli seconds since the alarm was triggered
boolean countDown = false;
long countDownTime = 0;
long currentCountDown = 0;
long startCountDown;
int countDownMin;
int countDownSec;
int countDownFlash;
int demoIntro = 0;
int j = 0;
long timeInterval = 5;
long currentMillis;
long previousMillis = 0;
float LEDBrightness = 0;
float fadeTime;
float brightFadeRad;

int state = 0;  // Variable of the state of the clock, with the following defined states
#define clockState 0
#define alarmState 1
#define setAlarmHourState 2
#define setAlarmMinState 3
#define setClockHourState 4
#define setClockMinState 5
#define setClockSecState 6
#define countDownState 7
#define demoState 8
int mode;         // Variable of the display mode of the clock
int modeMax = 6;  // Change this when new modes are added. This is so selecting modes can go back beyond.
int alarmMode;    // Variable of the alarm display mode
int alarmModeMax = 3;

Bounce menuBouncer = Bounce(menuPin, 20);  // Instantiate a Bounce object with a 50 millisecond debounce time for the menu button
boolean menuButton = false;
boolean menuPressed = false;
boolean menuReleased = false;
int advanceMove = 0;
boolean countTime = false;
long menuTimePressed;
long lastRotary;
int rotaryTime = 1000;

int LEDPosition;
int reverseLEDPosition;
int pendulumPos;
int fiveMins;
int odd;
int LEDOffset = 30;

void setup() {
  // Set up all pins
  pinMode(menuPin, INPUT_PULLUP);  // Uses the internal 20k pull up resistor. Pre Arduino_v.1.0.1 need to be "digitalWrite(menuPin,HIGH);pinMode(menuPin,INPUT);"

  // Start LEDs
  LEDS.addLeds<WS2812, LEDStripPin, GRB>(leds, numLEDs);  // Structure of the LED data. I have changed to from rgb to grb, as using an alternative LED strip. Test & change these if you're getting different colours.

  // Start RTC
  Wire.begin();  // Starts the Wire library allows I2C communication to the Real Time Clock
  RTC.begin();   // Starts communications to the RTC

  Serial.begin(9600);  // Starts the serial communications

  // Uncomment to reset all the EEPROM addresses. You will have to comment again and reload, otherwise it will not save anything each time power is cycled
  // write a 0 to all 512 bytes of the EEPROM
  //  for (int i = 0; i < 512; i++)
  //  {EEPROM.write(i, 0);}

  // Load any saved setting since power off, such as mode & alarm time
  mode = EEPROM.read(modeAddress);            // The mode will be stored in the address "0" of the EEPROM
  alarmMin = EEPROM.read(alarmMinAddress);    // The mode will be stored in the address "1" of the EEPROM
  alarmHour = EEPROM.read(alarmHourAddress);  // The mode will be stored in the address "2" of the EEPROM
  alarmSet = EEPROM.read(alarmSetAddress);    // The mode will be stored in the address "2" of the EEPROM
  alarmMode = EEPROM.read(alarmModeAddress);
  // Prints all the saved EEPROM data to Serial
  Serial.print("Mode is ");
  Serial.println(mode);
  Serial.print("Alarm Hour is ");
  Serial.println(alarmHour);
  Serial.print("Alarm Min is ");
  Serial.println(alarmMin);
  Serial.print("Alarm is set ");
  Serial.println(alarmSet);
  Serial.print("Alarm Mode is ");
  Serial.println(alarmMode);

  // create a loop that calcuated the number of counted milliseconds between each second.
  DateTime now = RTC.now();
  //  startTime = millis();
  //  while (RTC.old() = RTC.new())

  //  if (now.month() == 1 && now.day() == 1 && now.hour() == 0 && now.minute() == 0 && now.minute() == 0)
  //    {}

  Serial.print("Hour time is... ");
  Serial.println(now.hour());
  Serial.print("Min time is... ");
  Serial.println(now.minute());
  Serial.print("Sec time is... ");
  Serial.println(now.second());

  Serial.print("Year is... ");
  Serial.println(now.year());
  Serial.print("Month is... ");
  Serial.println(now.month());
  Serial.print("Day is... ");
  Serial.println(now.day());
}


void loop() {
  DateTime now = RTC.now();  // Fetches the time from RTC

  // Check for any button presses and action accordingley
  menuButton = menuBouncer.update();  // Update the debouncer for the menu button and saves state to menuButton
  rotary1Pos = rotary1.read();        // Checks the rotary position
  if (rotary1Pos <= -2 && lastRotary - millis() >= rotaryTime) {
    advanceMove = -1;
    rotary1.write(0);
    lastRotary = millis();
  }
  if (rotary1Pos >= 2 && lastRotary - millis() >= rotaryTime) {
    advanceMove = 1;
    rotary1.write(0);
    lastRotary = millis();
  }
  if (menuButton == true || advanceMove != 0 || countTime == true) { buttonCheck(menuBouncer, now); }

  // clear LED array
  memset(leds, 0, numLEDs * 3);

  // Check alarm and trigger if the time matches
  if (alarmSet == true && alarmDay != now.day())  // The alarmDay statement ensures it is a newly set alarm or repeat from previous day, not within the minute of an alarm cancel.
  {
    if (alarmTrig == false) {
      alarm(now);
    } else {
      alarmDisplay();
    }
  }
  // Check the Countdown Timer
  if (countDown == true) {
    currentCountDown = countDownTime + startCountDown - now.unixtime();
    if (currentCountDown <= 0) {
      state = countDownState;
    }
  }
  // Set the time LED's
  if (state == setClockHourState || state == setClockMinState || state == setClockSecState) {
    setClockDisplay(now);
  } else if (state == alarmState || state == setAlarmHourState || state == setAlarmMinState) {
    setAlarmDisplay();
  } else if (state == countDownState) {
    countDownDisplay(now);
  } else if (state == demoState) {
    runDemo(now);
  } else {
    timeDisplay(now);
  }

  // Update LEDs
  LEDS.show();
}

void buttonCheck(Bounce menuBouncer, DateTime now) {
  if (menuBouncer.fallingEdge())  // Checks if a button is pressed, if so sets countTime to true
  {
    countTime = true;
    Serial.println("rising edge");
  }
  if (menuBouncer.risingEdge())  // Checks if a button is released,
  {
    countTime = false;
    Serial.println("rising edge");
  }               // if so sets countTime to false. Now the ...TimePressed will not be updated when enters the buttonCheck,
  if (countTime)  // otherwise will menuBouncer.duration will
  {
    menuTimePressed = menuBouncer.duration();
    if (menuTimePressed >= (holdTime - 100) && menuTimePressed <= holdTime) {
      clearLEDs();
      LEDS.show();
      delay(100);
    }
  }
  menuReleased = menuBouncer.risingEdge();
  if (menuPressed == true) { Serial.println("Menu Button Pressed"); }
  if (menuReleased == true) { Serial.println("Menu Button Released"); }
  Serial.print("Menu Bounce Duration ");
  Serial.println(menuTimePressed);
  if (alarmTrig == true) {
    alarmTrig = false;
    alarmDay = now.day();  // When the alarm is cancelled it will not display until next day. As without it, it would start again if within a minute, or completely turn off the alarm.
    delay(300);            // I added this 300ms delay, so there is time for the button to be released
    return;                // This return exits the buttonCheck function, so no actions are performs
  }
  switch (state) {
    case clockState:  // State 0
      if (advanceMove == -1 && mode == 0) {
        mode = modeMax;
        advanceMove = 0;
      } else if (advanceMove != 0)  //if displaying the clock, advance button is pressed & released, then mode will change
      {
        mode = mode + advanceMove;
        EEPROM.write(modeAddress, mode);
        advanceMove = 0;
      } else if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          state = alarmState;
          newSecTime = millis();
        }                                    // if displaying the clock, menu button is pressed & released, then Alarm is displayed
        else { state = setClockHourState; }  // if displaying the clock, menu button is held & released, then clock hour can be set
      }
      break;
    case alarmState:  // State 1
      if (advanceMove == -1 && alarmMode <= 0) {
        alarmMode = alarmModeMax;
        alarmSet = 1;
      } else if (advanceMove == 1 && alarmMode >= alarmModeMax) {
        alarmMode = 0;
        alarmSet = 0;
      } else if (advanceMove != 0) {
        alarmMode = alarmMode + advanceMove;
        if (alarmMode == 0) {
          alarmSet = 0;
        } else {
          alarmSet = 1;
        }
      }
      Serial.print("alarmState is ");
      Serial.println(alarmState);
      Serial.print("alarmMode is ");
      Serial.println(alarmMode);
      EEPROM.write(alarmSetAddress, alarmSet);
      EEPROM.write(alarmModeAddress, alarmMode);
      advanceMove = 0;
      alarmTrig = false;
      if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          state = countDownState;
          j = 0;
        }                                    // if displaying the alarm time, menu button is pressed & released, then clock is displayed
        else { state = setAlarmHourState; }  // if displaying the alarm time, menu button is held & released, then alarm hour can be set
      }
      break;
    case setAlarmHourState:  // State 2
      if (menuReleased == true) {
        state = setAlarmMinState;
      } else if (advanceMove == 1 && alarmHour >= 23) {
        alarmHour = 0;
      } else if (advanceMove == -1 && alarmHour <= 0) {
        alarmHour = 23;
      } else if (advanceMove != 0) {
        alarmHour = alarmHour + advanceMove;
      }
      EEPROM.write(alarmHourAddress, alarmHour);
      advanceMove = 0;
      break;
    case setAlarmMinState:  // State 3
      if (menuReleased == true) {
        state = alarmState;
        alarmDay = 0;
        newSecTime = millis();
      } else if (advanceMove == 1 && alarmMin >= 59) {
        alarmMin = 0;
      } else if (advanceMove == -1 && alarmMin <= 0) {
        alarmMin = 59;
      } else if (advanceMove != 0) {
        alarmMin = alarmMin + advanceMove;
      }
      EEPROM.write(alarmMinAddress, alarmMin);
      advanceMove = 0;
      break;
    case setClockHourState:  // State 4
      if (menuReleased == true) {
        state = setClockMinState;
      } else if (advanceMove == 1 && now.hour() == 23) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), 0, now.minute(), now.second()));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.hour() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), 23, now.minute(), now.second()));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), (now.hour() + advanceMove), now.minute(), now.second()));
        advanceMove = 0;
      }
      break;
    case setClockMinState:  // State 5
      if (menuReleased == true) {
        state = setClockSecState;
      } else if (advanceMove == 1 && now.minute() == 59) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 0, now.second()));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.minute() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 59, now.second()));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), (now.minute() + advanceMove), now.second()));
        advanceMove = 0;
      }
      break;
    case setClockSecState:  // State 6
      if (menuReleased == true) {
        state = clockState;
      } else if (advanceMove == 1 && now.second() == 59) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 0));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.second() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 59));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), (now.second() + advanceMove)));
        advanceMove = 0;
      }
      break;
    case countDownState:  // State 7
      if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          if (countDown == true && countDownTime <= 0) {
            countDown = false;
            countDownTime = 0;
            currentCountDown = 0;
          } else if (countDown == false && countDownTime > 0) {
            countDown = true;
            startCountDown = now.unixtime();
          } else {
            state = demoState;
            demoIntro = 1;
            j = 0;
          }  // if displaying the count down, menu button is pressed & released, then demo State is displayed
        } else {
          countDown = false;
          countDownTime = 0;
          currentCountDown = 0;
          j = 0;
        }  // if displaying the clock, menu button is held & released, then the count down is reset
      } else if (advanceMove == -1 && currentCountDown <= 0) {
        countDown = false;
        countDownTime = 0;
        currentCountDown = 0;
        demoIntro = 0;
      } else if (advanceMove == 1 && currentCountDown >= 3600) {
        countDown = false;
        countDownTime = 3600;
      } else if (advanceMove != 0)  //if displaying the count down, rotary encoder is turned then will change accordingley
      {
        countDown = false;
        countDownTime = currentCountDown - currentCountDown % 60 + advanceMove * 60;  // This rounds the count down minute up to the next minute
      }
      advanceMove = 0;
      break;
    case demoState:  // State 8
      if (menuReleased == true) {
        state = clockState;
        mode = EEPROM.read(modeAddress);
      }  // if displaying the demo, menu button pressed then the clock will display and restore to the mode before demo started
      break;
  }
  if (menuReleased || advanceMove != 0) { countTime = false; }
  Serial.print("Mode is ");
  Serial.println(mode);
  Serial.print("State is ");
  Serial.println(state);
}

void setAlarmDisplay() {

  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 100;
      leds[i].g = 100;
      leds[i].b = 100;
    }
  }

  if (alarmSet == 0) {
    for (int i = 0; i < numLEDs; i++)  // Sets background to red, to state that alarm IS NOT set
    {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = 20;
        leds[i].g = 0;
        leds[i].b = 0;
      }
    }
  } else {
    for (int i = 0; i < numLEDs; i++)  // Sets background to green, to state that alarm IS set
    {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = 0;
        leds[i].g = 20;
        leds[i].b = 0;
      }
    }
  }
  if (alarmHour <= 11) {
    leds[(alarmHour * 5 + LEDOffset) % 60].r = 255;
  } else {
    leds[((alarmHour - 12) * 5 + LEDOffset + 59) % 60].r = 25;
    leds[((alarmHour - 12) * 5 + LEDOffset) % 60].r = 255;
    leds[((alarmHour - 12) * 5 + LEDOffset + 1) % 60].r = 25;
  }
  leds[(alarmMin + LEDOffset) % 60].g = 100;
  flashTime = millis();
  if (state == setAlarmHourState && flashTime % 300 >= 150) {
    leds[(((alarmHour % 12) * 5) + LEDOffset + 59) % 60].r = 0;
    leds[(((alarmHour % 12) * 5) + LEDOffset) % 60].r = 0;
    leds[(((alarmHour % 12) * 5) + LEDOffset + 1) % 60].r = 0;
  }
  if (state == setAlarmMinState && flashTime % 300 >= 150) {
    leds[(alarmMin + LEDOffset) % 60].g = 0;
  }
  leds[(alarmMode + LEDOffset) % 60].b = 255;
}

void setClockDisplay(DateTime now) {
  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 10;
      leds[i].g = 10;
      leds[i].b = 10;
    }
  }
  if (now.hour() <= 11) {
    leds[(now.hour() * 5 + LEDOffset) % 60].r = 255;
  } else {
    leds[((now.hour() - 12) * 5 + LEDOffset + 59) % 60].r = 255;
    leds[((now.hour() - 12) * 5 + LEDOffset) % 60].r = 255;
    leds[((now.hour() - 12) * 5 + LEDOffset + 1) % 60].r = 255;
  }
  flashTime = millis();
  if (state == setClockHourState && flashTime % 300 >= 150) {
    leds[(((now.hour() % 12) * 5) + LEDOffset + 59) % 60].r = 0;
    leds[((now.hour() % 12) * 5 + LEDOffset) % 60].r = 0;
    leds[(((now.hour() % 12) * 5) + LEDOffset + 1) % 60].r = 0;
  }
  if (state == setClockMinState && flashTime % 300 >= 150) {
    leds[(now.minute() + LEDOffset) % 60].g = 0;
  } else {
    leds[(now.minute() + LEDOffset) % 60].g = 255;
  }
  if (state == setClockSecState && flashTime % 300 >= 150) {
    leds[(now.second() + LEDOffset) % 60].b = 0;
  } else {
    leds[(now.second() + LEDOffset) % 60].b = 255;
  }
}

// Check if alarm is active and if is it time for the alarm to trigger
void alarm(DateTime now) {
  if ((alarmMin == now.minute() % 60) && (alarmHour == now.hour() % 24))  //check if the time is the same to trigger alarm
  {
    alarmTrig = true;
    alarmTrigTime = millis();
  }
}

void alarmDisplay()  // Displays the alarm
{
  switch (alarmMode) {
    case 1:
      // set all LEDs to a dim white
      for (int i = 0; i < numLEDs; i++) {
        leds[i].r = 100;
        leds[i].g = 100;
        leds[i].b = 100;
      }
      break;
    case 2:
      LEDPosition = ((millis() - alarmTrigTime) / 300);
      reverseLEDPosition = 60 - LEDPosition;
      if (LEDPosition >= 0 && LEDPosition <= 29) {
        for (int i = 0; i < LEDPosition; i++) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31) {
        for (int i = 59; i > reverseLEDPosition; i--) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      if (LEDPosition >= 30) {
        for (int i = 0; i < numLEDs; i++) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      break;
    case 3:
      fadeTime = 60000;
      brightFadeRad = (millis() - alarmTrigTime) / fadeTime;  // Divided by the time period of the fade up.
      if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255;
      else LEDBrightness = 255.0 * (1.0 + sin((1.57 * brightFadeRad) - 1.57));
      Serial.println(brightFadeRad);
      Serial.println(LEDBrightness);
      for (int i = 0; i < numLEDs; i++) {
        leds[i].r = LEDBrightness;
        leds[i].g = LEDBrightness;
        leds[i].b = LEDBrightness;
      }
      break;

      // Currently not working
      //      case 4:
      //        fadeTime = 60000;
      //        brightFadeRad = (millis() - alarmTrigTime)/fadeTime; // Divided by the time period of the fade up.
      //        LEDPosition = ((millis() - alarmTrigTime)/(fadeTime/30));
      ////        if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255; // If the fade time is complete, then the LED brightness will be set to full.
      //        if (brightFadeRad <= 0) LEDBrightness = 0;
      //        else if (brightFadeRad >= 0) LEDBrightness = 1;
      //        else LEDBrightness = 255.0*(1.0+sin((1.57*brightFadeRad)-1.57));
      //
      ////        Serial.println(brightFadeRad);
      ////        Serial.println(LEDBrightness);
      //        reverseLEDPosition = 60 - LEDPosition;
      //        if (LEDPosition >= 0 && LEDPosition <= 29)
      //          {
      //            for (int i = 0; i < LEDPosition; i++)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31)
      //          {
      //            for (int i = 59; i > reverseLEDPosition; i--)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        if (LEDPosition >= 30)
      //          {
      //            for (int i = 0; i < numLEDs; i++)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        break;
  }
}

//
void countDownDisplay(DateTime now) {
  flashTime = millis();
  if (countDown == true) {
    currentCountDown = countDownTime + startCountDown - now.unixtime();
    if (currentCountDown > 0) {
      countDownMin = currentCountDown / 60;
      countDownSec = currentCountDown % 60 * 4;                                           // have multiplied by 4 to create brightness
      for (int i = 0; i < countDownMin; i++) { leds[(i + LEDOffset + 1) % 60].b = 240; }  // Set a blue LED for each complete minute that is remaining
      leds[(countDownMin + LEDOffset + 1) % 60].b = countDownSec;                         // Display the remaining secconds of the current minute as its brightness
    } else {
      countDownFlash = now.unixtime() % 2;
      if (countDownFlash == 0) {
        for (int i = 0; i < numLEDs; i++)  // Set the background as all off
        {
          leds[i].r = 0;
          leds[i].g = 0;
          leds[i].b = 0;
        }
      } else {
        for (int i = 0; i < numLEDs; i++)  // Set the background as all blue
        {
          leds[i].r = 0;
          leds[i].g = 0;
          leds[i].b = 255;
        }
      }
    }
  } else {
    currentCountDown = countDownTime;
    if (countDownTime == 0) {
      currentMillis = millis();
      clearLEDs();
      switch (demoIntro) {
        case 0:
          for (int i = 0; i < j; i++) { leds[(i + LEDOffset + 1) % 60].b = 20; }
          if (currentMillis - previousMillis > timeInterval) {
            j++;
            previousMillis = currentMillis;
          }
          if (j == numLEDs) { demoIntro = 1; }
          break;
        case 1:
          for (int i = 0; i < j; i++) { leds[(i + LEDOffset + 1) % 60].b = 20; }
          if (currentMillis - previousMillis > timeInterval) {
            j--;
            previousMillis = currentMillis;
          }
          if (j < 0) { demoIntro = 0; }
          break;
      }
    } else if (countDownTime > 0 && flashTime % 300 >= 150) {
      countDownMin = currentCountDown / 60;                                               //
      for (int i = 0; i < countDownMin; i++) { leds[(i + LEDOffset + 1) % 60].b = 255; }  // Set a blue LED for each complete minute that is remaining
    }
  }
}

void runDemo(DateTime now) {
  currentDemoTime = now.unixtime();
  currentMillis = millis();
  clearLEDs();
  switch (demoIntro) {
    case 0:
      timeDisplay(now);
      if (currentDemoTime - previousDemoTime > demoTime) {
        previousDemoTime = currentDemoTime;
        mode++;
      }
      break;
    case 1:
      for (int i = 0; i < j; i++) { leds[i].r = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 2:
      for (int i = j; i < numLEDs; i++) { leds[i].r = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 3:
      for (int i = 0; i < j; i++) { leds[i].g = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 4:
      for (int i = j; i < numLEDs; i++) { leds[i].g = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 5:
      for (int i = 0; i < j; i++) { leds[i].b = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 6:
      for (int i = j; i < numLEDs; i++) { leds[i].b = 255; }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 7:
      for (int i = 0; i < j; i++) {
        leds[i].r = 255;
        leds[i].g = 255;
        leds[i].b = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 8:
      for (int i = j; i < numLEDs; i++) {
        leds[i].r = 255;
        leds[i].g = 255;
        leds[i].b = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        demoIntro = 0;
        mode = 0;
        Serial.print("Mode is ");
        Serial.println(mode);
        Serial.print("State is ");
        Serial.println(state);
      }
      break;
  }
}

void clearLEDs() {
  for (int i = 0; i < numLEDs; i++)  // Set all the LEDs to off
  {
    leds[i].r = 0;
    leds[i].g = 0;
    leds[i].b = 0;
  }
}

void timeDisplay(DateTime now) {
  switch (mode) {
    case 0:
      minimalClock(now);
      break;
    case 1:
      basicClock(now);
      break;
    case 2:
      smoothSecond(now);
      break;
    case 3:
      outlineClock(now);
      break;
    case 4:
      minimalMilliSec(now);
      break;
    case 5:
      simplePendulum(now);
      break;
    case 6:
      breathingClock(now);
      break;
    default:  // Keep this here and add more timeDisplay modes as defined cases.
      {
        mode = 0;
      }
  }
}

////////////////////////////////////////////////////////////////////////////////////////////
//   CLOCK DISPLAY MODES
// Add any new display mode functions here. Then add to the "void timeDisplay(DateTime now)" function.
// Add each of the new display mode functions as a new "case", leaving default last.
////////////////////////////////////////////////////////////////////////////////////////////

//
void minimalClock(DateTime now) {
  unsigned char hourPos = (now.hour() % 12) * 5;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

//
void basicClock(DateTime now) {
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset + 59) % 60].g = 0;
  leds[(hourPos + LEDOffset + 59) % 60].b = 0;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].g = 0;
  leds[(hourPos + LEDOffset) % 60].b = 0;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].g = 0;
  leds[(hourPos + LEDOffset + 1) % 60].b = 0;
  leds[(now.minute() + LEDOffset) % 60].r = 0;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.minute() + LEDOffset) % 60].b = 0;
  leds[(now.second() + LEDOffset) % 60].r = 0;
  leds[(now.second() + LEDOffset) % 60].g = 0;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

//
void smoothSecond(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = millis() - newSecTime;
    cyclesPerSecFloat = (float)cyclesPerSec;
    newSecTime = millis();
  }
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime) / cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec) { secondBrightness = 50.0 * (1.0 + sin((3.14 * fracOfSec) - 1.57)); }
  if (subSeconds < cyclesPerSec) { secondBrightness2 = 50.0 * (1.0 + sin((3.14 * fracOfSec) + 1.57)); }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = secondBrightness;
  leds[(now.second() + LEDOffset + 59) % 60].b = secondBrightness2;
}

//
void outlineClock(DateTime now) {
  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 100;
      leds[i].g = 100;
      leds[i].b = 100;
    }
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}
//
void minimalMilliSec(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = (millis() - newSecTime);
    newSecTime = millis();
  }
  // set hour, min & sec LEDs
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  subSeconds = (((millis() - newSecTime) * 60) / cyclesPerSec) % 60;  // This divides by 733, but should be 1000 and not sure why???
  // Millisec lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(subSeconds + LEDOffset) % 60].r = 50;
  leds[(subSeconds + LEDOffset) % 60].g = 50;
  leds[(subSeconds + LEDOffset) % 60].b = 50;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

// Pendulum will be at the bottom and left for one second and right for one second
void simplePendulum(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = millis() - newSecTime;
    cyclesPerSecFloat = (float)cyclesPerSec;
    newSecTime = millis();
    if (swingBack == true) {
      swingBack = false;
    } else {
      swingBack = true;
    }
  }
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime) / cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec && swingBack == true) { pendulumPos = 27.0 + 3.4 * (1.0 + sin((3.14 * fracOfSec) - 1.57)); }
  if (subSeconds < cyclesPerSec && swingBack == false) { pendulumPos = 27.0 + 3.4 * (1.0 + sin((3.14 * fracOfSec) + 1.57)); }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  // Pendulum lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(pendulumPos + LEDOffset) % 60].r = 100;
  leds[(pendulumPos + LEDOffset) % 60].g = 100;
  leds[(pendulumPos + LEDOffset) % 60].b = 100;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

void breathingClock(DateTime now) {
  if (alarmTrig == false) {
    breathBrightness = 15.0 * (1.0 + sin((3.14 * millis() / 2000.0) - 1.57));
    for (int i = 0; i < numLEDs; i++) {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = breathBrightness + 5;
        leds[i].g = breathBrightness + 5;
        leds[i].b = breathBrightness + 5;
      } else {
        leds[i].r = 0;
        leds[i].g = 0;
        leds[i].b = 0;
      }
    }
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}


/*
// Cycle through the color wheel, equally spaced around the belt
void rainbowCycle(uint8_t wait)
{
  uint16_t i, j;
  for (j=0; j < 384 * 5; j++)
    {     // 5 cycles of all 384 colors in the wheel
      for (i=0; i < numLEDs; i++)
        {
          // tricky math! we use each pixel as a fraction of the full 384-color
          // wheel (thats the i / strip.numPixels() part)
          // Then add in j which makes the colors go around per pixel
          // the % 384 is to make the wheel cycle around
          strip.setPixelColor(i, Wheel(((i * 384 / numLEDs) + j) % 384));
        }
      delay(wait);
    }
}

//Input a value 0 to 384 to get a color value.
//The colours are a transition r - g - b - back to r

uint32_t Wheel(uint16_t WheelPos)
{
  byte r, g, b;
  switch(WheelPos / 128)
  {
    case 0:
      r = 127 - WheelPos % 128; // red down
      g = WheelPos % 128;       // green up
      b = 0;                    // blue off
      break;
    case 1:
      g = 127 - WheelPos % 128; // green down
      b = WheelPos % 128;       // blue up
      r = 0;                    // red off
      break;
    case 2:
      b = 127 - WheelPos % 128; // blue down
      r = WheelPos % 128;       // red up
      g = 0;                    // green off
      break;
  }
  return(strip.Color(r,g,b));
}
*/

Can anybody help me incorporate the required elements of the second code into the original one to make the clocks dim automatically at a certain time, then go to full brightness the following morning.
I have tried doing this myself, but I am a programming novice and am really struggling.
Thanks in anticipation.

Modify every "...brightness..." variable with "...brightness/dimming..."

Daytime, set "dimming" to "1"
Nighttime, set "dimming" to "4" (or 2, 8, 16...).

You have 1000+ lines of code. Here is a simulation with 50 lines.

Thanks for your reply xpfd.
I have built the clock you sent through and it works a treat, using much less code. However, I would still like to use the original code as I like the facility to change clock faces and also the rotary encoder allows the time to be changed without reprogramming the ATMega328P.
How can I incorporate the nighttime dimming coding in sketch 2 into sketch 1?
I appreciate you have said to modify the "....brightness..." to "...brightness/dimming..", but the original sketch doesn't currently include anything to do with dimming the clock at night.
I would also like to have the DST part of the second sketch included in the original one, but haven't got a clue how to do this. Can you, or anybody else, help me do this, please.
Many thanks.

Referencing your drawing: Put an electrolytic capacitor (100uf? 1000uf?) across VCC and GND of the WS2812B to absorb surges of brightness changes in your 60 pixels. The DS3231 has accuracy, where the DS1307 will be stray by seconds every day.

Use the sketch with the functions (dimming) and hardware (dials) you like. Draw a picture and describe the clock face you would like, and share it to work on the code, here. (I will secretly work on adding an encoder to the 50-lines program, with your favorite clock face just to see if I can get it done in under 100 lines).

There are 6 occurrences of "LEDBrightness" where a "daytime" divider ("LEDbrightness/daytime") of "1" to indicate daytime (full brightness) or "4" to indicate nighttime (one-quarter brightness) could be inserted to automatically adjust the brightness. The "divider" would come from a condition of the output of your DS3231 (if current time is between 19h/7pm and 7h/7am... divider = 4... else divider = 1).

DST... can be programmed as a condition of the output of the DS3231 (if the date is DST, subtract and hour).

It is best to work on one part to completion, then move to the next part. Pick "the" sketch you will use and pick a direction to start working.

Hi again xpfd,
I really appreciate you taking time to have a look at this for me. I have tried to do this myself but I don't have your skill and knowledge, so I am struggling.
The 4 clocks I have built are for my 4 , fairly young, grandchildren and I would, if possible, like to keep as many of the original clock faces as possible. I think they would quite like scrolling through them to chose which one they like best. I understand that this will mean more code, but, unless you tell me otherwise, I'm quite happy with that. As long as the code fits on the ATMega328 I don't have a problem.
I have added the electrolytic cpacitor you mentioned and should be able to make the necessary changes to the clock cases to fit a DS3231, rather than the DS1307.
Can the original sketch

[type or paste code here](http://andydoro.com/ringclock/)

not be changed to incorporate the nighttime dimming?
I don't need the demo mode or the alarm and countdown features, so I suppose that part of the the code can be removed which, from my very limited knowledge of programming, would sem to be a significant part of the whole thing.
Please bear with me on this. I would love to get the clocks working as I would like and am prepared to learn from you what I need to do, but please always put it in very simple terms.
Thanks again.

Is your preferred sketch the first one on this topic? (I have pasted it below).

These two items you want addressed... any more?

  1. dimming for night hours (daylight = bright, night = half-bright)
  2. DST - pick the two dates for the change.
// Add options for background settings
// TO DO: Clean up and comment code...
// BUG: demo state should start as mode 0 after intro
// NICE TO HAVE: When alarm is cancelled, the alarm still remains set for next day.

//Add the following libraries to the respective folder for you operating system. See http://arduino.cc/en/Guide/Environment
#include <FastLED.h>  // FastSPI Library from http://code.google.com/p/fastspi/
#include <Wire.h>     //This is to communicate via I2C. On arduino Uno & Nano use pins A4 for SDA (yellow/orange) and A5 for SCL (green). For other boards see http://arduino.cc/en/Reference/Wire
#include <RTClib.h>   // Include the RTClib library to enable communication with the real time clock.
#include <EEPROM.h>   // Include the EEPROM library to enable the storing and retrevel of settings.
#include <Bounce.h>   // Include the Bounce library for de-bouncing issues with push buttons.
#include <Encoder.h>  // Include the Encoder library to read the out puts of the rotary encoders

RTC_DS1307 RTC;  // Establishes the chipset of the Real Time Clock

#define LEDStripPin A0  // Pin used for the data to the LED strip
#define menuPin A3      // Pin used for the menu button (green stripe)
#define numLEDs 60      // Number of LEDs in strip

// Setting up the LED strip
struct CRGB leds[numLEDs];
Encoder rotary1(2, 3);  // Setting up the Rotary Encoder

DateTime old;  // Variable to compare new and old time, to see if it has moved on.
int rotary1Pos = 0;
int subSeconds;  // 60th's of a second
int secondBrightness;
int secondBrightness2;
int breathBrightness;
long newSecTime;  // Variable to record when a new second starts, allowing to create milli seconds
long oldSecTime;
long flashTime;  //
long breathCycleTime;
#define holdTime 1500
int cyclesPerSec;
float cyclesPerSecFloat;  // So can be used as a float in calcs
float fracOfSec;
float breathFracOfSec;
boolean demo;
#define demoTime 12  // seconds
long previousDemoTime;
long currentDemoTime;
boolean swingBack = false;

int timeHour;
int timeMin;
int timeSec;
int alarmMin;               // The minute of the alarm
int alarmHour;              // The hour of the alarm 0-23
int alarmDay = 0;           // The day of the alarm
boolean alarmSet;           // Whether the alarm is set or not
int modeAddress = 0;        // Address of where mode is stored in the EEPROM
int alarmMinAddress = 1;    // Address of where alarm minute is stored in the EEPROM
int alarmHourAddress = 2;   // Address of where alarm hour is stored in the EEPROM
int alarmSetAddress = 3;    // Address of where alarm state is stored in the EEPROM
int alarmModeAddress = 4;   // Address of where the alarm mode is stored in the EEPROM
boolean alarmTrig = false;  // Whether the alarm has been triggered or not
long alarmTrigTime;         // Milli seconds since the alarm was triggered
boolean countDown = false;
long countDownTime = 0;
long currentCountDown = 0;
long startCountDown;
int countDownMin;
int countDownSec;
int countDownFlash;
int demoIntro = 0;
int j = 0;
long timeInterval = 5;
long currentMillis;
long previousMillis = 0;
float LEDBrightness = 0;
float fadeTime;
float brightFadeRad;

int state = 0;  // Variable of the state of the clock, with the following defined states
#define clockState 0
#define alarmState 1
#define setAlarmHourState 2
#define setAlarmMinState 3
#define setClockHourState 4
#define setClockMinState 5
#define setClockSecState 6
#define countDownState 7
#define demoState 8
int mode;         // Variable of the display mode of the clock
int modeMax = 6;  // Change this when new modes are added. This is so selecting modes can go back beyond.
int alarmMode;    // Variable of the alarm display mode
int alarmModeMax = 3;

Bounce menuBouncer = Bounce(menuPin, 20);  // Instantiate a Bounce object with a 50 millisecond debounce time for the menu button
boolean menuButton = false;
boolean menuPressed = false;
boolean menuReleased = false;
int advanceMove = 0;
boolean countTime = false;
long menuTimePressed;
long lastRotary;
int rotaryTime = 1000;

int LEDPosition;
int reverseLEDPosition;
int pendulumPos;
int fiveMins;
int odd;
int LEDOffset = 30;

void setup() {
  // Set up all pins
  pinMode(menuPin, INPUT_PULLUP);  // Uses the internal 20k pull up resistor. Pre Arduino_v.1.0.1 need to be "digitalWrite(menuPin,HIGH);pinMode(menuPin,INPUT);"

  // Start LEDs
  LEDS.addLeds<WS2812, LEDStripPin, GRB>(leds, numLEDs);  // Structure of the LED data. I have changed to from rgb to grb, as using an alternative LED strip. Test & change these if you're getting different colours.

  // Start RTC
  Wire.begin();  // Starts the Wire library allows I2C communication to the Real Time Clock
  RTC.begin();   // Starts communications to the RTC

  Serial.begin(9600);  // Starts the serial communications

  // Uncomment to reset all the EEPROM addresses. You will have to comment again and reload, otherwise it will not save anything each time power is cycled
  // write a 0 to all 512 bytes of the EEPROM
  //  for (int i = 0; i < 512; i++)
  //  {EEPROM.write(i, 0);}

  // Load any saved setting since power off, such as mode & alarm time
  mode = EEPROM.read(modeAddress);            // The mode will be stored in the address "0" of the EEPROM
  alarmMin = EEPROM.read(alarmMinAddress);    // The mode will be stored in the address "1" of the EEPROM
  alarmHour = EEPROM.read(alarmHourAddress);  // The mode will be stored in the address "2" of the EEPROM
  alarmSet = EEPROM.read(alarmSetAddress);    // The mode will be stored in the address "2" of the EEPROM
  alarmMode = EEPROM.read(alarmModeAddress);
  // Prints all the saved EEPROM data to Serial
  Serial.print("Mode is ");
  Serial.println(mode);
  Serial.print("Alarm Hour is ");
  Serial.println(alarmHour);
  Serial.print("Alarm Min is ");
  Serial.println(alarmMin);
  Serial.print("Alarm is set ");
  Serial.println(alarmSet);
  Serial.print("Alarm Mode is ");
  Serial.println(alarmMode);

  // create a loop that calcuated the number of counted milliseconds between each second.
  DateTime now = RTC.now();
  //  startTime = millis();
  //  while (RTC.old() = RTC.new())

  //  if (now.month() == 1 && now.day() == 1 && now.hour() == 0 && now.minute() == 0 && now.minute() == 0)
  //    {}

  Serial.print("Hour time is... ");
  Serial.println(now.hour());
  Serial.print("Min time is... ");
  Serial.println(now.minute());
  Serial.print("Sec time is... ");
  Serial.println(now.second());

  Serial.print("Year is... ");
  Serial.println(now.year());
  Serial.print("Month is... ");
  Serial.println(now.month());
  Serial.print("Day is... ");
  Serial.println(now.day());
}


void loop() {
  DateTime now = RTC.now();  // Fetches the time from RTC

  // Check for any button presses and action accordingley
  menuButton = menuBouncer.update();  // Update the debouncer for the menu button and saves state to menuButton
  rotary1Pos = rotary1.read();        // Checks the rotary position
  if (rotary1Pos <= -2 && lastRotary - millis() >= rotaryTime) {
    advanceMove = -1;
    rotary1.write(0);
    lastRotary = millis();
  }
  if (rotary1Pos >= 2 && lastRotary - millis() >= rotaryTime) {
    advanceMove = 1;
    rotary1.write(0);
    lastRotary = millis();
  }
  if (menuButton == true || advanceMove != 0 || countTime == true) {
    buttonCheck(menuBouncer, now);
  }

  // clear LED array
  memset(leds, 0, numLEDs * 3);

  // Check alarm and trigger if the time matches
  if (alarmSet == true && alarmDay != now.day())  // The alarmDay statement ensures it is a newly set alarm or repeat from previous day, not within the minute of an alarm cancel.
  {
    if (alarmTrig == false) {
      alarm(now);
    } else {
      alarmDisplay();
    }
  }
  // Check the Countdown Timer
  if (countDown == true) {
    currentCountDown = countDownTime + startCountDown - now.unixtime();
    if (currentCountDown <= 0) {
      state = countDownState;
    }
  }
  // Set the time LED's
  if (state == setClockHourState || state == setClockMinState || state == setClockSecState) {
    setClockDisplay(now);
  } else if (state == alarmState || state == setAlarmHourState || state == setAlarmMinState) {
    setAlarmDisplay();
  } else if (state == countDownState) {
    countDownDisplay(now);
  } else if (state == demoState) {
    runDemo(now);
  } else {
    timeDisplay(now);
  }

  // Update LEDs
  LEDS.show();
}

void buttonCheck(Bounce menuBouncer, DateTime now) {
  if (menuBouncer.fallingEdge())  // Checks if a button is pressed, if so sets countTime to true
  {
    countTime = true;
    Serial.println("rising edge");
  }
  if (menuBouncer.risingEdge())  // Checks if a button is released,
  {
    countTime = false;
    Serial.println("rising edge");
  }               // if so sets countTime to false. Now the ...TimePressed will not be updated when enters the buttonCheck,
  if (countTime)  // otherwise will menuBouncer.duration will
  {
    menuTimePressed = menuBouncer.duration();
    if (menuTimePressed >= (holdTime - 100) && menuTimePressed <= holdTime) {
      clearLEDs();
      LEDS.show();
      delay(100);
    }
  }
  menuReleased = menuBouncer.risingEdge();
  if (menuPressed == true) {
    Serial.println("Menu Button Pressed");
  }
  if (menuReleased == true) {
    Serial.println("Menu Button Released");
  }
  Serial.print("Menu Bounce Duration ");
  Serial.println(menuTimePressed);
  if (alarmTrig == true) {
    alarmTrig = false;
    alarmDay = now.day();  // When the alarm is cancelled it will not display until next day. As without it, it would start again if within a minute, or completely turn off the alarm.
    delay(300);            // I added this 300ms delay, so there is time for the button to be released
    return;                // This return exits the buttonCheck function, so no actions are performs
  }
  switch (state) {
    case clockState:  // State 0
      if (advanceMove == -1 && mode == 0) {
        mode = modeMax;
        advanceMove = 0;
      } else if (advanceMove != 0)  //if displaying the clock, advance button is pressed & released, then mode will change
      {
        mode = mode + advanceMove;
        EEPROM.write(modeAddress, mode);
        advanceMove = 0;
      } else if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          state = alarmState;
          newSecTime = millis();
        }                                    // if displaying the clock, menu button is pressed & released, then Alarm is displayed
        else {
          state = setClockHourState;  // if displaying the clock, menu button is held & released, then clock hour can be set
        }
      }
      break;
    case alarmState:  // State 1
      if (advanceMove == -1 && alarmMode <= 0) {
        alarmMode = alarmModeMax;
        alarmSet = 1;
      } else if (advanceMove == 1 && alarmMode >= alarmModeMax) {
        alarmMode = 0;
        alarmSet = 0;
      } else if (advanceMove != 0) {
        alarmMode = alarmMode + advanceMove;
        if (alarmMode == 0) {
          alarmSet = 0;
        } else {
          alarmSet = 1;
        }
      }
      Serial.print("alarmState is ");
      Serial.println(alarmState);
      Serial.print("alarmMode is ");
      Serial.println(alarmMode);
      EEPROM.write(alarmSetAddress, alarmSet);
      EEPROM.write(alarmModeAddress, alarmMode);
      advanceMove = 0;
      alarmTrig = false;
      if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          state = countDownState;
          j = 0;
        }                                    // if displaying the alarm time, menu button is pressed & released, then clock is displayed
        else {
          state = setAlarmHourState;  // if displaying the alarm time, menu button is held & released, then alarm hour can be set
        }
      }
      break;
    case setAlarmHourState:  // State 2
      if (menuReleased == true) {
        state = setAlarmMinState;
      } else if (advanceMove == 1 && alarmHour >= 23) {
        alarmHour = 0;
      } else if (advanceMove == -1 && alarmHour <= 0) {
        alarmHour = 23;
      } else if (advanceMove != 0) {
        alarmHour = alarmHour + advanceMove;
      }
      EEPROM.write(alarmHourAddress, alarmHour);
      advanceMove = 0;
      break;
    case setAlarmMinState:  // State 3
      if (menuReleased == true) {
        state = alarmState;
        alarmDay = 0;
        newSecTime = millis();
      } else if (advanceMove == 1 && alarmMin >= 59) {
        alarmMin = 0;
      } else if (advanceMove == -1 && alarmMin <= 0) {
        alarmMin = 59;
      } else if (advanceMove != 0) {
        alarmMin = alarmMin + advanceMove;
      }
      EEPROM.write(alarmMinAddress, alarmMin);
      advanceMove = 0;
      break;
    case setClockHourState:  // State 4
      if (menuReleased == true) {
        state = setClockMinState;
      } else if (advanceMove == 1 && now.hour() == 23) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), 0, now.minute(), now.second()));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.hour() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), 23, now.minute(), now.second()));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), (now.hour() + advanceMove), now.minute(), now.second()));
        advanceMove = 0;
      }
      break;
    case setClockMinState:  // State 5
      if (menuReleased == true) {
        state = setClockSecState;
      } else if (advanceMove == 1 && now.minute() == 59) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 0, now.second()));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.minute() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 59, now.second()));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), (now.minute() + advanceMove), now.second()));
        advanceMove = 0;
      }
      break;
    case setClockSecState:  // State 6
      if (menuReleased == true) {
        state = clockState;
      } else if (advanceMove == 1 && now.second() == 59) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 0));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.second() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 59));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), (now.second() + advanceMove)));
        advanceMove = 0;
      }
      break;
    case countDownState:  // State 7
      if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          if (countDown == true && countDownTime <= 0) {
            countDown = false;
            countDownTime = 0;
            currentCountDown = 0;
          } else if (countDown == false && countDownTime > 0) {
            countDown = true;
            startCountDown = now.unixtime();
          } else {
            state = demoState;
            demoIntro = 1;
            j = 0;
          }  // if displaying the count down, menu button is pressed & released, then demo State is displayed
        } else {
          countDown = false;
          countDownTime = 0;
          currentCountDown = 0;
          j = 0;
        }  // if displaying the clock, menu button is held & released, then the count down is reset
      } else if (advanceMove == -1 && currentCountDown <= 0) {
        countDown = false;
        countDownTime = 0;
        currentCountDown = 0;
        demoIntro = 0;
      } else if (advanceMove == 1 && currentCountDown >= 3600) {
        countDown = false;
        countDownTime = 3600;
      } else if (advanceMove != 0)  //if displaying the count down, rotary encoder is turned then will change accordingley
      {
        countDown = false;
        countDownTime = currentCountDown - currentCountDown % 60 + advanceMove * 60;  // This rounds the count down minute up to the next minute
      }
      advanceMove = 0;
      break;
    case demoState:  // State 8
      if (menuReleased == true) {
        state = clockState;
        mode = EEPROM.read(modeAddress);
      }  // if displaying the demo, menu button pressed then the clock will display and restore to the mode before demo started
      break;
  }
  if (menuReleased || advanceMove != 0) {
    countTime = false;
  }
  Serial.print("Mode is ");
  Serial.println(mode);
  Serial.print("State is ");
  Serial.println(state);
}

void setAlarmDisplay() {

  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 100;
      leds[i].g = 100;
      leds[i].b = 100;
    }
  }

  if (alarmSet == 0) {
    for (int i = 0; i < numLEDs; i++)  // Sets background to red, to state that alarm IS NOT set
    {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = 20;
        leds[i].g = 0;
        leds[i].b = 0;
      }
    }
  } else {
    for (int i = 0; i < numLEDs; i++)  // Sets background to green, to state that alarm IS set
    {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = 0;
        leds[i].g = 20;
        leds[i].b = 0;
      }
    }
  }
  if (alarmHour <= 11) {
    leds[(alarmHour * 5 + LEDOffset) % 60].r = 255;
  } else {
    leds[((alarmHour - 12) * 5 + LEDOffset + 59) % 60].r = 25;
    leds[((alarmHour - 12) * 5 + LEDOffset) % 60].r = 255;
    leds[((alarmHour - 12) * 5 + LEDOffset + 1) % 60].r = 25;
  }
  leds[(alarmMin + LEDOffset) % 60].g = 100;
  flashTime = millis();
  if (state == setAlarmHourState && flashTime % 300 >= 150) {
    leds[(((alarmHour % 12) * 5) + LEDOffset + 59) % 60].r = 0;
    leds[(((alarmHour % 12) * 5) + LEDOffset) % 60].r = 0;
    leds[(((alarmHour % 12) * 5) + LEDOffset + 1) % 60].r = 0;
  }
  if (state == setAlarmMinState && flashTime % 300 >= 150) {
    leds[(alarmMin + LEDOffset) % 60].g = 0;
  }
  leds[(alarmMode + LEDOffset) % 60].b = 255;
}

void setClockDisplay(DateTime now) {
  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 10;
      leds[i].g = 10;
      leds[i].b = 10;
    }
  }
  if (now.hour() <= 11) {
    leds[(now.hour() * 5 + LEDOffset) % 60].r = 255;
  } else {
    leds[((now.hour() - 12) * 5 + LEDOffset + 59) % 60].r = 255;
    leds[((now.hour() - 12) * 5 + LEDOffset) % 60].r = 255;
    leds[((now.hour() - 12) * 5 + LEDOffset + 1) % 60].r = 255;
  }
  flashTime = millis();
  if (state == setClockHourState && flashTime % 300 >= 150) {
    leds[(((now.hour() % 12) * 5) + LEDOffset + 59) % 60].r = 0;
    leds[((now.hour() % 12) * 5 + LEDOffset) % 60].r = 0;
    leds[(((now.hour() % 12) * 5) + LEDOffset + 1) % 60].r = 0;
  }
  if (state == setClockMinState && flashTime % 300 >= 150) {
    leds[(now.minute() + LEDOffset) % 60].g = 0;
  } else {
    leds[(now.minute() + LEDOffset) % 60].g = 255;
  }
  if (state == setClockSecState && flashTime % 300 >= 150) {
    leds[(now.second() + LEDOffset) % 60].b = 0;
  } else {
    leds[(now.second() + LEDOffset) % 60].b = 255;
  }
}

// Check if alarm is active and if is it time for the alarm to trigger
void alarm(DateTime now) {
  if ((alarmMin == now.minute() % 60) && (alarmHour == now.hour() % 24))  //check if the time is the same to trigger alarm
  {
    alarmTrig = true;
    alarmTrigTime = millis();
  }
}

void alarmDisplay()  // Displays the alarm
{
  switch (alarmMode) {
    case 1:
      // set all LEDs to a dim white
      for (int i = 0; i < numLEDs; i++) {
        leds[i].r = 100;
        leds[i].g = 100;
        leds[i].b = 100;
      }
      break;
    case 2:
      LEDPosition = ((millis() - alarmTrigTime) / 300);
      reverseLEDPosition = 60 - LEDPosition;
      if (LEDPosition >= 0 && LEDPosition <= 29) {
        for (int i = 0; i < LEDPosition; i++) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31) {
        for (int i = 59; i > reverseLEDPosition; i--) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      if (LEDPosition >= 30) {
        for (int i = 0; i < numLEDs; i++) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      break;
    case 3:
      fadeTime = 60000;
      brightFadeRad = (millis() - alarmTrigTime) / fadeTime;  // Divided by the time period of the fade up.
      if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255;
      else LEDBrightness = 255.0 * (1.0 + sin((1.57 * brightFadeRad) - 1.57));
      Serial.println(brightFadeRad);
      Serial.println(LEDBrightness);
      for (int i = 0; i < numLEDs; i++) {
        leds[i].r = LEDBrightness;
        leds[i].g = LEDBrightness;
        leds[i].b = LEDBrightness;
      }
      break;

      // Currently not working
      //      case 4:
      //        fadeTime = 60000;
      //        brightFadeRad = (millis() - alarmTrigTime)/fadeTime; // Divided by the time period of the fade up.
      //        LEDPosition = ((millis() - alarmTrigTime)/(fadeTime/30));
      ////        if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255; // If the fade time is complete, then the LED brightness will be set to full.
      //        if (brightFadeRad <= 0) LEDBrightness = 0;
      //        else if (brightFadeRad >= 0) LEDBrightness = 1;
      //        else LEDBrightness = 255.0*(1.0+sin((1.57*brightFadeRad)-1.57));
      //
      ////        Serial.println(brightFadeRad);
      ////        Serial.println(LEDBrightness);
      //        reverseLEDPosition = 60 - LEDPosition;
      //        if (LEDPosition >= 0 && LEDPosition <= 29)
      //          {
      //            for (int i = 0; i < LEDPosition; i++)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31)
      //          {
      //            for (int i = 59; i > reverseLEDPosition; i--)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        if (LEDPosition >= 30)
      //          {
      //            for (int i = 0; i < numLEDs; i++)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        break;
  }
}

//
void countDownDisplay(DateTime now) {
  flashTime = millis();
  if (countDown == true) {
    currentCountDown = countDownTime + startCountDown - now.unixtime();
    if (currentCountDown > 0) {
      countDownMin = currentCountDown / 60;
      countDownSec = currentCountDown % 60 * 4;                                           // have multiplied by 4 to create brightness
      for (int i = 0; i < countDownMin; i++) {
        leds[(i + LEDOffset + 1) % 60].b = 240;  // Set a blue LED for each complete minute that is remaining
      }
      leds[(countDownMin + LEDOffset + 1) % 60].b = countDownSec;                         // Display the remaining secconds of the current minute as its brightness
    } else {
      countDownFlash = now.unixtime() % 2;
      if (countDownFlash == 0) {
        for (int i = 0; i < numLEDs; i++)  // Set the background as all off
        {
          leds[i].r = 0;
          leds[i].g = 0;
          leds[i].b = 0;
        }
      } else {
        for (int i = 0; i < numLEDs; i++)  // Set the background as all blue
        {
          leds[i].r = 0;
          leds[i].g = 0;
          leds[i].b = 255;
        }
      }
    }
  } else {
    currentCountDown = countDownTime;
    if (countDownTime == 0) {
      currentMillis = millis();
      clearLEDs();
      switch (demoIntro) {
        case 0:
          for (int i = 0; i < j; i++) {
            leds[(i + LEDOffset + 1) % 60].b = 20;
          }
          if (currentMillis - previousMillis > timeInterval) {
            j++;
            previousMillis = currentMillis;
          }
          if (j == numLEDs) {
            demoIntro = 1;
          }
          break;
        case 1:
          for (int i = 0; i < j; i++) {
            leds[(i + LEDOffset + 1) % 60].b = 20;
          }
          if (currentMillis - previousMillis > timeInterval) {
            j--;
            previousMillis = currentMillis;
          }
          if (j < 0) {
            demoIntro = 0;
          }
          break;
      }
    } else if (countDownTime > 0 && flashTime % 300 >= 150) {
      countDownMin = currentCountDown / 60;                                               //
      for (int i = 0; i < countDownMin; i++) {
        leds[(i + LEDOffset + 1) % 60].b = 255;  // Set a blue LED for each complete minute that is remaining
      }
    }
  }
}

void runDemo(DateTime now) {
  currentDemoTime = now.unixtime();
  currentMillis = millis();
  clearLEDs();
  switch (demoIntro) {
    case 0:
      timeDisplay(now);
      if (currentDemoTime - previousDemoTime > demoTime) {
        previousDemoTime = currentDemoTime;
        mode++;
      }
      break;
    case 1:
      for (int i = 0; i < j; i++) {
        leds[i].r = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 2:
      for (int i = j; i < numLEDs; i++) {
        leds[i].r = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 3:
      for (int i = 0; i < j; i++) {
        leds[i].g = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 4:
      for (int i = j; i < numLEDs; i++) {
        leds[i].g = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 5:
      for (int i = 0; i < j; i++) {
        leds[i].b = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 6:
      for (int i = j; i < numLEDs; i++) {
        leds[i].b = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 7:
      for (int i = 0; i < j; i++) {
        leds[i].r = 255;
        leds[i].g = 255;
        leds[i].b = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 8:
      for (int i = j; i < numLEDs; i++) {
        leds[i].r = 255;
        leds[i].g = 255;
        leds[i].b = 255;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        demoIntro = 0;
        mode = 0;
        Serial.print("Mode is ");
        Serial.println(mode);
        Serial.print("State is ");
        Serial.println(state);
      }
      break;
  }
}

void clearLEDs() {
  for (int i = 0; i < numLEDs; i++)  // Set all the LEDs to off
  {
    leds[i].r = 0;
    leds[i].g = 0;
    leds[i].b = 0;
  }
}

void timeDisplay(DateTime now) {
  switch (mode) {
    case 0:
      minimalClock(now);
      break;
    case 1:
      basicClock(now);
      break;
    case 2:
      smoothSecond(now);
      break;
    case 3:
      outlineClock(now);
      break;
    case 4:
      minimalMilliSec(now);
      break;
    case 5:
      simplePendulum(now);
      break;
    case 6:
      breathingClock(now);
      break;
    default:  // Keep this here and add more timeDisplay modes as defined cases.
      {
        mode = 0;
      }
  }
}

////////////////////////////////////////////////////////////////////////////////////////////
//   CLOCK DISPLAY MODES
// Add any new display mode functions here. Then add to the "void timeDisplay(DateTime now)" function.
// Add each of the new display mode functions as a new "case", leaving default last.
////////////////////////////////////////////////////////////////////////////////////////////

//
void minimalClock(DateTime now) {
  unsigned char hourPos = (now.hour() % 12) * 5;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

//
void basicClock(DateTime now) {
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset + 59) % 60].g = 0;
  leds[(hourPos + LEDOffset + 59) % 60].b = 0;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].g = 0;
  leds[(hourPos + LEDOffset) % 60].b = 0;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].g = 0;
  leds[(hourPos + LEDOffset + 1) % 60].b = 0;
  leds[(now.minute() + LEDOffset) % 60].r = 0;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.minute() + LEDOffset) % 60].b = 0;
  leds[(now.second() + LEDOffset) % 60].r = 0;
  leds[(now.second() + LEDOffset) % 60].g = 0;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

//
void smoothSecond(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = millis() - newSecTime;
    cyclesPerSecFloat = (float)cyclesPerSec;
    newSecTime = millis();
  }
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime) / cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec) {
    secondBrightness = 50.0 * (1.0 + sin((3.14 * fracOfSec) - 1.57));
  }
  if (subSeconds < cyclesPerSec) {
    secondBrightness2 = 50.0 * (1.0 + sin((3.14 * fracOfSec) + 1.57));
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = secondBrightness;
  leds[(now.second() + LEDOffset + 59) % 60].b = secondBrightness2;
}

//
void outlineClock(DateTime now) {
  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 100;
      leds[i].g = 100;
      leds[i].b = 100;
    }
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}
//
void minimalMilliSec(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = (millis() - newSecTime);
    newSecTime = millis();
  }
  // set hour, min & sec LEDs
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  subSeconds = (((millis() - newSecTime) * 60) / cyclesPerSec) % 60;  // This divides by 733, but should be 1000 and not sure why???
  // Millisec lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(subSeconds + LEDOffset) % 60].r = 50;
  leds[(subSeconds + LEDOffset) % 60].g = 50;
  leds[(subSeconds + LEDOffset) % 60].b = 50;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

// Pendulum will be at the bottom and left for one second and right for one second
void simplePendulum(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = millis() - newSecTime;
    cyclesPerSecFloat = (float)cyclesPerSec;
    newSecTime = millis();
    if (swingBack == true) {
      swingBack = false;
    } else {
      swingBack = true;
    }
  }
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime) / cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec && swingBack == true) {
    pendulumPos = 27.0 + 3.4 * (1.0 + sin((3.14 * fracOfSec) - 1.57));
  }
  if (subSeconds < cyclesPerSec && swingBack == false) {
    pendulumPos = 27.0 + 3.4 * (1.0 + sin((3.14 * fracOfSec) + 1.57));
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  // Pendulum lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(pendulumPos + LEDOffset) % 60].r = 100;
  leds[(pendulumPos + LEDOffset) % 60].g = 100;
  leds[(pendulumPos + LEDOffset) % 60].b = 100;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}

void breathingClock(DateTime now) {
  if (alarmTrig == false) {
    breathBrightness = 15.0 * (1.0 + sin((3.14 * millis() / 2000.0) - 1.57));
    for (int i = 0; i < numLEDs; i++) {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = breathBrightness + 5;
        leds[i].g = breathBrightness + 5;
        leds[i].b = breathBrightness + 5;
      } else {
        leds[i].r = 0;
        leds[i].g = 0;
        leds[i].b = 0;
      }
    }
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255;
  leds[(hourPos + LEDOffset) % 60].r = 255;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255;
  leds[(now.minute() + LEDOffset) % 60].g = 255;
  leds[(now.second() + LEDOffset) % 60].b = 255;
}


/*
  // Cycle through the color wheel, equally spaced around the belt
  void rainbowCycle(uint8_t wait)
  {
  uint16_t i, j;
  for (j=0; j < 384 * 5; j++)
    {     // 5 cycles of all 384 colors in the wheel
      for (i=0; i < numLEDs; i++)
        {
          // tricky math! we use each pixel as a fraction of the full 384-color
          // wheel (thats the i / strip.numPixels() part)
          // Then add in j which makes the colors go around per pixel
          // the % 384 is to make the wheel cycle around
          strip.setPixelColor(i, Wheel(((i * 384 / numLEDs) + j) % 384));
        }
      delay(wait);
    }
  }

  //Input a value 0 to 384 to get a color value.
  //The colours are a transition r - g - b - back to r

  uint32_t Wheel(uint16_t WheelPos)
  {
  byte r, g, b;
  switch(WheelPos / 128)
  {
    case 0:
      r = 127 - WheelPos % 128; // red down
      g = WheelPos % 128;       // green up
      b = 0;                    // blue off
      break;
    case 1:
      g = 127 - WheelPos % 128; // green down
      b = WheelPos % 128;       // blue up
      r = 0;                    // red off
      break;
    case 2:
      b = 127 - WheelPos % 128; // blue down
      r = WheelPos % 128;       // red up
      g = 0;                    // green off
      break;
  }
  return(strip.Color(r,g,b));
  }
*/

I have started a simulation. I noticed states 0, 1, 7 and 8, with 0 being a the time. The button is touchy.

Hi xfpd,

Yes, that is the sketch I would like to use, as it has all the various clock faces and the rotary encoder included.

The two items you mentioned : -

1. dimming for night hours (daylight = bright, night = half-bright)
2. DST - pick the two dates for the change.

are the ones I would like addressed.

As I am in the UK the dates for the DST are the last Sunday in March and the last Sunday in October.

There seems to be a lot of code relating to the alarm feature, which I don't need. This, plus the countdown clock, could be removed to reduce the sketch size.

Appreciate your help.

Hello @cottonuk -

I added "dimming" by reading the hour (now.hour()) and if the hour is after 18h (6pm) OR less than 07h (7am), the Neopixel brightness (255 for everything but a "fading" function) is divided by 4. Otherwise "dimming" would be "1" so a brightness of 255/1 is still 255

The code compiles, but I can not see it "live" ... but only on the simulation I posted in Post #6.

// https://forum.arduino.cc/t/60-led-ws2812-clock-using-standalone-atmega328p/1238273/
// https://wokwi.com/projects/393090717241801729

// Add options for background settings
// TO DO: Clean up and comment code...
// BUG: demo state should start as displayMode 0 after intro
// NICE TO HAVE: When alarm is cancelled, the alarm still remains set for next day.
// 20240323 - "dimming" added as a divisor to "255" values.  if 18 > hour > 7 divisor is "4,"" else "1"
// 20240323 - grouped Serial Monitor output

//Add the following libraries to the respective folder for you operating system. See http://arduino.cc/en/Guide/Environment
#include <FastLED.h>  // FastSPI Library from http://code.google.com/p/fastspi/
#include <Wire.h>     //This is to communicate via I2C. On arduino Uno & Nano use pins A4 for SDA (yellow/orange) and A5 for SCL (green). For other boards see http://arduino.cc/en/Reference/Wire
#include <RTClib.h>   // Include the RTClib library to enable communication with the real time clock.
#include <EEPROM.h>   // Include the EEPROM library to enable the storing and retrevel of settings.
#include "Bounce.h"   // Include the Bounce library for de-bouncing issues with push buttons.
#include <Encoder.h>  // Include the Encoder library to read the out puts of the rotary encoders

RTC_DS1307 RTC;  // Establishes the chipset of the Real Time Clock

#define LEDStripPin A0  // Pin used for the data to the LED strip
#define menuPin A3      // Pin used for the menu button (green stripe)
#define numLEDs 60      // Number of LEDs in strip
int dimming = 1; // this will be for dimming the Neopixels during dark hours

// Setting up the LED strip
struct CRGB leds[numLEDs];
Encoder rotary1(2, 3);  // Setting up the Rotary Encoder

DateTime old;  // Variable to compare new and old time, to see if it has moved on.
int rotary1Pos = 0;
int subSeconds;  // 60th's of a second
int secondBrightness;
int secondBrightness2;
int breathBrightness;
long newSecTime;  // Variable to record when a new second starts, allowing to create milli seconds
long oldSecTime;
long flashTime;  //
// long breathCycleTime; // not used
#define holdTime 1500
int cyclesPerSec;
float cyclesPerSecFloat;  // So can be used as a float in calcs
float fracOfSec;
// float breathFracOfSec; // not used
boolean demo;
#define demoTime 12  // seconds
long previousDemoTime;
long currentDemoTime;
boolean swingBack = false;

int timeHour;
int timeMin;
int timeSec;
int alarmMin;               // The minute of the alarm
int alarmHour;              // The hour of the alarm 0-23
int alarmDay = 0;           // The day of the alarm
boolean alarmSet;           // Whether the alarm is set or not
int modeAddress = 0;        // Address of where mode is stored in the EEPROM
int alarmMinAddress = 1;    // Address of where alarm minute is stored in the EEPROM
int alarmHourAddress = 2;   // Address of where alarm hour is stored in the EEPROM
int alarmSetAddress = 3;    // Address of where alarm state is stored in the EEPROM
int alarmModeAddress = 4;   // Address of where the alarm mode is stored in the EEPROM
boolean alarmTrig = false;  // Whether the alarm has been triggered or not
long alarmTrigTime;         // Milli seconds since the alarm was triggered
boolean countDown = false;
long countDownTime = 0;
long currentCountDown = 0;
long startCountDown;
int countDownMin;
int countDownSec;
int countDownFlash;
int demoIntro = 0;
int j = 0;
long timeInterval = 5;
long currentMillis;
long previousMillis = 0;
float LEDBrightness = 0;
float fadeTime;
float brightFadeRad;

int state = 0;  // Variable of the state of the clock, with the following defined states

char *states[] = {"clockState",
                  "alarmState",
                  "setAlarmHourState",
                  "setAlarmMinState",
                  "setClockHourState",
                  "setClockMinState",
                  "setClockSecState",
                  "countDownState",
                  "demoState"
                 };
#define clockState 0
#define alarmState 1
#define setAlarmHourState 2
#define setAlarmMinState 3
#define setClockHourState 4
#define setClockMinState 5
#define setClockSecState 6
#define countDownState 7
#define demoState 8

// int mode;         // CHANGED TO displayMode // Variable of the display mode of the clock
int displayMode;         // Variable of the display mode of the clock
int modeMax = 6;  // Change this when new modes are added. This is so selecting modes can go back beyond.
int alarmMode;    // Variable of the alarm display mode
int alarmModeMax = 3;

Bounce menuBouncer = Bounce(menuPin, 20);  // Instantiate a Bounce object with a 50 millisecond debounce time for the menu button
boolean menuButton = false;
boolean menuPressed = false;
boolean menuReleased = false;
int advanceMove = 0;
boolean countTime = false;
long menuTimePressed;
long lastRotary;
int rotaryTime = 1000;

int LEDPosition;
int reverseLEDPosition;
int pendulumPos;
int fiveMins;
int odd;
int LEDOffset = 30;

void setup() {
  // Set up all pins
  pinMode(menuPin, INPUT_PULLUP);  // Uses the internal 20k pull up resistor. Pre Arduino_v.1.0.1 need to be "digitalWrite(menuPin,HIGH);pinMode(menuPin,INPUT);"

  // Start LEDs
  LEDS.addLeds<WS2812, LEDStripPin, GRB>(leds, numLEDs);  // Structure of the LED data. I have changed to from rgb to grb, as using an alternative LED strip. Test & change these if you're getting different colours.

  // Start RTC
  Wire.begin();  // Starts the Wire library allows I2C communication to the Real Time Clock
  RTC.begin();   // Starts communications to the RTC

  Serial.begin(9600);  // Starts the serial communications

  // Uncomment to reset all the EEPROM addresses. You will have to comment again and reload, otherwise it will not save anything each time power is cycled
  // write a 0 to all 512 bytes of the EEPROM
  //  for (int i = 0; i < 512; i++)
  //  {EEPROM.write(i, 0);}

  // Load any saved setting since power off, such as mode & alarm time
  displayMode = EEPROM.read(modeAddress);            // The mode will be stored in the address "0" of the EEPROM
  alarmMin = EEPROM.read(alarmMinAddress);    // The mode will be stored in the address "1" of the EEPROM
  alarmHour = EEPROM.read(alarmHourAddress);  // The mode will be stored in the address "2" of the EEPROM
  alarmSet = EEPROM.read(alarmSetAddress);    // The mode will be stored in the address "2" of the EEPROM
  alarmMode = EEPROM.read(alarmModeAddress);
  // Prints all the saved EEPROM data to Serial
  Serial.print("Display Mode ");
  Serial.println(displayMode);
  // Serial.print("Alarm Hour is ");
  // Serial.println(alarmHour);
  // Serial.print("Alarm Min is ");
  // Serial.println(alarmMin);
  // Serial.print("Alarm is set ");
  // Serial.println(alarmSet);
  // Serial.print("Alarm Mode is ");
  // Serial.println(alarmMode);
  Serial.print("Alarm (HH:MM) ");
  Serial.print(alarmHour);
  Serial.print(":");
  Serial.print(alarmMin);
  Serial.print(" ");
  if (alarmSet) Serial.print("ON"); else Serial.print("OFF");
  Serial.print(" Mode ");
  Serial.println(alarmMode);

  // create a loop that calcuated the number of counted milliseconds between each second.
  DateTime now = RTC.now();
  //  startTime = millis();
  //  while (RTC.old() = RTC.new())

  //  if (now.month() == 1 && now.day() == 1 && now.hour() == 0 && now.minute() == 0 && now.minute() == 0)
  //    {}

  Serial.print("Time (HH:MM.SS) ");
  Serial.print(now.hour());
  Serial.print(":");
  Serial.print(now.minute());
  Serial.print(".");
  Serial.println(now.second());

  Serial.print("Date (YYYY/MM/DD) ");
  Serial.print(now.year());
  Serial.print("/");
  Serial.print(now.month());
  Serial.print("/");
  Serial.println(now.day());
}

void loop() {
  DateTime now = RTC.now();  // Fetches the time from RTC

  // create a neopixel "dimming" value for hours of darkness
  if (now.hour() > 18 || now.hour() < 7)
    dimming = 4; // the dividend for neopixel brightness that was 255 ... now 255/dimming
  else dimming = 1; // 255 / 1 = 255 (no change in brightness)

  // Check for any button presses and action accordingley
  menuButton = menuBouncer.update();  // Update the debouncer for the menu button and saves state to menuButton
  rotary1Pos = rotary1.read();        // Checks the rotary position
  if (rotary1Pos <= -2 && lastRotary - millis() >= rotaryTime) {
    advanceMove = -1;
    rotary1.write(0);
    lastRotary = millis();
  }
  if (rotary1Pos >= 2 && lastRotary - millis() >= rotaryTime) {
    advanceMove = 1;
    rotary1.write(0);
    lastRotary = millis();
  }
  if (menuButton == true || advanceMove != 0 || countTime == true) {
    buttonCheck(menuBouncer, now);
  }

  // clear LED array
  memset(leds, 0, numLEDs * 3);

  // Check alarm and trigger if the time matches
  if (alarmSet == true && alarmDay != now.day())  // The alarmDay statement ensures it is a newly set alarm or repeat from previous day, not within the minute of an alarm cancel.
  {
    if (alarmTrig == false) {
      alarm(now);
    } else {
      alarmDisplay();
    }
  }
  // Check the Countdown Timer
  if (countDown == true) {
    currentCountDown = countDownTime + startCountDown - now.unixtime();
    if (currentCountDown <= 0) {
      state = countDownState;
    }
  }
  // Set the time LED's
  if (state == setClockHourState || state == setClockMinState || state == setClockSecState) {
    setClockDisplay(now);
  } else if (state == alarmState || state == setAlarmHourState || state == setAlarmMinState) {
    setAlarmDisplay();
  } else if (state == countDownState) {
    countDownDisplay(now);
  } else if (state == demoState) {
    runDemo(now);
  } else {
    timeDisplay(now);
  }

  // Update LEDs
  LEDS.show();
}

void buttonCheck(Bounce menuBouncer, DateTime now) {
  Serial.print("buttonCheck: ");

  if (menuBouncer.fallingEdge())  // Checks if a button is pressed, if so sets countTime to true
  {
    countTime = true;
    // Serial.println("rising edge"); // looks like "rising" is an error
    Serial.print("(falling edge)");
  }

  if (menuBouncer.risingEdge())  // Checks if a button is released,
  {
    countTime = false;
    Serial.print("(rising edge)");
  }               // if so sets countTime to false. Now the ...TimePressed will not be updated when enters the buttonCheck,

  if (countTime)  // otherwise will menuBouncer.duration will
  {
    menuTimePressed = menuBouncer.duration();
    if (menuTimePressed >= (holdTime - 100) && menuTimePressed <= holdTime) {
      clearLEDs();
      LEDS.show();
      delay(100);
    }
  }

  menuReleased = menuBouncer.risingEdge();
  menuPressed  = menuBouncer.fallingEdge(); // added for next condition on menuPressed

  if (menuPressed == true) { // "menuPressed" added above
    Serial.print(". Menu Button (pressed) ");
  }

  if (menuReleased == true) {
    Serial.print(". Menu Button (released) ");
  }

  Serial.print("Bounce Duration (");
  Serial.print(menuTimePressed);
  Serial.println(")");

  if (alarmTrig == true) {
    alarmTrig = false;
    alarmDay = now.day();  // When the alarm is cancelled it will not display until next day. As without it, it would start again if within a minute, or completely turn off the alarm.
    delay(300);            // I added this 300ms delay, so there is time for the button to be released
    return;                // This return exits the buttonCheck function, so no actions are performs
  }
  switch (state) {
    case clockState:  // State 0
      if (advanceMove == -1 && displayMode == 0) {
        displayMode = modeMax;
        advanceMove = 0;
      } else if (advanceMove != 0)  //if displaying the clock, advance button is pressed & released, then mode will change
      {
        displayMode = displayMode + advanceMove;
        EEPROM.write(modeAddress, displayMode);
        advanceMove = 0;
      } else if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          state = alarmState;
          newSecTime = millis();
        }                                    // if displaying the clock, menu button is pressed & released, then Alarm is displayed
        else {
          state = setClockHourState;  // if displaying the clock, menu button is held & released, then clock hour can be set
        }
      }
      break;
    case alarmState:  // State 1
      if (advanceMove == -1 && alarmMode <= 0) {
        alarmMode = alarmModeMax;
        alarmSet = 1;
      } else if (advanceMove == 1 && alarmMode >= alarmModeMax) {
        alarmMode = 0;
        alarmSet = 0;
      } else if (advanceMove != 0) {
        alarmMode = alarmMode + advanceMove;
        if (alarmMode == 0) {
          alarmSet = 0;
        } else {
          alarmSet = 1;
        }
      }
      Serial.print("alarmState is ");
      Serial.println(alarmState);
      Serial.print("alarmMode is ");
      Serial.println(alarmMode);
      EEPROM.write(alarmSetAddress, alarmSet);
      EEPROM.write(alarmModeAddress, alarmMode);
      advanceMove = 0;
      alarmTrig = false;
      if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          state = countDownState;
          j = 0;
        }                                    // if displaying the alarm time, menu button is pressed & released, then clock is displayed
        else {
          state = setAlarmHourState;  // if displaying the alarm time, menu button is held & released, then alarm hour can be set
        }
      }
      break;
    case setAlarmHourState:  // State 2
      if (menuReleased == true) {
        state = setAlarmMinState;
      } else if (advanceMove == 1 && alarmHour >= 23) {
        alarmHour = 0;
      } else if (advanceMove == -1 && alarmHour <= 0) {
        alarmHour = 23;
      } else if (advanceMove != 0) {
        alarmHour = alarmHour + advanceMove;
      }
      EEPROM.write(alarmHourAddress, alarmHour);
      advanceMove = 0;
      break;
    case setAlarmMinState:  // State 3
      if (menuReleased == true) {
        state = alarmState;
        alarmDay = 0;
        newSecTime = millis();
      } else if (advanceMove == 1 && alarmMin >= 59) {
        alarmMin = 0;
      } else if (advanceMove == -1 && alarmMin <= 0) {
        alarmMin = 59;
      } else if (advanceMove != 0) {
        alarmMin = alarmMin + advanceMove;
      }
      EEPROM.write(alarmMinAddress, alarmMin);
      advanceMove = 0;
      break;
    case setClockHourState:  // State 4
      if (menuReleased == true) {
        state = setClockMinState;
      } else if (advanceMove == 1 && now.hour() == 23) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), 0, now.minute(), now.second()));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.hour() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), 23, now.minute(), now.second()));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), (now.hour() + advanceMove), now.minute(), now.second()));
        advanceMove = 0;
      }
      break;
    case setClockMinState:  // State 5
      if (menuReleased == true) {
        state = setClockSecState;
      } else if (advanceMove == 1 && now.minute() == 59) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 0, now.second()));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.minute() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 59, now.second()));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), (now.minute() + advanceMove), now.second()));
        advanceMove = 0;
      }
      break;
    case setClockSecState:  // State 6
      if (menuReleased == true) {
        state = clockState;
      } else if (advanceMove == 1 && now.second() == 59) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 0));
        advanceMove = 0;
      } else if (advanceMove == -1 && now.second() == 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), 59));
        advanceMove = 0;
      } else if (advanceMove != 0) {
        RTC.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), (now.second() + advanceMove)));
        advanceMove = 0;
      }
      break;
    case countDownState:  // State 7
      if (menuReleased == true) {
        if (menuTimePressed <= holdTime) {
          if (countDown == true && countDownTime <= 0) {
            countDown = false;
            countDownTime = 0;
            currentCountDown = 0;
          } else if (countDown == false && countDownTime > 0) {
            countDown = true;
            startCountDown = now.unixtime();
          } else {
            state = demoState;
            demoIntro = 1;
            j = 0;
          }  // if displaying the count down, menu button is pressed & released, then demo State is displayed
        } else {
          countDown = false;
          countDownTime = 0;
          currentCountDown = 0;
          j = 0;
        }  // if displaying the clock, menu button is held & released, then the count down is reset
      } else if (advanceMove == -1 && currentCountDown <= 0) {
        countDown = false;
        countDownTime = 0;
        currentCountDown = 0;
        demoIntro = 0;
      } else if (advanceMove == 1 && currentCountDown >= 3600) {
        countDown = false;
        countDownTime = 3600;
      } else if (advanceMove != 0)  //if displaying the count down, rotary encoder is turned then will change accordingley
      {
        countDown = false;
        countDownTime = currentCountDown - currentCountDown % 60 + advanceMove * 60;  // This rounds the count down minute up to the next minute
      }
      advanceMove = 0;
      break;
    case demoState:  // State 8
      if (menuReleased == true) {
        state = clockState;
        displayMode = EEPROM.read(modeAddress);
      }  // if displaying the demo, menu button pressed then the clock will display and restore to the mode before demo started
      break;
  }
  if (menuReleased || advanceMove != 0) {
    countTime = false;
  }
  Serial.print("Display Mode (");
  Serial.print(displayMode);
  Serial.println(")");

  Serial.print("Clock State (");
  Serial.print(state);
  Serial.print(") ");
  Serial.println(states[state]);
}

void setAlarmDisplay() {

  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 100;
      leds[i].g = 100;
      leds[i].b = 100;
    }
  }

  if (alarmSet == 0) {
    for (int i = 0; i < numLEDs; i++)  // Sets background to red, to state that alarm IS NOT set
    {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = 20;
        leds[i].g = 0;
        leds[i].b = 0;
      }
    }
  } else {
    for (int i = 0; i < numLEDs; i++)  // Sets background to green, to state that alarm IS set
    {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = 0;
        leds[i].g = 20;
        leds[i].b = 0;
      }
    }
  }
  if (alarmHour <= 11) {
    leds[(alarmHour * 5 + LEDOffset) % 60].r = 255 / dimming;
  } else {
    leds[((alarmHour - 12) * 5 + LEDOffset + 59) % 60].r = 25;
    leds[((alarmHour - 12) * 5 + LEDOffset) % 60].r = 255 / dimming;
    leds[((alarmHour - 12) * 5 + LEDOffset + 1) % 60].r = 25;
  }
  leds[(alarmMin + LEDOffset) % 60].g = 100;
  flashTime = millis();
  if (state == setAlarmHourState && flashTime % 300 >= 150) {
    leds[(((alarmHour % 12) * 5) + LEDOffset + 59) % 60].r = 0;
    leds[(((alarmHour % 12) * 5) + LEDOffset) % 60].r = 0;
    leds[(((alarmHour % 12) * 5) + LEDOffset + 1) % 60].r = 0;
  }
  if (state == setAlarmMinState && flashTime % 300 >= 150) {
    leds[(alarmMin + LEDOffset) % 60].g = 0;
  }
  leds[(alarmMode + LEDOffset) % 60].b = 255 / dimming;
}

void setClockDisplay(DateTime now) {
  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 10;
      leds[i].g = 10;
      leds[i].b = 10;
    }
  }
  if (now.hour() <= 11) {
    leds[(now.hour() * 5 + LEDOffset) % 60].r = 255 / dimming;
  } else {
    leds[((now.hour() - 12) * 5 + LEDOffset + 59) % 60].r = 255 / dimming;
    leds[((now.hour() - 12) * 5 + LEDOffset) % 60].r = 255 / dimming;
    leds[((now.hour() - 12) * 5 + LEDOffset + 1) % 60].r = 255 / dimming;
  }
  flashTime = millis();
  if (state == setClockHourState && flashTime % 300 >= 150) {
    leds[(((now.hour() % 12) * 5) + LEDOffset + 59) % 60].r = 0;
    leds[((now.hour() % 12) * 5 + LEDOffset) % 60].r = 0;
    leds[(((now.hour() % 12) * 5) + LEDOffset + 1) % 60].r = 0;
  }
  if (state == setClockMinState && flashTime % 300 >= 150) {
    leds[(now.minute() + LEDOffset) % 60].g = 0;
  } else {
    leds[(now.minute() + LEDOffset) % 60].g = 255 / dimming;
  }
  if (state == setClockSecState && flashTime % 300 >= 150) {
    leds[(now.second() + LEDOffset) % 60].b = 0;
  } else {
    leds[(now.second() + LEDOffset) % 60].b = 255 / dimming;
  }
}

// Check if alarm is active and if is it time for the alarm to trigger
void alarm(DateTime now) {
  if ((alarmMin == now.minute() % 60) && (alarmHour == now.hour() % 24))  //check if the time is the same to trigger alarm
  {
    alarmTrig = true;
    alarmTrigTime = millis();
  }
}

void alarmDisplay()  // Displays the alarm
{
  switch (alarmMode) {
    case 1:
      // set all LEDs to a dim white
      for (int i = 0; i < numLEDs; i++) {
        leds[i].r = 100;
        leds[i].g = 100;
        leds[i].b = 100;
      }
      break;
    case 2:
      LEDPosition = ((millis() - alarmTrigTime) / 300);
      reverseLEDPosition = 60 - LEDPosition;
      if (LEDPosition >= 0 && LEDPosition <= 29) {
        for (int i = 0; i < LEDPosition; i++) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31) {
        for (int i = 59; i > reverseLEDPosition; i--) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      if (LEDPosition >= 30) {
        for (int i = 0; i < numLEDs; i++) {
          leds[(i + LEDOffset) % 60].r = 5;
          leds[(i + LEDOffset) % 60].g = 5;
          leds[(i + LEDOffset) % 60].b = 5;
        }
      }
      break;
    case 3:
      fadeTime = 60000;
      brightFadeRad = (millis() - alarmTrigTime) / fadeTime;  // Divided by the time period of the fade up.
      if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255 / dimming;
      else LEDBrightness = 255 / dimming * (1.0 + sin((1.57 * brightFadeRad) - 1.57));
      Serial.println(brightFadeRad);
      Serial.println(LEDBrightness);
      for (int i = 0; i < numLEDs; i++) {
        leds[i].r = LEDBrightness;
        leds[i].g = LEDBrightness;
        leds[i].b = LEDBrightness;
      }
      break;

      // Currently not working
      //      case 4:
      //        fadeTime = 60000;
      //        brightFadeRad = (millis() - alarmTrigTime)/fadeTime; // Divided by the time period of the fade up.
      //        LEDPosition = ((millis() - alarmTrigTime)/(fadeTime/30));
      ////        if (millis() > alarmTrigTime + fadeTime) LEDBrightness = 255; // If the fade time is complete, then the LED brightness will be set to full.
      //        if (brightFadeRad <= 0) LEDBrightness = 0;
      //        else if (brightFadeRad >= 0) LEDBrightness = 1;
      //        else LEDBrightness = 255.0*(1.0+sin((1.57*brightFadeRad)-1.57));
      //
      ////        Serial.println(brightFadeRad);
      ////        Serial.println(LEDBrightness);
      //        reverseLEDPosition = 60 - LEDPosition;
      //        if (LEDPosition >= 0 && LEDPosition <= 29)
      //          {
      //            for (int i = 0; i < LEDPosition; i++)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        if (reverseLEDPosition <= 59 && reverseLEDPosition >= 31)
      //          {
      //            for (int i = 59; i > reverseLEDPosition; i--)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        if (LEDPosition >= 30)
      //          {
      //            for (int i = 0; i < numLEDs; i++)
      //              {
      //                leds[i].r = LEDBrightness;
      //                leds[i].g = LEDBrightness;
      //                leds[i].b = LEDBrightness;
      //              }
      //          }
      //        break;
  }
}

//
void countDownDisplay(DateTime now) {
  flashTime = millis();
  if (countDown == true) {
    currentCountDown = countDownTime + startCountDown - now.unixtime();
    if (currentCountDown > 0) {
      countDownMin = currentCountDown / 60;
      countDownSec = currentCountDown % 60 * 4;                                           // have multiplied by 4 to create brightness
      for (int i = 0; i < countDownMin; i++) {
        leds[(i + LEDOffset + 1) % 60].b = 240;  // Set a blue LED for each complete minute that is remaining
      }
      leds[(countDownMin + LEDOffset + 1) % 60].b = countDownSec;                         // Display the remaining secconds of the current minute as its brightness
    } else {
      countDownFlash = now.unixtime() % 2;
      if (countDownFlash == 0) {
        for (int i = 0; i < numLEDs; i++)  // Set the background as all off
        {
          leds[i].r = 0;
          leds[i].g = 0;
          leds[i].b = 0;
        }
      } else {
        for (int i = 0; i < numLEDs; i++)  // Set the background as all blue
        {
          leds[i].r = 0;
          leds[i].g = 0;
          leds[i].b = 255 / dimming;
        }
      }
    }
  } else {
    currentCountDown = countDownTime;
    if (countDownTime == 0) {
      currentMillis = millis();
      clearLEDs();
      switch (demoIntro) {
        case 0:
          for (int i = 0; i < j; i++) {
            leds[(i + LEDOffset + 1) % 60].b = 20;
          }
          if (currentMillis - previousMillis > timeInterval) {
            j++;
            previousMillis = currentMillis;
          }
          if (j == numLEDs) {
            demoIntro = 1;
          }
          break;
        case 1:
          for (int i = 0; i < j; i++) {
            leds[(i + LEDOffset + 1) % 60].b = 20;
          }
          if (currentMillis - previousMillis > timeInterval) {
            j--;
            previousMillis = currentMillis;
          }
          if (j < 0) {
            demoIntro = 0;
          }
          break;
      }
    } else if (countDownTime > 0 && flashTime % 300 >= 150) {
      countDownMin = currentCountDown / 60;                                               //
      for (int i = 0; i < countDownMin; i++) {
        leds[(i + LEDOffset + 1) % 60].b = 255 / dimming; // Set a blue LED for each complete minute that is remaining
      }
    }
  }
}

void runDemo(DateTime now) {
  currentDemoTime = now.unixtime();
  currentMillis = millis();
  clearLEDs();
  switch (demoIntro) {
    case 0:
      timeDisplay(now);
      if (currentDemoTime - previousDemoTime > demoTime) {
        previousDemoTime = currentDemoTime;
        displayMode++;
      }
      break;
    case 1:
      for (int i = 0; i < j; i++) {
        leds[i].r = 255 / dimming;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 2:
      for (int i = j; i < numLEDs; i++) {
        leds[i].r = 255 / dimming;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 3:
      for (int i = 0; i < j; i++) {
        leds[i].g = 255 / dimming;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 4:
      for (int i = j; i < numLEDs; i++) {
        leds[i].g = 255 / dimming;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 5:
      for (int i = 0; i < j; i++) {
        leds[i].b = 255 / dimming;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 6:
      for (int i = j; i < numLEDs; i++) {
        leds[i].b = 255 / dimming;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 7:
      for (int i = 0; i < j; i++) {
        leds[i].r = 255 / dimming;
        leds[i].g = 255 / dimming;
        leds[i].b = 255 / dimming;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        j = 0;
        demoIntro++;
      }
      break;
    case 8:
      for (int i = j; i < numLEDs; i++) {
        leds[i].r = 255 / dimming;
        leds[i].g = 255 / dimming;
        leds[i].b = 255 / dimming;
      }
      if (currentMillis - previousMillis > timeInterval) {
        j++;
        previousMillis = currentMillis;
      }
      if (j == numLEDs) {
        demoIntro = 0;
        displayMode = 0;
        Serial.print("Mode is ");
        Serial.println(displayMode);
        Serial.print("State is ");
        Serial.println(state);
      }
      break;
  }
}

void clearLEDs() {
  for (int i = 0; i < numLEDs; i++)  // Set all the LEDs to off
  {
    leds[i].r = 0;
    leds[i].g = 0;
    leds[i].b = 0;
  }
}

void timeDisplay(DateTime now) {
  switch (displayMode) {
    case 0:
      minimalClock(now);
      break;
    case 1:
      basicClock(now);
      break;
    case 2:
      smoothSecond(now);
      break;
    case 3:
      outlineClock(now);
      break;
    case 4:
      minimalMilliSec(now);
      break;
    case 5:
      simplePendulum(now);
      break;
    case 6:
      breathingClock(now);
      break;
    default:  // Keep this here and add more timeDisplay modes as defined cases.
      {
        displayMode = 0;
      }
  }
}

////////////////////////////////////////////////////////////////////////////////////////////
//   CLOCK DISPLAY MODES
// Add any new display mode functions here. Then add to the "void timeDisplay(DateTime now)" function.
// Add each of the new display mode functions as a new "case", leaving default last.
////////////////////////////////////////////////////////////////////////////////////////////

//
void minimalClock(DateTime now) {
  unsigned char hourPos = (now.hour() % 12) * 5;
  leds[(hourPos + LEDOffset) % 60].r = 255 / dimming;
  leds[(now.minute() + LEDOffset) % 60].g = 255 / dimming;
  leds[(now.second() + LEDOffset) % 60].b = 255 / dimming;
}

//
void basicClock(DateTime now) {
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset + 59) % 60].g = 0;
  leds[(hourPos + LEDOffset + 59) % 60].b = 0;
  leds[(hourPos + LEDOffset) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset) % 60].g = 0;
  leds[(hourPos + LEDOffset) % 60].b = 0;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset + 1) % 60].g = 0;
  leds[(hourPos + LEDOffset + 1) % 60].b = 0;
  leds[(now.minute() + LEDOffset) % 60].r = 0;
  leds[(now.minute() + LEDOffset) % 60].g = 255 / dimming;
  leds[(now.minute() + LEDOffset) % 60].b = 0;
  leds[(now.second() + LEDOffset) % 60].r = 0;
  leds[(now.second() + LEDOffset) % 60].g = 0;
  leds[(now.second() + LEDOffset) % 60].b = 255 / dimming;
}

//
void smoothSecond(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = millis() - newSecTime;
    cyclesPerSecFloat = (float)cyclesPerSec;
    newSecTime = millis();
  }
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime) / cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec) {
    secondBrightness = 50.0 * (1.0 + sin((3.14 * fracOfSec) - 1.57));
  }
  if (subSeconds < cyclesPerSec) {
    secondBrightness2 = 50.0 * (1.0 + sin((3.14 * fracOfSec) + 1.57));
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255 / dimming;
  leds[(now.minute() + LEDOffset) % 60].g = 255 / dimming;
  leds[(now.second() + LEDOffset) % 60].b = secondBrightness;
  leds[(now.second() + LEDOffset + 59) % 60].b = secondBrightness2;
}

//
void outlineClock(DateTime now) {
  for (int i = 0; i < numLEDs; i++) {
    fiveMins = i % 5;
    if (fiveMins == 0) {
      leds[i].r = 100;
      leds[i].g = 100;
      leds[i].b = 100;
    }
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255 / dimming;
  leds[(now.minute() + LEDOffset) % 60].g = 255 / dimming;
  leds[(now.second() + LEDOffset) % 60].b = 255 / dimming;
}
//
void minimalMilliSec(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = (millis() - newSecTime);
    newSecTime = millis();
  }
  // set hour, min & sec LEDs
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  subSeconds = (((millis() - newSecTime) * 60) / cyclesPerSec) % 60;  // This divides by 733, but should be 1000 and not sure why???
  // Millisec lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(subSeconds + LEDOffset) % 60].r = 50;
  leds[(subSeconds + LEDOffset) % 60].g = 50;
  leds[(subSeconds + LEDOffset) % 60].b = 50;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255 / dimming;
  leds[(now.minute() + LEDOffset) % 60].g = 255 / dimming;
  leds[(now.second() + LEDOffset) % 60].b = 255 / dimming;
}

// Pendulum will be at the bottom and left for one second and right for one second
void simplePendulum(DateTime now) {
  if (now.second() != old.second()) {
    old = now;
    cyclesPerSec = millis() - newSecTime;
    cyclesPerSecFloat = (float)cyclesPerSec;
    newSecTime = millis();
    if (swingBack == true) {
      swingBack = false;
    } else {
      swingBack = true;
    }
  }
  // set hour, min & sec LEDs
  fracOfSec = (millis() - newSecTime) / cyclesPerSecFloat;  // This divides by 733, but should be 1000 and not sure why???
  if (subSeconds < cyclesPerSec && swingBack == true) {
    pendulumPos = 27.0 + 3.4 * (1.0 + sin((3.14 * fracOfSec) - 1.57));
  }
  if (subSeconds < cyclesPerSec && swingBack == false) {
    pendulumPos = 27.0 + 3.4 * (1.0 + sin((3.14 * fracOfSec) + 1.57));
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  // Pendulum lights are set first, so hour/min/sec lights override and don't flicker as millisec passes
  leds[(pendulumPos + LEDOffset) % 60].r = 100;
  leds[(pendulumPos + LEDOffset) % 60].g = 100;
  leds[(pendulumPos + LEDOffset) % 60].b = 100;
  // The colours are set last, so if on same LED mixed colours are created
  leds[(hourPos + LEDOffset + 59) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255 / dimming;
  leds[(now.minute() + LEDOffset) % 60].g = 255 / dimming;
  leds[(now.second() + LEDOffset) % 60].b = 255 / dimming;
}

void breathingClock(DateTime now) {
  if (alarmTrig == false) {
    breathBrightness = 15.0 * (1.0 + sin((3.14 * millis() / 2000.0) - 1.57));
    for (int i = 0; i < numLEDs; i++) {
      fiveMins = i % 5;
      if (fiveMins == 0) {
        leds[i].r = breathBrightness + 5;
        leds[i].g = breathBrightness + 5;
        leds[i].b = breathBrightness + 5;
      } else {
        leds[i].r = 0;
        leds[i].g = 0;
        leds[i].b = 0;
      }
    }
  }
  unsigned char hourPos = ((now.hour() % 12) * 5 + (now.minute() + 6) / 12);
  leds[(hourPos + LEDOffset + 59) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset) % 60].r = 255 / dimming;
  leds[(hourPos + LEDOffset + 1) % 60].r = 255 / dimming;
  leds[(now.minute() + LEDOffset) % 60].g = 255 / dimming;
  leds[(now.second() + LEDOffset) % 60].b = 255 / dimming;
}


/*
  // Cycle through the color wheel, equally spaced around the belt
  void rainbowCycle(uint8_t wait)
  {
  uint16_t i, j;
  for (j=0; j < 384 * 5; j++)
    {     // 5 cycles of all 384 colors in the wheel
      for (i=0; i < numLEDs; i++)
        {
          // tricky math! we use each pixel as a fraction of the full 384-color
          // wheel (thats the i / strip.numPixels() part)
          // Then add in j which makes the colors go around per pixel
          // the % 384 is to make the wheel cycle around
          strip.setPixelColor(i, Wheel(((i * 384 / numLEDs) + j) % 384));
        }
      delay(wait);
    }
  }

  //Input a value 0 to 384 to get a color value.
  //The colours are a transition r - g - b - back to r

  uint32_t Wheel(uint16_t WheelPos)
  {
  byte r, g, b;
  switch(WheelPos / 128)
  {
    case 0:
      r = 127 - WheelPos % 128; // red down
      g = WheelPos % 128;       // green up
      b = 0;                    // blue off
      break;
    case 1:
      g = 127 - WheelPos % 128; // green down
      b = WheelPos % 128;       // blue up
      r = 0;                    // red off
      break;
    case 2:
      b = 127 - WheelPos % 128; // blue down
      r = WheelPos % 128;       // red up
      g = 0;                    // green off
      break;
  }
  return(strip.Color(r,g,b));
  }
*/

1,000 lines of code!?! Mine is 490 and that includes functions to test the LED's, adjust for daylight savings time, set the time and do a sparkle show at noon.

Sorry, I don't have the time today to go through your code.

Mine's 50.

Hi xfpd,
That's fantastic, thanks very much for that.
I have uploaded the new code to the ATMega328, so I will see later how the dimming works later after 19.00, as I have changed that from the 18.00 you set.
I know I'm being cheeky, but did you manage to do anything re the DST? If not, no problem, I'll work with what you have sent me.
Many thanks again.

Very nice, that you found and made the dimming change. I picked a high latitude, winter, time. The dimming value of 4 means "63" is the maximum nighttime brightness, which seems bright to me... you might want the dimming divisor to be 8 or 16 if the Neopixels are too bright.

Sorry... I forgot to ask... what are the time-change dates where you live? I have lost touch with time change from decades of night work and mobile phones keeping time for me.

I'll check the brightness later, when the dimming kicks in, and see if the divisor needs to be increased.
I'm in the UK, so the dates for DST are the last Sunday in March and the last Sunday in October.
Thanks

I should be able to find code to find final Sunday in a month... (but first, a try of my own)

Thinking our loud... It seems the last Sunday can fall on 23 to 29 depending on the weekday of the first of the month. Standard time (+/- 0 hours) is autumn, so we are only interested in the vernal time change (standard time + 1 hour). Which means... when the month is 3 to 10 (inclusive) and the date is 23 to 29 (depending on the weekday (0 through 6) of the date 3/1), "thisHour = now.hour() + DST (1 or 0)"...

update: I just found the library DST_RTC that should give your sketch "DST" awareness... playing with the library now... update to update: DTS_RTC is made for US tz... dates are 8 to 14 March and 25 - 31 October... but the logic looks like my incomplete logic in my simulation (post #6)... seeing where I can improve/correct my logic. "BRB" as the kids say.

https://www.arduino.cc/reference/en/libraries/dst-rtc/

Hi xfpd,
I had a look at the DST_RTC library and have tried to incorporate into my sketch (the one you added the automatic dimming to) but I'm getting nowhere. I am just tying myself in knots.
Have you managed to see if DST can be added?
Thanks

Yes, DST can be added. The values inside the DST_RTC library are not "last Sunday" rather "second Sunday"... and different for US and UK... I am untying the knots to add DST as a function, rather than embedded in the loop() function.

The dimming code worked for me. Did it work for you?

Yes, the dimming code did work, though I increased the divisor to 8 to reduce the brightness further.
I'm not sure that I understand what you are trying to do with the DST but it got me baffled.
In the DST_RTC library the DST_RTC.cpp file, when opened in Notepad, has example coding for both the US and the EU. Though the EU DST rules are not exactly the same as the UK, they are close enough for what I need.
Can this coding be used?
Thanks

Good to know... I will put that in the simulation, also.

DST to me means DAYLIGHT SAVING TIME (spring/summer/"spring forward one hour") as opposed to STANDARD TIME (autumn/winter/"fall back one hour"). Therefore DST will add 1 hour (and NOT-DST will add 0 hours). Politics got in the way of determining the start of Autumn and Spring, and over the years, the months and dates have changed, although Sunday seems to be the constant (however; the library uses second Sunday, and not the last Sundays as you stated).

See post #19
Programmatically; Finding "the last" Sunday requires finding the FIRST date that can be the "Last Sunday" and also the LAST date that can be the "Last Sunday"... and for your area the FIRST date is 23 while the LAST date is 29. If a month begins on a Sunday, the "last Sunday" will be the 29th. If a month begins on a Saturday, the "last Sunday" will be on the 23rd. The month and hour start is straight-forward (if month > X and < Y... and... if hour > 2)... from there, DST checked every "time" loop and is +1 for summer, +0 for winter. More knots? Sorry. : )

On with the fun...

Let me see if I can help:

First, let:
yy = year - 2000
(so that, for example, yy is 24 in the year 2024)

Then let:
x1 = (5 + yy + (yy / 4)) % 7
and let:
x2 = (2 + yy + (yy / 4)) % 7

Then, your DST change dates are:
day (31 - x1) of March
and
day (31 - x2) of October

Is that any help?

Formula:

int yy = 24;
void setup() {
  Serial.begin(115200);
  int x1 = (5 + yy + (yy / 4)) % 7;
  int x2 = (2 + yy + (yy / 4)) % 7;
  Serial.println(31 - x1);
  Serial.println(31 - x2);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Result:

31
27

Works... and I see my error in "23 - 29" being penultimate Sunday... oops.

What are the significance of 5 and 2?