Automatic chicken door version two.

As it is getting cold again and my chickens made it through the summer just fine, it is time to revisit and revitalize my automatic chicken door.

The older model was a large door that slid on a track that would get leaves, snow, and ice messing the whole thing up. Also the mecanisim that opened the door was a string that tension was held on with springs, the string would knot up and stop working, blowing the fuse sometimes.

There is an older version of this project and you can read about it here.

image

Chicken door version 1

With version two I made the door smaller and lowered it down so the older chickens could more easily get through. Having the door up off of the ground helps keep wondering critters out but this design works better. I also made the door smaller so that it was easy for my motor to pull it up.

image

Chicken door version 2

Surprisingly the mechanical aspect of the door kicked my but the most. With the door out of the way it was time to revisit my code. The old code and circuit actually worked with the new door. The electronics is housed in a NEMA 4 electrical enclosure which is waterproof. Normally I would have drilled any holes for wires in the bottom of the enclosure but the box was used and there were already some holes in the side, I used CGBs to seal the wires coming in.

The electronics consist of an Arduino clone, voltage regulator, some transistors that power a couple relays to turn the motor. The whole thing is powered by a 9 amp our 12 volt battery that is charged by a 30 watt solar panel.

image

Electronics of the chicken door.

I was cleaning up last years code to post it and realized my coding skills have come a long way in a year, it was horrifying. I also checked on the chickens after it was dark to find the motor pulsing every few seconds. I cleaned up, debugged, and commented the code so it is WAY nicer this time. You can download the code here:ChickenLDR4 or copy it below.

I also created a schematic for your viewing pleasure, in the schematic I used a Duemilanove because it was already created in another schematic and it is clearer to view as you may not be using the same Arduino clone board. You can download the chicken door schematic PDF here.

image

Here is the code if for your copy and pasting pleasure. Click the view source button on the top right to open the code in notepad and copy it.

/* 
###########################################################
  Title:       Dawn to Dusk chicken door 
  Purpose:     Opens a door when it is light then closes the door when it is dark.
  Created by:  Fileark. see Fileark.com for more info.
  Note:        Please reuse, repurpose, and redistribute this code.
###########################################################
 */

int LDR = 0;               // select the input pin for the LDR
int CloseOutput = 8;       // select the pin for the close output
int OpenOutput = 7;        // select the pin for the open output
int LDRval = 0;            // variable to store the value coming from the light sensor
int Counter = 0;        
int OpenCounter = 0;
int CloseCounter = 0;
int ManualClosePin = 2;    // select the pin for the manual close input
int ManualOpenPin = 3;     // select the pin for the manual open input 
int TestEnablePin = 4;     // select the pin for the test mode input
int CloseLimitSw = 5;      // select the pin for the close limit switch
int OpenLimitSw = 6;       // select the pin for the open limit switch
int OpenLimitActive = 0 ;  //Variable to use when the open limit is active
int CloseLimitActive = 0;  //Variable to use when the close limit is active
int ManualOpen = 0;        //Variable to use when in manual open mode
int ManualClose = 0;       //Variable to use when in manual close mode
int TestEnable = 0;        //Variable to use when in test mode
int Delay1 = 60;           //Variable used for delay the value changes later depending on test mode    
int Delay2 = -60;          //Variable used for delay the value changes later depending on test mode
int ManualModeOneShot = 0; //Variable to ensure that when manual open or close is triggered that it will only trigger once
int AutoModeOneShot = 0;   //Variable to ensure that when auto mode open or close is triggered that it will only trigger once
int LEDpin = 13;
int LEDcounter = 0;

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
  pinMode(LDR, INPUT);             // declare LDR as an input
  pinMode(OpenOutput, OUTPUT);     // declare OpenOutput as an output
  pinMode(CloseOutput, OUTPUT);    // declare CloseOutput as an ooutput
  pinMode(ManualOpenPin, INPUT);   // declare ManualOpenPin as an input
  pinMode(ManualClosePin, INPUT);  // declare ManualCLosePin as an input
  pinMode(TestEnablePin, INPUT);   // declare TestEnablePin as an input
  pinMode(OpenLimitSw, INPUT);     // declare OpenLimitSw as an input
  pinMode(CloseLimitSw, INPUT);    // declare CloseLimitSw as an input
  pinMode(LEDpin, OUTPUT);         // declare the led pin as an output
}


