hobooeconomicus
Published © GPL3+

Automated Door for Chicken Coop

Hatch automatically opens and closes depending on light and time. After 2 years in use also some ideas what I would do differently.

AdvancedFull instructions provided575
Automated Door for Chicken Coop

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Real Time Clock (RTC)
Real Time Clock (RTC)
×1
Photo resistor
Photo resistor
×1
Relay (generic)
×2
Infrared Receiver, Remote Control
Infrared Receiver, Remote Control
×1
Breadboard (generic)
Breadboard (generic)
×1
Resistor 10k ohm
Resistor 10k ohm
×2
RGB LCD Shield Kit, 16x2 Character Display
RGB LCD Shield Kit, 16x2 Character Display
×1
DC motor (generic)
I used an salvaged wiper motor from an Audi here
×1
Limit Switch, 5 A
Limit Switch, 5 A
×2

Story

Read more

Schematics

Schematic

Code

sfr_ChickenManII.ino

Arduino
Sorry, comments are in German
/* Steuerung fr motorisierte Hhnerklappe ber Lichtsensor
 *  Material:
 *  Arduino Uno mit Protyping Board
 *  Lichtsensor
 *  IR Receiver
 *  Fernbedienung
 *  2 Relais
 *  16x2 LCD
 *  2 Endlagenschalter
 *  Real Time Clock
 *  Scheibewischermotor mit montierter Rolle
 *  Zustzliches 12V Netzteil
 */


/***************************
 * 
 *  ANLEITUNG FR DIE HHNERKLAPPE
 * 
 *  Im AUTO Modus ffnet die Klappe sich morgens um 9.00 und fhrt Abends bei Dunkelheit herunter.
 *  Im manuellen Modus kann die Klappe mit den Tasten <<< und >>> schrittweise bewegt werden, und bleibt in der Position.
 * 
 *  >|  - Schaltet um zwischen AUTO Modus und manuellem Modus
 *  <<< - Fhrt im manuellen Modus die Klappe einen Schritt herunter  
 *  >>> - Fhrt im manuellen Modus die Klappe einen Schritt hoch
 *  +   - Schaltet die Hintergrundbeleuchtung ein
 *  -   - Schaltet die Hintergrundbeleuchtung aus
 *   
 *  Achtung: Beim Umschalten von manuellem in AUTO-Modus muss die Klappe zuvor wieder in die richtige Position gebracht werden (tagsber auf, nachts unten). 
 *  
 */



// Klappe & Motor

int statusKlappe = 2;   // 1= down, 2 = up, d.h. der Initialstatus der Klappe ist oben, 
                        // wenn das Gert einschaltet. Klappe sollte oben sein, oder 
                        // manuell da hin gefahren werden
#define CW 8            // CW auf LOW fhrt die Klappe runter
#define CCW 9           // CCW auf LOW fhrt die Klappe hoch
#define lift 4000        // Manuelle Hebezeit in millisekunden (War mal auf kleine 500er 
                         // Schritte eingestellt, aber mit den Endlagenschaltern ist das nicht mehr ntig
#define liftUp 4000     // Automatische Hebezeit
#define liftDown 3000   // Automatische Senkzeit


#define endDownPin 6
#define endUpPin 7
unsigned long motorCounter = millis();

// COM an 5V, NC an PIN & GND via 10KOhm = HIGH wenn Taster nicht gedrckt, LOW wenn gedrckt
// Zum Simulieren des nicht gedrckten Tasters drhte Kurzschlieen



// Buttons & Modes

int modeAuto = 1;     // 0=Auto, 1= Manual
int button = 0;       // Status der IR RC Knpfe
#define threshold 35  // Schwellenwert fr den Auto-Mode wird festgelegt.
#define unlockTime 8    // Die Automatik ffnet die Klappe nur, wenn Uhrzeit erreich ist

// Light Sensor

int sensorPin = A0;
int sensorValue = 0;
int sensorAvg1;
int sensorAvg2;
int sensorAvg3;
int sensorAvg;
unsigned long counterStart = millis();
int pass = 1;

// Remote

#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

// Display
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LCD.h>
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);

