Little Free Library problem with door open / door closed function

The program is for a Little Free Library. The basic function is, open the door, have lights fade on in a sequence. Close the door, lights fade off in reverse.

I had the sketch fully functional, but ran into a problem when I wanted to include a time-out function. The idea was, since the library will be solar powered, I want there to be a time limit on how long the lights remain illuminated.

The problem came up when I realized, with the old sketch, it was a very large IF/ELSE statement. The loop would hang during the IF waiting for the ELSE. Checking millis() did no good, since it would only do it once at the end of the IF statement and wouldn't check it again until the door had been closed and reopened.

To fix the problem, I'm trying to get the loop running again, and relying on Boolean statements to keep things orderly.

The NEW problem is... the Arduino doesn't seem to care about the door switch anymore. It assumes the door is always open, and fades on the lights. Once they're all faded on, it cycles through again (never turning off the lights, but rather dropping each one to zero and fading on before moving to the next).

It's a hot mess, and I've spent hours trying to figure out how to fix. Please help, I think I've caused my brain to melt.

For now, I've reduced the sketch to its most basic function. Open the door, turn on the lights. Close the door, turn off the lights. Everything else, I've turned to comments. Once this basic function is working, I'll worry about making the rest functional again.

Code is too long to post all at once. Going to post up to the end of the loop first, then the rest in a subsequent post)

/*


   SwitchPin.   Using internal pullup resistor
   Magnetic Switch connected between Pin 17 (A3) and GND

   ButtonPin.  Using internal pullup resistor
   Pushbutton connected between Pin 15(A1) and GND
   Voltmeter pin A0

   LED attached from pin 3 to 68ohm resistor    (interior light)
   LED attached from pin 5 to 68ohm resistor    (landscape)
   LED attached from pin 6 to 68ohm resistor    (landscape)
   LED attached from pin 9 to 68ohm resistor    (landscape)
   LED attached from pin 10 to 68ohm resistor   (landscape)
   LED attached from pin 11 to 68ohm resistor   (lcd led)
   LED attached from pin 20 to 68ohm resistor   (attached not active)
   LED attached from pin A4(18) to 90ohm resistor (non pwm) (door left open)

   LCD connected pin VSS to gnd
   LCD connected pin VDD to 5+
   LCD connected pin V0 to 10k var resistor
   LCD connected pin 2 to RS
   LCD connected pin RW to ground
   LCD connected pin 4 to E
   LCD connected pin 7 to D4
   LCD connected pin 8 to D5
   LCD connected pin 12 to D6
   LCD connected pin 13 to D7
   LCD connected pin A ref. above LED pin 11
   LCD connected pin K to gnd

   Therm pin 1 (on the left) of the sensor to +5V
   Therm pin 2 to Arduino pin 16 (A2)
   Pin 2 use internal pull up resistor
   Therm pin 4 (on the right) of the sensor to GROUND



  created  10MAR16


*/

// include the library code:
#include <LiquidCrystal.h>
#include <DHT.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(2, 4, 7, 8, 12, 13);
#define DHTPIN 16     // Pin 16(A2) to temp sensor middle pin
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);

void fade_on_lights();
void fade_off_lights();
void fade_on_lcd_backlight();
void fade_off_lcd_backlight();
void door_open_lcd_cycle();
void display_current_temp();
void display_batteryVoltage();
void display_low_battery();
void LibraryTimedOut();


// this constant won't change:
const int ButtonPin = 15;    // the pin that the pushbutton is attached to (15(A1) to gnd)
const int SwitchPin = 17;    // the pin that the reed switch is attached to (17(A3) to gnd)
const int voltpin = A0;      // analog input for voltage sense  FRIED A0 PIN....NEW BOARD USE A0
const int ledPin1 = 3;       // interior light the pin that the LED is attached to  (5 to gnd)
const int ledPin2 = 5;       // landscape light pin that the LED is attached to  (6 to gnd)
const int ledPin3 = 6;       // landscape light
const int ledPin4 = 9;       // landscape light
const int ledPin5 = 10;      // landscape light
const int WarningLEDPin = 18; //door left open LED
//attached, not active.  const int ledpin6 = 20;
const int lcdledPin = 11;

