LED control lights for a slide door status

@kimdx You shoukd start using the Autoformat tool in the IDE. It can make things easier to spot.

You have other problems here, too. Why is raiseDoor() where it is? Why is lowerDoor() where it is? Why are the different? I expect to see symmetrical treatment of open, opening and closed, closing logic…

raiseDoor();
   if (digitalRead(doorUpSensorPin) == LOW );
   digitalWrite(transitLEDAmber, HIGH);
   Serial.println("Door state -- must be OPEN");    
    }

  else
  {
    lowerDoor();
    while ( digitalRead(doorDownSensorPin) == LOW )
    digitalWrite(transitLEDAmber, HIGH);
    Serial.println("Door state -- must be closed");
   }

This is a complete if statement

   if (digitalRead(doorUpSensorPin) == LOW );

Review the syntax of the if statement, and see that the semicolon is changing what I think you mean to have happen…

Please check all you { braces } to see that they are gathering up the correct statements.

Please check for other stray semicolons, they are not errors as far as the compiler is concerned but can kill you logic.

You shoukd start using the Autoformat tool in the IDE. It can make things easier to spot.

HTH

a7

1 Like

I've tried to make a non-code related scenario sequence:
Just to help me understand how code must match the script....
and to compare the script with any eventual code. Hope this will help to rewrite it fully from scratch. I'm nearly so far to trow the towel in the ring. So many replies, but i don't get it.....
It's beyond my knowledge to be honest.....

So :

What should happen, and in which sequence. In a human language......

  1. Set the time ( or LOOK at the time coming from the RTC timer )

  2. If "morning" so dawn - 45 min then OPEN the door ( Dawn is defined as SunRise)
    Open the door, means, turn on the motor to raise the door up.

  3. While opening, Turn the AMBER LED on
    AND watch the state of the UP SENSOR.

  4. When the door is FULL OPEN ( called by the Microswitch door UP, activated)

  5. Then : STOP MOTOR

  6. AND : Turn off the AMBER LED

  7. AND : Turn ON the GREEN LED ( indicating door Full open).

  8. phase 1 is no ok. Now the monitor phase starts.

  9. continue to look to the TIMER evolution.

  10. When the time is still between the sunrise and the sunset then do nothing.
    Dusk is defined as SunSet . The door remains OPEN (motor is cut-off. Green LED stays ON).

  11. While the door is OPEN, the manual override switch state should be watched.
    As long as it stays in AUTO mode, the program follows the timer.
    When switched to MAN, it will induce the motor to lower the door.

  12. in the MAN door DOWN mode,
    the GREEN LED light must turn off, the moment the DoorUp sensor is not longer active,

    AND the AMBER LED must come on as long as neither the UpSensor nor the DownSensor is
    activated.

  13. Once the door is at the Down state,( door down switch active)
    the MOTOR stops,

  14. The AMBER LED goes out

  15. The RED LED comes on.

  16. If the MAN OVERRIDE switch is NOT used, (from step 10) then the TIME will be the trigger to continue.

  17. When the time is before DAWN -45 min OR later than DUSK +20Min, then:

  18. Close the door, meaning activate the motor UP signal.

  19. When door open sensor is not longer activated, kill the GREEN LED power.

  20. AND, activate the AMBER LED signal.

  21. Hold this till the LOWER door sensor becomes activated.

  22. then : Kill the AMBER LED

  23. AND : Activate the RED LED.

  24. AND : cut off the motor signal.

  25. Start the timer monitor function again to see if the SUNRISE, SUNSET conditions change.

Hope now i can build or translate this script into the arduino code language.....
There's a lot of

IF - THEN conditions but also IF - AND, AND, THEN conditions.
so, not easy to translate. Certainly not with my limitted knowledge and experience.

The only "and" in your description that is a logical "and" is, curiously, the only one where you wrote "and" and not "AND".

Those ANDs are just consecutive lines of code. To do A() AND B() AND C() is just

  A();
  B();
  C();

You are making this more complicated. More than it was already not at all complicated, more than you need to make it. It happens.

