Pololu Robotics & Electronics
My account Comments or questions? About Pololu Contact Ordering information Distributors

Chicken Coop



The overall project is Chicken Coop (where my chickens live). It started when my kids got to lazy to open the coop door in the morning and i did not want to do it either. The chickens spend their days in my yard doing whatever, and at the end of the day they instinctively go straight to their coop. It includes a Raspberry Pi, wifi, a 50W solar panel, solar charge controller, 2 each 12 ah AGM batteries, a handful of temperature sensors, a humidity sensor, a luminosity sensor, a couple motion sensors, a couple industrial panel leds, an led strip light, a linear actuator, and a linear actuator controller. The wifi allows it to keep proper time, serve web pages. and send emails. I am datalogging the sensors to keep an eye on the environment (like make sure their water never freezes. it got to -16 degrees F in the coop this last winter). It also lets me keep an eye on their behavior (when an egg has likely been laid or when a bird is broody). The coop opens in the morning just before the sun comes up and then closes shortly after the sun goes down. Code is written in Python, with sunrise and sunset calculated using PyEphem.It sends me an email when the door successfully opens and another when the door successfully closes.

What matters here is the linear actuator and controller. From Pololu I am using these items:
Concentric LACT12P-12V-20 Linear Actuator with Feedback: 12" Stroke, 12V, 0.5"/s (and the brackets).
Pololu Jrk 21v3 USB Motor Controller with Feedback

I thought that these would be overkill. I was correct, but am very happy I went overboard. Here are some specific features of the actuator and JRK that I am using:

  1. I use feedback to set the door at a specific location for both open and closed.
  2. I use the acceleration setting in the JRK to keep the peak current draw at a minimum, to be respectful of the batteries.
  3. I read the current (amps) from the JRK to determine when the door has stopped moving, and as a safety to see if something may be caught in the door.
  4. The JRK is connected to the Raspberry Pi via USB (USB commands were easy enough to do in Python, read/write).

