Chicken Coop Arduino Controller

When I started my chicken coop, I knew I wanted it to be technically advanced, but I didn’t really want it to *look* too high tech, and not too “country” either. So I just went for it and I’m pretty happy with the results. Being the chicken nerd I am, I loved every phase of combining technology with building a chicken coop and raising chickens. (I actually don’t think I’ll ever want to stop adding to it b/c it’s just too fun) I mean, why shouldn’t technology keep them safer, more comfortable, and healthier? Ok, and why shouldn’t *I* have more fun with it? =)

What was the most important part for me (like most of us chicken owners) is keeping the chickens safe, especially at night. So for the automation part, it was all about the door. Predators are strong, sneaky and relentless critters, so you have to really get this door part right. After a while, you realize that one of the biggest pains is opening and closing the door every morning and evening. We chicken owners can’t go out to dinner without worrying whether or not a raccoon or a fox has been eyeballing them all day, waiting for the sun to go down to get into the coop to have *their* dinner. I also installed a chicken cam for a little added comfort.

Arduino Chicken Coop Controller (labelled)

Arduino Chicken Coop Controller (labelled)

The Build

coming soon…

Parts List

(my affiliate links)

Arduino MEGA 2560 Board R3 – by Arduino
(The Arduino Micro Controller to control the entire coop, including the door)

NEOMART L298N Stepper Motor Driver Controller Board Module – by Tontec
(The board that controls the motor)

DFGB37RG-136i Cylinder Shape DC 24V Speed 20 RPM Geared Motor – by Amico
The motor it self (make sure to pick a motor that isn’t too fast.I chose the 20rpm model)

White Inbuilt Type Alarm Contacts Door Window Reed Switch – by Amico
(The Reed Switches (magnetic) which signals when to start/top the motor)

20pcs Photo Light Sensitive Resistor Photoresistor Optoresistor 5mm GM5539 5539 – by sunkee-E
(The Photocell that continually reads light levels.In this project, it’s instructed to read ever 10mins)

10k Ohm Resistors – 1/4 Watt – 5% – 10K (25 Pieces) – by E-Projects
(10k resistors for the photocell and the reed switches – refer to wiring diagram)

BB830 Solderless Plug-in BreadBoard, 830 tie-points, 4 power rails – by BusBoard Prototype Systems
(To connect all devices and wiring.Tip: apply hot glue to wired connections on breadboard once set)

Polycom SoundPoint IP Universal AC Power Supply 24V DC – by Polycom Inc.
(power supply for 24v motor)

Wall Adapter Power Supply – 9V DC 650mA – by NKC Electronics
(power supply for arduino)

Acrylic Sheet, Transparent Clear, 0.08" Thickness, 12" Width, 24" Length – by Small Parts
(To cover door’s internal workings…prevents dust, shavings, feathers, etc.)

  • Arduino Mega 2560 R3
  • Real time clock
  • L298N Motor Driver Dual H-Bridge
  • 16 x 2 LCD
  • 5 pin din male and female connectors
  • RCA male and female connectors
  • 12 V cooling fan
  • Wire ties
  • Wire (yellow, read, black & green)
  • Tie downs
  • Box
  • Shrink tubing
  • Bread board
  • Resistors
  • Relays
  • Velcro
  • 9v power supply
  • 12v power supply
  • 24 volt power supply
  • USB connector
  • Cable labels

The Arduino Chicken Coop Code