Leaving off manual control for now, the code is so close to working I say it is a mistaken distraction.

Did you fix the code you posted following my observations in #41 above?

  if ((sunrise - 45 < currentMins && currentMins < sunset + 20) && ( buttonstateclose != HIGH))
  {
    Serial.println("Door state -- must be OPEN");

    while (digitalRead(doorUpSensorPin) == LOW ) {
      raiseDoor();
      digitalWrite(transitLEDAmber, HIGH);
    }
  }
  else
  {
    Serial.println("Door state -- must be closed");

    while ( digitalRead(doorDownSensorPin) == LOW ) {
      lowerDoor();
      digitalWrite(transitLEDAmber, HIGH);
    }
  }

Note the exact correspondence of steps the two sections take. Note that both use while loops now. Note that both call the required action routine for the same reason from the same place in each pattern.

I cannot test the code, but you can. And you can start, if you haven't, figuring out what's going on, or wrong, by putting your finger on the code and playing dumb computer line by line.

Get it working without worrying about manual control. And before we do, decide how the switches should be... in my working version of your earlier code, manual close worked fine except the next thing the code does is notice the door should be open, and make it so.

There are 17 ways to fix that, a few slightly better than the others. Decide how the manual override shoukd work and what kind of switch you want to use. Ignoring the time except as it passes the two times that are important is OK, it just means you might want to have a manual close button also, so when you reboot you can fix the door state if it is wrong.

a7

Ok, alto,
The code from your last post, seems to work. ( not tested in the manual mode thing). The only problem i face is that i can only change my laptop hour 1x, and do the upload to test the timer, but the scond time i try to change my laptop hour, and upload it again, it does not change the RTC hour anymore in my serial monitor indication.
I've tried to switch of the laptop and restart it, tried to cut all the power to my NANO and timer, disconnected the USB and power cord. but whatever i do, i cannot bring it back to the actual hour now. I've also changed the line //Do we need to set/adjust RTC? const bool setRTC = true;

and put FALSE, then upload, and then again TRUE, and upload, but my time remains now to my last setting.

After i've uploaded your code, my laptop time was around 10 o'clock in the morning.
So, i tested the function first in this state, which opened the door. Transit light worked, green light to when the up switch was activated.
Then
I changed my laptop time to 21:00 with the green led on and door open switch active.
Uploaded the same sketch, and saw the time was changed to 21:00 which made the motor turned into the other direction, so closing the door. Here too, the amber led came on, after the up sensor was deactivated and so, the green led out, and motor kept turning till the down sensor was active, so red led came on, amber out.

Exactly what was intended to get as end result.

So, i wanted to turn back to the actual time, around 10:15 and changed my laptop time back to normal time, then uploaded the unchanged sketch and expected the RTC DS1307 timer to get the new time from my PC, which wasn't the case. I still got the 21:00 time in the serial monitor.
Whatever i do, i cannot change it back to the actual current time.....

What would this have as root cause???

Kind regards

Testing sketches that play out over hours or days is painful.

I don't mess with the PC date/time, not even on the MUTT laptop we use in the lab for torture tests of, well, everything.

There are a variety of tricks that can help that part, but here all we need to do is install a switch to override the RTC, and postpone testing that.

  if (debug) {
    Serial.print("switch "); Serial.print(digitalRead(dayNightSwitch));
    currentMins = digitalRead(dayNightSwitch) ? 70 : 750;
    Serial.print(" cur "); Serial.print(currentMins);
  }

That just reads a slide switch and jams a time in there that is def night 1:10 AM or day 12:30 PM. The "door" is still manual on the slide fader, pay no attention to the automatic door neopixel addition work in oprogress.


Wokwi_badge See it in context here.


You could fit that code into your current sketch. You can use a jumper from pin 11 to GND if you don't have a slide or toggle switch. Testing easier boom.

Please post your latest version, either now or after you succeed in adding the day/night switch.

I'm with one foot out the door, but I can read at the beach. :wink:

a7

beach??? From where are you? I'm from Belgium. Bad weather. Rainy and overcasted... :wink:

Can you set the rtc to a specific time if you use date time values and not the macros.

