Trying to set button increments by +10 or -10

I'm trying to modify a sketch where when adjusting the start/end times of a function in the menu screen, it increases or decreases by 1 minute at a time. This is far too slow. I'd like to adjust it so it increases or decreases by 10 minutes at a time. I've seen similar posts on it, including one where the OP was modifying the actual sketch I'm also working with. The problem is, those suggestions result in an error.

Here's what the original sketch has...

if(menuCount == 3){
    //set start time for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Start");
    lcd.setCursor(0,1);
    printMins(oneStartMins, true);
    
    if(plus.isPressed() && oneStartMins < 1440){
        oneStartMins++;
        if(onePhotoPeriod >0){onePhotoPeriod--;}
        else{onePhotoPeriod=1439;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && oneStartMins > 0){
        oneStartMins--;
        if(onePhotoPeriod<1439){onePhotoPeriod++;}
        else{onePhotoPeriod=0;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

The suggestions I came across said to use '+10' and '-10' in place of '++' and '--'.

if(menuCount == 3){
    //set start time for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Start");
    lcd.setCursor(0,1);
    printMins(oneStartMins, true);
    
    if(plus.isPressed() && oneStartMins < 1440){
        oneStartMins+10;
        if(onePhotoPeriod >0){onePhotoPeriod-10;}
        else{onePhotoPeriod=1439;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && oneStartMins > 0){
        oneStartMins-10;
        if(onePhotoPeriod<1439){onePhotoPeriod+10;}
        else{onePhotoPeriod=0;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

But then the compiler throws an error... no match for 'operator+=', and no match for 'operator-='. What am I doing wrong?

Should be: oneStartMins = oneStartMins +10;

That will add 10 to oneStartMins

1 Like

I see no "+=" or "-=" in your snippet. Perhaps you tried unsuccessfully to use the language feature known as compound assignment. It would look like

       if (onePhotoPeriod > 0) {onePhotoPeriod -= 10;}

and similarly use

        if (onePhotoPeriod < 1439) {onePhotoPeriod += 10;}

a7

My apologies... I edited that by hand instead of c/p'ing again, and edited it wrong for the post. When using oneStartMins += 10; it gives the same error. Jim-p's suggestion worked though.

Awesome... that worked. Thank you very much. :slight_smile:

It should not. Please post a sketch where what you wrote was an error. You did something else that made it one.

a7

Here's the original sketch, edited for my Arduino Mega pinout, with only the oneStartMins+=10; edited in (menuCount == 3) section. I tried oneStartMins+=10, and oneStartMins += 10. Both give the same error.

/*
  // Typhon firmware
  // v0.3 alpha 2011-16-11
  // N. Enders, R. Ensminger
  //
  // This sketch provides firmware for the Typhon LED controller.
  // It provides a structure to fade 4 independent channels of LED lighting
  // on and off each day, to simulate sunrise and sunset.
  //
  // Current work in progress:
  // - store all LED variables in EEPROM so they are not reset by a loss of power
  // - allow for signals to be inverted for buckpucks or other drivers that consider 0 to be "on"
  //
  // Future developments may include:
  // - moon phase simulation
  // - storm simulation
  // - support for plugin hardware modules for temperature, pH, relay control, etc.
  //
  // Sketch developed in Arduino-22
  // Requires LiquidCrystal, Wire, EEPROM, EEPROMVar, and Button libraries.
  // Button is available here: http://www.arduino.cc/playground/Code/Button
  // EEPROMVar is available here: http://www.arduino.cc/playground/uploads/Profiles/EEPROMVar_01.zip
*/

// include the libraries:
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Button.h>
#include <EEPROM.h>
#include "EEPROMVar.h"


/**** Define Variables & Constants ****/
/**************************************/

// set the RTC's I2C address
#define DS1307_I2C_ADDRESS 0x68

// create the LCD
LiquidCrystal lcd(30, 31, 32, 33, 34, 35);

// set up backlight
int bkl         = 45;        // backlight pin
byte bklIdle    = 100;       // PWM value for backlight at idle
byte bklOn      = 255;       // PWM value for backlight when on
int bklDelay    = 10000;    // ms for the backlight to idle before turning off
unsigned long bklTime = 0;  // counter since backlight turned on

// create the menu counter
int menuCount   = 1;
int menuSelect = 0;

//create the plus and minus navigation delay counter with its initial maximum of 250.
byte btnMaxDelay = 200;
byte btnMinDelay = 25;
byte btnMaxIteration = 5;
byte btnCurrIteration;

//create manual override variables
boolean override = false;
byte overmenu = 0;
int overpercent = 0;

// create the buttons
Button menu     = Button(54, PULLDOWN);
Button select   = Button(55, PULLDOWN);
Button plus     = Button(56, PULLDOWN);
Button minus    = Button(57, PULLDOWN);
Button bklight  = Button(58, PULLDOWN);

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight.
int oldMinCounter = 0;      // counter that resets at midnight.
int oneLed = 9;             // pin for channel 1
int twoLed = 10;            // pin for channel 2
int threeLed = 11;          // pin for channel 3
int fourLed = 3;            // pin for channel 4

int oneVal = 0;             // current value for channel 1
int twoVal = 0;             // current value for channel 2
int threeVal = 0;           // current value for channel 3
int fourVal = 0;            // current value for channel 4


int Relay = 63;           // pin for pump
int feedOneStart = 1030;  // start time for feeding #1
int feedOneStop = 1035;  // stop time for feeding #1

int feedTwoStart = 1040;  // start time for feeding #2
int feedTwoStop = 1045;  // stop time for feeding #2



// Variables making use of EEPROM memory:

EEPROMVar<int> oneStartMins = 750;     // minute to start this channel.
EEPROMVar<int> onePhotoPeriod = 720;   // photoperiod in minutes for this channel.
EEPROMVar<int> oneMax = 100;           // max intensity for this channel, as a percentage
EEPROMVar<int> oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset

EEPROMVar<int> twoStartMins = 810;
EEPROMVar<int> twoPhotoPeriod = 600;
EEPROMVar<int> twoMax = 100;
EEPROMVar<int> twoFadeDuration = 60;

EEPROMVar<int> threeStartMins = 810;
EEPROMVar<int> threePhotoPeriod = 600;
EEPROMVar<int> threeMax = 100;
EEPROMVar<int> threeFadeDuration = 60;

EEPROMVar<int> fourStartMins = 480;
EEPROMVar<int> fourPhotoPeriod = 510;
EEPROMVar<int> fourMax = 100;
EEPROMVar<int> fourFadeDuration = 60;

// variables to invert the output PWM signal,
// for use with drivers that consider 0 to be "on"
// i.e. buckpucks. If you need to provide an inverted
// signal on any channel, set the appropriate variable to true.
boolean oneInverted = false;
boolean twoInverted = false;
boolean threeInverted = false;
boolean fourInverted = false;


/****** RTC Functions ******/
/***************************/

// Convert decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val / 10 * 16) + (val % 10) );
}

// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val)
{
  return ( (val / 16 * 10) + (val % 16) );
}

// Sets date and time, starts the clock
void setDate(byte second,        // 0-59
             byte minute,        // 0-59
             byte hour,          // 1-23
             byte dayOfWeek,     // 1-7
             byte dayOfMonth,    // 1-31
             byte month,         // 1-12
             byte year)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time
void getDate(byte *second,
             byte *minute,
             byte *hour,
             byte *dayOfWeek,
             byte *dayOfMonth,
             byte *month,
             byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down

int   setLed(int mins,         // current time in minutes
             int ledPin,        // pin for this channel of LEDs
             int start,         // start time for this channel of LEDs
             int period,        // photoperiod for this channel of LEDs
             int fade,          // fade duration for this channel of LEDs
             int ledMax,        // max value for this channel
             boolean inverted   // true if the channel is inverted
            )  {
  int val = 0;

  //fade up
  if (mins > start || mins <= start + fade)  {
    val = map(mins - start, 0, fade, 0, ledMax);
  }
  //fade down
  if (mins > start + period - fade && mins <= start + period)  {
    val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
  }
  //off or post-midnight run.
  if (mins <= start || mins > start + period)  {
    if ((start + period) % 1440 < start && (start + period) % 1440 > mins )
    {
      val = map((start + period - mins) % 1440, 0, fade, 0, ledMax);
    }
    else
      val = 0;
  }


  if (val > ledMax)  {
    val = ledMax;
  }
  if (val < 0) {
    val = 0;
  }

  if (inverted) {
    analogWrite(ledPin, map(val, 0, 100, 255, 0));
  }
  else {
    analogWrite(ledPin, map(val, 0, 100, 0, 255));
  }
  if (override) {
    val = overpercent;
  }
  return val;
}

/**** Display Functions ****/
/***************************/

//button hold function
int btnCurrDelay(byte curr)
{
  if (curr == btnMaxIteration)
  {
    btnCurrIteration = btnMaxIteration;
    return btnMaxDelay;
  }
  else if (btnCurrIteration == 0)
  {
    return btnMinDelay;
  }
  else
  {
    btnCurrIteration--;
    return btnMaxDelay;
  }
}

// format a number of minutes into a readable time (24 hr format)
void printMins(int mins,       //time in minutes to print
               boolean ampm    //print am/pm?
              )  {
  int hr = (mins % 1440) / 60;
  int mn = mins % 60;
  if (hr < 10) {
    lcd.print(" ");
  }
  lcd.print(hr);
  lcd.print(":");
  if (mn < 10) {
    lcd.print("0");
  }
  lcd.print(mn);
}

// format hours, mins, secs into a readable time (24 hr format)
void printHMS (byte hr,
               byte mn,
               byte sec      //time to print
              )
{

  if (hr < 10) {
    lcd.print(" ");
  }
  lcd.print(hr, DEC);
  lcd.print(":");
  if (mn < 10) {
    lcd.print("0");
  }
  lcd.print(mn, DEC);
  lcd.print(":");
  if (sec < 10) {
    lcd.print("0");
  }
  lcd.print(sec, DEC);
}
void ovrSetAll(int pct) {
  analogWrite(oneLed, map(pct, 0, 100, 0, 255));
  analogWrite(twoLed, map(pct, 0, 100, 0, 255));
  analogWrite(threeLed, map(pct, 0, 100, 0, 255));
  analogWrite(fourLed, map(pct, 0, 100, 0, 255));
}

/**** Setup ****/
/***************/

void setup() {
  Wire.begin();
  pinMode(bkl, OUTPUT);
  lcd.begin(16, 2);
  digitalWrite(bkl, HIGH);
  lcd.print("Typhon-Reef");
  lcd.setCursor(0, 1);
  lcd.print("");
  delay(5000);
  lcd.clear();
  analogWrite(bkl, bklIdle);
  btnCurrIteration = btnMaxIteration;

  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, LOW);
}

/***** Loop *****/
/****************/

void loop() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDate(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  oldMinCounter = minCounter;
  minCounter = hour * 60 + minute;

  //reset plus & minus acceleration counters if the button's state has changed
  if (plus.stateChanged())
  {
    btnCurrDelay(btnMaxIteration);
  }
  if (minus.stateChanged())
  {
    btnCurrDelay(btnMaxIteration);
  }


  /////// Feeding
  if (minCounter >= feedOneStart) {
    digitalWrite(Relay, HIGH);
  }
  
  if (minCounter >= feedOneStop) {
    digitalWrite(Relay, LOW);
  }

  if (minCounter >= feedTwoStart) {
    digitalWrite(Relay, HIGH);
  }

  if (minCounter >= feedTwoStop) {
    digitalWrite(Relay, LOW);
  }


  //check & set fade durations
  if (oneFadeDuration > onePhotoPeriod / 2 && onePhotoPeriod > 0) {
    oneFadeDuration = onePhotoPeriod / 2;
  }
  if (oneFadeDuration < 1) {
    oneFadeDuration = 1;
  }

  if (twoFadeDuration > twoPhotoPeriod / 2 && twoPhotoPeriod > 0) {
    twoFadeDuration = twoPhotoPeriod / 2;
  }
  if (twoFadeDuration < 1) {
    twoFadeDuration = 1;
  }

  if (threeFadeDuration > threePhotoPeriod / 2 && threePhotoPeriod > 0) {
    threeFadeDuration = threePhotoPeriod / 2;
  }
  if (threeFadeDuration < 1) {
    threeFadeDuration = 1;
  }

  if (fourFadeDuration > fourPhotoPeriod / 2 && fourPhotoPeriod > 0) {
    fourFadeDuration = fourPhotoPeriod / 2;
  }
  if (fourFadeDuration < 1) {
    fourFadeDuration = 1;
  }

  //check & set any time functions


  //set outputs
  if (!override) {
    oneVal = setLed(minCounter, oneLed, oneStartMins, onePhotoPeriod, oneFadeDuration, oneMax, oneInverted);
    twoVal = setLed(minCounter, twoLed, twoStartMins, twoPhotoPeriod, twoFadeDuration, twoMax, twoInverted);
    threeVal = setLed(minCounter, threeLed, threeStartMins, threePhotoPeriod, threeFadeDuration, threeMax, threeInverted);
    fourVal = setLed(minCounter, fourLed, fourStartMins, fourPhotoPeriod, fourFadeDuration, fourMax, fourInverted);
  }
  else {
    ovrSetAll(overpercent);
  }


  //turn the backlight off and reset the menu if the idle time has elapsed
  if (bklTime + bklDelay < millis() && bklTime > 0 ) {
    analogWrite(bkl, bklIdle);
    menuCount = 1;
    lcd.clear();
    bklTime = 0;
  }

  //iterate through the menus
  if (menu.uniquePress()) {
    analogWrite(bkl, bklOn);
    bklTime = millis();
    if (menuCount < 20) {
      menuCount++;
    } else {
      menuCount = 1;
    }
    lcd.clear();
  }
  if (menuCount == 1) {
    //main screen turn on!!!
    if (minCounter > oldMinCounter) {
      lcd.clear();
    }
    lcd.setCursor(0, 0);
    printHMS(hour, minute, second);
    lcd.setCursor(0, 1);
    lcd.print(oneVal);
    lcd.setCursor(4, 1);
    lcd.print(twoVal);
    lcd.setCursor(8, 1);
    lcd.print(threeVal);
    lcd.setCursor(12, 1);
    lcd.print(fourVal);
    //debugging function to use the select button to advance the timer by 1 minute
    //if(select.uniquePress()){setDate(second, minute+1, hour, dayOfWeek, dayOfMonth, month, year);}
  }

  if (menuCount == 2) {
    //Manual Override Menu
    lcd.setCursor(0, 0);
    lcd.print("Manual Overrides");
    lcd.setCursor(0, 1);
    lcd.print("All: ");
    if (select.uniquePress()) {
      if (menuSelect < 3) {
        menuSelect++;
      }
      else {
        menuSelect = 0;
      }
      bklTime = millis();
    }

    if (menuSelect == 0) {
      lcd.print("Timer");
      override = false;
    }
    if (menuSelect == 1) {
      lcd.print("ON   ");
      overpercent = 100;
      override = true;
    }
    if (menuSelect == 2) {
      lcd.print("OFF  ");
      overpercent = 0;
      override = true;
    }
    if (menuSelect == 3) {
      override = true;
      lcd.print(overpercent, DEC);
      lcd.print("%  ");
      if (plus.isPressed() && overpercent < 100)
      {
        overpercent++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }

      if (minus.isPressed() && overpercent > 0)
      {
        overpercent--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }



  if (menuCount == 3) {
    //set start time for channel one
    lcd.setCursor(0, 0);
    lcd.print("Channel 1 Start");
    lcd.setCursor(0, 1);
    printMins(oneStartMins, true);

    if (plus.isPressed() && oneStartMins < 1440) {
      oneStartMins+=10;
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && oneStartMins > 0) {
      oneStartMins--;
      if (onePhotoPeriod < 1439) {
        onePhotoPeriod++;
      }
      else {
        onePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 4) {
    //set end time for channel one
    lcd.setCursor(0, 0);
    lcd.print("Channel 1 End");
    lcd.setCursor(0, 1);
    printMins(oneStartMins + onePhotoPeriod, true);
    if (plus.isPressed()) {
      if (onePhotoPeriod < 1439) {
        onePhotoPeriod++;
      }
      else {
        onePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed()) {
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 5) {
    //set fade duration for channel one
    lcd.setCursor(0, 0);
    lcd.print("Channel 1 Fade");
    lcd.setCursor(0, 1);
    printMins(oneFadeDuration, false);
    if (plus.isPressed() && (oneFadeDuration < onePhotoPeriod / 2 || oneFadeDuration == 0)) {
      oneFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && oneFadeDuration > 1) {
      oneFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 6) {
    //set intensity for channel one
    lcd.setCursor(0, 0);
    lcd.print("Channel 1 Max");
    lcd.setCursor(1, 1);
    lcd.print(oneMax);
    lcd.print("  ");
    if (plus.isPressed() && oneMax < 100) {
      oneMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && oneMax > 0) {
      oneMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 7) {
    //set start time for channel two
    lcd.setCursor(0, 0);
    lcd.print("Channel 2 Start");
    lcd.setCursor(0, 1);
    printMins(twoStartMins, true);
    if (plus.isPressed() && twoStartMins < 1440) {
      twoStartMins++;
      if (twoPhotoPeriod > 0) {
        twoPhotoPeriod--;
      }
      else {
        twoPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && twoStartMins > 0) {
      twoStartMins--;
      if (twoPhotoPeriod < 1439) {
        twoPhotoPeriod++;
      }
      else {
        twoPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 8) {
    //set end time for channel two
    lcd.setCursor(0, 0);
    lcd.print("Channel 2 End");
    lcd.setCursor(0, 1);
    printMins(twoStartMins + twoPhotoPeriod, true);
    if (plus.isPressed()) {
      if (twoPhotoPeriod < 1439) {
        twoPhotoPeriod++;
      }
      else {
        twoPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed()) {
      if (twoPhotoPeriod > 0) {
        twoPhotoPeriod--;
      }
      else {
        twoPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 9) {
    //set fade duration for channel two
    lcd.setCursor(0, 0);
    lcd.print("Channel 2 Fade");
    lcd.setCursor(0, 1);
    printMins(twoFadeDuration, false);
    if (plus.isPressed() && (twoFadeDuration < twoPhotoPeriod / 2 || twoFadeDuration == 0)) {
      twoFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && twoFadeDuration > 1) {
      twoFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 10) {
    //set intensity for channel two
    lcd.setCursor(0, 0);
    lcd.print("Channel 2 Max");
    lcd.setCursor(1, 1);
    lcd.print(twoMax);
    lcd.print("  ");
    if (plus.isPressed() && twoMax < 100) {
      twoMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && twoMax > 0) {
      twoMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 11) {
    //set start time for channel three
    lcd.setCursor(0, 0);
    lcd.print("Channel 3 Start");
    lcd.setCursor(0, 1);
    printMins(threeStartMins, true);
    if (plus.isPressed() && threeStartMins < 1440) {
      threeStartMins++;
      if (threePhotoPeriod > 0) {
        threePhotoPeriod--;
      }
      else {
        threePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && threeStartMins > 0) {
      threeStartMins--;
      if (threePhotoPeriod < 1439) {
        threePhotoPeriod++;
      }
      else {
        threePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 12) {
    //set end time for channel three
    lcd.setCursor(0, 0);
    lcd.print("Channel 3 End");
    lcd.setCursor(0, 1);
    printMins(threeStartMins + threePhotoPeriod, true);
    if (plus.isPressed()) {
      if (threePhotoPeriod < 1439) {
        threePhotoPeriod++;
      }
      else {
        threePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed()) {
      if (threePhotoPeriod > 0) {
        threePhotoPeriod--;
      }
      else {
        threePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 13) {
    //set fade duration for channel three
    lcd.setCursor(0, 0);
    lcd.print("Channel 3 Fade");
    lcd.setCursor(0, 1);
    printMins(threeFadeDuration, false);
    if (plus.isPressed() && (threeFadeDuration < threePhotoPeriod / 2 || threeFadeDuration == 0)) {
      threeFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && threeFadeDuration > 1) {
      threeFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 14) {
    //set intensity for channel three
    lcd.setCursor(0, 0);
    lcd.print("Channel 3 Max");
    lcd.setCursor(1, 1);
    lcd.print(threeMax);
    lcd.print("  ");
    if (plus.isPressed() && threeMax < 100) {
      threeMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && threeMax > 0) {
      threeMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 15) {
    //set start time for channel four
    lcd.setCursor(0, 0);
    lcd.print("Channel 4 Start");
    lcd.setCursor(0, 1);
    printMins(fourStartMins, true);
    if (plus.isPressed() && fourStartMins < 1440) {
      fourStartMins++;
      if (fourPhotoPeriod > 0) {
        fourPhotoPeriod--;
      }
      else {
        fourPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && fourStartMins > 0) {
      fourStartMins--;
      if (fourPhotoPeriod < 1439) {
        fourPhotoPeriod++;
      }
      else {
        fourPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 16) {
    //set end time for channel four
    lcd.setCursor(0, 0);
    lcd.print("Channel 4 End");
    lcd.setCursor(0, 1);
    printMins(fourStartMins + fourPhotoPeriod, true);
    if (plus.isPressed()) {
      if (fourPhotoPeriod < 1439) {
        fourPhotoPeriod++;
      }
      else {
        fourPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed()) {
      if (fourPhotoPeriod > 0) {
        fourPhotoPeriod--;
      }
      else {
        fourPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 17) {
    //set fade duration for channel four
    lcd.setCursor(0, 0);
    lcd.print("Channel 4 Fade");
    lcd.setCursor(0, 1);
    printMins(fourFadeDuration, false);
    if (plus.isPressed() && (fourFadeDuration < fourPhotoPeriod / 2 || fourFadeDuration == 0)) {
      fourFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && fourFadeDuration > 1) {
      fourFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 18) {
    //set intensity for channel four
    lcd.setCursor(0, 0);
    lcd.print("Channel 4 Max");
    lcd.setCursor(1, 1);
    lcd.print(fourMax);
    lcd.print("   ");
    if (plus.isPressed() && fourMax < 100) {
      fourMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && fourMax > 0) {
      fourMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 19) {
    //set hours
    lcd.setCursor(0, 0);
    lcd.print("Set Time: Hrs");
    lcd.setCursor(0, 1);
    printHMS(hour, minute, second);
    if (plus.isPressed() && hour < 23) {
      hour++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && hour > 0) {
      hour--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 20) {
    //set minutes
    lcd.setCursor(0, 0);
    lcd.print("Set Time: Mins");
    lcd.setCursor(0, 1);
    printHMS(hour, minute, second);
    if (plus.isPressed() && minute < 59) {
      minute++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && minute > 0) {
      minute--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
}
Typhon_-_Original_-_testing:506:19: error: no match for 'operator+=' (operand types are 'EEPROMVar<int>' and 'int')

       oneStartMins+=10;

       ~~~~~~~~~~~~^~~~

exit status 1

no match for 'operator+=' (operand types are 'EEPROMVar<int>' and 'int')

Thanks. This is why posting snippets is fraught!

Here

// Variables making use of EEPROM memory:

EEPROMVar<int> oneStartMins = 750;     // minute to start this channel.

is the explanation - what looked like an ordinary variable was in fact an instance of a class designed to make using EEPROM easier.

The authors of that library did not choose to implement (override) the compound assignment operator(s). Lazy or maybe it's harder than I realize.

I am curious about

#include "EEPROMVar.h"

and wonder if it means you are potentially hammering on the EEPROM inadvertently - EEPROM has a limited number of writes for its lifetime. It's a huge number, but processors are very fast and can easily write too much sooner than you'd like. I did not read your code, so it is possible that you are taking care not to. Write too often to the EEPROM.

The github page for the library has somethings to say about it, and some ways to protect yourself. If you haven't, it might be worth a few minutes.

You may have found a different library than I, but the caveats are just sad truths.

a7

1 Like

As far as I knew, EEPROM can be written to 100,000 times in it's lifetime. And as far as I understand this script, it only stores the variables in EEPROM, and only rewrites them when the settings are changed in the menu. So as long as I don't change them more than 100,000 times, I should be fine.

.... I think. :stuck_out_tongue:

Edit: EEPROMVar stores the settings in EEPROM, so when the device lose power, the settings remain. Using the regular EEPROM, ie: no EEPROMVar.h, it doesn't keep the settings after reboot.

Well, I just realized something I should have seen earlier... the thread I found where the OP was modifying the same sketch, the suggestion was to +10 and -10, but doing so means you can't adjust the 01's, only 10's. So, I'm only using +10 for count up, then the regular -1 if I need to count back a few steps. Unless I add separate +10 and -10 buttons(?).

Here's my current edited version in full. Can you suggest a better way? Is it possible to add a longPress duration to determine if going by +1/-1 or +10/-10 depending on the button press?

/*
  // Sketch is a modified version of the Typhon firmware v0.3 alpha 2011-16-11,
  // Originally developed by N. Enders and R. Ensminger, over at Reef Central forums.
  // https://forums.reefcentral.com/threads/who-wants-a-cheap-simple-arduino-based-led-controller.1187729/
*/

// include the libraries:
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Button.h>
#include <EEPROM.h>
#include <EEPROMVar.h>
#include <DHT.h>

/////  Setup DS18B20 Sensor
#include "OneWire.h"
#include "DallasTemperature.h"
#define ONE_WIRE_BUS 62 //Define the pin of the DS18B20
#define TEMPERATURE_PRECISION 12

int fanPWMpin = 63;    //Define the pin of the Fan
const int HtempMin = 50.0;    //Define temp when heatsink fan starts (25C = 77F)
const int HtempMax = 95.0;   //Define temp when heatsink fan is 100% (35C = 95F)

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

/**** Define Variables & Constants ****/
/**************************************/

// Constants
#define DHTPIN 49     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22
DHT dht(DHTPIN, DHTTYPE);

// set the RTC's I2C address
#define DS1307_I2C_ADDRESS 0x68

// create the LCD
LiquidCrystal lcd(30, 31, 32, 33, 34, 35);

// set up backlight
int bkl         = 45;        // backlight pin
byte bklIdle    = 100;       // PWM value for backlight at idle
byte bklOn      = 255;       // PWM value for backlight when on
int bklDelay    = 10000;    // ms for the backlight to idle before turning off
unsigned long bklTime = 0;  // counter since backlight turned on

// create the menu counter
int menuCount   = 1;
int menuSelect = 0;

//create the plus and minus navigation delay counter with its initial maximum of 250.
byte btnMaxDelay = 200;
byte btnMinDelay = 25;
byte btnMaxIteration = 5;
byte btnCurrIteration;

//create manual override variables
boolean override = false;
byte overmenu = 0;
int overpercent = 0;

// create the buttons
Button menu     = Button(54, PULLDOWN);
Button select   = Button(55, PULLDOWN);
Button plus     = Button(56, PULLDOWN);
Button minus    = Button(57, PULLDOWN);
Button bklight  = Button(58, PULLDOWN);

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight.
int oldMinCounter = 0;      // counter that resets at midnight.
int oneLed = 2;             // pin for Cool White
int twoLed = 3;             // pin for Warm White
int threeLed = 4;           // pin for Photo Red
int fourLed = 5;            // pin for Far Red

int oneVal = 0;             // current value for Cool White
int twoVal = 0;             // current value for Warm White
int threeVal = 0;           // current value for Photo Red
int fourVal = 0;            // current value for Far Red

int onePump = 64;           // pin for pump #1
int twoPump = 65;           // pin for pump #2


// Variables making use of EEPROM memory:

EEPROMVar<int> oneStartMins = 1319;     // minute to start this channel.
EEPROMVar<int> onePhotoPeriod = 720;    // photoperiod in minutes for this channel.
EEPROMVar<int> oneMax = 100;            // max intensity for this channel, as a percentage
EEPROMVar<int> oneFadeDuration = 30;    // duration of the fade on and off for sunrise and sunset for this channel.

EEPROMVar<int> twoStartMins = 1334;
EEPROMVar<int> twoPhotoPeriod = 720;
EEPROMVar<int> twoMax = 100;
EEPROMVar<int> twoFadeDuration = 30;

EEPROMVar<int> threeStartMins = 1349;
EEPROMVar<int> threePhotoPeriod = 720;
EEPROMVar<int> threeMax = 100;
EEPROMVar<int> threeFadeDuration = 30;

EEPROMVar<int> fourStartMins = 1364;
EEPROMVar<int> fourPhotoPeriod = 720;
EEPROMVar<int> fourMax = 100;
EEPROMVar<int> fourFadeDuration = 30;


/// Pump 1 ////////////////////////////
/// Feeding #1
EEPROMVar<int> feedOneStart = 1209;
EEPROMVar<int> feedOneStop = 5;

/// Feeding #2
EEPROMVar<int> feedTwoStart = 1219;
EEPROMVar<int> feedTwoStop = 5;

/// Feeding #3
EEPROMVar<int> feedThreeStart = 1219;
EEPROMVar<int> feedThreeStop = 5;

/// Feeding #4
EEPROMVar<int> feedFourStart = 1219;
EEPROMVar<int> feedFourStop = 5;

/// Pump 2 ////////////////////////////
/// Feeding #1
EEPROMVar<int> feedFiveStart = 1219;
EEPROMVar<int> feedFiveStop = 5;

/// Feeding #2
EEPROMVar<int> feedSixStart = 1219;
EEPROMVar<int> feedSixStop = 5;

/// Feeding #3
EEPROMVar<int> feedSevenStart = 1219;
EEPROMVar<int> feedSevenStop = 5;

/// Feeding #4
EEPROMVar<int> feedEightStart = 1219;
EEPROMVar<int> feedEightStop = 5;


// variables to invert the output PWM signal,
// for use with drivers that consider 0 to be "on"
// i.e. buckpucks. If you need to provide an inverted
// signal on any channel, set the appropriate variable to true.
boolean oneInverted = false;
boolean twoInverted = false;
boolean threeInverted = false;
boolean fourInverted = false;

/****** RTC Functions ******/
/***************************/

// Convert decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val / 10 * 16) + (val % 10) );
}

// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val)
{
  return ( (val / 16 * 10) + (val % 16) );
}

// Sets date and time, starts the clock
void setDate(byte second,        // 0-59
             byte minute,        // 0-59
             byte hour,          // 1-23
             byte dayOfWeek,     // 1-7
             byte dayOfMonth,    // 1-31
             byte month,         // 1-12
             byte year)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time
void getDate(byte *second,
             byte *minute,
             byte *hour,
             byte *dayOfWeek,
             byte *dayOfMonth,
             byte *month,
             byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down

int   setLed(int mins,         // current time in minutes
             int ledPin,        // pin for this channel of LEDs
             int start,         // start time for this channel of LEDs
             int period,        // photoperiod for this channel of LEDs
             int fade,          // fade duration for this channel of LEDs
             int ledMax,        // max value for this channel
             boolean inverted   // true if the channel is inverted
            )  {
  int val = 0;

  //fade up
  if (mins > start || mins <= start + fade)  {
    val = map(mins - start, 0, fade, 0, ledMax);
  }
  //fade down
  if (mins > start + period - fade && mins <= start + period)  {
    val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
  }
  //off or post-midnight run.
  if (mins <= start || mins > start + period)  {
    if ((start + period) % 1440 < start && (start + period) % 1440 > mins )
    {
      val = map((start + period - mins) % 1440, 0, fade, 0, ledMax);
    }
    else
      val = 0;
  }


  if (val > ledMax)  {
    val = ledMax;
  }
  if (val < 0) {
    val = 0;
  }

  if (inverted) {
    analogWrite(ledPin, map(val, 0, 100, 255, 0));
  }
  else {
    analogWrite(ledPin, map(val, 0, 100, 0, 255));
  }
  if (override) {
    val = overpercent;
  }
  return val;
}

/**** Display Functions ****/
/***************************/

//button hold function
int btnCurrDelay(byte curr)
{
  if (curr == btnMaxIteration)
  {
    btnCurrIteration = btnMaxIteration;
    return btnMaxDelay;
  }
  else if (btnCurrIteration == 0)
  {
    return btnMinDelay;
  }
  else
  {
    btnCurrIteration--;
    return btnMaxDelay;
  }
}

// format a number of minutes into a readable time (24 hr format)
void printMins(int mins,       //time in minutes to print
               boolean ampm    //print am/pm?
              )  {
  int hr = (mins % 1440) / 60;
  int mn = mins % 60;
  if (hr < 10) {
    lcd.print(" ");
  }
  lcd.print(hr);
  lcd.print(":");
  if (mn < 10) {
    lcd.print("0");
  }
  lcd.print(mn);
}

// format hours, mins, secs into a readable time (24 hr format)
void printHMS (byte hr,
               byte mn,
               byte sec      //time to print
              )
{
  if (hr < 10) {
    lcd.print(" ");
  }
  lcd.print(hr, DEC);
  lcd.print(":");
  if (mn < 10) {
    lcd.print("0");
  }
  lcd.print(mn, DEC);
  lcd.print(":");
  if (sec < 10) {
    lcd.print("0");
  }
  lcd.print(sec, DEC);
}

void printDate() {

  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  //  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  int hour = bcdToDec(Wire.read() & 01010010); //24 hour time
  int dayOfWeek = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  int dayOfMonth = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());


  //////   Uncomment the following to initially set the time and date
  //////   After you load the sketch, then comment out the section again, and reload the sketch 1 more time.
  //////   This prevents the sketch from resetting back to the beginning. ;)



  second = 0;
  minute = 20;
  hour = 0;
  dayOfWeek = 7;
  dayOfMonth = 8;
  month = 2;
  year = 25;

  ///   setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);


  //print the date EG   3/1/11 23:59:59
  //  lcd.print(dayOfWeek);

  switch (dayOfWeek) {
    case 1:
      lcd.print("Sun");
      break;
    case 2:
      lcd.print("Mon");
      break;
    case 3:
      lcd.print("Tue");
      break;
    case 4:
      lcd.print("Wed");
      break;
    case 5:
      lcd.print("Thu");
      break;
    case 6:
      lcd.print("Fri");
      break;
    case 7:
      lcd.print("Sat");
      break;
  }

  lcd.print(" ");
  if (dayOfMonth < 10) {
    lcd.print("0");
  }
  lcd.print(dayOfMonth);
  lcd.print(".");
  if (month < 10) {
    lcd.print("0");
  }
  lcd.print(month);
  //  lcd.print(".20");
  //  if (year < 10){
  //    lcd.print("0");
  //  }
  //  lcd.print(year);
}

void ovrSetAll(int pct) {
  analogWrite(oneLed, map(pct, 0, 100, 0, 255));
  analogWrite(twoLed, map(pct, 0, 100, 0, 255));
  analogWrite(threeLed, map(pct, 0, 100, 0, 255));
  analogWrite(fourLed, map(pct, 0, 100, 0, 255));
}

void checkTemp()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  delay(10);

  float temp1 = 0, temp2 = 0;

  //  lcd.setCursor(0, 2);
  //  lcd.print("T:");
  temp1 = sensors.getTempFByIndex(0);
  //  lcd.print(sensors.getTempFByIndex(0));
  //  lcd.print((char)223);
  //  lcd.print("F");

  //  lcd.setCursor(0, 3);
  //  lcd.print("Led:");
  temp2 = sensors.getTempFByIndex(1);
  //  lcd.print(sensors.getTempFByIndex(1));
  //  lcd.print((char)223);
  //  lcd.print("F");


  if (temp1 < 0) temp1 = 0;                  //if sensor not connected reading is -127 deg
  else if (temp1 > 99) temp1 = 99;
  if (temp2 < 0) temp2 = 0;
  else if (temp2 > 99) temp2 = 99;

  int tempval1 = int(temp1 * 10);
  int tempval2 = int(temp1 * 10);
  int fanSpeed1 = map(tempval1, (HtempMin * 10), (HtempMax * 10), 0, 255);   //---------heatsink 1 fan control
  int fanSpeed2 = map(tempval2, (HtempMin * 10), (HtempMax * 10), 0, 255);   //---------heatsink 2 fan control
  if (fanSpeed1 <= 0)
    fanSpeed1 = 0;
  if (fanSpeed1 > 255)
    fanSpeed1 = 255;

  if (fanSpeed2 <= 0)
    fanSpeed2 = 0;
  if (fanSpeed2 > 255)
    fanSpeed2 = 255;

  analogWrite(fanPWMpin, fanSpeed1);
  analogWrite(fanPWMpin, fanSpeed2);
  Serial.println(fanSpeed1);
  Serial.println(fanSpeed2);
  //   lcd.setCursor(0,1);
  //   lcd.print(fanSpeed);
}

/**** Setup ****/
/***************/

void setup() {

  Wire.begin();
  pinMode(bkl, OUTPUT);
  lcd.begin(20, 4);
  dht.begin();
  digitalWrite(bkl, HIGH);
  lcd.setCursor(6, 0);
  lcd.print("Welcome");
  lcd.setCursor(8, 1);
  lcd.print("To");
  lcd.setCursor(4, 2);
  lcd.print("The Garden");
  delay(5000);
  lcd.clear();
  analogWrite(bkl, bklIdle);
  btnCurrIteration = btnMaxIteration;
  sensors.begin();              // Start up the DS18B20 Temp library
  pinMode(fanPWMpin, OUTPUT);
  pinMode(onePump, OUTPUT);
  digitalWrite(onePump, LOW);
  pinMode(twoPump, OUTPUT);
  digitalWrite(twoPump, LOW);
}

/***** Loop *****/
/****************/

void loop() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  const char* ampm;  // Change to a pointer to a string

  getDate(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  oldMinCounter = minCounter;
  minCounter = hour * 60 + minute;

  // Wait a few seconds between measurements.
  //  delay(10);

  float celsius = dht.readTemperature(); // Read temperature in Celsius
  float fahrenheit = (celsius * 9 / 5) + 32; // Convert to Fahrenheit

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();

  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    lcd.print(F("Failed to read from DHT sensor!"));
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);

  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  {
    checkTemp();
  }

  //reset plus & minus acceleration counters if the button's state has changed
  if (plus.stateChanged())
  {
    btnCurrDelay(btnMaxIteration);
  }
  if (minus.stateChanged())
  {
    btnCurrDelay(btnMaxIteration);
  }


  //check & set fade durations
  if (oneFadeDuration > onePhotoPeriod / 2 && onePhotoPeriod > 0) {
    oneFadeDuration = onePhotoPeriod / 2;
  }
  if (oneFadeDuration < 1) {
    oneFadeDuration = 1;
  }

  if (twoFadeDuration > twoPhotoPeriod / 2 && twoPhotoPeriod > 0) {
    twoFadeDuration = twoPhotoPeriod / 2;
  }
  if (twoFadeDuration < 1) {
    twoFadeDuration = 1;
  }

  if (threeFadeDuration > threePhotoPeriod / 2 && threePhotoPeriod > 0) {
    threeFadeDuration = threePhotoPeriod / 2;
  }
  if (threeFadeDuration < 1) {
    threeFadeDuration = 1;
  }

  if (fourFadeDuration > fourPhotoPeriod / 2 && fourPhotoPeriod > 0) {
    fourFadeDuration = fourPhotoPeriod / 2;
  }
  if (fourFadeDuration < 1) {
    fourFadeDuration = 1;
  }

  //check & set any time functions


  //set outputs
  if (!override) {
    oneVal = setLed(minCounter, oneLed, oneStartMins, onePhotoPeriod, oneFadeDuration, oneMax, oneInverted);
    twoVal = setLed(minCounter, twoLed, twoStartMins, twoPhotoPeriod, twoFadeDuration, twoMax, twoInverted);
    threeVal = setLed(minCounter, threeLed, threeStartMins, threePhotoPeriod, threeFadeDuration, threeMax, threeInverted);
    fourVal = setLed(minCounter, fourLed, fourStartMins, fourPhotoPeriod, fourFadeDuration, fourMax, fourInverted);
  }
  else {
    ovrSetAll(overpercent);
  }

  /// Backlight Override //////////////////////

  if (bklight.uniquePress()) {
    analogWrite(bkl, bklOn);
    bklTime = millis();
  }

  //turn the backlight off and reset the menu if the idle time has elapsed
  if (bklTime + bklDelay < millis() && bklTime > 0 ) {
    analogWrite(bkl, bklIdle);
    menuCount = 1;
    lcd.clear();
    lcd.clear();
    bklTime = 0;
  }

  //iterate through the menus
  if (menu.uniquePress()) {
    analogWrite(bkl, bklOn);
    bklTime = millis();
    if (menuCount < 40) {
      menuCount++;
    } else {
      menuCount = 1;
    }
    lcd.clear();
  }
  if (menuCount == 1) {
    lcd.setCursor(0, 0);
    if (hour >= 12) {
      ampm = "p";
      if (hour > 12) {
        hour -= 12;
      }
    } else {
      ampm = "a";
    }
    printHMS(hour, minute, second);
    lcd.setCursor(8, 0);
    lcd.print(ampm);  // Now prints correctly
    lcd.setCursor(11, 0);
    printDate();
    lcd.setCursor(10, 1);
    lcd.print(" ");
    lcd.print(sensors.getTempFByIndex(0), 0); //////// Display LED Temp #1
    lcd.print((char)223);
    lcd.setCursor(15, 1);
    lcd.print(" ");
    lcd.print(sensors.getTempFByIndex(1), 0); //////// Display LED Temp #2
    lcd.print((char)223);
    lcd.setCursor(0, 2);
    lcd.print("CW:");
    lcd.setCursor(0, 3);
    lcd.print(" ");
    lcd.print(oneVal);
    lcd.print("%");
    lcd.setCursor(5, 2);
    lcd.print("WW:");
    lcd.setCursor(5, 3);
    lcd.print(" ");
    lcd.print(twoVal);
    lcd.print("%");
    lcd.setCursor(10, 2);
    lcd.print("PR:");
    lcd.setCursor(10, 3);
    lcd.print(" ");
    lcd.print(threeVal);
    lcd.print("%");
    lcd.setCursor(15, 2);
    lcd.print("FR:");
    lcd.setCursor(15, 3);
    lcd.print(" ");
    lcd.print(fourVal);
    lcd.print("%");
    lcd.setCursor(0, 1);
    lcd.print(" ");
    lcd.print(fahrenheit, 0);
    lcd.print((char)223);
    lcd.setCursor(4, 1);
    lcd.print(F(" "));
    lcd.print(h, 0);
    lcd.print(F("%"));

    //debugging function to use the select button to advance the timer by 1 minute
    //if(select.uniquePress()){setDate(second, minute+1, hour, dayOfWeek, dayOfMonth, month, year);}
  }

  if (menuCount == 2) {
    //Manual Override Menu
    lcd.setCursor(0, 0);
    lcd.print("Manual Overrides");
    lcd.setCursor(0, 3);
    lcd.print("All: ");
    if (select.uniquePress()) {
      if (menuSelect < 3) {
        menuSelect++;
      }
      else {
        menuSelect = 0;
      }
      bklTime = millis();
    }

    if (menuSelect == 0) {
      lcd.print("Timer");
      override = false;
    }
    if (menuSelect == 1) {
      lcd.print("ON   ");
      overpercent = 100;
      override = true;
    }
    if (menuSelect == 2) {
      lcd.print("OFF  ");
      overpercent = 0;
      override = true;
    }
    if (menuSelect == 3) {
      override = true;
      lcd.print(overpercent, DEC);
      lcd.print("%  ");
      if (plus.isPressed() && overpercent < 100)
      {
        overpercent++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }

      if (minus.isPressed() && overpercent > 0)
      {
        overpercent--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 3) {
    //set start time for channel one
    lcd.setCursor(0, 0);
    lcd.print("Cool White Start");
    lcd.setCursor(0, 3);
    printMins(oneStartMins, true);

    if (plus.isPressed() && oneStartMins < 1440) {
      oneStartMins = oneStartMins + 10;
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && oneStartMins > 0) {
      oneStartMins--;
      if (onePhotoPeriod < 1439) {
        onePhotoPeriod++;
      }
      else {
        onePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 4) {
    //set end time for channel one
    lcd.setCursor(0, 0);
    lcd.print("Cool White End");
    lcd.setCursor(0, 3);
    printMins(oneStartMins + onePhotoPeriod, true);
    if (plus.isPressed()) {
      if (onePhotoPeriod < 1439) {
        onePhotoPeriod = onePhotoPeriod + 10;
      }
      else {
        onePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed()) {
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 5) {
    //set fade duration for channel one
    lcd.setCursor(0, 0);
    lcd.print("Cool White Fade");
    lcd.setCursor(0, 3);
    printMins(oneFadeDuration, false);
    if (plus.isPressed() && (oneFadeDuration < onePhotoPeriod / 2 || oneFadeDuration == 0)) {
      oneFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && oneFadeDuration > 1) {
      oneFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 6) {
    //set intensity for channel one
    lcd.setCursor(0, 0);
    lcd.print("Cool White Max");
    lcd.setCursor(0, 3);
    lcd.print(oneMax);
    lcd.print("  ");
    if (plus.isPressed() && oneMax < 100) {
      oneMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && oneMax > 0) {
      oneMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 7) {
    //set start time for channel two
    lcd.setCursor(0, 0);
    lcd.print("Warm White Start");
    lcd.setCursor(0, 3);
    printMins(twoStartMins, true);
    if (plus.isPressed() && twoStartMins < 1440) {
      twoStartMins = twoStartMins + 10;
      if (twoPhotoPeriod > 0) {
        twoPhotoPeriod--;
      }
      else {
        twoPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && twoStartMins > 0) {
      twoStartMins--;
      if (twoPhotoPeriod < 1439) {
        twoPhotoPeriod++;
      }
      else {
        twoPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 8) {
    //set end time for channel two
    lcd.setCursor(0, 0);
    lcd.print("Warm White End");
    lcd.setCursor(0, 3);
    printMins(twoStartMins + twoPhotoPeriod, true);
    if (plus.isPressed()) {
      if (twoPhotoPeriod < 1439) {
        twoPhotoPeriod = twoPhotoPeriod + 10;
      }
      else {
        twoPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed()) {
      if (twoPhotoPeriod > 0) {
        twoPhotoPeriod--;
      }
      else {
        twoPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 9) {
    //set fade duration for channel two
    lcd.setCursor(0, 0);
    lcd.print("Warm White Fade");
    lcd.setCursor(0, 3);
    printMins(twoFadeDuration, false);
    if (plus.isPressed() && (twoFadeDuration < twoPhotoPeriod / 2 || twoFadeDuration == 0)) {
      twoFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && twoFadeDuration > 1) {
      twoFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 10) {
    //set intensity for channel two
    lcd.setCursor(0, 0);
    lcd.print("Warm White Max");
    lcd.setCursor(0, 3);
    lcd.print(twoMax);
    lcd.print("  ");
    if (plus.isPressed() && twoMax < 100) {
      twoMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && twoMax > 0) {
      twoMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 11) {
    //set start time for channel three
    lcd.setCursor(0, 0);
    lcd.print("Photo Red Start");
    lcd.setCursor(0, 3);
    printMins(threeStartMins, true);
    if (plus.isPressed() && threeStartMins < 1440) {
      threeStartMins = threeStartMins + 10;
      if (threePhotoPeriod > 0) {
        threePhotoPeriod--;
      }
      else {
        threePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && threeStartMins > 0) {
      threeStartMins--;
      if (threePhotoPeriod < 1439) {
        threePhotoPeriod++;
      }
      else {
        threePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 12) {
    //set end time for channel three
    lcd.setCursor(0, 0);
    lcd.print("Photo Red End");
    lcd.setCursor(0, 3);
    printMins(threeStartMins + threePhotoPeriod, true);
    if (plus.isPressed()) {
      if (threePhotoPeriod < 1439) {
        threePhotoPeriod = threePhotoPeriod + 10;
      }
      else {
        threePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed()) {
      if (threePhotoPeriod > 0) {
        threePhotoPeriod--;
      }
      else {
        threePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 13) {
    //set fade duration for channel three
    lcd.setCursor(0, 0);
    lcd.print("Photo Red Fade");
    lcd.setCursor(0, 3);
    printMins(threeFadeDuration, false);
    if (plus.isPressed() && (threeFadeDuration < threePhotoPeriod / 2 || threeFadeDuration == 0)) {
      threeFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && threeFadeDuration > 1) {
      threeFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 14) {
    //set intensity for channel three
    lcd.setCursor(0, 0);
    lcd.print("Photo Red Max");
    lcd.setCursor(0, 3);
    lcd.print(threeMax);
    lcd.print("  ");
    if (plus.isPressed() && threeMax < 100) {
      threeMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && threeMax > 0) {
      threeMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 15) {
    //set start time for channel four
    lcd.setCursor(0, 0);
    lcd.print("Far Red Start");
    lcd.setCursor(0, 3);
    printMins(fourStartMins, true);
    if (plus.isPressed() && fourStartMins < 1440) {
      fourStartMins = fourStartMins + 10;
      if (fourPhotoPeriod > 0) {
        fourPhotoPeriod--;
      }
      else {
        fourPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && fourStartMins > 0) {
      fourStartMins--;
      if (fourPhotoPeriod < 1439) {
        fourPhotoPeriod++;
      }
      else {
        fourPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 16) {
    //set end time for channel four
    lcd.setCursor(0, 0);
    lcd.print("Far Red End");
    lcd.setCursor(0, 3);
    lcd.setCursor(0, 3);
    printMins(fourStartMins + fourPhotoPeriod, true);
    if (plus.isPressed()) {
      if (fourPhotoPeriod < 1439) {
        fourPhotoPeriod = fourPhotoPeriod + 10;
      }
      else {
        fourPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed()) {
      if (fourPhotoPeriod > 0) {
        fourPhotoPeriod--;
      }
      else {
        fourPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 17) {
    //set fade duration for channel four
    lcd.setCursor(0, 0);
    lcd.print("Far Red Fade");
    lcd.setCursor(0, 3);
    printMins(fourFadeDuration, false);
    if (plus.isPressed() && (fourFadeDuration < fourPhotoPeriod / 2 || fourFadeDuration == 0)) {
      fourFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && fourFadeDuration > 1) {
      fourFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 18) {
    //set intensity for channel four
    lcd.setCursor(0, 0);
    lcd.print("Far Red Max");
    lcd.setCursor(0, 3);
    lcd.print(fourMax);
    lcd.print("   ");
    if (plus.isPressed() && fourMax < 100) {
      fourMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && fourMax > 0) {
      fourMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 19) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 1:  Start");
    lcd.setCursor(0, 3);
    printMins(feedOneStart, true);
    lcd.print("  ");
    if (plus.isPressed() && feedOneStart < 1440) {
      feedOneStart = feedOneStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedOneStart > 0) {
      feedOneStart--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 20) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 1:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedOneStop, true);
    lcd.print("  ");
    if (plus.isPressed() && feedOneStop < 1439) {
      feedOneStop = feedOneStop +10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedOneStop > 0) {
      feedOneStop--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }


  if (menuCount == 21) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 2:  Start");
    lcd.setCursor(0, 3);
    printMins(feedTwoStart, true);
    lcd.print("  ");
    if (plus.isPressed() && feedTwoStart < 1440) {
      feedTwoStart = feedTwoStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedTwoStart > 0) {
      feedTwoStart--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 22) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 2:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedTwoStop, true);
    lcd.print("  ");
    if (plus.isPressed() && feedTwoStop < 1439) {
      feedTwoStop = feedTwoStop +10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedTwoStop > 0) {
      feedTwoStop--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }


  if (menuCount == 23) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 3:  Start");
    lcd.setCursor(0, 3);
    printMins(feedThreeStart, true);
    lcd.print("  ");
    if (plus.isPressed() && feedThreeStart < 1440) {
      feedThreeStart = feedThreeStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedThreeStart > 0) {
      feedThreeStart--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 24) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 3:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedThreeStop, true);
    lcd.print("  ");
    if (plus.isPressed() && feedThreeStop < 1439) {
      feedThreeStop = feedThreeStop +10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedThreeStop > 0) {
      feedThreeStop--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }


  if (menuCount == 25) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 4:  Start");
    lcd.setCursor(0, 3);
    printMins(feedFourStart, true);
    lcd.print("  ");
    if (plus.isPressed() && feedFourStart < 1440) {
      feedFourStart = feedFourStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedFourStart > 0) {
      feedFourStart--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 26) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 4:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedFourStop, true);
    lcd.print("  ");
    if (plus.isPressed() && feedFourStop < 1439) {
      feedFourStop = feedFourStop +10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedFourStop > 0) {
      feedFourStop--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }


  if (menuCount == 27) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 1:  Start");
    lcd.setCursor(0, 3);
    printMins(feedFiveStart, true);
    lcd.print("  ");
    if (plus.isPressed() && feedFiveStart < 1440) {
      feedFiveStart = feedFiveStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedFiveStart > 0) {
      feedFiveStart--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 28) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 1:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedFiveStop, true);
    lcd.print("  ");
    if (plus.isPressed() && feedFiveStop < 1439) {
      feedFiveStop = feedFiveStop +10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedFiveStop > 0) {
      feedFiveStop--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 29) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 2:  Start");
    lcd.setCursor(0, 3);
    printMins(feedSixStart, true);
    lcd.print("  ");
    if (plus.isPressed() && feedSixStart < 1440) {
      feedSixStart = feedSixStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedSixStart > 0) {
      feedSixStart--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 30) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 2:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedSixStop, true);
    lcd.print("  ");
    if (plus.isPressed() && feedSixStop < 1439) {
      feedSixStop = feedSixStop +10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedSixStop > 0) {
      feedSixStop--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }


  if (menuCount == 31) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 3:  Start");
    lcd.setCursor(0, 3);
    printMins(feedSevenStart, true);
    lcd.print("  ");
    if (plus.isPressed() && feedSevenStart < 1440) {
      feedSevenStart = feedSevenStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedSevenStart > 0) {
      feedSevenStart--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 32) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 3:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedSevenStop, true);
    lcd.print("  ");
    if (plus.isPressed() && feedSevenStop < 1439) {
      feedSevenStop = feedSevenStop +10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedSevenStop > 0) {
      feedSevenStop--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 33) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 4:  Start");
    lcd.setCursor(0, 3);
    printMins(feedEightStart, true);
    lcd.print("  ");
    if (plus.isPressed() && feedEightStart < 1440) {
      feedEightStart = feedEightStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedEightStart > 0) {
      feedEightStart--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 34) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 4:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedEightStop, true);
    lcd.print("  ");
    if (plus.isPressed() && feedEightStop < 1439) {
      feedEightStop = feedEightStop +10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && feedEightStop > 0) {
      feedEightStop--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }



  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  if (menuCount == 35) {
    //set hours
    lcd.setCursor(0, 0);
    lcd.print("Set Time:  Hrs");
    lcd.setCursor(0, 3);
    printHMS(hour, minute, second);
    if (plus.isPressed() && hour < 23) {
      hour++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && hour > 0) {
      hour--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 36) {
    //set minutes
    lcd.setCursor(0, 0);
    lcd.print("Set Time:  Mins");
    lcd.setCursor(0, 3);
    printHMS(hour, minute, second);
    if (plus.isPressed() && minute < 59) {
      minute++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && minute > 0) {
      minute--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 37) {
    //set dayOfWeek
    lcd.setCursor(0, 0);
    lcd.print("Set Date:  Day");
    lcd.setCursor(0, 3);
    printDate();
    lcd.setCursor(10, 3);
    lcd.print(year);
    if (plus.isPressed() && dayOfWeek < 7) {
      dayOfWeek++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && dayOfWeek > 1) {
      dayOfWeek--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 38) {
    //set dayOfMonth
    lcd.setCursor(0, 0);
    lcd.print("Set Date:  Date");
    lcd.setCursor(0, 3);
    printDate();
    lcd.setCursor(10, 3);
    lcd.print(year);
    if (plus.isPressed() && dayOfMonth < 31) {
      dayOfMonth++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && dayOfMonth > 1) {
      dayOfMonth--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 39) {
    //set Month
    lcd.setCursor(0, 0);
    lcd.print("Set Date:  Month");
    lcd.setCursor(0, 3);
    printDate();
    lcd.setCursor(10, 3);
    lcd.print(year);
    if (plus.isPressed() && month < 12) {
      month++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && month > 1) {
      month--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 40) {
    //set Year
    lcd.setCursor(0, 0);
    lcd.print("Set Date:  Year");
    lcd.setCursor(0, 3);
    printDate();
    lcd.setCursor(10, 3);
    lcd.print(year);
    if (plus.isPressed() && year < 99) {
      year++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && year > 1) {
      year--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
}

https://www.nano-reef.com/forums/topic/321174-help-with-led-controller-code-based-on-typhon-almost-done/

Which exact Button.h library are you using?

You could add buttons, or use long press, or just see the button down and accelerate, I'm sure you've used annoying button interfaces and have seen all of those.

Easily implemented all; some button libraries do all the heavy lifting and they don't all suck.

I don't use anything beyond the fact the button went down and the fact it is still down, I hand-make anything beyond that.

a7

Yeah, that could be the case. It's a sketch from 2010~2012 era, and it called for a specific EEPROMVar.h, and probably the older Button.c pp and Button.h, as the newer Button library threw fits about PULLDOWN.

Here's the Button.h:

/*
||
|| @file Button.h
|| @version 1.6
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Provide an easy way of making buttons
|| #
||
|| @license
|| | Copyright (c) 2009 Alexander Brevig. All rights reserved.
|| | This code is subject to AlphaLicence.txt
|| | alphabeta.alexanderbrevig.com/AlphaLicense.txt
|| #
||
*/

#ifndef BUTTON_H
#define BUTTON_H

#include "Arduino.h" //changed from WProgram.h

#define PULLUP HIGH
#define PULLDOWN LOW

#define CURRENT 0
#define PREVIOUS 1
#define CHANGED 2

class Button{
  public:
    Button(uint8_t buttonPin, uint8_t buttonMode=PULLDOWN);
    void pullup();
    void pulldown();
    bool isPressed();
    bool wasPressed();
    bool stateChanged();
	bool uniquePress();
  private: 
    uint8_t pin;
    uint8_t mode;
    uint8_t state;
};

#endif

/*
|| @changelog
|| | 1.6 2009-05-05 - Alexander Brevig : Added uniquePress, it returns true if the state has changed AND the button is pressed
|| | 1.5 2009-04-24 - Alexander Brevig : Added stateChanged, @contribution http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?action=viewprofile;username=klickadiklick
|| | 1.4 2009-04-24 - Alexander Brevig : Added wasPressed, @contribution http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?action=viewprofile;username=klickadiklick
|| | 1.3 2009-04-12 - Alexander Brevig : Added constructor with one parameter Button(uint8_t buttonPin)
|| | 1.2 2009-04-10 - Alexander Brevig : Namechange from Switch to Button
|| | 1.1 2009-04-07 - Alexander Brevig : Altered API
|| | 1.0 2008-10-23 - Alexander Brevig : Initial Release
|| #
*/
Button.cpp:
/*
||
|| @file Button.cpp
|| @version 1.6
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Provide an easy way of making buttons
|| #
||
|| @license
|| | Copyright (c) 2009 Alexander Brevig. All rights reserved.
|| | This code is subject to AlphaLicence.txt
|| | alphabeta.alexanderbrevig.com/AlphaLicense.txt
|| #
||
*/

//include the class definition
#include "Button.h"

/*
|| <<constructor>>
|| @parameter buttonPin sets the pin that this switch is connected to
|| @parameter buttonMode indicates PULLUP or PULLDOWN resistor
*/
Button::Button(uint8_t buttonPin, uint8_t buttonMode){
	this->pin=buttonPin;
    pinMode(pin,INPUT);
	buttonMode==PULLDOWN ? pulldown() : pullup();
    state = 0;
    bitWrite(state,CURRENT,!mode);
}

/*
|| Set pin HIGH as default
*/
void Button::pullup(void){
	mode=PULLUP;
	digitalWrite(pin,HIGH);
}

/*
|| Set pin LOW as default
*/
void Button::pulldown(void){
	mode=PULLDOWN;
	//digitalWrite(pin,LOW);
}

/*
|| Return the bitWrite(state,CURRENT, of the switch
*/
bool Button::isPressed(void){
    bitWrite(state,PREVIOUS,bitRead(state,CURRENT));
    if (digitalRead(pin) == mode){
        bitWrite(state,CURRENT,false);
    } else {
        bitWrite(state,CURRENT,true);
    }
    if (bitRead(state,CURRENT) != bitRead(state,PREVIOUS)){
        bitWrite(state,CHANGED,true);
    }else{
        bitWrite(state,CHANGED,false);
    }
	return bitRead(state,CURRENT);
}

/*
|| Return true if the button has been pressed
*/
bool Button::wasPressed(void){
    if (bitRead(state,CURRENT)){
        return true;
    } else {
        return false;
    }
}

/*
|| Return true if state has been changed
*/
bool Button::stateChanged(void){
    return bitRead(state,CHANGED);
}

/*
|| Return true if the button is pressed, and was not pressed before
*/
bool Button::uniquePress(void){
    return (isPressed() && stateChanged());
}

/*
|| @changelog
|| | 2009-05-05 - Alexander Brevig : Added uniquePress()
|| | 2009-04-24 - Alexander Brevig : Added wasPressed()
|| | 2009-04-12 - Alexander Brevig : Added constructor
|| |                                 Shortened logic
|| | 2009-04-10 - Alexander Brevig : Namechange from Switch
|| | 2009-04-07 - Alexander Brevig : Altered API
|| | 2008-10-23 - Alexander Brevig : Initial Release
|| | 2008-10-22 - Alexander Brevig : Class implemented
|| # 
*/

And EEPROMVar.h... used to be hosted here, but the link now says it's not.
http://www.arduino.cc/playground/uploads/Profiles/EEPROMVar_01.zip

#include <Arduino.h> //changed from WProgram.h
#include <EEPROM.h>
/*
   www.alexanderbrevig.com
   AlphaBeta
*/

class EEPROMAddressCounter {
protected:
  static int availableAddress;
};
int EEPROMAddressCounter::availableAddress = 0;

template<typename T>
class EEPROMVar : 
public EEPROMAddressCounter {
public:
  static const byte IS_INITIALIZED = B10101010;
  EEPROMVar(T init) {
    address = availableAddress;
    var = init;
    restore();
    availableAddress += sizeof(T) + 1; //make room for the is initialized flag
  }
  operator T () { 
    return var; 
  }
  EEPROMVar &operator=(T val) {
    var = val;
    save();
  }
  void operator++(int) {
    var += T(1); //cast for safety
    save();
  }
  void operator--(int) {
    var -= T(1); //cast for safety
    save();
  }
  void operator++() {
    var += T(1); //cast for safety
    save();
  }
  void operator--() {
    var -= T(1); //cast for safety
    save();
  }
  template<typename V>
    void operator /= (V divisor) {
    var = var / divisor;
    save();
  }
  template<typename V>
    void operator *= (V multiplicator) {
    var = var * multiplicator;
    save();
  }
protected:
  void save(){
    union {
      byte raw[ sizeof(T) ];
      T data;
    } writer;
    writer.data = var;
    for (byte i=0; i<sizeof(T); i++) {
       EEPROM.write(address + 1 + i, writer.raw[i]);
    }
  }
  void restore(){
    
    byte init = EEPROM.read(address);
    
    if (init!=EEPROMVar::IS_INITIALIZED) {
      //it was not initialized
      EEPROM.write(address,EEPROMVar::IS_INITIALIZED);
      union {
        byte raw[ sizeof(T) ];
        T data;
      } writer;
      writer.data = var;
      for (byte i=0; i<sizeof(T); i++) {
         EEPROM.write(address + 1 + i, writer.raw[i]);
      }
    }
    //read from EEPROM
    union {
      byte raw[ sizeof(T) ];
      T data;
    } reader;
    for (byte i=0; i<sizeof(T); i++) {
       reader.raw[i] =  EEPROM.read(address + 1 + i);\
    }
    var = reader.data;
  }
  T var;
  int address;
};

I was able to simply add Button plusTen and Button minusTen though, so unless you can suggest an easy way for a longPress, this is probably the easiest solution. Just like adding the code to wake the backlight if pressing Menu, but without it automatically continuing to the next page of the menu unless the backlight was already awake, it was easier to just add a 'bklight' button instead.

if (plusTen.isPressed() && oneStartMins < 1440) {
      oneStartMins = oneStartMins + 10;
    } else {

    if (plus.isPressed() && oneStartMins < 1440) {
      oneStartMins++;
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

Actually. my code has too many } or {... or not enough. After menuCounts 3 and 4, I get a blank screen. I went through that last night when adding the feeding menus, resulting in a huge tail at the bottom...

                   }
                  }
                 }
                }
               }
              }
             }
            }
           }
          }
         }
        }
       }
      }
     }
    }
   }
  }
 }
}

It took me forever to figure it out.

Got it...

if (plusTen.isPressed() && oneStartMins < 1440) {
      oneStartMins = oneStartMins + 10;
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      } 
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    
    if (plus.isPressed() && oneStartMins < 1440) {
      oneStartMins++;
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

Now it advances to the next menu item. Still need to adjust the minus settings, but at least that tail isn't as long at the bottom, and everything isn't indented to 1/2 way across the page. I'm getting there....... :slight_smile:

I casually strolled scrolled through your code looking to see how you got so deeply nested and didn't see it. Nevertheless, you may like to watch this brief video and consider its basic points

BTW this jumped out

oneStartMins = oneStartMins + 10;

and a few like it can jump the value over what was your upper limit. You could put logic all over to fix that, or make sure everything somehow was routed through one code section that would fix anything like that.

constrain() is a useful macro if you don't want to code it at all.

https://docs.arduino.cc/language-reference/en/functions/math/constrain/

HTH

a7

2 Likes

Crap... and I just finished... lol. I'll give it a look, but this is working so far. Unless it breaks anything, I'll stick with it.

// include the libraries:
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Button.h>
#include <EEPROM.h>
#include <EEPROMVar.h>
#include <DHT.h>

/////  Setup DS18B20 Sensor
#include "OneWire.h"
#include "DallasTemperature.h"
#define ONE_WIRE_BUS 62 //Define the pin of the DS18B20
#define TEMPERATURE_PRECISION 12

int fanPWMpin = 63;    //Define the pin of the Fan
const int HtempMin = 50.0;    //Define temp when heatsink fan starts (25C = 77F)
const int HtempMax = 95.0;   //Define temp when heatsink fan is 100% (35C = 95F)

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

/**** Define Variables & Constants ****/
/**************************************/

// Constants
#define DHTPIN 49     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22
DHT dht(DHTPIN, DHTTYPE);

// set the RTC's I2C address
#define DS1307_I2C_ADDRESS 0x68

// create the LCD
LiquidCrystal lcd(30, 31, 32, 33, 34, 35);

// set up backlight
int bkl         = 45;        // backlight pin
byte bklIdle    = 100;       // PWM value for backlight at idle
byte bklOn      = 255;       // PWM value for backlight when on
int bklDelay    = 10000;    // ms for the backlight to idle before turning off
unsigned long bklTime = 0;  // counter since backlight turned on

// create the menu counter
int menuCount   = 1;
int menuSelect = 0;

//create the plus and minus navigation delay counter with its initial maximum of 250.
byte btnMaxDelay = 200;
byte btnMinDelay = 25;
byte btnMaxIteration = 5;
byte btnCurrIteration;

//create manual override variables
boolean override = false;
byte overmenu = 0;
int overpercent = 0;

// create the buttons
Button menu     = Button(54, PULLDOWN);
Button select   = Button(55, PULLDOWN);
Button plus     = Button(56, PULLDOWN);
Button minus    = Button(57, PULLDOWN);
Button bklight  = Button(58, PULLDOWN);
Button plusTen  = Button(60, PULLDOWN);
Button minusTen  = Button(61, PULLDOWN);

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight.
int oldMinCounter = 0;      // counter that resets at midnight.
int oneLed = 2;             // pin for Cool White
int twoLed = 3;             // pin for Warm White
int threeLed = 4;           // pin for Photo Red
int fourLed = 5;            // pin for Far Red

int oneVal = 0;             // current value for Cool White
int twoVal = 0;             // current value for Warm White
int threeVal = 0;           // current value for Photo Red
int fourVal = 0;            // current value for Far Red

int onePump = 64;           // pin for pump #1
int twoPump = 65;           // pin for pump #2


// Variables making use of EEPROM memory:

EEPROMVar<int> oneStartMins = 1319;     // minute to start this channel.
EEPROMVar<int> onePhotoPeriod = 720;    // photoperiod in minutes for this channel.
EEPROMVar<int> oneMax = 100;            // max intensity for this channel, as a percentage
EEPROMVar<int> oneFadeDuration = 30;    // duration of the fade on and off for sunrise and sunset for this channel.

EEPROMVar<int> twoStartMins = 1334;
EEPROMVar<int> twoPhotoPeriod = 720;
EEPROMVar<int> twoMax = 100;
EEPROMVar<int> twoFadeDuration = 30;

EEPROMVar<int> threeStartMins = 1349;
EEPROMVar<int> threePhotoPeriod = 720;
EEPROMVar<int> threeMax = 100;
EEPROMVar<int> threeFadeDuration = 30;

EEPROMVar<int> fourStartMins = 1364;
EEPROMVar<int> fourPhotoPeriod = 720;
EEPROMVar<int> fourMax = 100;
EEPROMVar<int> fourFadeDuration = 30;


/// Pump 1 ////////////////////////////
/// Feeding #1
EEPROMVar<int> feedOneStart = 1209;
EEPROMVar<int> feedOneStop = 5;

/// Feeding #2
EEPROMVar<int> feedTwoStart = 1219;
EEPROMVar<int> feedTwoStop = 5;

/// Feeding #3
EEPROMVar<int> feedThreeStart = 1219;
EEPROMVar<int> feedThreeStop = 5;

/// Feeding #4
EEPROMVar<int> feedFourStart = 1219;
EEPROMVar<int> feedFourStop = 5;

/// Pump 2 ////////////////////////////
/// Feeding #1
EEPROMVar<int> feedFiveStart = 1219;
EEPROMVar<int> feedFiveStop = 5;

/// Feeding #2
EEPROMVar<int> feedSixStart = 1219;
EEPROMVar<int> feedSixStop = 5;

/// Feeding #3
EEPROMVar<int> feedSevenStart = 1219;
EEPROMVar<int> feedSevenStop = 5;

/// Feeding #4
EEPROMVar<int> feedEightStart = 1219;
EEPROMVar<int> feedEightStop = 5;


// variables to invert the output PWM signal,
// for use with drivers that consider 0 to be "on"
// i.e. buckpucks. If you need to provide an inverted
// signal on any channel, set the appropriate variable to true.
boolean oneInverted = false;
boolean twoInverted = false;
boolean threeInverted = false;
boolean fourInverted = false;

/****** RTC Functions ******/
/***************************/

// Convert decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val / 10 * 16) + (val % 10) );
}

// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val)
{
  return ( (val / 16 * 10) + (val % 16) );
}

// Sets date and time, starts the clock
void setDate(byte second,        // 0-59
             byte minute,        // 0-59
             byte hour,          // 1-23
             byte dayOfWeek,     // 1-7
             byte dayOfMonth,    // 1-31
             byte month,         // 1-12
             byte year)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time
void getDate(byte *second,
             byte *minute,
             byte *hour,
             byte *dayOfWeek,
             byte *dayOfMonth,
             byte *month,
             byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down

int   setLed(int mins,         // current time in minutes
             int ledPin,        // pin for this channel of LEDs
             int start,         // start time for this channel of LEDs
             int period,        // photoperiod for this channel of LEDs
             int fade,          // fade duration for this channel of LEDs
             int ledMax,        // max value for this channel
             boolean inverted   // true if the channel is inverted
            )  {
  int val = 0;

  //fade up
  if (mins > start || mins <= start + fade)  {
    val = map(mins - start, 0, fade, 0, ledMax);
  }
  //fade down
  if (mins > start + period - fade && mins <= start + period)  {
    val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
  }
  //off or post-midnight run.
  if (mins <= start || mins > start + period)  {
    if ((start + period) % 1440 < start && (start + period) % 1440 > mins )
    {
      val = map((start + period - mins) % 1440, 0, fade, 0, ledMax);
    }
    else
      val = 0;
  }


  if (val > ledMax)  {
    val = ledMax;
  }
  if (val < 0) {
    val = 0;
  }

  if (inverted) {
    analogWrite(ledPin, map(val, 0, 100, 255, 0));
  }
  else {
    analogWrite(ledPin, map(val, 0, 100, 0, 255));
  }
  if (override) {
    val = overpercent;
  }
  return val;
}

/**** Display Functions ****/
/***************************/

//button hold function
int btnCurrDelay(byte curr)
{
  if (curr == btnMaxIteration)
  {
    btnCurrIteration = btnMaxIteration;
    return btnMaxDelay;
  }
  else if (btnCurrIteration == 0)
  {
    return btnMinDelay;
  }
  else
  {
    btnCurrIteration--;
    return btnMaxDelay;
  }
}

// format a number of minutes into a readable time (24 hr format)
void printMins(int mins,       //time in minutes to print
               boolean ampm    //print am/pm?
              )  {
  int hr = (mins % 1440) / 60;
  int mn = mins % 60;
  if (hr < 10) {
    lcd.print(" ");
  }
  lcd.print(hr);
  lcd.print(":");
  if (mn < 10) {
    lcd.print("0");
  }
  lcd.print(mn);
}

// format hours, mins, secs into a readable time (24 hr format)
void printHMS (byte hr,
               byte mn,
               byte sec      //time to print
              )
{
  if (hr < 10) {
    lcd.print(" ");
  }
  lcd.print(hr, DEC);
  lcd.print(":");
  if (mn < 10) {
    lcd.print("0");
  }
  lcd.print(mn, DEC);
  lcd.print(":");
  if (sec < 10) {
    lcd.print("0");
  }
  lcd.print(sec, DEC);
}

void printDate() {

  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  //  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
  int hour = bcdToDec(Wire.read() & 01010010); //24 hour time
  int dayOfWeek = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  int dayOfMonth = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());


  //////   Uncomment the following to initially set the time and date
  //////   After you load the sketch, then comment out the section again, and reload the sketch 1 more time.
  //////   This prevents the sketch from resetting back to the beginning. ;)



  second = 0;
  minute = 20;
  hour = 0;
  dayOfWeek = 7;
  dayOfMonth = 8;
  month = 2;
  year = 25;

  ///   setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);


  //print the date EG   3/1/11 23:59:59
  //  lcd.print(dayOfWeek);

  switch (dayOfWeek) {
    case 1:
      lcd.print("Sun");
      break;
    case 2:
      lcd.print("Mon");
      break;
    case 3:
      lcd.print("Tue");
      break;
    case 4:
      lcd.print("Wed");
      break;
    case 5:
      lcd.print("Thu");
      break;
    case 6:
      lcd.print("Fri");
      break;
    case 7:
      lcd.print("Sat");
      break;
  }

  lcd.print(" ");
  if (dayOfMonth < 10) {
    lcd.print("0");
  }
  lcd.print(dayOfMonth);
  lcd.print(".");
  if (month < 10) {
    lcd.print("0");
  }
  lcd.print(month);
  //  lcd.print(".20");
  //  if (year < 10){
  //    lcd.print("0");
  //  }
  //  lcd.print(year);
}

void ovrSetAll(int pct) {
  analogWrite(oneLed, map(pct, 0, 100, 0, 255));
  analogWrite(twoLed, map(pct, 0, 100, 0, 255));
  analogWrite(threeLed, map(pct, 0, 100, 0, 255));
  analogWrite(fourLed, map(pct, 0, 100, 0, 255));
}

void checkTemp()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  delay(10);

  float temp1 = 0, temp2 = 0;

  //  lcd.setCursor(0, 2);
  //  lcd.print("T:");
  temp1 = sensors.getTempFByIndex(0);
  //  lcd.print(sensors.getTempFByIndex(0));
  //  lcd.print((char)223);
  //  lcd.print("F");

  //  lcd.setCursor(0, 3);
  //  lcd.print("Led:");
  temp2 = sensors.getTempFByIndex(1);
  //  lcd.print(sensors.getTempFByIndex(1));
  //  lcd.print((char)223);
  //  lcd.print("F");


  if (temp1 < 0) temp1 = 0;                  //if sensor not connected reading is -127 deg
  else if (temp1 > 99) temp1 = 99;
  if (temp2 < 0) temp2 = 0;
  else if (temp2 > 99) temp2 = 99;

  int tempval1 = int(temp1 * 10);
  int tempval2 = int(temp1 * 10);
  int fanSpeed1 = map(tempval1, (HtempMin * 10), (HtempMax * 10), 0, 255);   //---------heatsink 1 fan control
  int fanSpeed2 = map(tempval2, (HtempMin * 10), (HtempMax * 10), 0, 255);   //---------heatsink 2 fan control
  if (fanSpeed1 <= 0)
    fanSpeed1 = 0;
  if (fanSpeed1 > 255)
    fanSpeed1 = 255;

  if (fanSpeed2 <= 0)
    fanSpeed2 = 0;
  if (fanSpeed2 > 255)
    fanSpeed2 = 255;

  analogWrite(fanPWMpin, fanSpeed1);
  analogWrite(fanPWMpin, fanSpeed2);
  Serial.println(fanSpeed1);
  Serial.println(fanSpeed2);
  //   lcd.setCursor(0,1);
  //   lcd.print(fanSpeed);
}

/**** Setup ****/
/***************/

void setup() {

  Wire.begin();
  pinMode(bkl, OUTPUT);
  lcd.begin(20, 4);
  dht.begin();
  digitalWrite(bkl, HIGH);
  lcd.setCursor(6, 0);
  lcd.print("Welcome");
  lcd.setCursor(8, 1);
  lcd.print("To");
  lcd.setCursor(4, 2);
  lcd.print("The Garden");
  delay(5000);
  lcd.clear();
  analogWrite(bkl, bklIdle);
  btnCurrIteration = btnMaxIteration;
  sensors.begin();              // Start up the DS18B20 Temp library
  pinMode(fanPWMpin, OUTPUT);
  pinMode(onePump, OUTPUT);
  digitalWrite(onePump, LOW);
  pinMode(twoPump, OUTPUT);
  digitalWrite(twoPump, LOW);
}

/***** Loop *****/
/****************/

void loop() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  const char* ampm;  // Change to a pointer to a string

  getDate(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  oldMinCounter = minCounter;
  minCounter = hour * 60 + minute;

  // Wait a few seconds between measurements.
  //  delay(10);

  float celsius = dht.readTemperature(); // Read temperature in Celsius
  float fahrenheit = (celsius * 9 / 5) + 32; // Convert to Fahrenheit

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();

  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    lcd.print(F("Failed to read from DHT sensor!"));
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);

  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  {
    checkTemp();
  }

  //reset plus & minus acceleration counters if the button's state has changed
  if (plus.stateChanged())
  {
    btnCurrDelay(btnMaxIteration);
  }
  if (minus.stateChanged())
  {
    btnCurrDelay(btnMaxIteration);
  }


  //check & set fade durations
  if (oneFadeDuration > onePhotoPeriod / 2 && onePhotoPeriod > 0) {
    oneFadeDuration = onePhotoPeriod / 2;
  }
  if (oneFadeDuration < 1) {
    oneFadeDuration = 1;
  }

  if (twoFadeDuration > twoPhotoPeriod / 2 && twoPhotoPeriod > 0) {
    twoFadeDuration = twoPhotoPeriod / 2;
  }
  if (twoFadeDuration < 1) {
    twoFadeDuration = 1;
  }

  if (threeFadeDuration > threePhotoPeriod / 2 && threePhotoPeriod > 0) {
    threeFadeDuration = threePhotoPeriod / 2;
  }
  if (threeFadeDuration < 1) {
    threeFadeDuration = 1;
  }

  if (fourFadeDuration > fourPhotoPeriod / 2 && fourPhotoPeriod > 0) {
    fourFadeDuration = fourPhotoPeriod / 2;
  }
  if (fourFadeDuration < 1) {
    fourFadeDuration = 1;
  }

  //check & set any time functions


  //set outputs
  if (!override) {
    oneVal = setLed(minCounter, oneLed, oneStartMins, onePhotoPeriod, oneFadeDuration, oneMax, oneInverted);
    twoVal = setLed(minCounter, twoLed, twoStartMins, twoPhotoPeriod, twoFadeDuration, twoMax, twoInverted);
    threeVal = setLed(minCounter, threeLed, threeStartMins, threePhotoPeriod, threeFadeDuration, threeMax, threeInverted);
    fourVal = setLed(minCounter, fourLed, fourStartMins, fourPhotoPeriod, fourFadeDuration, fourMax, fourInverted);
  }
  else {
    ovrSetAll(overpercent);
  }

  /// Backlight Override //////////////////////

    if (bklight.uniquePress()) {
      analogWrite(bkl, bklOn);
      bklTime = millis();
    }

  //turn the backlight off and reset the menu if the idle time has elapsed
  if (bklTime + bklDelay < millis() && bklTime > 0 ) {
    analogWrite(bkl, bklIdle);
    menuCount = 1;
    lcd.clear();
    lcd.clear();
    bklTime = 0;
  }

  //iterate through the menus
  if (menu.uniquePress()) {
    analogWrite(bkl, bklOn);
    bklTime = millis();
    if (menuCount < 40) {
      menuCount++;
    } else {
      menuCount = 1;
    }
    lcd.clear();
  }
  if (menuCount == 1) {
    lcd.setCursor(0, 0);
    if (hour >= 12) {
      ampm = "p";
      if (hour > 12) {
        hour -= 12;
      }
    } else {
      ampm = "a";
    }
    printHMS(hour, minute, second);
    lcd.setCursor(8, 0);
    lcd.print(ampm);  // Now prints correctly
    lcd.setCursor(11, 0);
    printDate();
    lcd.setCursor(10, 1);
    lcd.print(" ");
    lcd.print(sensors.getTempFByIndex(0), 0); //////// Display LED Temp #1
    lcd.print((char)223);
    lcd.setCursor(15, 1);
    lcd.print(" ");
    lcd.print(sensors.getTempFByIndex(1), 0); //////// Display LED Temp #2
    lcd.print((char)223);
    lcd.setCursor(0, 2);
    lcd.print("CW:");
    lcd.setCursor(0, 3);
    lcd.print(" ");
    lcd.print(oneVal);
    lcd.print("%");
    lcd.setCursor(5, 2);
    lcd.print("WW:");
    lcd.setCursor(5, 3);
    lcd.print(" ");
    lcd.print(twoVal);
    lcd.print("%");
    lcd.setCursor(10, 2);
    lcd.print("PR:");
    lcd.setCursor(10, 3);
    lcd.print(" ");
    lcd.print(threeVal);
    lcd.print("%");
    lcd.setCursor(15, 2);
    lcd.print("FR:");
    lcd.setCursor(15, 3);
    lcd.print(" ");
    lcd.print(fourVal);
    lcd.print("%");
    lcd.setCursor(0, 1);
    lcd.print(" ");
    lcd.print(fahrenheit, 0);
    lcd.print((char)223);
    lcd.setCursor(4, 1);
    lcd.print(F(" "));
    lcd.print(h, 0);
    lcd.print(F("%"));

    //debugging function to use the select button to advance the timer by 1 minute
    //if(select.uniquePress()){setDate(second, minute+1, hour, dayOfWeek, dayOfMonth, month, year);}
  }

  if (menuCount == 2) {
    //Manual Override Menu
    lcd.setCursor(0, 0);
    lcd.print("Manual Overrides");
    lcd.setCursor(0, 3);
    lcd.print("All: ");
    if (select.uniquePress()) {
      if (menuSelect < 3) {
        menuSelect++;
      }
      else {
        menuSelect = 0;
      }
      bklTime = millis();
    }

    if (menuSelect == 0) {
      lcd.print("Timer");
      override = false;
    }
    if (menuSelect == 1) {
      lcd.print("ON   ");
      overpercent = 100;
      override = true;
    }
    if (menuSelect == 2) {
      lcd.print("OFF  ");
      overpercent = 0;
      override = true;
    }
    if (menuSelect == 3) {
      override = true;
      lcd.print(overpercent, DEC);
      lcd.print("%  ");
      if (plus.isPressed() && overpercent < 100)
      {
        overpercent++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }

      if (minus.isPressed() && overpercent > 0)
      {
        overpercent--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 3) {
    //set start time for channel one
    lcd.setCursor(0, 0);
    lcd.print("Cool White Start");
    lcd.setCursor(0, 3);
    printMins(oneStartMins, true);

    if (plusTen.isPressed() && oneStartMins < 1440) {
      oneStartMins = oneStartMins + 10;
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (plus.isPressed() && oneStartMins < 1440) {
      oneStartMins++;
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minusTen.isPressed() && oneStartMins > 0) {
      oneStartMins = oneStartMins - 10;
      if (onePhotoPeriod < 1439) {
        onePhotoPeriod = onePhotoPeriod - 10;
      }
      else {
        onePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minus.isPressed() && oneStartMins > 0) {
      oneStartMins--;
      if (onePhotoPeriod < 1439) {
        onePhotoPeriod++;
      }
      else {
        onePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 4) {
    //set end time for channel one
    lcd.setCursor(0, 0);
    lcd.print("Cool White End");
    lcd.setCursor(0, 3);
    printMins(oneStartMins + onePhotoPeriod, true);
    if (plusTen.isPressed()) {
      if (onePhotoPeriod < 1439) {
        onePhotoPeriod = onePhotoPeriod + 10;
      }
      else {
        onePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (plus.isPressed()) {
      if (onePhotoPeriod < 1439) {
        onePhotoPeriod++;
      }
      else {
        onePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minusTen.isPressed()) {
      if (onePhotoPeriod > 0) {
        onePhotoPeriod = onePhotoPeriod - 10;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minus.isPressed()) {
      if (onePhotoPeriod > 0) {
        onePhotoPeriod--;
      }
      else {
        onePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 5) {
    //set fade duration for channel one
    lcd.setCursor(0, 0);
    lcd.print("Cool White Fade");
    lcd.setCursor(0, 3);
    printMins(oneFadeDuration, false);
    if (plus.isPressed() && (oneFadeDuration < onePhotoPeriod / 2 || oneFadeDuration == 0)) {
      oneFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && oneFadeDuration > 1) {
      oneFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 6) {
    //set intensity for channel one
    lcd.setCursor(0, 0);
    lcd.print("Cool White Max");
    lcd.setCursor(0, 3);
    lcd.print(oneMax);
    lcd.print("  ");
    if (plus.isPressed() && oneMax < 100) {
      oneMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && oneMax > 0) {
      oneMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 7) {
    //set start time for channel two
    lcd.setCursor(0, 0);
    lcd.print("Warm White Start");
    lcd.setCursor(0, 3);
    printMins(twoStartMins, true);
    if (plusTen.isPressed() && twoStartMins < 1440) {
      twoStartMins = twoStartMins + 10;
      if (twoPhotoPeriod > 0) {
        twoPhotoPeriod--;
      }
      else {
        twoPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (plus.isPressed() && twoStartMins < 1440) {
      twoStartMins++;
      if (twoPhotoPeriod > 0) {
        twoPhotoPeriod--;
      }
      else {
        twoPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minusTen.isPressed() && twoStartMins > 0) {
      twoStartMins = twoStartMins - 10;
      if (twoPhotoPeriod < 1439) {
        twoPhotoPeriod = twoPhotoPeriod - 10;
      }
      else {
        twoPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minus.isPressed() && twoStartMins > 0) {
      twoStartMins--;
      if (twoPhotoPeriod < 1439) {
        twoPhotoPeriod++;
      }
      else {
        twoPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 8) {
    //set end time for channel two
    lcd.setCursor(0, 0);
    lcd.print("Warm White End");
    lcd.setCursor(0, 3);
    printMins(twoStartMins + twoPhotoPeriod, true);
    if (plusTen.isPressed()) {
      if (twoPhotoPeriod < 1439) {
        twoPhotoPeriod = twoPhotoPeriod + 10;
      }
      else {
        twoPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (plus.isPressed()) {
      if (twoPhotoPeriod < 1439) {
        twoPhotoPeriod++;
      }
      else {
        twoPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minusTen.isPressed()) {
      if (twoPhotoPeriod > 0) {
        twoPhotoPeriod = twoPhotoPeriod - 10;
      }
      else {
        twoPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minus.isPressed()) {
      if (twoPhotoPeriod > 0) {
        twoPhotoPeriod--;
      }
      else {
        twoPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 9) {
    //set fade duration for channel two
    lcd.setCursor(0, 0);
    lcd.print("Warm White Fade");
    lcd.setCursor(0, 3);
    printMins(twoFadeDuration, false);
    if (plus.isPressed() && (twoFadeDuration < twoPhotoPeriod / 2 || twoFadeDuration == 0)) {
      twoFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && twoFadeDuration > 1) {
      twoFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 10) {
    //set intensity for channel two
    lcd.setCursor(0, 0);
    lcd.print("Warm White Max");
    lcd.setCursor(0, 3);
    lcd.print(twoMax);
    lcd.print("  ");
    if (plus.isPressed() && twoMax < 100) {
      twoMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && twoMax > 0) {
      twoMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 11) {
    //set start time for channel three
    lcd.setCursor(0, 0);
    lcd.print("Photo Red Start");
    lcd.setCursor(0, 3);
    printMins(threeStartMins, true);
    if (plusTen.isPressed() && threeStartMins < 1440) {
      threeStartMins = threeStartMins + 10;
      if (threePhotoPeriod > 0) {
        threePhotoPeriod--;
      }
      else {
        threePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (plus.isPressed() && threeStartMins < 1440) {
      threeStartMins++;
      if (threePhotoPeriod > 0) {
        threePhotoPeriod--;
      }
      else {
        threePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minusTen.isPressed() && threeStartMins > 0) {
      threeStartMins = threeStartMins - 10;
      if (threePhotoPeriod < 1439) {
        threePhotoPeriod = threePhotoPeriod - 10;
      }
      else {
        threePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minus.isPressed() && threeStartMins > 0) {
      threeStartMins--;
      if (threePhotoPeriod < 1439) {
        threePhotoPeriod++;
      }
      else {
        threePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 12) {
    //set end time for channel three
    lcd.setCursor(0, 0);
    lcd.print("Photo Red End");
    lcd.setCursor(0, 3);
    printMins(threeStartMins + threePhotoPeriod, true);
    if (plusTen.isPressed()) {
      if (threePhotoPeriod < 1439) {
        threePhotoPeriod = threePhotoPeriod + 10;
      }
      else {
        threePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (plus.isPressed()) {
      if (threePhotoPeriod < 1439) {
        threePhotoPeriod++;
      }
      else {
        threePhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minusTen.isPressed()) {
      if (threePhotoPeriod > 0) {
        threePhotoPeriod = threePhotoPeriod - 10;
      }
      else {
        threePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minus.isPressed()) {
      if (threePhotoPeriod > 0) {
        threePhotoPeriod--;
      }
      else {
        threePhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 13) {
    //set fade duration for channel three
    lcd.setCursor(0, 0);
    lcd.print("Photo Red Fade");
    lcd.setCursor(0, 3);
    printMins(threeFadeDuration, false);
    if (plus.isPressed() && (threeFadeDuration < threePhotoPeriod / 2 || threeFadeDuration == 0)) {
      threeFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && threeFadeDuration > 1) {
      threeFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 14) {
    //set intensity for channel three
    lcd.setCursor(0, 0);
    lcd.print("Photo Red Max");
    lcd.setCursor(0, 3);
    lcd.print(threeMax);
    lcd.print("  ");
    if (plus.isPressed() && threeMax < 100) {
      threeMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && threeMax > 0) {
      threeMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 15) {
    //set start time for channel four
    lcd.setCursor(0, 0);
    lcd.print("Far Red Start");
    lcd.setCursor(0, 3);
    printMins(fourStartMins, true);

    if (plusTen.isPressed() && fourStartMins < 1440) {
      fourStartMins = fourStartMins + 10;
      if (fourPhotoPeriod > 0) {
        fourPhotoPeriod--;
      }
      else {
        fourPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (plus.isPressed() && fourStartMins < 1440) {
      fourStartMins++;
      if (fourPhotoPeriod > 0) {
        fourPhotoPeriod--;
      }
      else {
        fourPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minusTen.isPressed() && fourStartMins > 0) {
      fourStartMins = fourStartMins - 10;
      if (fourPhotoPeriod < 1439) {
        fourPhotoPeriod = fourPhotoPeriod - 10;
      }
      else {
        fourPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minus.isPressed() && fourStartMins > 0) {
      fourStartMins--;
      if (fourPhotoPeriod < 1439) {
        fourPhotoPeriod++;
      }
      else {
        fourPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 16) {
    //set end time for channel four
    lcd.setCursor(0, 0);
    lcd.print("Far Red End");
    lcd.setCursor(0, 3);
    lcd.setCursor(0, 3);
    printMins(fourStartMins + fourPhotoPeriod, true);
    if (plusTen.isPressed()) {
      if (fourPhotoPeriod < 1439) {
        fourPhotoPeriod = fourPhotoPeriod + 10;
      }
      else {
        fourPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (plus.isPressed()) {
      if (fourPhotoPeriod < 1439) {
        fourPhotoPeriod++;
      }
      else {
        fourPhotoPeriod = 0;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minusTen.isPressed()) {
      if (fourPhotoPeriod > 0) {
        fourPhotoPeriod = fourPhotoPeriod - 10;
      }
      else {
        fourPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }

    if (minus.isPressed()) {
      if (fourPhotoPeriod > 0) {
        fourPhotoPeriod--;
      }
      else {
        fourPhotoPeriod = 1439;
      }
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 17) {
    //set fade duration for channel four
    lcd.setCursor(0, 0);
    lcd.print("Far Red Fade");
    lcd.setCursor(0, 3);
    printMins(fourFadeDuration, false);
    if (plus.isPressed() && (fourFadeDuration < fourPhotoPeriod / 2 || fourFadeDuration == 0)) {
      fourFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && fourFadeDuration > 1) {
      fourFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 18) {
    //set intensity for channel four
    lcd.setCursor(0, 0);
    lcd.print("Far Red Max");
    lcd.setCursor(0, 3);
    lcd.print(fourMax);
    lcd.print("   ");
    if (plus.isPressed() && fourMax < 100) {
      fourMax++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && fourMax > 0) {
      fourMax--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
  }

  if (menuCount == 19) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 1:  Start");
    lcd.setCursor(0, 3);
    printMins(feedOneStart, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedOneStart < 1440) {
      feedOneStart = feedOneStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedOneStart < 1440) {
        feedOneStart++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedOneStart > 0) {
      feedOneStart = feedOneStart - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedOneStart > 0) {
        feedOneStart--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 20) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 1:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedOneStop, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedOneStop < 1439) {
      feedOneStop = feedOneStop + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedOneStop < 1439) {
        feedOneStop++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedOneStop > 0) {
      feedOneStop = feedOneStop - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedOneStop > 0) {
        feedOneStop--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }


  if (menuCount == 21) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 2:  Start");
    lcd.setCursor(0, 3);
    printMins(feedTwoStart, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedTwoStart < 1440) {
      feedTwoStart = feedTwoStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedTwoStart < 1440) {
        feedTwoStart++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedTwoStart > 0) {
      feedTwoStart = feedTwoStart - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedTwoStart > 0) {
        feedTwoStart--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 22) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 2:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedTwoStop, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedTwoStop < 1439) {
      feedTwoStop = feedTwoStop + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedTwoStop < 1439) {
        feedTwoStop++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedTwoStop > 0) {
      feedTwoStop = feedTwoStop - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedTwoStop > 0) {
        feedTwoStop--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }


  if (menuCount == 23) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 3:  Start");
    lcd.setCursor(0, 3);
    printMins(feedThreeStart, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedThreeStart < 1440) {
      feedThreeStart = feedThreeStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedThreeStart < 1440) {
        feedThreeStart++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedThreeStart > 0) {
      feedThreeStart = feedThreeStart - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedThreeStart > 0) {
        feedThreeStart--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 24) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 3:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedThreeStop, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedThreeStop < 1439) {
      feedThreeStop = feedThreeStop + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedThreeStop < 1439) {
        feedThreeStop++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedThreeStop > 0) {
      feedThreeStop = feedThreeStop - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedThreeStop > 0) {
        feedThreeStop--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }


  if (menuCount == 25) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 4:  Start");
    lcd.setCursor(0, 3);
    printMins(feedFourStart, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedFourStart < 1440) {
      feedFourStart = feedFourStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedFourStart < 1440) {
        feedFourStart++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedFourStart > 0) {
      feedFourStart = feedFourStart - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedFourStart > 0) {
        feedFourStart--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 26) {
    lcd.setCursor(0, 0);
    lcd.print("Pump1 Feed 4:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedFourStop, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedFourStop < 1439) {
      feedFourStop = feedFourStop + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedFourStop < 1439) {
        feedFourStop++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedFourStop > 0) {
      feedFourStop = feedFourStop - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedFourStop > 0) {
        feedFourStop--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }


  if (menuCount == 27) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 1:  Start");
    lcd.setCursor(0, 3);
    printMins(feedFiveStart, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedFiveStart < 1440) {
      feedFiveStart = feedFiveStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedFiveStart < 1440) {
        feedFiveStart++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedFiveStart > 0) {
      feedFiveStart = feedFiveStart - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedFiveStart > 0) {
        feedFiveStart--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 28) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 1:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedFiveStop, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedFiveStop < 1439) {
      feedFiveStop = feedFiveStop + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedFiveStop < 1439) {
        feedFiveStop++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedFiveStop > 0) {
      feedFiveStop = feedFiveStop - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedFiveStop > 0) {
        feedFiveStop--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 29) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 2:  Start");
    lcd.setCursor(0, 3);
    printMins(feedSixStart, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedSixStart < 1440) {
      feedSixStart = feedSixStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedSixStart < 1440) {
        feedSixStart++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedSixStart > 0) {
      feedSixStart = feedSixStart - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedSixStart > 0) {
        feedSixStart--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 30) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 2:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedSixStop, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedSixStop < 1439) {
      feedSixStop = feedSixStop + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedSixStop < 1439) {
        feedSixStop++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedSixStop > 0) {
      feedSixStop = feedSixStop - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedSixStop > 0) {
        feedSixStop--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }


  if (menuCount == 31) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 3:  Start");
    lcd.setCursor(0, 3);
    printMins(feedSevenStart, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedSevenStart < 1440) {
      feedSevenStart = feedSevenStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedSevenStart < 1440) {
        feedSevenStart++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedSevenStart > 0) {
      feedSevenStart = feedSevenStart - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedSevenStart > 0) {
        feedSevenStart--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 32) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 3:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedSevenStop, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedSevenStop < 1439) {
      feedSevenStop = feedSevenStop + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedSevenStop < 1439) {
        feedSevenStop++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedSevenStop > 0) {
      feedSevenStop = feedSevenStop - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedSevenStop > 0) {
        feedSevenStop--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 33) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 4:  Start");
    lcd.setCursor(0, 3);
    printMins(feedEightStart, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedEightStart < 1440) {
      feedEightStart = feedEightStart + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedEightStart < 1440) {
        feedEightStart++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedEightStart > 0) {
      feedEightStart = feedEightStart - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedEightStart > 0) {
        feedEightStart--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }

  if (menuCount == 34) {
    lcd.setCursor(0, 0);
    lcd.print("Pump2 Feed 4:  Stop");
    lcd.setCursor(0, 3);
    printMins(feedEightStop, true);
    lcd.print("  ");
    if (plusTen.isPressed() && feedEightStop < 1439) {
      feedEightStop = feedEightStop + 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (plus.isPressed() && feedEightStop < 1439) {
        feedEightStop++;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
    if (minusTen.isPressed() && feedEightStop > 0) {
      feedEightStop = feedEightStop - 10;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    } else {

      if (minus.isPressed() && feedEightStop > 0) {
        feedEightStop--;
        delay(btnCurrDelay(btnCurrIteration - 1));
        bklTime = millis();
      }
    }
  }



  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  if (menuCount == 35) {
    //set hours
    lcd.setCursor(0, 0);
    lcd.print("Set Time:  Hrs");
    lcd.setCursor(0, 3);
    printHMS(hour, minute, second);
    if (plus.isPressed() && hour < 23) {
      hour++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && hour > 0) {
      hour--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 36) {
    //set minutes
    lcd.setCursor(0, 0);
    lcd.print("Set Time:  Mins");
    lcd.setCursor(0, 3);
    printHMS(hour, minute, second);
    if (plus.isPressed() && minute < 59) {
      minute++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && minute > 0) {
      minute--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 37) {
    //set dayOfWeek
    lcd.setCursor(0, 0);
    lcd.print("Set Date:  Day");
    lcd.setCursor(0, 3);
    printDate();
    lcd.setCursor(10, 3);
    lcd.print(year);
    if (plus.isPressed() && dayOfWeek < 7) {
      dayOfWeek++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && dayOfWeek > 1) {
      dayOfWeek--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 38) {
    //set dayOfMonth
    lcd.setCursor(0, 0);
    lcd.print("Set Date:  Date");
    lcd.setCursor(0, 3);
    printDate();
    lcd.setCursor(10, 3);
    lcd.print(year);
    if (plus.isPressed() && dayOfMonth < 31) {
      dayOfMonth++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && dayOfMonth > 1) {
      dayOfMonth--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 39) {
    //set Month
    lcd.setCursor(0, 0);
    lcd.print("Set Date:  Month");
    lcd.setCursor(0, 3);
    printDate();
    lcd.setCursor(10, 3);
    lcd.print(year);
    if (plus.isPressed() && month < 12) {
      month++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && month > 1) {
      month--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }

  if (menuCount == 40) {
    //set Year
    lcd.setCursor(0, 0);
    lcd.print("Set Date:  Year");
    lcd.setCursor(0, 3);
    printDate();
    lcd.setCursor(10, 3);
    lcd.print(year);
    if (plus.isPressed() && year < 99) {
      year++;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    if (minus.isPressed() && year > 1) {
      year--;
      delay(btnCurrDelay(btnCurrIteration - 1));
      bklTime = millis();
    }
    setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
}

Forgot to mention earlier about that Button library... although I could still get it to compile with the new library by simply deleting the PULLDOWN on the buttons, the increments were even slower than what it is now.

Also forgot to mention... earlier I was using regular notepad to edit my patches, but after opening Notepad++, it was easier to follow the { } simply by clicking on them with the mouse pointer. I used to use Linux for years, but forced to have a Windows machine for VHS captures and for VR. Blah. I hate Windows. :stuck_out_tongue:

Crap... just posted this in the wrong post.. lol. Let's try again...

I've come across quite a few versions of this exact sketch a few times, even on this site. It originated from a reef tank community, where they use high powered LEDs over planted fish tanks. The sketch was free, open source. But someone had to go and make a buck off of it... BoostLED. Their version has the button routine to speed up after a few increments, but it's also cleaned up and condensed, so I couldn't figure out how to use an existing LED channel as a relay for the pumps like I did in my other thread. But now that I figured out how to add a relay on a schedule, I don't need to modify any of that. It would also save me 2 pins and I can go back to using a Nano. The plusTen and minusTen buttons lock me into the Mega. I'll play with the sketch tomorrow.

/*
 // Typhon firmware
 // v0.2 alpha 2010-23-11
 // N. Enders, R. Ensminger
 // Changes made by BoostLED have notations as below.
 // This sketch provides firmware for the Typhon LED controller.
 // It provides a structure to fade 4 independent channels of LED lighting
 // on and off each day, to simulate sunrise and sunset.
 //
 // Current work in progress:
 // - store all LED variables in EEPROM so they are not reset by a loss of power
 //
 // Future developments may include:
 // - moon phase simulation
 // - storm simulation
 // 
 // Sketch developed in Arduino-18
 // Requires LiquidCrystal, Wire, EEPROM, EEPROMVar, and Button libraries.
 // Button is available here: http://www.arduino.cc/playground/Code/Button
 // EEPROMVar is available here: http://www.arduino.cc/playground/uploads/Profiles/EEPROMVar_01.zip
*/

// include the libraries:
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Button.h>
#include <EEPROM.h>
#include <EEPROMVar.h>

/**** Define Variables & Constants ****/
/**************************************/

// set the RTC's I2C address
#define DS1307_I2C_ADDRESS 0x68

// create the LCD
LiquidCrystal lcd(8, 7, 5, 4, 16, 2);

// set up backlight
int bkl         = 6;        // backlight pin
byte bklIdle    = 10;       // PWM value for backlight at idle
byte bklOn      = 70;       // PWM value for backlight when on
int bklDelay    = 10000;    // ms for the backlight to idle before turning off
unsigned long bklTime = 0;  // counter since backlight turned on

// create the menu counter
int menuCount   = 1;
int menuSelect = 0;

//create manual override variables
boolean override = false;
byte overmenu = 0;
int overpercent = 0;

// create the buttons
Button menu     = Button(12,PULLDOWN);
Button select   = Button(13,PULLDOWN);
Button plus     = Button(14,PULLDOWN);
Button minus    = Button(15,PULLDOWN);

// Button state constants.
byte buttonNotPressed  = 0;
byte buttonUniquePress = 1;
byte buttonIsPressed   = 2;
byte slowCount = 3;         // number of intervals to do a "slowDelay" when holding a button
int slowDelay = 1000;       // milliseconds to delay when initially holding a button
int fastDelay = 100;        // milliseconds to delay after holding the button for "slowCount" intervals

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight.
int oldMinCounter = 0;      // counter that resets at midnight.

EEPROMVar<boolean> inverted = false; //Modified by NetSurge

// Used for button hold down
int intervalCounter = 0;
int oldIntervalCounter;
unsigned long currMil = 0;         // current millisecond

int oneVal = 0;             // current value for channel 1
int twoVal = 0;             // current value for channel 2
int threeVal = 0;           // current value for channel 3
int fourVal = 0;            // current value for channel 4

// Variables making use of EEPROM memory:
EEPROMVar<int> oneStartMins = 750;     // minute to start this channel.
EEPROMVar<int> onePhotoPeriod = 720;   // photoperiod in minutes for this channel.
EEPROMVar<int> oneMax = 100;           // max intensity for this channel, as a percentage
EEPROMVar<int> oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset for
                                       //    this channel.
EEPROMVar<int> twoStartMins = 810;
EEPROMVar<int> twoPhotoPeriod = 600;
EEPROMVar<int> twoMax = 100;
EEPROMVar<int> twoFadeDuration = 60;
EEPROMVar<int> threeStartMins = 810;
EEPROMVar<int> threePhotoPeriod = 600;
EEPROMVar<int> threeMax = 100;
EEPROMVar<int> threeFadeDuration = 60;
EEPROMVar<int> fourStartMins = 480;
EEPROMVar<int> fourPhotoPeriod = 510;  
EEPROMVar<int> fourMax = 100;          
EEPROMVar<int> fourFadeDuration = 60;  

typedef struct {
  int Led;            // channel pin
  int StartMins;      // minute to start this channel.
  int PhotoPeriod;    // photoperiod in minutes for this channel.
  int Max;            // max intensity for this channel, as a percentage
  int FadeDuration;   // duration of the fade on and off for sunrise and sunset for
                      //    this channel.
} 
channelVals_t;
channelVals_t channel[4];

/*
 int oneStartMins = 1380;    // minute to start this channel.
 int onePhotoPeriod = 120;   // photoperiod in minutes for this channel.
 int oneMax = 100;           // max intensity for this channel, as a percentage
 int oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset for
                             //    this channel.                                    
 int twoStartMins = 800;
 int twoPhotoPeriod = 60;
 int twoMax = 100;
 int twoFadeDuration = 15;
 int threeStartMins = 800;
 int threePhotoPeriod = 60;
 int threeMax = 100;
 int threeFadeDuration = 30;
 int fourStartMins = 800;
 int fourPhotoPeriod = 120;  
 int fourMax = 100;          
 int fourFadeDuration = 60;  
*/

/****** RTC Functions ******/
/***************************/

// Convert decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// Sets date and time, starts the clock
void setDate(byte second,        // 0-59
byte minute,        // 0-59
byte hour,          // 1-23
byte dayOfWeek,     // 1-7
byte dayOfMonth,    // 1-31
byte month,         // 1-12
byte year)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time
void getDate(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down
int   setLed(int mins,    // current time in minutes
int ledPin,  // pin for this channel of LEDs
int start,   // start time for this channel of LEDs
int period,  // photoperiod for this channel of LEDs
int fade,    // fade duration for this channel of LEDs
int ledMax   // max value for this channel
)  {
  int val = 0;

  //fade up
  if (mins > start || mins <= start + fade)  {
    val = map(mins - start, 0, fade, 0, ledMax);
  }

  //fade down
  if (mins > start + period - fade && mins <= start + period)  {
    val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
  }

  //off or post-midnight run.
  if (mins <= start || mins > start + period)  {
    if((start+period)%1440 < start && (start + period)%1440 > mins )
    {
      val=map((start+period-mins)%1440,0,fade,0,ledMax);
    }
    else  
      val = 0; 
  }


//invert for BuckPuck Functions
//Added by NetSurge
if(inverted){
//  val=~val;
//  val=val&255;
//  ledMax=~ledMax;
//  ledMax=100-ledMax;
}
  if (val > ledMax)  {
    val = ledMax;
  } 

  if (val < 0) {
    val = 0; 
  } 


if(inverted){
  analogWrite(ledPin, map(val, 0, 100, 255, 0));
}
else{
  analogWrite(ledPin, map(val, 0, 100, 0, 255));
}

//Debugging info 0-255 PWM Output
//Modified by NetSurge
/*
if(inverted){
if(ledPin == 9){
lcd.setCursor(0,0);
  lcd.print(map(val, 0, 100, 255, 0));
}

if(ledPin == 10){
  lcd.setCursor(4,0);
  lcd.print(map(val, 0, 100, 255, 0));
}

if(ledPin == 11){
  lcd.setCursor(8,0);
  lcd.print(map(val, 0, 100, 255, 0));
}

if(ledPin == 3){
  lcd.setCursor(12,0);
  lcd.print(map(val, 0, 100, 255, 0));
}
}


else{
if(ledPin == 9){
lcd.setCursor(0,0);
  lcd.print(map(val, 0, 100, 0, 255));
}

if(ledPin == 10){
  lcd.setCursor(4,0);
  lcd.print(map(val, 0, 100, 0, 255));
}

if(ledPin == 11){
  lcd.setCursor(8,0);
  lcd.print(map(val, 0, 100, 0, 255));
}

if(ledPin == 3){
  lcd.setCursor(12,0);
  lcd.print(map(val, 0, 100, 0, 255));
  }
}

*/

  if(override){
    val=overpercent;
  }

  return val;
}

/**** Display Functions ****/
/***************************/

// format a number of minutes into a readable time (24 hr format)
void printMins(int mins,       //time in minutes to print
boolean ampm    //print am/pm?
)  {
  int hr = (mins%1440)/60;
  int mn = mins%60;
  if(hr<10){
    lcd.print(" ");
  }
  lcd.print(hr);
  lcd.print(":");
  if(mn<10){
    lcd.print("0");
  }
  lcd.print(mn); 
}

// format hours, mins, secs into a readable time (24 hr format)
void printHMS (byte hr,
byte mn,
byte sec      //time to print
)  
{

  if(hr<10){
    lcd.print(" ");
  }
  lcd.print(hr, DEC);
  lcd.print(":");
  if(mn<10){
    lcd.print("0");
  }
 
  lcd.print(mn, DEC);
  lcd.print(":");
  if(sec<10){
    lcd.print("0");
  }
  lcd.print(sec, DEC);
}

void ovrSetAll(int pct){
  analogWrite(channel[0].Led, map(pct,0,100,0,255));
  analogWrite(channel[1].Led, map(pct,0,100,0,255));
  analogWrite(channel[2].Led, map(pct,0,100,0,255));
  analogWrite(channel[3].Led, map(pct,0,100,0,255));
}

byte buttonCheck(Button *button) {
  if (button->uniquePress()) {
    return buttonUniquePress;
  } 
  else if (button->isPressed()) {
    return buttonIsPressed;
  } 
  else {
    return buttonNotPressed;
  }
}

boolean checkButtonAction(Button *button) {
  byte buttonState = buttonCheck(button);
  unsigned long mil = millis();
  if (buttonState == buttonUniquePress) {
    intervalCounter = slowCount;
    currMil = mil;
    return true;
  } 
  else if (buttonState == buttonIsPressed) {
    if (intervalCounter > 0) {
      if (currMil < (mil - slowDelay)) {
        intervalCounter--;
        currMil = mil;
        return true;
      }
    } 
    else {
      if (currMil < (mil - fastDelay)) {
        currMil = mil;
        return true;
      }
    }
  }
  return false;
}

/**** Setup ****/
/***************/

void setup() {
  // Initialize channel variables. Set LED channel pin and retrieve values from EEPROM
  channel[0].Led = 9;
  channel[0].StartMins = oneStartMins;
  channel[0].PhotoPeriod = onePhotoPeriod;
  channel[0].Max = oneMax;
  channel[0].FadeDuration = oneFadeDuration;
  channel[1].Led = 10;
  channel[1].StartMins = twoStartMins;
  channel[1].PhotoPeriod = twoPhotoPeriod;
  channel[1].Max = twoMax;
  channel[1].FadeDuration = twoFadeDuration;
  channel[2].Led = 11;
  channel[2].StartMins = threeStartMins;
  channel[2].PhotoPeriod = threePhotoPeriod;
  channel[2].Max = threeMax;
  channel[2].FadeDuration = threeFadeDuration;
  channel[3].Led = 3;
  channel[3].StartMins = fourStartMins;
  channel[3].PhotoPeriod = fourPhotoPeriod;
  channel[3].Max = fourMax;
  channel[3].FadeDuration = fourFadeDuration;

// Title & Credits added
  Wire.begin();
  pinMode(bkl, OUTPUT);
  lcd.begin(16, 2);
  digitalWrite(bkl, HIGH);
  lcd.setCursor(0,0); //Modified by NetSurge
  lcd.print("Typhon Reef LED");
  lcd.setCursor(0,1);
  lcd.print("Controller"); 
  delay(1000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("by N. Enders &");
  lcd.setCursor(0,1);
  lcd.print("R. Ensminger    ");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Brought to you  ");
  lcd.setCursor(0,1);
  lcd.print("by BoostLED     ");
  delay(2000);
  lcd.clear();
  analogWrite(bkl,bklIdle);
}

/***** Loop *****/
/****************/

void loop() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDate(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  oldMinCounter = minCounter;
  minCounter = hour * 60 + minute;

  int i;
  for (i=0; i<4; i++) {
    //check & set fade durations
    if(channel[i].FadeDuration > channel[i].PhotoPeriod/2 && channel[i].PhotoPeriod >0) {
      channel[i].FadeDuration = channel[i].PhotoPeriod/2;
    }
    if(channel[i].FadeDuration<1){
      channel[i].FadeDuration=1;
    }
  }

  //check & set any time functions
  //set outputs
  if(!override){
    oneVal = setLed(minCounter, channel[0].Led, channel[0].StartMins, channel[0].PhotoPeriod, channel[0].FadeDuration, channel[0].Max);
    twoVal = setLed(minCounter, channel[1].Led, channel[1].StartMins, channel[1].PhotoPeriod, channel[1].FadeDuration, channel[1].Max);
    threeVal = setLed(minCounter, channel[2].Led, channel[2].StartMins, channel[2].PhotoPeriod, channel[2].FadeDuration, channel[2].Max);
    fourVal = setLed(minCounter, channel[3].Led, channel[3].StartMins, channel[3].PhotoPeriod, channel[3].FadeDuration, channel[3].Max);
  }
  else{
    oneVal = overpercent;
    twoVal = overpercent;
    threeVal = overpercent;
    fourVal = overpercent;
    ovrSetAll(overpercent);
  }
  // Update EEProms with any values that may have changed
  if (channel[0].StartMins != oneStartMins) {
    oneStartMins = channel[0].StartMins;
  }
  if (channel[0].PhotoPeriod != onePhotoPeriod) {
    onePhotoPeriod = channel[0].PhotoPeriod;
  }
  if (channel[0].Max != oneMax) {
    oneMax = channel[0].Max;
  }
  if (channel[0].FadeDuration != oneFadeDuration) {
    oneFadeDuration = channel[0].FadeDuration;
  }
  if (channel[1].StartMins != twoStartMins) {
    twoStartMins = channel[1].StartMins;
  }
  if (channel[1].PhotoPeriod != twoPhotoPeriod) {
    twoPhotoPeriod = channel[1].PhotoPeriod;
  }
  if (channel[1].Max != twoMax) {
    twoMax = channel[1].Max;
  }
  if (channel[1].FadeDuration != twoFadeDuration) {
    twoFadeDuration = channel[1].FadeDuration;
  }
  if (channel[2].StartMins != threeStartMins) {
    threeStartMins = channel[2].StartMins;
  }
  if (channel[2].PhotoPeriod != threePhotoPeriod) {
    threePhotoPeriod = channel[2].PhotoPeriod;
  }
  if (channel[2].Max != threeMax) {
    threeMax = channel[2].Max;
  }
  if (channel[2].FadeDuration != threeFadeDuration) {
    threeFadeDuration = channel[2].FadeDuration;
  }

  if (channel[3].StartMins != fourStartMins) {
    fourStartMins = channel[3].StartMins;
  }
  if (channel[3].PhotoPeriod != fourPhotoPeriod) {
    fourPhotoPeriod = channel[3].PhotoPeriod;
  }
  if (channel[3].Max != fourMax) {
    fourMax = channel[3].Max;
  }
  if (channel[3].FadeDuration != fourFadeDuration) {
    fourFadeDuration = channel[3].FadeDuration;
  }

  //  if (intervalCounter > 0) {
  //    unsigned long milsec = millis();
  //    if ((currMil < (milsec - 1000)) || (currMil > milsec)) {
  //      currMil = milsec;
  //      intervalCounter--;
  //    }
  //  }

  //turn the backlight off and reset the menu if the idle time has elapsed
  if(bklTime + bklDelay < millis() && bklTime > 0 ){
    analogWrite(bkl,bklIdle);
    menuCount = 1;
    lcd.clear();
    bklTime = 0;
  }

  //iterate through the menus
  if(menu.uniquePress()){
    analogWrite(bkl,bklOn);
    bklTime = millis();
    if(menuCount < 21){  //Modified by NetSurge
      menuCount++;
    }
   else {
      menuCount = 1;
    }
    lcd.clear();
  }

  switch (menuCount) {
  case 1:
    doMainMenu(minCounter, oldMinCounter, hour, minute, second,
    oneVal, twoVal, threeVal, fourVal);
    break;
  case 2:
    doOverride(second);
    break;
  case 3:
    doStartTime(0);
    break;
  case 4:
    doEndTime(0);
    break;
  case 5:
    doFadeDuration(0);
    break;
  case 6:
    doMaxIntensity(0);
    break;
  case 7:
   doStartTime(1);
    break;
  case 8:
    doEndTime(1);
    break;
  case 9:
    doFadeDuration(1);
    break;
  case 10:
    doMaxIntensity(1);
    break;
  case 11:
    doStartTime(2);
    break;
  case 12:
    doEndTime(2);
    break;
  case 13:
    doFadeDuration(2);
    break;
  case 14:
    doMaxIntensity(2);
    break;
  case 15:
    doStartTime(3);
    break;
  case 16:
    doEndTime(3);
    break;
  case 17:
    doFadeDuration(3);
    break;
  case 18:
    doMaxIntensity(3);
    break;
  case 19:
    setHour(&hour, minute, second, dayOfWeek, dayOfMonth, month, year);
    break;
  case 20:
    setMinute(hour, &minute, second, dayOfWeek, dayOfMonth, month, year);
    break;
  case 21:
 doinvertPWM();
  break;
  }
}

void doMainMenu(int minCounter,
int oldMinCounter,
byte hour,
byte minute,
byte second,
int oneVal,
int twoVal,
int threeVal,
int fourVal) {


 //main screen turn on!!!
  if (minCounter > oldMinCounter){
    lcd.clear();
  }
  lcd.setCursor(0,0);

//Take out display time and uncomment in the led funtion for PWM value debugging
//NetSurge
  lcd.print("Time: "); // Displays Time.
  printHMS(hour, minute, second);
  lcd.setCursor(0,1);
  lcd.print(oneVal);
  lcd.setCursor(4,1);
  lcd.print(twoVal);
  lcd.setCursor(8,1);
  lcd.print(threeVal);
  lcd.setCursor(12,1);
  lcd.print(fourVal);
 
 if(inverted){
   lcd.setCursor(15,0);
   lcd.print("V");
  }
  //debugging function to use the select button to advance the timer by 1 minute
  //if(select.uniquePress()){setDate(second, minute+1, hour, dayOfWeek, dayOfMonth, month, year);}
}

void doOverride(byte second) {
  //Manual Override Menu
  lcd.setCursor(0,0);
  lcd.print("SETTING MODE:        "); // Changed by BoostLED
  lcd.setCursor(0,1);

//if(menuSelect ==4){
//menuSelect = 0;            //modified by NetSurge
//}

  if(select.uniquePress()){
    if(menuSelect < 4){
      menuSelect++;
    }
    else{
      menuSelect = 0;
    }
    bklTime = millis();
  }

  if(menuSelect == 0){
    lcd.print("Timer           "); // Changed by BoostLED
    override = false;
  }
  if(menuSelect == 1){
    lcd.print("All Channels ON "); // Changed by BoostLED
    overpercent = 100;
    override = true;
  }
  if(menuSelect == 2){
    lcd.print("All Channels OFF"); // Changed by BoostLED
    overpercent = 0;
    override = true;
  }    
  if(menuSelect == 3){
    override = true;
    lcd.print("Custom ");   // Added by BoostLED
    lcd.print(overpercent,DEC);
    lcd.print("%        "); 
    if (overpercent < 100) {
      if (checkButtonAction(&plus)) {
        overpercent++;
        bklTime = millis();
      }
     }
    if (overpercent > 0) {
      if (checkButtonAction(&minus)) {
        overpercent--;
        bklTime = millis();
      }
    }
  }
  
//invert PWM 
//Modified by NetSurge
/* Moved to Main Menu and not in Overide Menu

if(menuSelect == 4){
   if(inverted == true)
  lcd.print("PWM Inverted:YES ");
   if(inverted == false)
  lcd.print("PWM Inverted:NO ");
  if (checkButtonAction(&minus) || checkButtonAction(&plus)) {
   inverted = !inverted;
 }
 override = false;
}
*/
}

void doStartTime(int val) {
  //set start time
  lcd.setCursor(0,0);
  lcd.print("Channel ");
  lcd.print(val+1);
  lcd.print(" Start");
  lcd.setCursor(0,1);
  printMins(channel[val].StartMins, true);
  if (channel[val].StartMins < 1440) {
    if (checkButtonAction(&plus)) {
      channel[val].StartMins++;
      if (channel[val].PhotoPeriod > 0) {
        channel[val].PhotoPeriod--;
      } 
     else {
         channel[val].PhotoPeriod = 1439;
      }
      bklTime = millis();
    }
  } 
  if (channel[val].StartMins > 0) {
    if (checkButtonAction(&minus)) {
      channel[val].StartMins--;
      if (channel[val].PhotoPeriod < 1439) {
        channel[val].PhotoPeriod++;
      } 
     else {
        channel[val].PhotoPeriod=0;
      }
      bklTime = millis();
    }
  } 
}

void doEndTime(int val) {
  //set end time
  lcd.setCursor(0,0);
  lcd.print("Channel ");
  lcd.print(val+1);
  lcd.print(" End");
  lcd.setCursor(0,1);
  printMins(channel[val].StartMins+channel[val].PhotoPeriod, true);
  if (checkButtonAction(&plus)) {
    if(channel[val].PhotoPeriod < 1439){
      channel[val].PhotoPeriod++;
    } 
    else {
      channel[val].PhotoPeriod=0;
    }
    bklTime = millis();
  }
  if (checkButtonAction(&minus)) {
    if(channel[val].PhotoPeriod > 0){
      channel[val].PhotoPeriod--;
    } 
    else {
      channel[val].PhotoPeriod = 1439;
    }
    bklTime = millis();
  }
}

void doFadeDuration(int val) {
  //set fade duration
  lcd.setCursor(0,0);
  lcd.print("Channel ");
  lcd.print(val+1);
  lcd.print(" Fade");
  lcd.setCursor(0,1);
  lcd.print("Duration ");
  printMins(channel[val].FadeDuration, false);
  if (channel[val].FadeDuration < channel[val].PhotoPeriod/2 || channel[val].FadeDuration == 0) {
    if (checkButtonAction(&plus)) {
      channel[val].FadeDuration++;
      bklTime = millis();
    }
  }
  if (channel[val].FadeDuration > 1) {
    if (checkButtonAction(&minus)) {
      channel[val].FadeDuration--;
      bklTime = millis();
    }
  }
}


void doMaxIntensity(int val) {
  //set intensity
  lcd.setCursor(0,0);
  lcd.print("Channel ");
  lcd.print(val+1);
  lcd.print(" Max");
  lcd.setCursor(0,1);
  lcd.print("Level: "); // Added by BoostLED
  lcd.print(channel[val].Max);
  lcd.print("%        "); // Added by BoostLED
  if (channel[val].Max < 100) {
    if (checkButtonAction(&plus)) {
      lcd.clear();
      channel[val].Max++;
      bklTime = millis();
    }
  }
  if (channel[val].Max > 0) {
    if (checkButtonAction(&minus)) {
      lcd.clear();
      channel[val].Max--;
      bklTime = millis();
    }
  }
}

//Select Inverted PWM or not
//Added  By NetSurge
void doinvertPWM() {
lcd.setCursor(0,0);
  lcd.print("PWM Inverted... ");
lcd.setCursor(0,1);
   if(inverted == true)
  lcd.print("YES ");
   if(inverted == false)
  lcd.print("NO ");
  if (checkButtonAction(&minus) || checkButtonAction(&plus)) {
   inverted = !inverted;
 }
}

void setHour(byte *hour, byte minute, byte second,
byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
  //set hours
  lcd.setCursor(0,0);
  lcd.print("Set Time: Hrs");
  lcd.setCursor(0,1);
  printHMS(*hour, minute, second);
  if (checkButtonAction(&plus)) {
    if (*hour < 23) {
      (*hour)++;
    } 
   else {
      *hour = 0;
    }
    bklTime = millis();
  }
  if (checkButtonAction(&minus)) {
    if (*hour > 0) {
      (*hour)--;
    } 
    else {
      *hour = 23;
    }
    bklTime = millis();
  }
  setDate(second, minute, *hour, dayOfWeek, dayOfMonth, month, year);
}

void setMinute(byte hour, byte *minute, byte second,
byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
  //set minutes
  lcd.setCursor(0,0);
  lcd.print("Set Time: Mins");
  lcd.setCursor(0,1);
  printHMS(hour, *minute, second);
  if (checkButtonAction(&plus)) {
    if (*minute < 59) {
      (*minute)++;
    } 
   else {
      *minute = 0;
    }
    bklTime = millis();
  }
  if (checkButtonAction(&minus)) {
    if (*minute > 0) {
      (*minute)--;
    } 
   else {
      *minute = 59;
    }
    bklTime = millis();
  }
  setDate(second, *minute, hour, dayOfWeek, dayOfMonth, month, year);
}

Looking at the sketch a bit more in detail, I should just be able to adapt the button routine into my sketch instead. I can be a bit backwards sometimes. :stuck_out_tongue: