Fleming Family Farm Chicken Coop Automatic Door Opener Arduino Code
4 comments
Here is the final working Arduino code for the automatic chicken coop door opener. It now resets the clock every morning at 12:01AM from an NTP server, provides a web page with many statistics, sets the open and close time automatically by season (you set the months), opens based on time and the light level, and provides the temperature and humidity. The LCD shows the IP address if you have DHCP so you can update the bookmark for the web page.
The button is ornamental now since I removed the servo latch.
You can copy and paste the following code into the Arduino IDE and change to suit your needs. Ensure you make the arduino_secrets.h file (ctrl shift N).
/*
Fleming Family Farm Chicken Coop Automatic Door Opener
Based on Time And Light Level
At 7am if the light level is under 600 the door opens and
at 8pm if the light level is above 600 the door closes
Parts Required:
Uno R4 WiFi
Shensor Shield
Photoresistor with resistors to set value correct to your board
DHT-11 Temperature and Hummidity sensor with resistor and capacitor
20x4 LCD I2C Display
Stepper Motor (I used Stepperonliine #23HS30-2804S)
Motor mounting bracket
TB6600 Stepper Motor Driver
Jumper Wires
Fine gauge steeel wire about 3ft/1m long
Pulley to fit motor shaft (To hold the wire that opens and closes the door)
2x4 to mount on and to install a bushing with washer on the end of for the wire to run over
Wood sheet for door
Hinges, Screws, Eye bolt, Wire clamp, 12v power supply
The LCD displays the current IP address in case you have DHCP so you can update the bookmark
for the webpage which displays more info than the LCD can.
The time is set on startup from an NTP server, then every night at 12:01 AM it resets the time from NTP
(I found that the RTC ran 20 minutes fast over a week with no battery attached to the R4 WiFi)
My door is hinged on top and I have a large magnet installed on the edge that locks the door to
a metal piece attached to the coop wall. The wire winds onto the shaft of the motor and the door
is pulled open off the magnet. At night the motor unspools the wire and the door closes shut thanks
to the weight of and the magnet.
You need to set all of these suit:
DOOR_OPEN time
DOOR_CLOSE time
The door opening and closing time is autoset seasonally in the very bottom code
timeZoneOffsetHours
stepper.moveTo(-XXXXX)
light <=/>= 600 - varies depending on your photoresistor
Make new file arduino_secrets.h and paste this and fill in your info
#define SECRET_SSID "YOUR SSID"
#define SECRET_PASS "YOUR PASSWORD"
Make sure you have installed all the libraries below
*/
//Libraries included
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include "AccelStepper.h"
#include "RTC.h"
#include <NTPClient.h>
#include <WiFiS3.h>
#include <WiFiUdp.h>
#include "arduino_secrets.h"
//Definitions
#define DHT11_PIN 7
#define DHTTYPE DHT11
#define motorInterfaceType 1
#define dirPin 4
#define stepPin 3
#define enPin 2
//Pins used: 2,3,4,7,A0,SDA/SCL
//Constants/Variables
const int pResistor = A0; // Photoresistor at Arduino analog pin A0
int DOOR_OPEN_HH = 7; // Is "int" so it can be changed seasonally
const int DOOR_OPEN_MM = 00; // Is "const" since minutes never change
int DOOR_CLOSE_HH = 20;
const int DOOR_CLOSE_MM = 00;
const int stepsPerRevolution = 200;
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
//Object creation
DHT DHT11_Sensor(DHT11_PIN, DHTTYPE);
LiquidCrystal_I2C MyLCD(0x27, 20, 4); // Creates I2C LCD Object With (Address=0x27, Cols=20, Rows=4)
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin, enPin);
WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP
NTPClient timeClient(Udp);
WiFiServer server(80);
//Variables
int light; // Store value from photoresistor (0-1023)
int door_state; // Door open or closed
float DHT11_TempF; //Declaration needed to display on webpage
float DHT11_Humidity; //Same as above
int wifiStatus = WL_IDLE_STATUS;
void connectToWiFi(){
wifiStatus = WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network.
delay(5000); // wait 5 seconds for connection:
}
void setup() {
// Object initiation
Serial.begin(9600);
connectToWiFi();
RTC.begin();
server.begin();
timeClient.begin();
timeClient.update();
DHT11_Sensor.begin();
MyLCD.init();
// Set stepper motor speed
stepper.setMaxSpeed(3000);
stepper.setAcceleration(500);
// Declare pins as output:
pinMode(stepPin, OUTPUT); // motor driver
pinMode(dirPin, OUTPUT); // motor driver
pinMode(enPin, OUTPUT); // motor driver
pinMode(pResistor, INPUT); // Set pResistor - A0 pin as an input
// Get the current date and time from an NTP server
auto timeZoneOffsetHours = -7;
auto unixTime = timeClient.getEpochTime() + (timeZoneOffsetHours * 3600);
RTCTime timeToSet = RTCTime(unixTime);
RTC.setTime(timeToSet);
}
void loop() {
RTCTime currentTime;
RTC.getTime(currentTime);
light = analogRead(pResistor);
//Checks NTP Server time and sets board to correct time every night at 12:01 AM
if (currentTime.getHour() == 0 &&
currentTime.getMinutes() == 1) {
// Get the current date and time from an NTP server
auto timeZoneOffsetHours = -7;
auto unixTime = timeClient.getEpochTime() + (timeZoneOffsetHours * 3600);
RTCTime timeToSet = RTCTime(unixTime);
RTC.setTime(timeToSet);
}
//Temp & Humidity section
float DHT11_Humidity = DHT11_Sensor.readHumidity();
float DHT11_TempF = DHT11_Sensor.readTemperature(true); // Read Temperature(°F)
float hif = DHT11_Sensor.computeHeatIndex(DHT11_TempF, DHT11_Humidity); // Compute heat index in Fahrenheit
// Webpage Server Section
WiFiClient client = server.available(); // listen for incoming clients
if (client) { // if you get a client,
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println();
client.print("<div style=\"font-size:4em; text-align: center\">Fleming Family Farm Chicken Coop");
client.println("<br />");
client.print(Month2int(currentTime.getMonth()));
client.print('/');
client.print(currentTime.getDayOfMonth());
client.print('/');
client.print(currentTime.getYear());
client.print(" ");
client.print(currentTime.getHour());
client.print(':');
client.print(currentTime.getMinutes());
client.println("<br />");
client.print("THE DOOR OPENING TIME IS: ");
client.print(DOOR_OPEN_HH);
client.print(':');
client.print(DOOR_OPEN_MM);
client.println("<br />");
client.print("THE DOOR CLOSING TIME IS: ");
client.print(DOOR_CLOSE_HH);
client.print(':');
client.print(DOOR_CLOSE_MM);
client.println("<br />");
client.println("<br />");
// output the state of the door
if (door_state == 0) {
client.print("THE DOOR IS CLOSED");
}
else if (door_state == 1) {
client.print("THE DOOR IS OPEN");
}
client.println("<br />");
client.println("<br />");
client.print("The Temperature is: ");
client.print(DHT11_TempF);
client.print("°F");
client.println("<br />");
client.print("The Humidity is: ");
client.print(DHT11_Humidity);
client.print(" %");
client.println("<br />");
client.print("The Heat Index is: ");
client.print(hif);
client.print("°F");
client.println("<br />");
client.print("The Light Level is: ");
client.print(light);
client.print(" (0 = Light to 1023 = Dark)");
client.println("<br />");
IPAddress ip = WiFi.localIP();
client.print("IP Address: ");
client.println(ip);
client.println("</div></html>");
break;
} else { // if you got a newline, then clear currentLine:
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// close the connection:
client.stop();
}
//COOP DOOR OPENING SECTION
// The door opens at the DOOR_OPEN_HR and MM when the light is brighter than 600 reading and not closing time
if (currentTime.getHour() >= DOOR_OPEN_HH &&
currentTime.getMinutes() >= DOOR_OPEN_MM &&
currentTime.getHour() != DOOR_CLOSE_HH && //comment for testing <---------------
stepper.currentPosition() != -51000 &&
light <= 600) {
//This opens the door and holds it open until close time
digitalWrite(dirPin, LOW); // Sets motor direction
stepper.moveTo(-51000); // Set the target position = 8 rotations of shaft - Final position for open door <---------------
//stepper.moveTo(-12000); // Test - comment for normal operation <---------------
stepper.runToPosition(); // Run to target position with set speed and acceleration/deceleration:
door_state = 1; //Sets door_state to 1 which = open
}
// COOP DOOR CLOSING SECTION
// the door closes when the time reaches the DOOR_CLOSE_HR and MM and the light is above the 600 reading
if (currentTime.getHour() >= DOOR_CLOSE_HH && //<---------------
currentTime.getMinutes() >= DOOR_CLOSE_MM && //<---------------
stepper.currentPosition() != 0 &&
light >= 600) {
digitalWrite(dirPin, HIGH); // Sets motor direction
stepper.moveTo(0); // Set the target position:
stepper.runToPosition(); // Run to target position with set speed and acceleration/deceleration:
door_state = 0; // Sets door_state to 0 which = closed
}
// LCD DISPLAY SECTION
MyLCD.backlight();
MyLCD.setCursor(0, 0);
MyLCD.print(Month2int(currentTime.getMonth()));
MyLCD.print('/');
MyLCD.print(currentTime.getDayOfMonth());
MyLCD.print('/');
MyLCD.print(currentTime.getYear());
MyLCD.print(" ");
MyLCD.print(currentTime.getHour());
MyLCD.print(':');
MyLCD.print(currentTime.getMinutes());
MyLCD.print(':');
MyLCD.println(currentTime.getSeconds());
MyLCD.print(" ");
MyLCD.setCursor(0, 1);
MyLCD.print(DHT11_TempF);
MyLCD.print(" °F ");
MyLCD.print(DHT11_Humidity);
MyLCD.print(" %");
MyLCD.setCursor(0, 2);
MyLCD.print("Light ");
MyLCD.print(light);
MyLCD.print(" (0-1023)");
IPAddress ip = WiFi.localIP();
if (door_state == 0) {
MyLCD.setCursor(0, 3);
MyLCD.print("CLOSED -");
MyLCD.print(ip);
}
if (door_state == 1) {
MyLCD.setCursor(0, 3);
MyLCD.print("OPEN - ");
MyLCD.print(ip);
}
// Automatically set the door open and close time based on the month of the year
// April 1 to September 30 the door opens at 7am and closes after 8pm based on light level
// October 1 to March 31 the door opens at 8am and closes after 5pm based on light level
if (currentTime.getDayOfMonth(), DEC >= 4 &&
currentTime.getDayOfMonth(), DEC < 10){
int DOOR_OPEN_HH = 7;
}
else if (currentTime.getDayOfMonth() < 4 &&
currentTime.getDayOfMonth() >= 10) {
int DOOR_OPEN_HH = 8;
}
if (currentTime.getDayOfMonth(), DEC >= 4 &&
currentTime.getDayOfMonth(), DEC < 10){
int DOOR_CLOSE_HH = 20;
}
else if (currentTime.getDayOfMonth() < 4 &&
currentTime.getDayOfMonth() >= 10) {
int DOOR_CLOSE_HH = 17;
}
}
^Affiliate/Referral Link^
Fleming Family Farm
FLEMING FAMILY FARM, LLC
Sustainable & Organic Methods | Heirloom Produce
All images are original works of Fleming Family Farm unless otherwise notated and credited.
If you find this post useful or entertaining, your support is greatly appreciated by upvoting, following, and sharing!
You can Also Find Me On:
Donations or Tips
Zap Me ⚡️ LBTC
Waivio AI Assistant
How can I help you today?
Comments