if (setRTC)
  {  
     //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
     rtc.adjust(DateTime(2023, 4, 14, 7, 9, 20));         
  }

If the manual setting fails, then there is a hardware problem with the rtc.

1 Like

Hey Cattledog,
I changed it, but nothing happened. The timer stayed at 21:40 instead of my current time....

So,

i followed this link :
Understanding the Code | DS1307 Real Time Clock Breakout Board Kit | Adafruit Learning System

and inserted a new battery into the DS1307.
The result was that the serial monitor gave me the correct date and time ( local actual time). After this i assumed that the DS1307 was resetted and uploaded again my chicken coop's code.
unfortunatelly, i didn't got my local time again.

That brings me to the question that suspect that my NANO board is not reading the instruction from the DS1307 timer. The timer works fine, as tested by the previous link test, so i rather suspect an issue between the timer and the nano board.

i always get this from the serial monitor :

FinishedSetup

Door is closed

SERVO LOOP
2023/4/16 - 21:40:401300
Door state -- must be closed
Door Full CLOSED
Door Stop

now that the led's are working as should, now my timer doesnt want to change in this code. why is the separate test ok? and why not working in this code?

Please post the code demonstrating this problem.

#include <math.h>
#include <Dusk2Dawn.h>
#include <EEPROM.h>
#include <Wire.h>
#include <RTClib.h>

//Define what pins are used
const int doorUpSensorPin = 4;        // reedswitch door open
const int doorDownSensorPin = 5;      // reedswitch door down
const int doorDownMotorPin = 10;      // wind motor down
const int DoorUpMotorPin = 9;         // wind motor up
const int LEDRED = 12;                // LED indicating door closed (for microswitch on pin 5)
const int LEDGREEN = 8;               // LED indicating door OPEN ( for microswitch on pin 4)
const int transitLEDAmber = 7;        // LED indicating door in TRANSIT ( neither of the microswitches active)
const byte CloseDoorManual = 3;       // Close door by hand

int buttonstateclose = 0;
int currentMins;
int sunrise;
int sunset;
DateTime now;

//Are We Debugging?
const bool debug = true;
//Do we need to set/adjust RTC?
const bool setRTC = true;

//Define RTC
RTC_DS1307 rtc;

//define the location / timezone for dusk2dawn (this is yourcity, countrycode 2 digit)
// change yourcity an fill in coordinates and timezone
Dusk2Dawn Kapellen(51.31483014538207, 4.458376022992936,+1); 

// the setup function runs once when you press reset or power the board
void setup() {
  
  //Set the mode the pins will operate in.
    pinMode(DoorUpMotorPin, OUTPUT);
    pinMode(doorDownMotorPin, OUTPUT);
    pinMode(CloseDoorManual, INPUT); 

  
  //Set Serial for Debugging
  if (debug) {
    Serial.begin(9600);

    if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
    }
    
  rtc.begin();
  //   //Lets just set the date/time when setRTC = true.
  // if (setRTC)
  {
   //write PC date and time while uploading and when setRTC = true
   //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  if (setRTC) 
     {
       //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));   
   //uncomment line 71 to write date and time manually into RTC when line 38 setRTC = true. For testing sunset/sunrise
       rtc.adjust(DateTime(2020, 7, 23, 10, 9, 20));       
  }
}
 
  
  //switches setup
  pinMode(doorUpSensorPin, INPUT);
  pinMode(doorDownSensorPin, INPUT);
  pinMode(LEDRED, OUTPUT);
  pinMode(LEDGREEN, OUTPUT);
  pinMode(transitLEDAmber,OUTPUT);
    
  Serial.println("FinishedSetup");
  if (digitalRead(doorUpSensorPin) == HIGH) 
  {
   Serial.println("Door is open");
   }

   if (digitalRead(doorDownSensorPin) == HIGH)
   {
    Serial.println("Door is closed");
   }
   delay(3000);
}

