The Code for Arduino Chicken Coop Door

NOTE: To hopefully save you some time, I’ll let you in on the trick that FINALLY got this door to work with the light levels, debouncing the switches and *the chickens*. (as you’ll see in the code)

Check the light levels every 10 minutes to avoid the readings bouncing back and forth between dark/twilight/light during those dawn/dusk minutes. Then, when “dark” is reached (for me i chose >= 0 && <= 3 based on when my chickens actually went & stayed in the coop) enable motor dir down > debounce the switches > stop. Then do the opposite for morning. I’m sure there are different, maybe more efficient methods, but this code has been running flawlessly for a while now and I’m feeling confident enough to go out at night without worrying about predators. Although I still somehow find a reason to check the ChickenCam from time to time. (currently waiting for my new servo motors and night vision web cam to arrive in the mail)
[callout font_size=”13px” style=”limegreen”]

David Naves

David Naves

I’m hoping that if you use or modify my code or ideas, you will share *your* coop project with me and the world (pictures, whatever) I’m big on sharing.

Cheers,
//D

[/callout]

I guess there has been some issue with copy and pasting the code, so I zipped up
the latest clean .ino for you here

 

/*
* Copyright 2016, David Naves (http://daveworks.net, http://davenaves.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not,  write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
* 02110-1301, USA. 

*/

 /*
* I'm hoping that if you use/modify this code, you will share your
* coop project with me and the world (pictures, whatever)
* I'm big on sharing.
* Cheers,
* //D
*/



// libraries


#include                          // load the onewire library for thermometer
#include                    // load the liquid crystal library



// print debug messages or not to serial
const boolean SerialDisplay = true;




// pins assignments

// temperature chip i/o
const int photocellPin = A0;                 // photocell connected to analog 0
const int enableCoopDoorMotorB = 7;          // enable motor b - pin 7
const int directionCloseCoopDoorMotorB = 8;  // direction close motor b - pin 8
const int directionOpenCoopDoorMotorB = 9;   // direction open motor b - pin 9
const int bottomSwitchPin = 26;              // bottom switch is connected to pin 26
const int topSwitchPin = 27;                 // top switch is connected to pin 27



// variables



// photocell
int photocellReading;                            // analog reading of the photocel
int photocellReadingLevel;                       // photocel reading levels (dark, twilight, light)

// reed switches top and bottom of coop door

// top switch

int topSwitchPinVal;                   // top switch var for reading the pin status
int topSwitchPinVal2;                  // top switch var for reading the pin delay/debounce status
int topSwitchState;                    // top switch var for to hold the switch state

// bottom switch

int bottomSwitchPinVal;                // bottom switch var for reading the pin status
int bottomSwitchPinVal2;               // bottom switch var for reading the pin delay/debounce status
int bottomSwitchState;                 // bottom switch var for to hold the switch state



// photocell reading delay
unsigned long lastPhotocellReadingTime = 0;
unsigned long photocellReadingDelay = 600000;   // 10 minutes

// debounce delay
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 100;





// ************************************** the setup **************************************

void setup(void) {

  Serial.begin(9600); // initialize serial port hardware


  // welcome message
  if (SerialDisplay) {
    Serial.println(" Processes running:");
    Serial.println(" Timer doReadPhotoCell every 10 minutes - light levels: open or close door");
  }
 

  // coop door

  // coop door motor
  pinMode (enableCoopDoorMotorB, OUTPUT);           // enable motor pin = output
  pinMode (directionCloseCoopDoorMotorB, OUTPUT);   // motor close direction pin = output
  pinMode (directionOpenCoopDoorMotorB, OUTPUT);    // motor open direction pin = output

  // coop door leds
  pinMode (coopDoorOpenLed, OUTPUT);                // enable coopDoorOpenLed = output
  pinMode (coopDoorClosedLed, OUTPUT);              // enable coopDoorClosedLed = output
  digitalWrite(coopDoorClosedLed, LOW);

  // coop door switches
  // bottom switch
  pinMode(bottomSwitchPin, INPUT);                  // set bottom switch pin as input
  digitalWrite(bottomSwitchPin, HIGH);              // activate bottom switch resistor

  // top switch
  pinMode(topSwitchPin, INPUT);                     // set top switch pin as input
  digitalWrite(topSwitchPin, HIGH);                 // activate top switch resistor



}

// ************************************** functions **************************************



// operate the coop door

// photocel to read levels of exterior light

void doReadPhotoCell() { // function to be called repeatedly - per coopPhotoCellTimer set in setup

  photocellReading = analogRead(photocellPin);

  if ((unsigned long)(millis() - lastPhotocellReadingTime) >= photocellReadingDelay) {
    lastPhotocellReadingTime = millis();

    //  set photocel threshholds
    if (photocellReading >= 0 && photocellReading <= 3) {
      photocellReadingLevel = '1';

      if (SerialDisplay) {
        Serial.println(" Photocel Reading Level:");
        Serial.println(" - Dark");
      }
    }
    else if (photocellReading  >= 4 && photocellReading <= 120) {
      photocellReadingLevel = '2';
      if (SerialDisplay) {
        Serial.println(" Photocel Reading Level:");
        Serial.println(" - Twilight");
      }
    }
    else if (photocellReading  >= 125 ) {
      photocellReadingLevel = '3';
      if (SerialDisplay) {
        Serial.println(" Photocel Reading Level:");
        Serial.println(" - Light");
      }
    }
    if (SerialDisplay) {
      Serial.println(" Photocel Analog Reading = ");
      Serial.println(photocellReading);
    }
  }
}

//debounce bottom reed switch