// Variables will change:
int SwitchCounter = 0;   // counter for the number of times Door has been opened
int SwitchState = 0;         // current state of the Door Switch
int lastSwitchState = 0;     // previous state of the Door Switch
int ButtonState = 0;    //current state of the button
int lastButtonState = 0;  //previous state of the button


//battery voltmeter initialize
float vout = 0;
float batteryVoltage = 0;
float R1 = 998000.0;
float R2 = 267500.0;
int value = 0;

//door left open intialize
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long timeout = 10000;
//unsigned long interval = 1000;
//unsigned long timeout = 600000;
//int ledState = LOW;

long lastDebounceTime = 0;
long debounceDelay = 50;


boolean DoorClosed = false;
boolean BatteryBad = false;
boolean VoltageButtonNotPressed = false;
boolean NotTimedOut = false;


void setup()
{ //begining of void setup
  lcd.begin(16, 2);
  dht.begin();

  pinMode(SwitchPin, INPUT_PULLUP); // initialize the switch pin as an input
  pinMode(ButtonPin, INPUT_PULLUP); // initialize the button pin as an input
  pinMode(DHTPIN, INPUT_PULLUP);  //initialize the temp sensor pin as input pulled up
  pinMode(ledPin1, OUTPUT);   // initialize the LED as an output:
  pinMode(ledPin2, OUTPUT);  //initialize LED as an output
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  pinMode(ledPin5, OUTPUT);
  //attached, not active  pinMode(ledPin6, OUTPUT);
  pinMode(WarningLEDPin, OUTPUT);
  pinMode(lcdledPin, OUTPUT);
  Serial.begin(9600);   // initialize serial communication:
} //end of void setup