// the loop function runs over and over again until power down or reset
void loop() {
  delay(2000);
  if (debug){
    Serial.println();
    Serial.println("SERVO LOOP");
  }
  //Get the Date/Time from the RTC
  now = rtc.now();
  //Get Sunrise/Sunset for the current year/month/day as INT's that equate to minutes from midnight that he sunrise/sunset will occur (THE TRUE is passing in Daylight Savings Time!)
  sunrise = Kapellen.sunrise(now.year(), now.month(), now.day(), true);
  sunset = Kapellen.sunset(now.year(), now.month(), now.day(), true);
  if (debug) {
    Serial.println();
    Serial.print(now.year());
    Serial.print('/');
    Serial.print(now.month());
    Serial.print('/');
    Serial.print(now.day());
    Serial.print(" - ");
    Serial.print(now.hour());
    Serial.print(':');
    Serial.print(now.minute());
    Serial.print(':');
    Serial.print(now.second());
  }


    buttonstateclose = digitalRead(CloseDoorManual);
    if(buttonstateclose == HIGH){
      ManualClose();
    }

  
  //Lets get add the "now" Minutes and "now" hours*60 to see how many minutes from midnight we are
  currentMins = ((now.hour()) * 60) + (now.minute());
  Serial.println(currentMins);

  //lets start comparisons, if the door should be up....
  //delay of 30 minutes after sunset time to make sure all chickens are inside before closing the door. 

  if ((sunrise - 45 < currentMins && currentMins < sunset + 20) && ( buttonstateclose != HIGH))
  {
    Serial.println("Door state -- must be OPEN");

    while (digitalRead(doorUpSensorPin) == LOW ) {
      raiseDoor();
      digitalWrite(transitLEDAmber, HIGH);
    }
  }
  else
  {
    Serial.println("Door state -- must be closed");

    while ( digitalRead(doorDownSensorPin) == LOW ) {
      lowerDoor();
      digitalWrite(transitLEDAmber, HIGH);
    }
  }

  int DoorUp = digitalRead(doorUpSensorPin);
  int DoorDown = digitalRead(doorDownSensorPin);
  /* This is just temporary switch debug code*/
  //DoorUp is DOOR OPEN   -  DoorDown is DOOR CLOSED
  if (DoorUp == HIGH)
  {
    Serial.println("Door Full OPEN");
    digitalWrite(LEDRED, LOW);
    digitalWrite(LEDGREEN, HIGH);
    digitalWrite(transitLEDAmber, LOW);
    stopDoor();
    
  }

 if (DoorDown == HIGH)
  { 
    Serial.println("Door Full CLOSED");
    digitalWrite(LEDRED, HIGH);
    digitalWrite(LEDGREEN, LOW);
    digitalWrite(transitLEDAmber, LOW);
    stopDoor();

  }

if ( (DoorDown == LOW) && (DoorUp == LOW) )
  {
    Serial.println("Door TRANSIT");
    digitalWrite(LEDRED, LOW);
    digitalWrite(LEDGREEN, LOW);
    digitalWrite(transitLEDAmber, HIGH);
    
  }
}
 

//Wind the Door Up
void raiseDoor() {
  digitalWrite(DoorUpMotorPin, HIGH);
  digitalWrite(doorDownMotorPin, LOW);
  if (debug) {
    Serial.println("Door moving UP");
    stopDoor(); 
  }
}

//Wind The Door Down
void lowerDoor() {
  digitalWrite(doorDownMotorPin, HIGH);
  digitalWrite(DoorUpMotorPin, LOW);
  if (debug) {
    Serial.println("Door moving DOWN");
    stopDoor(); 
  }
}

//Stop the Door
void stopDoor() {
  digitalWrite(DoorUpMotorPin, LOW);
  digitalWrite(doorDownMotorPin, LOW);
  if (debug) {
    Serial.println("Door Stop");
  }
}

//Close door manual
void ManualClose() { 
  digitalWrite(doorDownMotorPin, HIGH);
  digitalWrite(DoorUpMotorPin, LOW);
  if (debug) {
    Serial.println("Door Closing Manual");
  while ( digitalRead(doorDownSensorPin) == LOW)
    digitalWrite(transitLEDAmber, HIGH);
    stopDoor(); 
  }
 }

