chickencoop door based on sunset/sunrise

Hi all,

Hi, I found a sketch online (github offcourse) for a chickencoop door based on sunset/sunrise. The previous one I've build was with an LDR but not accurate enough in some circumstances.
I've hooked up everything together, RTC clock working and running and the serial monitor prints text "door should be open" or "door should be down", so comparison works.

When the door is open (and should be open) the serial monitor prints "door opened all the way" "door stopped".
when I lower the door a bit by hand it starts raising it until reedswitch is activated again, so this also works.

The voids for door movements or also fine.
But... I cant figure out how I can lower the door when its sunset. It's also not programmed in this sketch.
Who can put me in the right direction? I'm getting a headache. I assume it's stupid simple but it's still quite new for me.
Many thanks,

#include <math.h>
#include <Dusk2Dawn.h>
#include <EEPROM.h>
#include <Wire.h>
//#include <OneWire.h>
//#include <DallasTemperature.h>
#include "RTClib.h"



//Define what pins things are hooked up to

const int doorUpSensorPin = 3;        // reedswitch door open
const int doorDownSensorPin = 2;      // reedswitch door down
const int doorDownMotorPin = 10;      // wind motor down
const int DoorUpMotorPin = 9;         // wind motor up
const int builtInLED = 13;            // LED idicating door closed (reedswitch on pin 2)
int currentMins;
int sunrise;
int sunset;
DateTime now;

//Are We Debugging?
const bool debug = true;

//Define RTC
RTC_DS1307 rtc;

//define the location / timezone for dusk2dawn (this is Kessel, BE)
Dusk2Dawn Kessel(43.789369, -96.927453, -6);

// the setup function runs once when you press reset or power the board
void setup() {
  //Set the mode the pins will operate in. In this case on/off as outputs
  pinMode(DoorUpMotorPin, OUTPUT);
  pinMode(doorDownMotorPin, OUTPUT);
  //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 every time we upload a debug build, since we know the RTC module is good with a good battery.
  if (debug)
  {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
 }
  
  
  
  //switches setup
  pinMode(doorUpSensorPin, INPUT);
  pinMode(doorDownSensorPin, INPUT);
  pinMode(builtInLED, OUTPUT);
    Serial.println("FinishedSetup");
  if (digitalRead(doorUpSensorPin) == HIGH)
  {
    //door is open all the way
  
  }
}


// the loop function runs over and over again until power down or reset
void loop() {
  delay(2000);
  if (debug){
    Serial.println();
    Serial.println("LoopHead");
  }
  //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 = Kessel.sunrise(now.year(), now.month(), now.day(), true);
  sunset = Kessel.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());
  }
  
  //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....
  if (sunrise < currentMins && currentMins < sunset)
  {
    Serial.println("Door should be up");
    }

  else
  {
    Serial.println("Door should be down");
    }



  int DoorUp = digitalRead(doorUpSensorPin);
  int DooDown = digitalRead(doorDownSensorPin);
  /* This is just temporary switch debug code*/
  if (DoorUp == HIGH)
  {
    Serial.println("Door Opened All The Way");
    stopDoor();
    digitalWrite(builtInLED, LOW);
  }
  else
  {
    digitalWrite(builtInLED, HIGH);
    ("Door Not Open all the way");
    raiseDoor();
  }
}

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

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

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

You already have code that tells you whether the door should be up or down.

Where you print that the door should be down, check the down sensor to see if it is. If not, lower the door.

wildbill:
You already have code that tells you whether the door should be up or down.

Where you print that the door should be down, check the down sensor to see if it is. If not, lower the door.

It is, but the door only goes up if it's needed and then stops. It's not going down when it's sunset.
The serial monitor prints

"door should be down"
"door opened all the way"
"door stop"

When i remove the upper reedswitch, the door raises again.

You need the raise and lower commands inside the if that determines the desired state of the door. Currently you're not using it other than to print messages.

vanderwanten:
the door only goes up if it's needed and then stops. It's not going down when it's sunset.

No, the door goes UP regardless. All day, every day. This is part of loop(). It says, if the door isn't fully up, raise the door. There is no code for 'Should the door be up?' or 'What if the door should be down?'.

  int DoorUp = digitalRead(doorUpSensorPin);
  int DooDown = digitalRead(doorDownSensorPin);
  
  /* This is just temporary switch debug code*/
  if (DoorUp == HIGH)
  {
    Serial.println("Door Opened All The Way");
    stopDoor();
    digitalWrite(builtInLED, LOW);
  }
  else
  {
    digitalWrite(builtInLED, HIGH);
    ("Door Not Open all the way");
    raiseDoor();
  }

You need to add code to this section to keep track of whether the door should be UP or DOWN and then use that to select the existing "Door up" code above or very similar "Door down" code that you have yet to write.

 //lets start comparisons, if the door should be up....
  if (sunrise < currentMins && currentMins < sunset)
  {
    Serial.println("Door should be up");
  }
  else
  {
    Serial.println("Door should be down");
  }

Hi all,

Meanwhile (with some help :slight_smile: ) the sketch is working in automatic mode.
I've integrated 30 minutes extra at sunset to make sure the chickens are all inside.

Now I've added a toggle switch DPDT (on-off-on).
This is to open/close the door by hand and keep it in that state.
This is partly working.

For example... when I activate the switch to close position(CloseDoorManual) the door goes down until the doorDownSensorPin is high but then door goes open again to it's actual state because the loop in the sketch goes on.
How can become a way that the door stays in closed position when doorDownSensor is high and the CloseDoorManual switch is stil activated?