void debounceBottomReedSwitch() {

  //debounce bottom reed switch
  bottomSwitchPinVal = digitalRead(bottomSwitchPin);       // read input value and store it in val

  if ((unsigned long)(millis() - lastDebounceTime) > debounceDelay) {    // delay 10ms for consistent readings

    bottomSwitchPinVal2 = digitalRead(bottomSwitchPin);    // read input value again to check or bounce

    if (bottomSwitchPinVal == bottomSwitchPinVal2) {       // make sure we have 2 consistant readings
      if (bottomSwitchPinVal != bottomSwitchState) {       // the switch state has changed!
        bottomSwitchState = bottomSwitchPinVal;
      }
      if (SerialDisplay) {
        Serial.print (" Bottom Switch Value: ");           // display "Bottom Switch Value:"
        Serial.println(digitalRead(bottomSwitchPin));      // display current value of bottom switch;
      }
    }
  }
}



// debounce top reed switch
void debounceTopReedSwitch() {

  topSwitchPinVal = digitalRead(topSwitchPin);             // read input value and store it in val

  if ((unsigned long)(millis() - lastDebounceTime) > debounceDelay) {     // delay 10ms for consistent readings

    topSwitchPinVal2 = digitalRead(topSwitchPin);          // read input value again to check or bounce

    if (topSwitchPinVal == topSwitchPinVal2) {             // make sure we have 2 consistant readings
      if (topSwitchPinVal != topSwitchState) {             // the button state has changed!
        topSwitchState = topSwitchPinVal;
      }
      if (SerialDisplay) {
        Serial.print (" Top Switch Value: ");              // display "Bottom Switch Value:"
        Serial.println(digitalRead(topSwitchPin));         // display current value of bottom switch;
      }
    }
  }
}


// stop the coop door motor
void stopCoopDoorMotorB() {
  digitalWrite (directionCloseCoopDoorMotorB, LOW);      // turn off motor close direction
  digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn on motor open direction
  analogWrite (enableCoopDoorMotorB, 0);                 // enable motor, 0 speed
}



// close the coop door motor (motor dir close = clockwise)
void closeCoopDoorMotorB() {
  digitalWrite (directionCloseCoopDoorMotorB, HIGH);     // turn on motor close direction
  digitalWrite (directionOpenCoopDoorMotorB, LOW);       // turn off motor open direction
  analogWrite (enableCoopDoorMotorB, 255);               // enable motor, full speed
  if (bottomSwitchPinVal == 0) {                         // if bottom reed switch circuit is closed
    stopCoopDoorMotorB();
    if (SerialDisplay) {
      Serial.println(" Coop Door Closed - no danger");
    }
  }
}



// open the coop door (motor dir open = counter-clockwise)
void openCoopDoorMotorB() {
  digitalWrite(directionCloseCoopDoorMotorB, LOW);       // turn off motor close direction
  digitalWrite(directionOpenCoopDoorMotorB, HIGH);       // turn on motor open direction
  analogWrite(enableCoopDoorMotorB, 255);                // enable motor, full speed
  if (topSwitchPinVal == 0) {                            // if top reed switch circuit is closed
    stopCoopDoorMotorB();
    if (SerialDisplay) {
      Serial.println(" Coop Door open - danger!");
    }
  }
}





// do the coop door
void doCoopDoor() {
  if (photocellReadingLevel  == '1') {              // if it's dark
    if (photocellReadingLevel != '2') {             // if it's not twilight
      if (photocellReadingLevel != '3') {           // if it's not light
        debounceTopReedSwitch();                    // read and debounce the switches
        debounceBottomReedSwitch();
        closeCoopDoorMotorB();                      // close the door
      }
    }
  }
  if (photocellReadingLevel  == '3') {              // if it's light
    if (photocellReadingLevel != '2') {             // if it's not twilight
      if (photocellReadingLevel != '1') {           // if it's not dark
        debounceTopReedSwitch();                    // read and debounce the switches
        debounceBottomReedSwitch();
        openCoopDoorMotorB();                       // Open the door
      }
    }
  }
}



// ************************************** the loop **************************************

void loop() {
  
  doReadPhotoCell();
  doCoopDoor();

}


I guess there has been some issue with copy and pasting the code, so I zipped up
the latest clean .ino for you here

Parts Used

(my affiliate links)

The Wiring Diagram for the Automatic Chicken Coop Door

Arduino Automatic Chicken Coop Door Fritzing Wiring Diagram

Arduino Automatic Chicken Coop Door Fritzing Wiring Diagram

The Installed Arduino Chicken Door

How I built the Automated Chicken Coop Door

Testing the door with the Arduino

Lessons Learned

What I’ve learned about the door, Arduino, light and construction:

  • Best to check the light levels every 10 minutes to avoid the readings bouncing back and forth between dark/twilight/light during those dawn/dusk minutes
  • Test your door with your chickens to see if any of them like to hang outside after hours
  • Testing the actual light values outside is very important (many variables involved: light from neighbor’s house, clouds, internal/external coop lights etc.)
  • Debouncing of your switches within your Arduino code is important (door will jump around and fail as electronic readings vary greatly by the millisecond)
  • Reach out for help on the Arduino Forums before pulling out your hair. (be nice, do your homework and ask very specific questions)
  • I changed from micro-switches to reed switches (magnets) because I didn’t want the mechanics of the micro-switches to fail over time

What I’ve learned about the chickens:

  • Keeping on a light within the coop can keep chickens outside longer (I think b/c the ambient light shines outside) And that’s important when it comes to automating this door, so they won’t get accidentally locked out.
  • They can jump and fly (high and far)
  • They love to roost in safety at night, but want nothing more than to get OUT as soon as it’s light out