This is the full code

I can not confirm your issue. I am not set up to completely test your code beyond the rtc functions, but this simplified version of your code indeed update the time.

10:36:49.868 -> FinishedSetup
10:36:54.886 -> 
10:36:54.886 -> SERVO LOOP
10:36:54.886 -> 
10:36:54.886 -> 2020/7/23 - 10:9:25609
10:36:56.903 -> 
10:36:56.903 -> SERVO LOOP
10:36:56.903 -> 
10:36:56.903 -> 2020/7/23 - 10:9:27609
10:36:58.938 -> 
10:36:58.938 -> SERVO LOOP
10:36:58.938 -> 
10:36:58.938 -> 2020/7/23 - 10:9:29609
10:37:00.965 -> 
10:37:00.965 -> SERVO LOOP
10:37:00.965 -> 
10:37:00.965 -> 2020/7/23 - 10:9:31609
10:37:02.991 -> 
10:37:02.991 -> SERVO LOOP
10:37:02.991 -> 
10:37:02.991 -> 2020/7/23 - 10:9:33609
#include <math.h>
#include <Dusk2Dawn.h>
#include <EEPROM.h>
#include <Wire.h>
#include <RTClib.h>

//Define what pins are used
const int doorUpSensorPin = 4;    // reedswitch door open
const int doorDownSensorPin = 5;  // reedswitch door down
const int doorDownMotorPin = 10;  // wind motor down
const int DoorUpMotorPin = 9;     // wind motor up
const int LEDRED = 12;            // LED indicating door closed (for microswitch on pin 5)
const int LEDGREEN = 8;           // LED indicating door OPEN ( for microswitch on pin 4)
const int transitLEDAmber = 7;    // LED indicating door in TRANSIT ( neither of the microswitches active)
const byte CloseDoorManual = 3;   // Close door by hand

int buttonstateclose = 0;
int currentMins;
int sunrise;
int sunset;
DateTime now;

//Are We Debugging?
const bool debug = true;
//Do we need to set/adjust RTC?
const bool setRTC = true;

//Define RTC
RTC_DS1307 rtc;

//define the location / timezone for dusk2dawn (this is yourcity, countrycode 2 digit)
// change yourcity an fill in coordinates and timezone
Dusk2Dawn Kapellen(51.31483014538207, 4.458376022992936, +1);

// the setup function runs once when you press reset or power the board
void setup()
{
  //Set the mode the pins will operate in.
  pinMode(DoorUpMotorPin, OUTPUT);
  pinMode(doorDownMotorPin, OUTPUT);
  pinMode(CloseDoorManual, INPUT);


  //Set Serial for Debugging
  if (debug)
  {
    Serial.begin(9600);

    if (!rtc.begin())
    {
      Serial.println("Couldn't find RTC");
      while (1)
        ;
    }

    rtc.begin();
    //   //Lets just set the date/time when setRTC = true.
    // if (setRTC)
    {
      //write PC date and time while uploading and when setRTC = true
      //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      if (setRTC)
      {
        //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
        //uncomment line 71 to write date and time manually into RTC when line 38 setRTC = true. For testing sunset/sunrise
        rtc.adjust(DateTime(2020, 7, 23, 10, 9, 20));
      }
    }


    //switches setup
    pinMode(doorUpSensorPin, INPUT);
    pinMode(doorDownSensorPin, INPUT);
    pinMode(LEDRED, OUTPUT);
    pinMode(LEDGREEN, OUTPUT);
    pinMode(transitLEDAmber, OUTPUT);

    Serial.println("FinishedSetup");
    if (digitalRead(doorUpSensorPin) == HIGH)
    {
      Serial.println("Door is open");
    }

    if (digitalRead(doorDownSensorPin) == HIGH)
    {
      Serial.println("Door is closed");
    }
    delay(3000);
  }
}