void loop()
{ //begining of loop



  //check battery voltage
  value = analogRead(voltpin);
  vout = (value * 4.985) / 1024.0;
  batteryVoltage = vout / (R2 / (R1 + R2));
  Serial.println("checking voltage");



  if (batteryVoltage > 0.5)
    {
      BatteryBad = !BatteryBad;
    }




  int Reading = digitalRead(SwitchPin);  // compare the SwitchState to its previous state
  if (Reading != lastSwitchState) // if the state has changed, execute
    { //begining of bracket for door switch if/else
      lastDebounceTime = millis();
    }

  if ((millis() - lastDebounceTime) > debounceDelay)
    {
      if (Reading != SwitchState)
        {
          SwitchState = Reading;
          Serial.println("SwitchState now = Reading");
        }
          lastSwitchState = Reading;
          DoorClosed = !DoorClosed;
          Serial.println("ReadingReadingReading");
          
    
    //       unsigned long currentMillis = millis();
    //   if ((unsigned long)(currentMillis - previousMillis) >= timeout)
    //      {
    //      NotTimedOut = !NotTimedOut;
    //       previousMillis = millis();
    //      }
      }


  if (DoorClosed)
    {
      Serial.println("fading off lights");
      fade_off_lights();      
    }


  

  //  ButtonState = digitalRead(ButtonPin);
  //    if (ButtonState == LOW)
  //      {
  //        VoltageButtonNotPressed = !VoltageButtonNotPressed;
  //      }




    if (!DoorClosed)// && !BatteryBad && NotTimedOut)
    {
      SwitchCounter++;  //increment counter if door has opened
      Serial.println("Door Open");
      Serial.print("Number of times door has been opened:  ");
      Serial.println(SwitchCounter);
      Serial.println(digitalRead(SwitchPin));  //Display current value
      delay(20);
      fade_on_lights();
      //    delay(500);
      //door_open_lcd_cycle();
      //    delay(25);
      //display_current_temp();
      //    delay (2500);
    }




  //    if (!DoorClosed && !BatteryBad && !NotTimedOut)
  //      {
  //         LibraryTimedOut();
  //      }




  //    if (!DoorClosed && BatteryBad && NotTimedOut)
  //      {
  //    fade_on_lcd_backlight();
  //    delay(525);
  //    display_low_battery();
  //      }




  //    if (!DoorClosed && BatteryBad && !NotTimedOut)
  //      {
  //        LibraryTimedOut();
  //      }




  //    if (!DoorClosed && !BatteryBad && !VoltageButtonNotPressed)
  //      {
  //      display_batteryVoltage();
  //      }




  //    if (!DoorClosed && BatteryBad && !VoltageButtonNotPressed)
  //      {
  //        display_batteryVoltage();
  //      }


} //end of loop
void fade_on_lights()
{ //begin fade_on_lights
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin1, fadeValue);
    // wait for 30 milliseconds to see the dimming effect        // sets the value (range from 0 to 255)
    delay(50);
  }

  for (int fadeValue = 10 ; fadeValue <= 255; fadeValue += 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin2, fadeValue);
    // wait for 30 milliseconds to see the dimming effect        // sets the value (range from 0 to 255)
    delay(25);
  }

  for (int fadeValue = 20 ; fadeValue <= 255; fadeValue += 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);
    // wait for 30 milliseconds to see the dimming effect        // sets the value (range from 0 to 255)
    delay(20);
  }

  for (int fadeValue = 10 ; fadeValue <= 255; fadeValue += 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin4, fadeValue);
    // wait for 30 milliseconds to see the dimming effect        // sets the value (range from 0 to 255)
    delay(13);
  }

  for (int fadeValue = 10 ; fadeValue <= 255; fadeValue += 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin5, fadeValue);
    // wait for 30 milliseconds to see the dimming effect        // sets the value (range from 0 to 255)
    delay(8);
  }

  //attached not active      for (int fadeValue = 10 ; fadeValue <= 255; fadeValue += 5)
  //attached not active        {
  //attached not active        // sets the value (range from 0 to 255):
  //attached not active        analogWrite(ledPin6, fadeValue);
  //attached not active        // wait for 30 milliseconds to see the dimming effect        // sets the value (range from 0 to 255)
  //attached not active        delay(6);
  //attached not active        }

  for (int fadeValue = 10 ; fadeValue <= 255; fadeValue += 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(lcdledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect        // sets the value (range from 0 to 255)
    delay(30);
  }
}  //end of fade_on_lights




void fade_off_lights()
{ //begin fade off lights

  //attached not active      for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5)
  //attached not active      {
  //attached not active        // sets the value (range from 0 to 255):
  //attached not active        analogWrite(ledPin6, fadeValue);
  //attached not active        analogWrite(lcdledPin, fadeValue);
  //attached not active        // wait for 30 milliseconds to see the dimming effect
  //attached not active        delay(15);
  //attached not active      }

  lcd.clear();

  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin5, fadeValue);
    analogWrite(lcdledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(15);
  }

  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin4, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(15);
  }

  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin3, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(20);
  }

  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin2, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(25);
  }

  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin1, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(35);
  }
}   //end fade off lights




void fade_on_lcd_backlight()
{ //begin fading on LCD backlight
  for (int fadeValue = 10 ; fadeValue <= 255; fadeValue += 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(lcdledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect        // sets the value (range from 0 to 255)
    delay(30);
  }
}   //end fading on LCD backlight




void fade_off_lcd_backlight()
{ //begin fading off lcd backlight
  lcd.clear();
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5)
  {
    // sets the value (range from 0 to 255):
    analogWrite(lcdledPin, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(35);
  }
}   //end fading off lcd backlight




void door_open_lcd_cycle()
{ //begin printing welcome messages to LCD
  lcd.clear();
  lcd.print("Welcome To");
  delay(2500);
  lcd.clear();
  lcd.print("My Little");
  lcd.setCursor(0, 2);
  lcd.print("Free Library");
  delay(2500);

  for (int positionCounter = 0; positionCounter < 16; positionCounter++)
  {
    // scroll one position left:
    lcd.scrollDisplayLeft();
    // wait a bit:
    delay(150);
  }

  // scroll 13 positions (string length) to the left
  // to move it offscreen left:

  lcd.clear();
  lcd.print(SwitchCounter);
  lcd.print(" Visitors");
  lcd.setCursor(0, 2);
  lcd.print("and counting!");
  delay(2500);

  // scroll 29 positions (string length + display length) to the right
  // to move it offscreen right:
  for (int positionCounter = 0; positionCounter < 16; positionCounter++)
  {
    // scroll one position right:
    lcd.scrollDisplayRight();
    // wait a bit:
    delay(150);
  }
}   //end printing welcome messages to LCD



void display_current_temp()

{ //begin reading from temp sensor and display value
  // 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();
  float t = dht.readTemperature();
  t = t * 9 / 5 + 32;

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h))
  { //if sensor is failed
    lcd.setCursor(0, 0);
    lcd.print("Failed to read from DHT");
    //Serial.println("Failed to read from DHT");
  }   //if sensor is failed
  else
  { //if sensor is not failed
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Temp: ");
    lcd.print(t);
    lcd.print("F");

    lcd.setCursor(0, 1);
    lcd.print("Humidity: ");
    lcd.print(h);
    lcd.print("%");

    //Serial.print("Humidity: ");
    //Serial.print(h);
    //Serial.print(" %\t");
    //Serial.print("Temperature: ");
    //Serial.print(t);
    //Serial.println(" *C");


  }  //if sensor is not failed
}   //end of displaying temp value




void display_batteryVoltage()
{ //begin displaying batteryVoltage
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Charge Status");
  lcd.setCursor(0, 1);
  lcd.print(batteryVoltage);
  lcd.print("v");

  Serial.print(batteryVoltage);
  Serial.println (" V");
}   //end displaying batteryVoltage




void display_low_battery()
{ //begin displaying low battery message
  lcd.clear();
  lcd.setCursor(6, 0);
  lcd.print("LOW");
  lcd.setCursor(4, 2);
  lcd.print("BATTERY");
  delay(3000);
}   //end displaying low battery message



void LibraryTimedOut()
{
  lcd.clear();
  digitalWrite(ledPin1, LOW);
  digitalWrite(ledPin2, LOW);
  digitalWrite(ledPin3, LOW);
  digitalWrite(ledPin4, LOW);
  digitalWrite(ledPin5, LOW);
  digitalWrite(lcdledPin, LOW);
  digitalWrite(WarningLEDPin, HIGH);
}









//door left open code
//unsigned long currentMillis = millis();
//    if ((unsigned long)(currentMillis - previousMillis) >= timeout)
//    {
//        lcd.clear();
//        digitalWrite(ledPin1, LOW);
//        digitalWrite(ledPin2, LOW);
//        digitalWrite(ledPin3, LOW);
//        digitalWrite(ledPin4, LOW);
//        digitalWrite(ledPin5, LOW);
//        digitalWrite(lcdledPin, LOW);
//        digitalWrite(WarningLEDPin, HIGH);
//        previousMillis = millis();
//    }  //end of door left open code



//door left open code
//    if (((currentMillis - previousMillis) >= timeout)  &&  (ButtonState == LOW)) //alternate door open code
//      if ((unsigned long)(millis() - currentMillis >= timeout))
//    {
//        lcd.clear();
//        digitalWrite(ledPin1, LOW);
//        digitalWrite(ledPin2, LOW);
//        digitalWrite(ledPin3, LOW);
//        digitalWrite(ledPin4, LOW);
//        digitalWrite(ledPin5, LOW);
//        digitalWrite(lcdledPin, LOW);
//        digitalWrite(WarningLEDPin, HIGH);
//        previousMillis = millis();
//    }  //end of door left open code