Originally I had planned on a sliding door that went up and down in tracks. After extensive construction I realized that the actuator was too long (more than the 12" stroke) and I would only have about 4" of door opening when I wanted 8-12. So I redesigned as a flap door. It works kind of like a blast door. The actuator pushes a couple millimeters into the closed position and with that compression, the door is rock solid when closed.

It is a work in progress, of course, still have wiring to clean up, and will never be fully complete. I have attached a couple pictures.

Edits to Posts

Hello, Bennard.

Cool project; thanks for sharing. How did you test the current sensing to make sure that it would trigger if anything was caught in the door?




Since the door generally moves without any resistance, the actuator should always run at or below its rated no-load current (500 ma). I ran it back and forth a bunch and never saw it go over 532. The threshold is currently set at 550 ma. Any read above that means the actuator is under load, when it should not be. This sets a flag, tells the door to open immediately, keeps the door open for the rest of the day, and sends an email.

Codewise, when the door is opening or closing, it uses a loop to read the feedback and current. I made the assumption with this project that zero current indicates the set target operation is complete. With very low acceleration set in the JRK, it takes almost a second to register any current. So, after sending the set target command it has to first read ~some~ amount of current before it then reacts to reading a zero. Within this loop is when it also checks for over-current which would suggest it might be squishing something.

Along with the max acceleration, I also have the max current set, using the configuration utility. I do not want the actuator tearing the coop apart if something really goes wrong.

I am interested in seeing how it works in winter. If there is any effect from snow in the way of the door, any ice gumming up anything, or if freezing temperatures do anything in the actuator.

The reality with chickens is that they know where they sleep and are afraid of everything. They are always in the coop before the sun goes down. They are fast and the door moves very slow. Chickens are not going to get caught in the door. I am more concerned about friend’s dogs or even neighborhood kids that want to see “what will happen” when a linear actuator applies 100lbs to their forearm through a flap door. Besides, new chickens are $5 each.


The Concentric linear actuators have an IP63 rating, which only protects from water sprays at certain angles. So, splashing water could still enter the actuator (which sounds especially bad during freezing weather).

By the way, since you mentioned children might be around your project, please note that we do not recommend using our products where their failure could result in injury.



This is AWESOME. Thanks for posting on it. I

've been planning a similar project for a couple of days now for our Eglu coop to make sure the ladies stay warm through the winter. I just came across your post. It looks like you did a great job. I was just working on figuring out how to deal with motor driving from a Pi, and it looks like you already solved that. I’d also like to get an egg sensor ready. The chickens don’t lay much in the winter, but it would be kind of fun to have an “egg ready” email when they do.


Would you be willing to share any of your Python code or let me know if there’s any open source portions that I could use? I’d obviously respect any copyright and/or open-source licensing you use.



Follow up on the coop:

The whole thing has been running awesomely for the last few months. Door opens in the morning and closes at night. Never locked the birds out too early. The only problems have been from my lazy coding. Stuff like not catching exceptions so if a sensor doesn’t read then the program stops. Ive been fixing them as they happen. The environmental monitoring program is separate from the door control program so the door isnt affected by this.

We have had a few days/nights in the negatives. Down to -15F (yes, minus). Actuator keeps on going. I did have to adjust the current sensing to allow a little more current due to the extra cold. And i think snow piled up in front of the door once and it registered as a blockage. Not like it matters, my chickens hate walking in snow and wont come out when its colder than 30.

Overall, still very happy with the actuator and JRK control. It is working great!

(send me a PM and Ill share code.)


I already have an automated coop door (dusk/dawn sensor) but would be really interested in the other automation you added. I was considering adding the humidity and temp sensors to control vent fans. What did you use for the nest boxes?


Great project. I am also working on a Pi controlled linear actuator, but I’m having trouble with the code. It appears that I am using the same hardware and was hoping you would share your Python code. FYI, from what I can see I am not yet permitted to pm another user yet.


Hi Ben

I am also unable to DM you - I would really appreciate if you can share your python code that sends commands over usb, it will save me ton of time and testing. Thanks a lot!



I too would really appreciate seeing your Python code, but cannot yet PM you. Any chance you can PM me with the code? The part I’m most interested in is being able to monitor the amps being consumed and reacting to that. Great project btw. I love it. Regards, Al (Houston)



Sorry this took a while. While functional, I wrote it sloppily. I dont like some of the functions I used, like ord(). I had intended to clean it up before posting and this dragged out many months. This small python script that is attached can be used to open and close the JRK controlled linear actuator to presets at each end. In my case 0 is fully open (actuator short as possible) and 2650 is closed (where the actuator presses on the door a little bit).

This does not include any over-current sensing that would be used to check for a door blockage. The code running in the coop now does this over-current sensing to make sure it isnt squishing a critter. It will reopen the door if it shuts on something. When the door is opening/closing, I have it recording position and current (from the JRK) and voltage/current/power (from an INA219) every 0.01 seconds and it puts all that into openSQL. I then get a plot (matlibplot) so I can see how it is running. I attached this afternoon’s plot. I had it running off a 12v power supply with a 15 foot cheapo power cord so its showing around 9.7 volts (it has been raining and the solar ran out).

The other thing to note about the plot below is that it represents two each 10-second events that happen over 24-hours. The door opens once per day and closes once per day. The first half is the door closing (745pm). The second half is the door opening (530am). The x-axis is just readings at regular intervals during two teeny time slices from the 24-hours.


#!/usr/bin/env python

import sys
import time
from time import sleep
import serial

# this connects to USB port
ser = serial.Serial( "/dev/ttyACM0", 115200)
print("connected to: " + ser.portstr)

# some global settings and variables
doorSetOpen = 0 #
doorSetClose = 2650 # 2650 seems to make it just a little snug.
doorPosition = 0 # this is the feedback value
doorCMDSetTarget = "\xC0"
doorCMDSetStop = "\xFF"
doorCMDReadFeedback = "\xA5"
doorCMDReadCurrent = "\x8F"

doorArgue = sys.argv # returns: argument
print doorArgue

def jrkTarget (target):
    lowByte = (target & ord("\x1F")) | ord(doorCMDSetTarget)
    highByte = (target >> 5) & ord("\x7F")
    return(lowByte,highByte) # feedback

def checkDoorStatus ():
    ser.write(doorCMDReadFeedback) # feedback
    sleep (0.01)
    checkFeedback = (ord(ser.read()) | ord(ser.read())<<8)
    return checkFeedback

def setDoor (set):
    if set == 1:
        highByte, lowByte = jrkTarget(doorSetOpen)
        highByte, lowByte = jrkTarget(doorSetClose)
# Since the JRK is set at the bare minimum acceleration, need a little time for there to be some current.
# When current reads zero again, it is assumed to be stopped at the set position     
sleep (1.0)
    checkCurrent = 1
    while checkCurrent != 0:
        sleep (0.01)
        checkCurrent = ord(ser.read())
        print ("\r{} of 4095".format(checkDoorStatus())),
    ser.write(doorCMDSetStop) # stop actuator command
    print ("- Finished.") # sneak in a newline

def main():

    if len(doorArgue) <= 1:
            print ("Please include proper argument\nopen close quit")
        elif doorArgue[1] == 'close':
            setDoor(0) # 0 closed, 1 open
        elif doorArgue[1] == 'open':
            setDoor(1) # 0 closed, 1 open
        while 1:
            var = raw_input()
            if var == 'close':
                setDoor(0) # 0 closed, 1 open
            elif var == 'open':
                setDoor(1) # 0 closed, 1 open
            elif var == 'quit':