// the loop function runs over and over again until power down or reset
void loop()
{
  delay(2000);
  if (debug)
  {
    Serial.println();
    Serial.println("SERVO LOOP");
  }
  //Get the Date/Time from the RTC
  now = rtc.now();
  //Get Sunrise/Sunset for the current year/month/day as INT's that equate to minutes from midnight that he sunrise/sunset will occur (THE TRUE is passing in Daylight Savings Time!)
  sunrise = Kapellen.sunrise(now.year(), now.month(), now.day(), true);
  sunset = Kapellen.sunset(now.year(), now.month(), now.day(), true);
  if (debug)
  {
    Serial.println();
    Serial.print(now.year());
    Serial.print('/');
    Serial.print(now.month());
    Serial.print('/');
    Serial.print(now.day());
    Serial.print(" - ");
    Serial.print(now.hour());
    Serial.print(':');
    Serial.print(now.minute());
    Serial.print(':');
    Serial.print(now.second());
  }




  buttonstateclose = digitalRead(CloseDoorManual);
  if (buttonstateclose == HIGH)
  {
    ManualClose();
  }


  //Lets get add the "now" Minutes and "now" hours*60 to see how many minutes from midnight we are
  currentMins = ((now.hour()) * 60) + (now.minute());
  Serial.println(currentMins);

  //lets start comparisons, if the door should be up....
  //delay of 30 minutes after sunset time to make sure all chickens are inside before closing the door.

  /*
  if ((sunrise - 45 < currentMins && currentMins < sunset + 20) && (buttonstateclose != HIGH))
  {
    Serial.println("Door state -- must be OPEN");

    while (digitalRead(doorUpSensorPin) == LOW)
    {
      raiseDoor();
      digitalWrite(transitLEDAmber, HIGH);
    }
  }
  else
  {
    Serial.println("Door state -- must be closed");

    while (digitalRead(doorDownSensorPin) == LOW)
    {
      lowerDoor();
      digitalWrite(transitLEDAmber, HIGH);
    }
  }

  int DoorUp = digitalRead(doorUpSensorPin);
  int DoorDown = digitalRead(doorDownSensorPin);
  //This is just temporary switch debug code
  //DoorUp is DOOR OPEN   -  DoorDown is DOOR CLOSED
  if (DoorUp == HIGH)
  {
    Serial.println("Door Full OPEN");
    digitalWrite(LEDRED, LOW);
    digitalWrite(LEDGREEN, HIGH);
    digitalWrite(transitLEDAmber, LOW);
    stopDoor();
  }

  if (DoorDown == HIGH)
  {
    Serial.println("Door Full CLOSED");
    digitalWrite(LEDRED, HIGH);
    digitalWrite(LEDGREEN, LOW);
    digitalWrite(transitLEDAmber, LOW);
    stopDoor();
  }

  if ((DoorDown == LOW) && (DoorUp == LOW))
  {
    Serial.println("Door TRANSIT");
    digitalWrite(LEDRED, LOW);
    digitalWrite(LEDGREEN, LOW);
    digitalWrite(transitLEDAmber, HIGH);
  }
  */
}

//Wind the Door Up
void raiseDoor()
{
  digitalWrite(DoorUpMotorPin, HIGH);
  digitalWrite(doorDownMotorPin, LOW);
  if (debug)
  {
    Serial.println("Door moving UP");
    stopDoor();
  }
}

//Wind The Door Down
void lowerDoor()
{
  digitalWrite(doorDownMotorPin, HIGH);
  digitalWrite(DoorUpMotorPin, LOW);
  if (debug)
  {
    Serial.println("Door moving DOWN");
    stopDoor();
  }
}

//Stop the Door
void stopDoor()
{
  digitalWrite(DoorUpMotorPin, LOW);
  digitalWrite(doorDownMotorPin, LOW);
  if (debug)
  {
    Serial.println("Door Stop");
  }
}

//Close door manual
void ManualClose()
{
  digitalWrite(doorDownMotorPin, HIGH);
  digitalWrite(DoorUpMotorPin, LOW);
  if (debug)
  {
    Serial.println("Door Closing Manual");
    while (digitalRead(doorDownSensorPin) == LOW)
      digitalWrite(transitLEDAmber, HIGH);
    stopDoor();
  }
}

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