Everything else, I've turned to comments.

If you had deleted those lines and the superfluous blank lines you may have been able to post the code in one piece.

Nothing to do with your problem, but I spotted this in the loop() function.

  if (batteryVoltage > 0.5)
    {
      BatteryBad = !BatteryBad;
    }

Do you really want BatteryBad to change state every time through loop() ?

Sorry, I had put the extra blank lines in to help separate functions for easier locating when scrolling.

Hmm, perhaps I misunderstood the way that piece of code worked.

As written, I was under the impression that, each time through the loop, so long as battery voltage was greater than 0.5v, battery good. !BatteryBad

I suppose I'm still looking at it wrong. I dont see how it should flip states each time it goes through the loop. If battery voltage is still > 0.5, shouldn't it keep running unchanged?

Consider what happens when it is <= 0.5. First time through it sets bad battery. Second time through it is still <= 0.5 so it toggles back to battery good (not bad is good right?). Then bad then good etc… Seems like you should simply be setting it to true there every time.

AxeMurderer:
Consider what happens when it is <= 0.5. First time through it sets bad battery. Second time through it is still <= 0.5 so it toggles back to battery good (not bad is good right?). Then bad then good etc… Seems like you should simply be setting it to true there every time.

Would the correct statement then be:

if (batteryVoltage < 0.5)
    {
      BatteryBad = true;
    }

The part with the door that gets me, is even when I rearrange the code a dozen different times, the best I've been able to achieve is the lights fading on when SwitchPin is grounded and fading off when not grounded. But even in this state, once they're all faded on, they will repeatedly fade on until the SwitchPin is high again.

When SwitchPin is high, the lights fade off repeatedly.

On the Serial Monitor, It simply keeps repeating and counting, even though the state of the switch has not changed.

I want it to latch in one position and not do anything else, until the state of the switch has changed. However, I want the loop to keep running so that millis() continues to count, this way if a time limit is reached, LibraryTimedOut(); can be reached

As the code is currently written, the arduino doesn't seem to care about SwitchPin at all, it just keeps fading on the lights endlessly.

Yup. You can also simplify those fade functions by using another for loop:

void fade_on_lights()
{ // begin fade_on_lights
  int pins[7]   = { ledPin1, ledPin2, ledPin3, ledPin4, ledPin5, ledPin6, lcdledPin };
  int delays[7] = { 50, 25, 20, 13, 8, 6, 30 };

  for( int p = 0; p < 7; p++ )
    for( int fadeValue = 0; fadeValue <= 255; fadeValue += 5)  // fade in from min to max in increments of 5 points:
    { // Sets the value (range from 0 to 255)
      if( p != 6 )                                             // skip pin6
      { analogWrite( pins[p], fadeValue );
        delay( delays[p] );                                    // wait to see the dimming effect.
      }
    }
}

Likewise for the fade out function. Easier to read IMHO.
I put an “if” in there to skip pin6 since you have it commented out, but if you end up doing them all then that can be removed.

OK I think I found your problem. You have a timer (a counter) in there called lastDebounceTime. You reset that timer when what you read from the switch is different than what it was the previous time through the loop. This is fine when the switch changes. But consider what happens when the switch does not change. In that case, (millis() -lastDebounceTime) will always be greater than debounceDelay because the timer never gets reset. This means the door open state will be toggled between true & false every time through the loop when the switch does not change due to: DoorClosed = !DoorClosed Thus every other time through the loop, DoorClosed will be true and the lights will be faded off. Also every other time through the loop DoorClosed will be false and the lights will be faded on. You should expect to see the lights continually fade on and off alternately whenever you don't touch the switch. First thing you ought to do is combine your two if statements that check the door flag into a single if that has an else part. Like so:

if (DoorClosed)
{ Serial.println("fading off lights");
   fade_off_lights();      
}
else if( !BatteryBad && NotTimedOut)
{ SwitchCounter++;  //increment counter if door has opened
   Serial.println("Door Open");
   Serial.print("Number of times door has been opened:  ");
   Serial.println(SwitchCounter);
   Serial.println(digitalRead(SwitchPin));  //Display current value
   delay(20);
   fade_on_lights();
   //    delay(500);
   //door_open_lcd_cycle();
   //    delay(25);
   //display_current_temp();
   //    delay (2500);
}

Your suggestions to reduce the amount of language were wonderful, the fade on and fade off functions work just as they did before, but consume so many fewer lines! Thank You for that.

However, I'm still stuck with this door open/door closed issue.

I see what you're saying with the repeat every two loops, and I can see it on the serial monitor. I tried first for a while to try and correct it with tweaks to the "debounceDelay" portion. I have not been able to make it work.

I then tried to do something new, I downloaded the button library, and tried to configure the door switch as a button, including .wasReleased / .wasPressed. I have not been able to make that work either.

The problem still exists, whichever state the switch is in, it continues to cycle. Currently the serial monitor states:

checking voltage turning off the lights (repeating)

If I "open" the door, I get:

checking voltage ReadingReadingReading checking voltage ReadingReadingReading turning off the lights (repeat)

One thing that really makes this code difficult to follow is the double negatives everywhere. You name your state variables using a negative (NotPressed, NotTimedOut) then test them by saying !NotPressed (a double negative, tough to follow). When you initialize them, you set them to false (NotPressed = false) which means it starts out pressed?? Is that right? Again, double negative is not straight forward. It would be easier to follow if you got rid of those logical confusions. Name them positive then test for positive, or name them negative then test for negative. I also think you have too many state variables. For example, it seems that DoorClosed and SwitchState track the exact same thing. This means they have to remain synchronized or ambiguities will result. Simpler to just use one flag everywhere.
Here’s how I’d change it. IMHO this is an order of magnitude simpler and easier to follow. State machine would be better, but this ought to suffice (assuming it works-- I did not test or compile).

#define TIMEOUT_THRESHOLD 5000               // Timeout set to maximum of 5 minutes of continuous light.
#define DEBOUNCE_DELAY    50                 // Debounce for 50ms.


bool          debouncing       = false;      // Start with no debouncing until the door opens.
bool          doorState        = true;       // Start with the door closed.
bool          lastDoorState    = true;       // Start with the previous door state closed.
bool          timeoutRunning   = false;      // Start with no timeout running.
unsigned long timeout          = millis();   // Initialize the timeout timer.
unsigned long lastDebounceTime = millis();   // Initialize the timeout timer.


setup()
{ blah blah pinMode blah
}


