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”]
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
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
Dave,
My wife has been demanding to know who the heck Dave Naves is, and WHY her husband carries with him, 24-7, a tattered, smudged multi-page document with computer code all over it! So PLEASE, I need just a little counsel on fixing this code problem. My problem is this: When I copy and paste your code into my arduino, and then use the check box to see if the code will compile, it NEVER does without various error messages, and at this point, I’m going crazy and more crucial, my chickens aren’t as safe as they could be with an operating Dave Naves Arduino Door. WHY do you think it might not be compiling. Thanks much, Dave.
Joe Walburn
Hiya Joe,
Please let your wife know that ~my~ wife is president and founder of The “Why is this #$%^&*!@#$%^ Chicken Coop More Important Than Family?” Support group. Membership is growing internationally and weekly meetings include plenty of wine and delicious bread. =)
Hehehehehe…
As far as the compiling, the error messages are most definitely important. Believe me, I’ve dealt with many hours of hair-pulling/frustration. (all part of the learning curve) Hint: typically the very 1st line in the message is the culprit… and sometimes there are multiple.
Also note: make ~sure~ you have all of the libraries installed (they are listed at the very top of the code and if not installed, will definitely throw errors)
If you copy/paste the errors to this thread of comments, I’d be happy to take a peek (and others here often like to chime in as well)
Cheers,
Dave “The Relationship Whisperer” Naves
=)
Joe,
Please let your wife know that ~my~ wife is both founder and president of the now International “Why is this Chicken Coop so !@#$%^ Important” Support Group. Memberships are still free and typically include plenty of wine and fresh sour dough. =)
Sorry to hear about the errors. (hint: the error messages are infinitely important – typically the culprit is the very first line printed in the message itself… and sometimes there are multiple) If you copy and paste them into this comment thread, I (and i’m sure a few others would be willing to help)
Also, make sure to have all of the Arduino “libraries” installed… they are a common reason for errors.
Talk soon,
Dave “The Relationship Whisperer” Naves
Hi Dave,
all but great work done so far, congrats…
I´m duplicating your coop door project with two mods, the switches and the way that the door is opened and closed, and for that I´m having a problem…
in my system the 24v (30rpm) motor is connected to the sliding door by a axle like a screw so as it turns it opens or closes very slowly (avoiding hurting the ladies… just in case and to avoid the lock system that you have, witch is great by the way) but as it closes/opens very slowly the motor doesn´t stop at the limit switch (my variation is a magnetic swicth(x2) connected to a relay(x2) when the top or bottom position is reached on the door and the both relays are connected to the same input pins of the mega as yours.
the only problem is that the motor doesn´t stop when the switch indicate the presence of the door, maybe because the door movement is too slow..I´m totally new to arduino and code,
So please can you help me out…
Thanks and best regards… and keep up the excellent job.
p.s Sorry for my poor English
Gil, Luxembourg
Great question, Gil…
(and your English is perfect) =)
I’m not 100%, but I’d venture to guess it’s not debouncing properly. (meaning the switch is reading on/off/on/off very quickly and essentially bypassing a constant reading) I had exactly the same problem and it was driving me nuts! Take a careful look at my code within the debouncing section:
// bottom switch (for example- lines 56 – 60)
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
and lines 122 – 138
//debounce bottom reed switch
void debounceBottomReedSwitch() {
//debounce bottom reed switch
bottomSwitchPinVal = digitalRead(bottomSwitchPin); // read input value and store it in val
delay(10);
bottomSwitchPinVal2 = digitalRead(bottomSwitchPin); // read input value again to check or bounce
if (bottomSwitchPinVal == bottomSwitchPinVal2) { // make sure we got 2 consistant readings!
if (bottomSwitchPinVal != bottomSwitchState) { // the switch state has changed!
bottomSwitchState = bottomSwitchPinVal;
}
Serial.print (” Bottom Switch Value: “); // display “Bottom Switch Value:”
Serial.println(digitalRead(bottomSwitchPin)); // display current value of bottom switch;
}
}
also read this, to get a better understanding of the importance of debouncing: http://arduino.cc/en/Tutorial/Debounce
Hope that helps,
//D
I am try to follow and duplicate your process on the Coop Door. You list ZITRADES New IIC/I2C/TWI 1602 Serial LCD Module Display for the LCD. I ordered this unit and got an I2C device that appears to need the SDA and SCL lines of the Ardunio Mega board. I am trying very hard to understand how to use this device as the ‘LCD” library appears to need a discreet connected device. Any help you can give I would much appreciate.
I love your project and your efforts. I will provide information on my project as it gels more. Currently I am just building the coop for my Son and his Wife. I have the coop door control on the burner as well. Put I must have a coop first.
Hi Mark,
Thanks for the comment. Not sure exactly what part was sent to you without an image, but as my code shows, all you would need is to make the following connections:
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
Let me know if the labeling is different on your LDC display.
Cheers,
//D
He got a LCD I2C unit, not just an LCD. I haven’t researched them much, but you send the screen info to it via I2C. You don’t use all the pins, just +,-, SDA,SCL. Ther must be a library available for these beasts, I just haven’t looked for it. It is basically a serial in / parallel out (to the LCD unit). Nice for low pin count, probably not terribly hard to use if the I2C comm is handled for you in the lib.
Mark: search for I2C 1602 LCD Library, and I’ll bet you get something…well, at least I did!
Dave
Great site, my son and i are building an automatic chicken door for a science project. This site will be a great Guide!
matt
Thanks much Matt!
I’m *just* getting my 13 year old into Arduino projects, including more coop additions. (Arduino was one of his xmas presents this year) The Arduino actually inspired me to write an article to help put kids’ techno-obsessions to good use (instead of gaming): http://davenaves.com/blog/arduino/tired-of-fighting-your-kids-to-stay-off-computer-games-arduino-may-be-the-answer/ =)
Please feel free to ping me via comments if you have questions or comments. And keep me posted with your project… I’m big on sharing! =)
Cheers!