void loop() 
{

  //###########################################################
  // Read all the digital input pins that are connected to switches, set delay times
  ManualOpen = digitalRead(ManualOpenPin);       
  ManualClose = digitalRead(ManualClosePin);
  TestEnable = digitalRead(TestEnablePin);
  OpenLimitActive = digitalRead(OpenLimitSw);
  CloseLimitActive = digitalRead(CloseLimitSw);
  
  //###########
  //Test mode evaluation  
  if (TestEnable == HIGH)         //Set the delay times depending on test mode
    {
       Delay1 = 30;
       Delay2 = -30; 
    }
  else
    {
       Delay1 = 9000;
       Delay2 = -9000; 
    }
  

  //###########################################################
  //Manual open or close cycle starts here
  if (ManualOpen == HIGH or ManualClose == HIGH && ManualModeOneShot == 0)     
    {  
      if (ManualOpen == HIGH && OpenCounter == 0)          // if the open switch is true and couter less than 70 then...
        {
           OpenCounter += 1;                               // add one to the open counter, this kicks off the open evaluation below
        }   
       if (ManualClose == HIGH && CloseCounter == 0)       // if the open close switch is true and couter less than 70 then...
        {
           CloseCounter += 1;                              // add one to the close counter, this kicks off the open evaluation below
        }   
       ManualModeOneShot = 1;                              //setting the one shot variable prevents an endles loop... i.e. makes it-
                                                           //  open or close one time and not keep doing it forever.
    }
  
  if (ManualOpen == LOW and ManualClose == LOW)            //if the switch is in auto mode then... 
    {
      ManualModeOneShot = 0;                               //reset the one shot so that manual mode will work when triggered again
    }


  //###########################################################
  //Auto mode starts here
  if (ManualOpen == LOW && ManualClose == LOW)              
  { 
      LDRval = analogRead(LDR);                                               // read the value from the light sensor
  
   
  //###########
  //Start counters if threshold is reach one way or the other on the light sensor 
      if (LDRval > 970 && Counter <= Delay1) Counter += 1;                    //if true this starts the close cycle
                                                                              //If the LDR value is greater than the threshold (see below) and counter is less than
                                                                              // then delay2 then add 1 to the counter.   
                                                                              //(970 is the threshold for my sensor (the value is from pin 0), yours will be different)
                                                                
      if (LDRval < 600 && Counter >= Delay2) Counter -= 1;                    //if true this starts the Open cycle, it will use the same counter 
                                                                              //but will start subtracting 1 each time.
      if (LDRval > 600 && LDRval < 970) Counter = 0;                                                       
      
      if (Counter >= Delay1 && AutoModeOneShot == 0) OpenCounter = 1;         //kicks off the open timer below                     
      if (Counter <= Delay2 && AutoModeOneShot == 0) CloseCounter = 1;        //kicks off the close timer below
      
      if (Counter >= Delay1 or Counter <= Delay2) AutoModeOneShot = 1;        //if we have kicked off an open or close sets the one shot to prevent endles loop
      else AutoModeOneShot = 0;                                               //if the value is between threshold clear the one shot

      if (Counter > Delay1) Counter = Delay1;                                 //If test mode is triggered pulls the counter down so that it doesn't have to count down from the auto delay setpoint
      if (Counter < Delay2) Counter = Delay2;                                 //If test mode is triggered pulls the counter up so that it doesn't have to count up from the auto delay setpoint
  }
 
   //###########################################################
   //Open and close timers
   //these timers make the door open and close pulses only last 6 seconds incase the limit switches fail    

   //###########
   //Limit switch evaluation before we even get going
   if (OpenLimitActive == LOW)                 //If the open limit is reached, reset the counter to end the open cycle prematurely
     {OpenCounter = 0;}
   if (CloseLimitActive == LOW)                //if the close limit is reached, reset the counter to end the close cycle prematurely
     {CloseCounter = 0;}
     
   if (OpenCounter >= 1 && CloseCounter >= 1)  //Make sure we dont some how try to open and close at the same time, if so, reset counters
     {
       OpenCounter == 0;
       CloseCounter == 0;
     }
     
    
   //############
   //Open
    if (OpenCounter >= 1 && OpenCounter <= 50 ) //if the open counter is greater than 1 and less than 60...
      {
        OpenCounter += 1;                      //add one to the counter
        digitalWrite(OpenOutput, HIGH);        //set the open output true 
      }
    else                                       //if the open counter is greater than 60 (6 seconds)...
      {
        digitalWrite(OpenOutput, LOW);         //set the open output to false
        OpenCounter = 0;                       //reset the counter 
      }
      
    //############
    //Close 
    if (CloseCounter >= 1 && CloseCounter <= 50)  //same as above but for close
      {
        CloseCounter += 1;
        digitalWrite(CloseOutput, HIGH);
      }
    else
      {
        digitalWrite(CloseOutput, LOW); 
        CloseCounter = 0;
      }

   //###########################################################
   //Fanciness that blinks the onoard LED to show program health  
    if (LEDcounter >= 10)
      {
        LEDcounter = 0;
        digitalWrite(LEDpin, HIGH);
      }
    else
      {
        digitalWrite(LEDpin, LOW); 
        LEDcounter += 1;
      }

  
     if (LEDcounter == 9)
      {
        // print the results to the serial monitor once per second
        Serial.print("LDRval = " );                       
        Serial.print(LDRval);      
        Serial.print(" Cntr = ");      
        Serial.println(Counter);
        Serial.print(" OpenCntr = ");      
        Serial.println(OpenCounter);
        Serial.print(" CloseCntr = ");      
        Serial.println(CloseCounter);   
        Serial.print(" ManualOpen = ");      
        Serial.println(ManualOpen);  
        Serial.print(" ManualClose = ");      
        Serial.println(ManualClose);  
        Serial.print(" TestEnable = ");      
        Serial.println(TestEnable);  
        Serial.print(" Delay1 = ");      
        Serial.println(Delay1);  
        Serial.print(" Delay2 = ");      
        Serial.println(Delay2);  
        Serial.print(" OpenLimitActive = ");      
        Serial.println(OpenLimitActive);  
        Serial.print(" CloseLimitActive = ");      
        Serial.println(CloseLimitActive);
        Serial.print(" Counter = ");      
        Serial.println(Counter);
        Serial.print(" OpenCounter = ");      
        Serial.println(OpenCounter);
        Serial.print(" CloseCounter = ");      
        Serial.println(CloseCounter);
        Serial.print(" AutoModeOneShot = ");      
        Serial.println(AutoModeOneShot);       
        Serial.print(" ManualModeOneShot = ");      
        Serial.println(ManualModeOneShot);        
      }

  
  delay(100);                                //Wait 100ms before starting the loop again
}

Hi there i really like what you did here, and am currently doing a project in college which is the same as what you did; am just wondering if i can do the same with arduino uno. thanks.

Thanks for you reply, can you give me some tips as am a pure bigger with Arduino. i will tell you what i want the arduino to do and i want you to please tell me what i need to get. have built the mechanical part of the project its just the control system i need to figure out. the project requirement is for a simple low voltage (12V Max) system that will open a vertically opening hatch at dawn and close it a short time after dark. what i have for now arduino sparkfun inventor’s kit, 12V DC motor, two D45X limit switches, LDR and few other bits. if you want me to send you some picture of it all i can. i will really appreciate any help from you thanks.

That is exactly what this project should help you to do. I can not guarantee the code will run seamlessly for you, there will be some tinkering and debugging involved. If you have no experience with Arduino I suggest spending some time doing tutorials, blinking the led, ect to get used to the Arduino IDE.

Hi again. I just wanted you to know I didn’t crap out on you. I mean, I wasn’t full of chicken poop when I said I was going to build this. I had a rough auto accident and must get back on my feet, then on to the chicken coop. Thanks again for the great info.

I am new to both Arduino and chickens and found your infor on an automated coop fantastic. Very useful and gives me a good starting point. What kind of LDR did you use and what are the size of your solar panels? This is exactly the type of system I am looking to set up for my soon to be arriving flock. Any info or help would be greatly appreciated.
Thanks
Jon