[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

Download The Arduino Automated Chicken Coop Code (zipped)
[/callout]


// libraries


#include                      // load the SimpleTimer library to make timers, instead of delays & too many millis statements
#include                          // load the onewire library for thermometer
// #include                            // load the servo library
#include                    // load the liquid crystal library



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

/*
* 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, see 
 
*/
 
 /*
* 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
*/
 


// pins assignments

// temperature chip i/o
const int photocellPin = A0;                 // photocell connected to analog 0
const int thermometer = 3;                   // thermometer DS18S20 on digital pin 3

const int relayHeat = 5;                     // heat lamp relay set to digital pin 5
const int relayFan = 6;                      // exhaust fan relay set to digital pin 6
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
const int coopDoorOpenLed = 40;              // led set to digital pin 40
const int coopDoorClosedLed = 41;            // led set to digital pin 41
// const int relayElectricFence = 43;        // heat lamp relay set to digital pin 43
const int relayInteriorLight = 45;           // interior lights relay set to digital pin 45


// 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

// SimpleTimer objects
SimpleTimer coopPhotoCellTimer;


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


// temperature check delay
long lastTempCheckTime = 0;
long TempCheckDelay = 600000;           // 10 minutes


// interior lights twighlight delay
long lastTwilightTime = 0;
long TwilightDelay = 300000;           // 5 minutes


// temperature chip i/o
OneWire ds(thermometer);               // thermometer on digital pin 3

// chicken cam servo 
// Servo chickenCamServo;              //  servo object to control chickenCam
// int chickenCamServoPos = 0;         // chickenCamServoPosition var

// lcd
LiquidCrystal lcd(38, 37, 36, 32, 33, 34, 35);   // lcd pin assignments
int backLight = 13;                              // pin 13 controls backlight
/*
LCD Pin	 > arduino Pin
 
 lcd pin 1 VSS >	    gnd arduino pin
 lcd pin 2 VDD >	    +5v arduino pin
 lcd pin 3 VO(contrast) >   330 ohm resistor to gnd arduino pin
 lcd pin 4 RS	            arduino pin 38
 lcd pin 5 R/W	            arduino pin 37
 lcd pin 6 Enable	    arduino pin 36
 lcd pin 7  -	 
 lcd pin 8  -	 
 lcd pin 9  -	 
 lcd pin 10 -	 
 lcd pin 11 (Data 4)    >   arduino pin 32
 lcd pin 12 (Data 5)    >   arduino pin 33
 lcd pin 13 (Data 6)    >   arduino pin 34
 lcd pin 14 (Data 7)    >   arduino pin 35
 lcd pin 15 Backlight + >   arduino pin 13 (built-in resistor)
 lcd pin 16 Backlight   >   arduino gnd pin
 */




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

void setup(void) {

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


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

  pinMode(relayHeat, OUTPUT);   //set heat lamp relay output
  pinMode(relayFan, OUTPUT);    //set exhaust fan relay output

  // 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

  // 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  

  // interior lights relay
  pinMode(relayInteriorLight, OUTPUT);
  digitalWrite(relayInteriorLight, HIGH);

  // electric fence relay
  // pinMode(relayElectricFence, OUTPUT);                   // set electric fence relay as output

  // timed actions setup
  coopPhotoCellTimer.setInterval(600000, readPhotoCell);   // read the photocell every 10 minutes



  // servo for interior chicken web cam  
  //  chickenCamServo.attach(11);                          // chickenCamServo on pin 11



}

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

// coop hvac

void doCoopHVACHeat() {

  float temperature = getTemp();                    // create temperature variable
  float tempF = (temperature * 9.0)/ 5.0 + 32.0;    // convert celcius to fahrenheit
  if(SerialDisplay){
    Serial.print(" Coop Temperature:");             // print out coop temperature 
    Serial.println(tempF);                          // print out the temperature 
  }

  if ((millis() - lastTempCheckTime) > TempCheckDelay) {    // check temperature every 10 minutes

    // if cold, turn on heat lamps
    if (tempF <= 40) {                                      // if temp drops below 40F turn on heat lamp(s) relay
      digitalWrite(relayHeat, HIGH); 
    }
    else if (tempF > 40) {
      digitalWrite(relayHeat, LOW);                        // if temp remains above 40F turn off heat lamp(s) relay
    }
  }
}



// if hot, turn on cooling fans

void doCoopHVACCool() {

  float temperature = getTemp();                    // create temperature variable
  float tempF = (temperature * 9.0)/ 5.0 + 32.0;    // convert celcius to fahrenheit
  if(SerialDisplay){
    Serial.print(" Coop Temperature:");             // print out coop temperature 
    Serial.println(tempF);                          // print out the temperature 
  }

  if ((millis() - lastTempCheckTime) > TempCheckDelay) {    // check temperature every 10 minutes
    if (tempF >= 83) {                                      // if temp rises above 85F turn on cooling fan(s) relay
      digitalWrite(relayFan, HIGH);
    }

    else if (tempF < 83) {
      digitalWrite(relayFan, LOW);
    }
  }
}



// credit: bildr.org/2011/07/ds18b20-arduino/
// DS18S20 digital thermometer stuff

float getTemp(){                 //returns the temperature from one DS18S20 in DEG Celsius

  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
    //no more sensors on chain, reset search
    ds.reset_search();
    return -1000;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return -1000;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
    Serial.print("Device is not recognized");
    return -1000;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);                 // start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);  
  ds.write(0xBE);                   // Read Scratchpad


  for (int i = 0; i < 9; i++) {     // we need 9 bytes
    data[i] = ds.read();
  }

  ds.reset_search();

  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;

  return TemperatureSum;

}


// operate the coop door

// photocel to read levels of exterior light

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

  photocellReading = analogRead(photocellPin);
  if(SerialDisplay){
    Serial.print(" Photocel Analog Reading = ");
    Serial.println(photocellReading);
  }


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

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

//debounce bottom reed switch