// Clock
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};



char buffer[30];

/*---------------------------------------------------------------------------------------------------------*/
 
void setup() {

// Only for Testing: Remove for Production
// Serial.begin(9600);


// Display initial beschreiben

  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("L: ");
  lcd.setCursor(0,1);
  lcd.print("M:");
  lcd.setCursor(2,1);
  lcd.print("Mn");
  lcd.setCursor(6,1);
  lcd.print("D:");
  lcd.setCursor(8,1);
  lcd.print ("Mn");  

  // Remote einschalten
 
  irrecv.enableIRIn(); 

  // Motor und Endlagen PINs zuweisen

  pinMode(CW, OUTPUT); //Set CW as an output//
  pinMode(CCW, OUTPUT); //Set CCW as an output// 
 
  digitalWrite(CW, HIGH); //Motor stops// 
  digitalWrite(CCW, HIGH); //Motor stops// 
  
  pinMode(endDownPin, INPUT); // Endlagenschalter fr unten
  pinMode(endUpPin, INPUT); // Endlagenschalterfr oben
  

// Initiate RTC

 if (! rtc.begin()) {
     lcd.setCursor(0,1);
    lcd.print("Couldn't find RTC");
    while (1);
  }


  if (rtc.lostPower()) {
    lcd.setCursor(0,1);
    lcd.print("RTC lost power!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
  //   rtc.adjust(DateTime(2020, 8, 1, 14, 30, 0));
  }

  // Uhr stellen
  // rtc.adjust(DateTime(2020, 4, 20, 17, 18, 0));
  // Uhr beim kompilieren stellen
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  
  DateTime now = rtc.now();

}

/* --------------------------------------------------------------------------------------*/
          
void loop() {

// Lesen des Lichtsensors und schreiben des Ergebnisses

sensorValue = analogRead(sensorPin);
lcd.setCursor(2,0);
sprintf(buffer,"%04d", sensorValue);
lcd.print(buffer);

// Display Clock 

  DateTime now = rtc.now();

  lcd.setCursor(11,12);
  sprintf(buffer,"%02d",now.hour());
  lcd.print(buffer);
  lcd.print(":");
  sprintf(buffer,"%02d",now.minute());
  lcd.print(buffer);




// Lesen und bersetzen der IR Fernbedienung

  if (irrecv.decode(&results))          //Wenn ein IR-Signal erkannt wurde,
  {
      if (results.value == 16720605)  {               // Wenn der Schalter <<< gedrckt wurde
        button = 1;
        if (modeAuto == 1) {                           // uns der Modus "manuell" ist         
          motorCounter = millis();                     // Motorzhler auf jetzt.
          
          while ((millis()-motorCounter < lift) && (digitalRead(endDownPin) == HIGH)){  // Solange die Zeit "lift" nicht erreicht                                                                          
            digitalWrite(CW,LOW);                                                   // und der Endlagenschalter nicht gedrckt ist.
          }                                                                         // fhrt die Klappe runter
          digitalWrite(CW, HIGH);                                                   // und schaltet wieder ab.  
          
        }            
      }
      else if (results.value == 16712445)  {            // Wenn der Schalter >>> gedrckt wurde
        button = 2;
        // statusKlappe=0;
        if (modeAuto == 1) {                            // uns der Modus "manuell" ist
          motorCounter = millis();                                      
          while ((millis()-motorCounter < lift) && (digitalRead(endUpPin) == HIGH )){                 
            digitalWrite(CCW,LOW);                         
          }                                           
          digitalWrite(CCW, HIGH);                       
        }    
      }
      else if (results.value == 16761405)  {            // Wenn der "Modus" Knopf >|| gedrckt wurde schalte den Modus um
        button = 3;
        // statusKlappe=0;
        if (modeAuto == 0) {
          modeAuto= 1;
          lcd.setCursor(2,1);
          lcd.print("Mn  ");
        }
        else if (modeAuto == 1) {
          modeAuto=0;
          lcd.setCursor(2,1);
          lcd.print("Au  ");
          if (now.hour() < unlockTime) { // Wenn die unlockTime nicht erreicht ist, wird ein Sternchen angezeigt
            lcd.setCursor(4,1);            
            lcd.print ("*");  
          }
          if (statusKlappe == 1) {
            lcd.setCursor(8,1);
            lcd.print ("Dn");  
          }
          else if (statusKlappe == 2) {
            lcd.setCursor(8,1);
            lcd.print ("Up  ");  
          }
        }  
      }
      else if (results.value == 16769055)  {            // Knopf - schaltet Backlight ab
        button = 4;
        lcd.noBacklight();
      }
      else if (results.value == 16754775)  {            // Knopf + schaltet Backlight an
        button = 5;
        lcd.backlight();
      }
      else {
        button =0;
      }

    irrecv.resume();
  }
  else
     {
      button =0;
     }



// Drei Messdurchgnge werden durchgefhrt

  if (millis() - counterStart >= 3000) {
    
       counterStart = millis();
       lcd.setCursor(12,0);
       lcd.print("P:");
       lcd.print (pass);
 //      sensorAvg[pass] = sensorValue; // Sensorwert wird in Array geschrieben
      if (pass == 1) {
        sensorAvg1 = sensorValue;
      }
      else if (pass == 2) {
        sensorAvg2 = sensorValue;
      }
      else if (pass == 3) {
        sensorAvg3 = sensorValue;
      }

       // Hochzhlen bis 3 


       
       if (pass < 3) { 
        pass++;
       }

      // Beim dritten Durchgang wird der Klappenstatus gesetzt.
       
       else {

        sensorAvg = (sensorAvg1 + sensorAvg2 + sensorAvg3)/3; 
        lcd.setCursor(7,0);
        sprintf(buffer,"%04d", sensorAvg);
        lcd.print(buffer);

// Wenn es dunkel ist und die Klappe oben, dann fhrt sie runter

        if ((modeAuto == 0) && (sensorAvg < threshold) && (statusKlappe == 2)) { 
          statusKlappe=1;   
          
          motorCounter = millis();                                                  // Motorzhler auf jetzt.
          while ((millis()- motorCounter < liftDown) && (digitalRead(endDownPin) == HIGH )){  // Solange die Zeit "lift" nicht erreicht  
            digitalWrite(CW,LOW);                 
          } 
          digitalWrite(CW, HIGH);                     // und schaltet wieder ab        
        }

// Wenn es vor Unlocktime ist und die Klappe oben, dann fhrt sie runter

        else if ((modeAuto == 0) && (now.hour() < unlockTime) && (statusKlappe == 2) ) { 
          statusKlappe=1;   
          
          motorCounter = millis();                                                      // Motorzhler auf jetzt.
          while ((millis()-motorCounter < liftDown) && (digitalRead(endDownPin) == HIGH )){  // Solange die Zeit "lift" nicht erreicht           
            digitalWrite(CW,LOW);                         
          }
          digitalWrite(CW, HIGH);                            
        }

// Wenn es hell ist und die Klappen unten und die Unlcktime erreicht, fhrt sie hoch
        
        else if ((modeAuto == 0) && (sensorAvg >= threshold) && (statusKlappe == 1) && (now.hour() >= unlockTime)) {
          statusKlappe=2;
          motorCounter = millis();                                                      // Motorzhler auf jetzt.
          while ((millis()-motorCounter < liftUp) && (digitalRead(endUpPin) == HIGH )){  // Solange die Zeit "lift" nicht erreicht             
            digitalWrite(CCW,LOW);                        // Relais schaltet 
          }
          digitalWrite(CCW, HIGH);                      // und schaltet wieder ab          
        }

        pass =1;
       }
  }


// Status korrekt schreiben

if (modeAuto == 1) {
  lcd.setCursor(8,1);
  lcd.print ("Mn");  
}
else if (statusKlappe == 1) {
  lcd.setCursor(8,1);
  lcd.print ("Dn");  
}
else if (statusKlappe == 2) {
  lcd.setCursor(8,1);
  lcd.print ("Up");  
}

}

Credits

hobooeconomicus

hobooeconomicus

1 project • 0 followers

Comments