loop()
{ // check battery voltage
  value          = analogRead(voltpin);
  vout           = (value * 4.985) / 1024.0;
  batteryVoltage = vout / (R2 / (R1 + R2));
  Serial.println("checking voltage");
  if( batteryVoltage < 0.5 )
  { // Battery is low. Just display the voltage when the voltage button is pressed and do nothing else.
    if( digitalRead( ButtonPin) == LOW ) display_batteryVoltage();
    
    // Probably ought to also turn off the lights and stop the timeout timer.
    // Also need to stop debouncing and reset the door state since we are no longer gonna respond to the door at all until battery recharges.
    fade_off_lights();
    timeoutRunning = false;
    debouncing     = false;
    doorState      = lastDoorState = true;
  }
  
  else
  { // Battery is OK. Run the library normally.
    if( debouncing )
    { // Debouncing the button. See if it's done. If not then do nothing at all, just let the loop repeat and check again next time.
      if( (millis() -lastDebounceTime) >= DEBOUNCE_DELAY)
      { // Should be debounced by now so read and process the damn thing.
        DoorState  = digitalRead( SwitchPin );
        debouncing = false;                                     // done with debouncing.
        
        if( DoorState != lastDoorState )                        // only do something when the door state changed.
        { // Debounced button has changed state.
          lastDoorState = DoorState;                            // Remember the new state.
          
          if( DoorState )
          { // Door was just closed
            Serial.println( "Fading out lights" );
            fade_off_lights();
            timeoutRunning = false;                             // Stop timeout timer when lights turn off.
          }
          else
          { // Door was just opened
            ++SwitchCounter;
            Serial.println("Door Open");
            Serial.print("Number of times door has been opened:  ");
            Serial.println(SwitchCounter);
            fade_on_lights();                                   // Turn on the lights.
            timeoutRunning = true;                              // Start up the timeout timer.
            timeout        = millis();                          // Reset the timer for a new period.
          }
        }
      }
    }
    else
    { // Not debouncing. Check for a state change in the switch. If it hasn't changed, do nothing more.
      if( DoorState != lastDoorState )
      { // Button has changed state. Start debouncing the button.
        debouncing       = true;
        lastDebounceTime = millis();
      }
    }
  }
  
  // Deal with turning off the lights when they've been on too long.
  if( timeoutRunning && ((millis() -timeout) >= TIMEOUT_THRESHOLD)
  { // Lights have been on too long. Turn them all off.
    Serial.println( "Timeout-- Fading out lights" );
    LibraryTimedOut();
    fade_off_lights();                                          // Turn off the lights.
    timeoutRunning = false;                                     // Turn off the timeout timer.
  }
}

Sorry about all the confusing statements in the sketch. boolean statements are one of the most recent additions to the sketch.

Your code looks a LOT cleaner than what I had been running. I went ahead and put it in and did minimal tweaking to any part that wouldn't compile (just a few capital letters). I loaded it and had no response from the LEDs to the door switch.

I toyed a bit and all it needed was a read statement declared above the debounce if

{ // Battery is OK. Run the library normally.
    DoorState = digitalRead(SwitchPin);  // compare the SwitchState to its previous state 
    if( debouncing )
    { // Debouncing the button. See if it's done. If not then do nothing at all, just let the loop repeat and check again next time.
      if( (millis() -lastDebounceTime) >= DEBOUNCE_DELAY)

THIS IS WONDERFUL. The lights come on when the door is "opened" and fade off when "closed". The timeout is working perfectly as well! THANK YOU.

With this basic function working, I can start bringing back in all the other variables. I'll keep the forum updated as it comes together.

Again, I can't thank you enough. This is my first sketch. It started with just BLINK...it's been building from there, so things have gotten muddy. I've done my best to clean as I go, but since I'm new to this, I am reluctant/uninformed to make large changes.

IT WORKS!!!!

Ok, I have to apologize though...in an effort to get all aspects functional, I muddied up the sketch again by copy/pasting the working door code into the battery bad code. The idea was, if somebody opens the door and the battery is low, the counter will still count the occurrence, and a few lights will turn on, just not the whole show.

THANK YOU THANK YOU THANK YOU.

I owe you a case of beer.

Here is the final loop code(thus far)

void loop()

{ // Begin Loop check battery voltage
  value          = analogRead(voltpin);
  vout           = (value * 4.985) / 1024.0;
  batteryVoltage = vout / (R2 / (R1 + R2));
  Serial.println("checking voltage");
  if( batteryVoltage < 0.5 )


  { // Battery is NOT OK. Run the low voltage code.
    DoorState = digitalRead(SwitchPin);  // compare the SwitchState to its previous state  LATEST ADD
    if( debouncing )
    { // Debouncing the button. See if it's done. If not then do nothing at all, just let the loop repeat and check again next time.
      if( (millis() -lastDebounceTime) >= DEBOUNCE_DELAY)
      { // Should be debounced by now so read and process the damn thing.
        DoorState  = digitalRead( SwitchPin );
        debouncing = false;                                     // done with debouncing.
       
        if( DoorState != lastDoorState )                        // only do something when the door state changed.
        { // Debounced button has changed state.
          lastDoorState = DoorState;                            // Remember the new state.
         
          if( DoorState )
          { // Door was just closed
            Serial.println( "Fading out LCD" );
            fade_off_lcd_backlight();
            //fade_off_lights();
            timeoutRunning = false;                             // Stop timeout timer when lights turn off.
          }
          else
          { // Door was just opened
            ++SwitchCounter;
            Serial.println("Door Open");
            Serial.print("Number of times door has been opened:  ");
            Serial.println(SwitchCounter);
            fade_on_lcd_backlight(); 
            display_low_battery();
            CheckVoltageButton();          
            timeoutRunning = true;                              // Start up the timeout timer.
            timeout        = millis();                          // Reset the timer for a new period.
          }
        }
      }
    }
    else
    { // Not debouncing. Check for a state change in the switch. If it hasn't changed, do nothing more.
      if( DoorState != lastDoorState )
      { // Button has changed state. Start debouncing the button.
        debouncing       = true;
        lastDebounceTime = millis();
      }
    }
  }
  
    // Probably ought to also turn off the lights and stop the timeout timer.
//    // Also need to stop debouncing and reset the door state since we are no longer gonna respond to the door at all until battery recharges.
//    fade_off_lights();
//    timeoutRunning = false;
//    debouncing     = false;
//    DoorState      = lastDoorState = true;
//  }
 
  else
  { // Battery is OK. Run the library normally.
    DoorState = digitalRead(SwitchPin);  // compare the SwitchState to its previous state  LATEST ADD
    if( debouncing )
    { // Debouncing the button. See if it's done. If not then do nothing at all, just let the loop repeat and check again next time.
      if( (millis() -lastDebounceTime) >= DEBOUNCE_DELAY)
      { // Should be debounced by now so read and process the damn thing.
        DoorState  = digitalRead( SwitchPin );
        debouncing = false;                                     // done with debouncing.
       
        if( DoorState != lastDoorState )                        // only do something when the door state changed.
        { // Debounced button has changed state.
          lastDoorState = DoorState;                            // Remember the new state.
         
          if( DoorState )
          { // Door was just closed
            Serial.println( "Fading out lights" );
            fade_off_lights();
            timeoutRunning = false;                             // Stop timeout timer when lights turn off.
          }
          else
          { // Door was just opened
            ++SwitchCounter;
            Serial.println("Door Open");
            Serial.print("Number of times door has been opened:  ");
            Serial.println(SwitchCounter);
            fade_on_lights();                                   // Turn on the lights.
            door_open_lcd_cycle();
//   //    delay(25);
            display_current_temp();
            CheckVoltageButton();                               // Check to see if voltage button is pressed
            timeoutRunning = true;                              // Start up the timeout timer.
            timeout        = millis();                          // Reset the timer for a new period.
          }
        }
      }
    }
    else
    { // Not debouncing. Check for a state change in the switch. If it hasn't changed, do nothing more.
      if( DoorState != lastDoorState )
      { // Button has changed state. Start debouncing the button.
        debouncing       = true;
        lastDebounceTime = millis();
      }
    }
  }
 
  // Deal with turning off the lights when they've been on too long.
  if( timeoutRunning && ((millis() -timeout) >= TIMEOUT_THRESHOLD))
  { // Lights have been on too long. Turn them all off.
    Serial.println( "Timeout-- Fading out lights" );
    LibraryTimedOut();
    //fade_off_lights();                                          // Turn off the lights.
    timeoutRunning = false;                                     // Turn off the timeout timer.
  }
}

//END OF LOOP