void debounceBottomReedSwitch() { 

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

  if ((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
  //  delay(10);

  if ((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.print(" 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.print(" Coop Door open - danger!");
    }
  }
}

// blink coop door red led if door is stuck 

// blink  CoopDoorLedOpen (red)
// void doCoopDoorLedError(){
// digitalWrite (coopDoorOpenLed, HIGH);                  // blinks coopDoorOpenLed
//  }


//  coop door status: red if open, green if closed, blinking red if stuck 

void doCoopDoorLed() {
  if (bottomSwitchPinVal == 0) {                         // if bottom reed switch circuit is closed
    digitalWrite (coopDoorClosedLed, HIGH);              // turns on coopDoorClosedLed (green)
    digitalWrite (coopDoorOpenLed, LOW);                 // turns off coopDoorOpenLed (red)
  }
  else if(topSwitchPinVal == 0) {                        // if top reed switch circuit is closed 
    digitalWrite (coopDoorClosedLed, LOW);               // turns off coopDoorClosedLed (green)
    digitalWrite (coopDoorOpenLed, HIGH);                // turns on coopDoorOpenLed (red)
  }
  //    else if (topSwitchPinVal != 0)  && if (bottomSwitchPinVal != 0) {                // if bottom and top reed switch circuits are open 
  //            doCoopDoorLedError();                         // blink the coopDoorOpenLed
  //         }
  //         }
  else {
    digitalWrite (coopDoorClosedLed, LOW);              // turns off coopDoorClosedLed (green)
    digitalWrite (coopDoorOpenLed, LOW);                // turns off coopDoorOpenLed (red)
  }
}



//  turn on interior lights at dusk and turn off after door shuts

void doCoopInteriorLightDusk() {

  if ((millis() - lastTwilightTime) > TwilightDelay) {     // delay 5 mins

    readPhotoCell();
    bottomSwitchPinVal = digitalRead(bottomSwitchPin);
    if (bottomSwitchPinVal == 1 && photocellReading  >= 4 && photocellReading <= 120) {   // if bottom reed switch circuit is open and it's twilight
      digitalWrite (relayInteriorLight, HIGH);
      if (SerialDisplay) {
        Serial.println(" Interior Light: On");
      }
    }
    else if (bottomSwitchPinVal == 0) {
      digitalWrite (relayInteriorLight, LOW);
      if (SerialDisplay) {
        Serial.println(" Interior Light: Off");
      }
    }
  }
}




// 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
      }
    }
  }
}

// chickenCamServo
/*
void doChickenCamServo() {
 for (chickenCamServoPos = 0; chickenCamServoPos < 75; chickenCamServoPos += 1) {   // turns servo 0 to 75 degrees; 1 degree at a time
 chickenCamServo.write(chickenCamServoPos);                                     // read chickenCamServoPosition variable chickenCamServoPos
 }
 
 for(chickenCamServoPos = 75; chickenCamServoPos>=1; chickenCamServoPos-= 1){      // return from 75 degrees to 0 degrees; 1 degree at a time
 chickenCamServo.write(chickenCamServoPos);                                    // read chickenCamServoPosition variable chickenCamServoPos
 }
 }
 
 */

//  lcd
void doLcdMsg() {

  float temperature = getTemp();                 // create temperature variable
  float tempF = (temperature * 9.0)/ 5.0 + 32.0; // convert celcius to fahrenheit

  pinMode(backLight, OUTPUT);            // backlight pin set as output
  digitalWrite(backLight, HIGH);         // backlight on
  lcd.begin(16,2);                       // columns, rows
  lcd.clear();                           // start with blank screen
  lcd.setCursor(0,0);                    // set cursor to column 0, row 0
  lcd.print("Coop Temp:");               // show "Temp"
  lcd.print (tempF) ;                    // show temperature of interior coop
  lcd.print("F");                        // show "F" 
  lcd.setCursor(0,1);                    // set cursor to column 0, row 1
  lcd.print("Coop Door:");               // show "Coop Door"

  if (bottomSwitchPinVal == 0) {         // if coop door bottom switch is closed
    lcd.print("Closed");                 // display "Closed"
  } 
  else if (topSwitchPinVal == 0) {     // if coop door bottom switch is open
    lcd.print("Open");  // display "Open"
  }
}



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

void loop() {
  coopPhotoCellTimer.run();      // timer for readPhotoCell
  doCoopHVACCool();
  doCoopHVACHeat();
  doCoopDoor();
  // doChickenCamServo();
  doCoopDoorLed();
  doCoopInteriorLightDusk();
  doLcdMsg();

}


The Wiring Diagram

(Fritzing)
coming soon…

Lessons Learned

coming soon…