The LDR I used was actually a Photo Transistor which does the same thing as a LDR. I just had both on hand and after experimenting I liked the curve of the PT better than the LDR but you could use either you would just tune the threshold in the code.
http://www.newark.com/vishay-semiconductor/tept5600/transistor-photo-npn-570nm-t-1/dp/93K0362?in_merch=true&MER=ACC_N_L5_SemiconductorsToolsAndAccessories_None

The solar panel is a 30 watt panel and I actually need a bigger one. You should size the solar depending on load and how far you live from the equator. I live in New Mexico, USA so I should get plenty of sun but I have trees that in the winter interfere with all but about 3 hours of sunlight. The unit will work great for a while but if I get a few days of snow storms and no sun the battery dies and I have to swap it out with a charged one.
A 30 watt panel can produce about two amp hours of energy per hour of direct sunlight (watts/volts = amps) this should be more than enough if you have good unobstructed sunlight. I think there is also a lot that could be done to make the code more efficient, I have just never focused on that aspect. Making the code sleep more which is totally doable would cut down on power consumption. I think when I measured it the unit was consuming about 100 milliamps or o.1 amps at that rate you deplete your battery a couple amp hours during the night and can easily replace that with a couple good hours of sun. Turning the motor takes about two amps but it is only for about five seconds so that doesn’t take much of the battery. It’s the snowy days that makes you think about upsizing the size of the battery and solar panel. If the coop is near power it would save some headache and cost to just grab a cheap battery maintainer to keep the battery charged.

How difficult would it be to add a minimum temperature sensor so that the door will not open until the outside temp reaches a preset level?

Super easy, just get a thermistor (around $1.00) and two resistors (for a voltage divider) wire it into one of the analog inputs of the board. After that just edit the code to add temperature evaluation.

Thank you for the quick response. I have ordered the relays, etc. and am putting together the mechanics. I originally wanted to use a servo with encoder, but simple is better at my coding level. I hope to embed the atmega chip into the wiring, so your advice on the regulator is just right. I will let you know how my door comes together. Hopefully the chickens will miss me every morning afterwards.

Great article on the chicken door, I needed this info to build one for my coop. Can you give me a parts list, specifically what relay and transistors do you use? The image above of your board shows some capacitors which are not on the schematic, what do they do? Any additional info you can provide would be extremely helpful, thanks for publishing this design.

In the video one of the capacitors is a 1000uf 16v cap across + and – just to help filter the DC from spikes or noise from battery chargers or the motor. The two other capacitors and resistors are for the voltage regulator, as I didn’t want to build that into my schematic I used an Arduino Pro Mini in the schematic that has a built in voltage regulator for the Arduino.

If you want to see my voltage regulator you can find the schematic on the second page of the spec sheet here for the LM317T. http://www.ti.com/lit/ds/symlink/lm117.pdf

The relays I used are 5 volt OEG OUA-55-105D http://www.te.com/catalog/pn/en/8-1419130-3 I ended up using 5 volt relays because it seemed like my power supply was isolated and 12 volt relays didn’t work… I should have just put more effort into it but i had those lying around. I suggest using the Arduino Pro Mini and supply it with 12 volts so you can use standard 12 volt relays. I like IDEC RH1BU, http://www.newark.com/idec/rh1b-udc12v/power-relay-spdt-12vdc-10a-plug/dp/66M8460?Ntt=RH1B-UDC12V it pulls 60ma and has 10 amp contacts. For sure, grab smaller relays if you have a small motor that doesn’t need much current.

Yes duelimenove and uno are the same, you can use 12 volts in place of 5v and it works fine. And I would say some trial and error to get the setting for the light sensor.

Hi,

Great Upgrade !

I have 2 questions.

1.
I got an arduino uno and 12V DC motor. (I understand arduino uno and duemilanove has almost same specs. Am I right ?)
I’d like to connect them to 12V DC power.
Then, what would the schematic be changed to ?
(I guess some registers should be changed.)

2. You set the threshold for light sensor to 970 and 600.
How can I know these values ? By try and error method ?

Thank you.

Harrison

I mean, if I do not use voltage regulator,
what should the schematic be.

You installed voltage regulator to down to 5V,
but it is not included in the diagram.
Where should it be in the diagram ?

Thanks.