Chicken Coop controller based on Arduino.

Discussion in 'Coop & Run - Design, Construction, & Maintenance' started by victorpv, Jan 19, 2015.

  1. victorpv

    victorpv New Egg

    4
    0
    7
    Jan 19, 2015
    Hi all,

    This is my first post at the forum, so I'll intruduce myself first.

    My name is Victor, I live near Austin, TX, and have a few hens since around the summer.
    One of them was an adult and was laying almost 1 egg a day all summer long.
    The other 2 were small pullets that are now young adults.

    I am building a chicken coop controller based on Arduino. I have seen some of the designs in instructables and other places, but decided to build my own for a couple of reasons.

    I will share my design and script so anyone else can add to it, improve it, or build it for personal use.

    These are the functions I am incorporating to it:

    -Low power. Can run on solar panels with a battery, or AC if available.
    -LED Lighting. Controls a high power LED to provide enough hours of light during the winter.
    -It does not require to know what time is going to be day or night or what not. It measures the available light with a light sensor, and calculates when should it turn on the artificial lights.
    -Coop temperature sensor. If AC is availalble, it can control a heating lamp when the temperature reaches a minimum set level. The temperature sensor is used to control the AC lamp duty cycle to keep the hen house warm enough but not too hot. I am thinking on adding a second sensor for Safeguard. With an additional sensor outside we can compare and make sure a failure on a component doesn't turn the hen house into a sauna.
    -Door Control. At the moment not implemented because I dont need it, but I can implement it. It would again depend on light levels, when is dark enought that the hens should be sleeping, it closes the door. When it is daylight, or earlier if we want, it opens the door.
    -Wifi connection with a super cheap ESP-8266 module. It can upload daily temperatures or whatever other statistic. Alse serves a webpage to monitor the hen house status (temperatures, door close/open, lights running, heat lamp running, etc), so I can monitor my chickens welfare from the couch.
    -Probably add manual control of the door, the light and the heater from the webpage.

    So far I have everything setup except for the door control and the wifi part, because I am waiting on the ESP8266 modules to arrive so I can test them.

    I have built the first prototype on breadboard and have it running since a couple of days ago, and seems to run fairly good. I will see if the hens start laying or not, and may have to increase the light levels.
    Right now I am using a 10W led but running it only at about 1.5W. I am using a very simple constant current single FET driver, support PWM (dimming), I could change it to use an specific led driving IC, but I dont see the need as of right now.
    That still should be plenty of light for my small 3 hens coop.

    I have not had time to connect the heating lamp, but I plan to do so before the next freeze.

    I plan on building a custom shield to control and connect it all, except for the heating control. As that would control an AC heating lamp, it needs AC and I dont want to put that in the same board, so I am keeping that separate. Besides I have a bunch of AC control Triac boards that I built for my Christmas lights control. The arduino and the sketch can also control any of the multiple 5V relay board available on ebay and everywhere else.

    Well, if anyone thinks I am missing any feature or has any other comment, please go ahead.
    I will post my sketch and the schematic later. Both are still on development.
     
  2. 21hens-incharge

    21hens-incharge Chicken Obsessed

    5,604
    5,189
    421
    Mar 9, 2014
    Northern Colorado
    I do not know much about the coop controllers but I would like to say [​IMG]. You will find a lot of chicken folk with a lot of great information here.
    One thing I am certain you will hear is that you do not need a heat lamp. It is a huge fire hazard with adult birds and not a benefit for them.
    We get down right frigid here at sometimes a week or two not getting above 0 even during the day. I have only supplied heat when it was -16 and I had molting ie: naked birds. When I did add heat it was in the form of a radiant heater like this one. It has a tip over shut off and does not get hot enough to start a fire.
    http://www.homedepot.com/s/sealed%20oil%20heater?NCNI-5

    -It does not require to know what time is going to be day or night or what not. It measures the available light with a light sensor, and calculates when should it turn on the artificial lights.
    Does that mean if it is night it would turn on the light? That would make my hens totally insane.

    Just my thoughts.

    Babs
     
  3. victorpv

    victorpv New Egg

    4
    0
    7
    Jan 19, 2015
    Thanks for the advice on the heating lamp. I had been thinking a lot on it, not sure if they really needed it or not.
    We have a small coop. It has a door, but we never close it, so I was a bit concerned on cold wind freezing them up. It doesn't get any lower than 20F over here though (central Texas). Do you think with that temp, even if the chicken house has the door open they will be ok?

    About the light, the sensor measures when it gets really dark. I did some measuring before to set the level when the hens go inside the house to sleep. At that point, it start counting minutes until a certain set time (at the moment I have set it to 8 hours), and at that point, it starts turning the light on progressively over the course of 5 minutes or so. Then the light stays on until a certain level of natural light is detected outside, and at that level it turns off.
    So as I have it now, the hens should get 8 hours of complete dark to sleep.
    I am considering changing that to allow more sleep hours and reduce it progressively.
    As you see I don't need to worry about time changes, daylight saving and all that. Instead I make sure it gets dark, and count the number of hours until the lights will come on.
     
  4. blucoondawg

    blucoondawg Chillin' With My Peeps

    1,650
    188
    186
    Jan 27, 2013
    Northern Wisconsin
    I am not against using heat lamps when I feel they are necessary but I am in the minority in that respect on this site. That said I will also say that you will never need added heat in Texas. 20 degrees is nothing for chickens though you may need to somehow heat the water to keep from freezing. I don't worry about any heat until it gets severely cold, we get extended periods of down to -30 or colder with high temps not reaching above 0 for days at time, in these periods I will start to add some heat, but not enough to really make it warm in the coop just enough to make it more tolerable.

    I'd you do use heat lamps do so safely, use as low a wattage as possible to get the desired heat and keep it away from combustibles, fasten it securely don't use the clamp on fixture that can be knocked down, and add permanent wiring to the coop rather than stringing light weight extension cords around. You will also want to keep the bulbs free of dust, feathers, or anything else that could catch fire. If you do it right adding heat isn't that dangerous.
     
  5. victorpv

    victorpv New Egg

    4
    0
    7
    Jan 19, 2015
    This is the sketch I am using right now. It is still a Beta version, I have had it running for 3 days now to make sure it all works as it should with the light detection and artificial light control, and seems to be good.
    I need to add the Wifi section so it can provide a webserver to monitor the coop.

    /* ********
    THE HVAC CONTROL IS DISABLED AT THE MOMENT.

    can use an NTC: http://playground.arduino.cc/ComponentLib/Thermistor2
    */
    #include <avr/eeprom.h>

    #define LightSensorPin A0 // Radioshack light sensor pin. With 100 ohm resistor to ground reads almost 0 with no light.
    #define TempSensorPin A1 // LM35
    #define TempBiasPin A2 // Measures the voltage at the diode (or ground reference for LM35)
    #define LedControlPin 3 // Led PWM lighting control pin.
    #define LightControlPin 13 // Light triac control pin.
    #define HeaterControlPin 12 // Heater triac control pin.
    #define MinDarkMinutes 540 //540. Desired amount of dark sleepin time in minutes. 9 hours * 60 minutes.
    #define TotalDayMinutes 1440 // 1440. Maximum number of minutes a Cycle can run if day and night are not detected, 1440 min = 24 hours.
    #define day HIGH
    #define night LOW
    #define NightTshld 10 // light level to decide is night
    #define DayTshld 50 // light level to decide is day
    #define ON LOW // The triac circuit uses active low signals, GND turns on, and +5V turns off.
    #define OFF HIGH

    #define ControlCharAddr 1 //eeprom address to save a control code, in case the power goes down and up again, it will know it was running before.
    #define ExtraSleepAddr 3 //eeprom address to save the number of days running down to the shortest sleep time
    #define InitialExtraSleep 40 // will be reduced by 1 each day until it reaches 0.
    // The light time will be incremented 2 minutes per day (sleep time decremented 2 minutes per day). So the first day it will be 540 + (40 * 2)
    #define EEControlChar 0xAA

    // definitions for temp calculations
    #define B 3975 // used in the seedstudio routine, should be remove or changed when using a different NTC. B value from datasheet
    #define Pad_resistor 10000 // the resistor used for the divider. Should measure it with multimeter.
    //

    int light_level = 0;
    int light_avg = 100; // We start on day mode, if it is dark already within 5 minutes the average should drop to almost 0.
    float temp_current = 25; // current value of the temperature. Don't need that much precision, so we may leave it with integers after all.
    float temp_avg = 25; // we start with 25C so it doesn't do anything crazy on startup.
    int minutes = 0;
    int seconds = 0;
    unsigned long last_millis = 0;
    unsigned long current_millis = 0;
    boolean CurrentMode = day; // We start in day mode (lights off)
    int current_led_value = 0; // Holds the PWM cycled applied to the LED Lighting pin
    int TotalDarkMinutes;
    uint8_t extra_time;
    void setup()
    {
    Serial.begin (9600);
    pinMode (LightSensorPin, INPUT);
    pinMode (LightControlPin, OUTPUT);
    pinMode (HeaterControlPin, OUTPUT);
    pinMode (LedControlPin, OUTPUT);
    // set the temp pin mode, and the heater control mode.
    // Test the light and heater for 1 second upon reboot.
    digitalWrite (LightControlPin, ON);
    digitalWrite (HeaterControlPin, ON);
    analogWrite (LedControlPin, 128);
    Serial.println ("Lights and heater on for five seconds.");
    Serial.print ("Total max lenght of day (Dark time + Natural or articifical light): ");
    Serial.println (TotalDayMinutes);
    Serial.print ("Night time light threshold: ");
    Serial.println (NightTshld);
    Serial.print ("Day time light threshold: ");
    Serial.println (DayTshld);
    delay (5000);
    // Start running with lights and heater off.
    digitalWrite (LightControlPin, OFF);
    digitalWrite (HeaterControlPin, OFF);
    digitalWrite (LedControlPin, LOW);
    Serial.println ("Lights and heater OFF. Initializing EEPROM");
    // Check if the EEPROM was already initialized. If not, do it now.
    while (!eeprom_is_ready());
    if (eeprom_read_word((uint16_t*)ControlCharAddr) != EEControlChar) {
    Serial.println ("Control Chars not found");
    // while (1){
    // }
    while (!eeprom_is_ready());
    eeprom_write_word((uint16_t*)ControlCharAddr, EEControlChar);
    while (!eeprom_is_ready());
    eeprom_write_byte((uint8_t*)ExtraSleepAddr, InitialExtraSleep);
    extra_time = InitialExtraSleep;
    TotalDarkMinutes = MinDarkMinutes + (InitialExtraSleep * 2);
    }
    else {
    Serial.println ("Control Chars found in EEprom, reading extra sleep time duration from there.");
    // while (1){
    // }
    while (!eeprom_is_ready());
    extra_time = eeprom_read_byte((uint8_t*)ExtraSleepAddr);
    TotalDarkMinutes = MinDarkMinutes + (extra_time * 2);
    }
    Serial.print ("Total Sleep Time today will be: ");
    Serial.print (TotalDarkMinutes);
    Serial.println (" minutes.");
    }
    /* The main loop will just count time, and if a certain period of time has passed, call the scheduler routine.
    It is probably fine to call the scheduler every minute.

    ******* During testing it is set to 1 second, remember to change that, and the duration of night and day.
    */
    void loop ()
    {
    /* light_level = analogRead(LightSensorPin);
    Serial.print ("Light reading : ");
    Serial.println (light_level);
    delay (1000);
    //light_avg = 50;
    if (light_level >= 100){
    CurrentMode == day;
    }
    */
    current_millis = millis ();
    unsigned int elapsed_seconds = (current_millis-last_millis)/1000;
    if ( elapsed_seconds >= 1){
    last_millis = current_millis;
    seconds = seconds + elapsed_seconds;
    if (seconds >= 60) {
    seconds = seconds - 60;
    minutes = minutes + 1;
    scheduler (); //Here runs every minute.
    }
    //here it runs every second, move it above to run every minute
    }
    }
    /* This is the routine that we will call every second, minute, hour or whatever time we decide (better every minute or so).
    It will run a few things in sequence, and then go back to the main loop
    USED VARIABLES: CurrentMode is checked to decide if we run the day time code or night time code
    */
    void scheduler (){
    Serial.print ("time running: ");
    Serial.print (minutes);
    Serial.print (":");
    Serial.print (seconds);
    if (CurrentMode == day){
    day_mode();
    }
    else {
    night_mode();
    }
    // *** HVAC is disabled at the moment.
    // hvac ();
    }
    // Check the temp and control heater. We will use a lm35
    /* commented out as at the moment using a resistor
    void hvac (){
    //read the temp and average it
    //if over a certan value turn the heater off
    // if under a certain value, turn the heater on.
    int temp_sensor = analogRead (TempSensorPin);
    int temp_bias = analogRead (TempBiasPin);
    temp_current = (temp_sensor - temp_bias) * 0.32226;
    temp_avg = (4 * temp_avg + temp_current) / 5;
    Serial.print( "Temperature: " );
    Serial.println( temp_current, DEC );
    if (temp_avg < 12){
    digitalWrite (HeaterControlPin,ON);
    }
    else if (temp_avg > 14){
    digitalWrite (HeaterControlPin,OFF);
    }
    }
    */
    /* Routine for reading temp with the seedstudio thing.
    No Inputs and no Outputs to the funtion.
    USED VARIABLES: temp_current and temp_average, and updates them.
    USED I/O: IN: TempSensorPin and TempBiasPin
    */
    void hvac (){
    //read the temp and average it
    //if over a certan value turn the heater off
    // if under a certain value, turn the heater on.
    int resistance=(int)(Pad_resistor*(1024.0f/float(analogRead(TempSensorPin))-1));
    // temp_current = (int)(1/(log(resistance/10000)/B+1/298.15)-273.15); // global variable
    temp_current = (1/(log(resistance/10000)/B+1/298.15)-273.15); // global variable
    temp_avg = (4 * temp_avg + temp_current) / 5; // global variable
    Serial.print( "Temperature: " );
    Serial.print( temp_current, 1 );
    Serial.write(186);
    Serial.println("C");
    if (temp_avg < 6){
    digitalWrite (HeaterControlPin,ON);
    }
    else if (temp_avg > 8){
    digitalWrite (HeaterControlPin,OFF);
    }
    }
    /* What we do if we are in day mode
    No Inputs and no Outputs to the funtion.
    USED VARIABLES: light_level and light_average, and updates them.
    CurrentMode will be set to night after 5 readings < NightTshld
    USED I/O: IN: LightSensorPin and TempBiasPin
    */
    void day_mode (){
    light_level = analogRead (LightSensorPin);
    light_avg = ((4 * light_avg + light_level)/5);
    // Averages the light reading with 5 total readings. That way if it becomes bright or dark for a moment for whatever reason, it will not affect anything
    Serial.print (" Day mode. Light reading : ");
    Serial.print (light_level);
    Serial.print (" Light avg : ");
    Serial.println (light_avg);
    // delay (1000);
    if (light_avg <= NightTshld){
    CurrentMode = night;
    // digitalWrite (LightControlPin, HIGH);
    minutes = 0; // Reset the minutes counter so we start counting the cycle once it gets dark.
    }
    }
    /* What we do if we are in Night mode
    First we read the light value and average it.
    We check the number of minutes ww have been running, if > TotalDayMinutes means we have been running a complete cycle (night and day) and we start a new 24 hours cycle going to sleep time.
    If we have been running for longer than sleep time but less than a full cycle, and have no daylight, we turn the lights one.
    If we have been running for longer than sleep time and we have day light, then turn off the lights and go to day mode.
    USED VARIABLES: light_level and light_average, and updates them.
    current_led_value get increased up to 255 if we need light, and saved to PWM pin 3.
    CurrentMode will be set to night after 5 readings < NightTshld
    USED I/O:
    IN: LightSensorPin
    OUT: LightControlPin, LedControlPin

    */
    void night_mode (){
    light_level = analogRead(LightSensorPin);
    light_avg = ((4 * light_avg + light_level)/5);
    // Averages the light reading with 5 total readings. That way if it becomes bright or dark for a moment for whatever reason, it will not affect anything
    Serial.print (" Night mode. Light reading : ");
    Serial.print (light_level);
    Serial.print (" Light avg : ");
    Serial.println (light_avg);
    Serial.print ("PWM Value : ");
    Serial.println (current_led_value);
    Serial.print ("Total Sleep Time today will be: ");
    Serial.print (TotalDarkMinutes);
    Serial.println (" minutes.");
    // delay (1000);
    if (minutes >= TotalDayMinutes){ // Check if something has gone wrong and we are still thinking it is night even after 24 hours.
    minutes = 0; //Restart the minutes counter to start a new sleep cycle for 8 hours, and turn off lights.
    current_led_value = 0;
    analogWrite (LedControlPin, 0);
    digitalWrite (LightControlPin, OFF);
    }
    else if (minutes >= TotalDarkMinutes) { // Check if we had enought hours of sleep (should be around 8)
    if (light_avg >= DayTshld){ // Check if there is enough ambient light to consider it day light, if so we turn off lights and change mode.
    current_led_value = 0;
    analogWrite (LedControlPin, 0);
    digitalWrite (LightControlPin, OFF);
    if (extra_time > 0) { // We still didn't reach the minimum, so substract 1, save the new value, and recalculate the Total Dark Time for the next period.
    extra_time = extra_time - 1;
    while (!eeprom_is_ready());
    eeprom_write_byte((uint8_t*)ExtraSleepAddr, extra_time);
    TotalDarkMinutes = MinDarkMinutes + (extra_time * 2);
    }
    CurrentMode = day; // if so, change to day light mode, and turn off electric lights
    }
    else { //it is not day light yet, so...
    if (current_led_value < 128) { //We increase the PWM cycle until half duty.
    current_led_value = (current_led_value * 2) + 1;
    if (current_led_value > 128) {
    current_led_value = 128;
    }
    analogWrite (LedControlPin, current_led_value);
    }
    digitalWrite (LightControlPin, ON); // also turn on the triac lights.
    }
    }
    }
     

BackYard Chickens is proudly sponsored by