Thanks for helping me out..

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



//Define what pins things are hooked up to
/*********************************************************************************************
*                                 Pinnummers nog aanpassen naar nano setup                   *
**********************************************************************************************/
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 builtInLED = 12;            // LED idicating door closed (reedswitch on pin 5)
const byte CloseDoorManual = 3;
const byte OpenDoorManual = 2;

int buttonstateclose = 0;
int buttonstateopen = 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 Kessel, BE)
Dusk2Dawn Kessel(0,0, +1);

// the setup function runs once when you press reset or power the board
void setup() {
  //Set the mode the pins will operate in.
  //Set interrupts for manual control off the door by a switch
  pinMode(DoorUpMotorPin, OUTPUT);
  pinMode(doorDownMotorPin, OUTPUT);
  pinMode(CloseDoorManual, INPUT); 
  pinMode(OpenDoorManual, INPUT);
//  attachInterrupt(digitalPinToInterrupt(3), ManualClose, RISING);
//  attachInterrupt(digitalPinToInterrupt(2), ManualOpen, RISING);
  
  //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)
  {
   // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    rtc.adjust(DateTime(2020, 7, 23, 7, 9, 20));      //write date and time manually into RTC when setRTC = true 
  }
 }
  
  
  
  //switches setup
  pinMode(doorUpSensorPin, INPUT);
  pinMode(doorDownSensorPin, INPUT);
  pinMode(builtInLED, 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("LoopHead");
  }
  //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 = Kessel.sunrise(now.year(), now.month(), now.day(), true);
  sunset = Kessel.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();
}


buttonstateopen = digitalRead(OpenDoorManual);
if(buttonstateopen == HIGH){
  ManualOpen();
}


  
  //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 + 30 < currentMins && currentMins < sunset + 30)
  {
    Serial.println("Door should be up");
    while ( digitalRead(doorUpSensorPin) == LOW )
    raiseDoor();
    }

  else
  {
    Serial.println("Door should be down");
    while ( digitalRead(doorDownSensorPin) == LOW )
    lowerDoor();
    
    }


  int DoorUp = digitalRead(doorUpSensorPin);
  int DoorDown = digitalRead(doorDownSensorPin);
  /* This is just temporary switch debug code*/
  if (DoorUp == HIGH)
  {
    Serial.println("Door Opened All The Way");
    digitalWrite(builtInLED, LOW);
    stopDoor();
    
  }

  else
  {
    digitalRead(doorDownSensorPin == HIGH);
    Serial.println("Door Closed All The Way");
    digitalWrite(builtInLED, HIGH);
    stopDoor();
    
  } 
}



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


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

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


//Open door manual by switch
  void ManualOpen() { 
  digitalWrite(doorDownMotorPin, LOW);
  digitalWrite(DoorUpMotorPin, HIGH);
  if (debug) {
    Serial.println("Door Opening Manual");
  while ( digitalRead(doorUpSensorPin) == LOW)
    stopDoor();  
 }
}


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

Normally everyone is sent a dozen eggs when a project comes to fruition. 8)

Add a check in this if:

  if (sunrise + 30 < currentMins && currentMins < sunset + 30)

To also check that buttonstateclose is not HIGH.

larryd:
Normally everyone is sent a dozen eggs when a project comes to fruition. 8)

I will send you some

wildbill:
Add a check in this if:

  if (sunrise + 30 < currentMins && currentMins < sunset + 30)

To also check that buttonstateclose is not HIGH.

Tried this one but result is the same.

&& ( buttonstateopen != HIGH )

When I toggle the switch, serial monitor shows "door closing manual" and door goes down. when door is down and doordownsensorpin is high serial monitor shows "door stop" and right after that "door should be up" "door raising"and it goes back up.

vanderwanten:
When I toggle the switch, serial monitor shows "door closing manual" and door goes down. when door is down and doordownsensorpin is high serial monitor shows "door stop" and right after that "door should be up" "door raising"and it goes back up.

Your sketch currently forces the door open any time the sun is up. You need State Change Detection (See: File->Examples->02.Digital->StateChangeDetection) to automatically open the door only at the START of the day, when the state changes from night to day. Similarly it should automatically close the door only at the END of the day, when the state changes from day to night. All other times the manual buttons will work.

You apparently used the state of the wrong switch.

johnwasser:
Your sketch currently forces the door open any time the sun is up. You need State Change Detection (See: File->Examples->02.Digital->StateChangeDetection) to automatically open the door only at the START of the day, when the state changes from night to day. Similarly it should automatically close the door only at the END of the day, when the state changes from day to night. All other times the manual buttons will work.

I was thinking... isn’t there any quick and dirty way to make my sketch thinking it’s 2 o’clock in the night when I toggle the switch? Or write a forced time into the rtc when the switch input is high?

Won’t use the function that much, but I have a damn chicken that sometimes want to breed all the eggs in the coop even when there are nog eggs. Then I would like to close the door manual

vanderwanten:
Or write a forced time into the rtc when the switch input is high?

...when you have complete control over the door, unrestricted access to the time, and switch status always available? I should think no, never this.

If you use events to toggle states, an over-ride at 2am is really easy. You just set it up so either the time becoming sunrise, or the override switch becoming active, will close the door. That's dead easy. You just have to remember the state of the door, open or closed. That will be a variable.