Thursday, December 8, 2016

Clockwork Coop Version 2: A Good Decision

Remember the decision to use two door switches on this post?  It turns out this was a good decision.  Things seemed to operate very well when everything was installed.  But I soon after I started using remote manual controls I got an error.  It seems the coupler holding the threaded rod onto the shaft of the stepper motor failed and the door fell into the closed position.  If I had used a single switch to detect the door state, I might not have noticed the error.  Instead, I went to investigate and quickly realized I needed an adhesive to secure the coupler to the stepper motor.  After a quick fix with some silicone caulk I was back in business.

Clockwork Coop Version 1 Mechanics Second Try

After several failures using DC motors, I wanted explore other options to open, close, and secure the door.  I decided to investigate a stepper motor and lead screw mechanism.  The door would open and close exactly as before, but the new setup had several advantages.

1)  The door was lowered under power so there was less chance of it getting stuck
2)  The door could be "locked" at any location simply by stopping the motor.  This meant the mechanics was simpler
3)  The stepper motor I chose had more power than my DC motor and could raise and lower the door faster.

I used a pair of A4988 driver chips under full-step mode to run the stepper motors.  Initially I just used two pins for each chip, but I realized the motors were drawing a lot of unnecessary power this way.  I decided to use the enable line on the chips to reduce power consumption but this would require 6 total pins (when I only had 5 available).  However, since I wasn't using the serial port for anything, I could re-purpose the TX line (D1) as one of the 6 pins.

I quickly realized an installation and maintenance problem needed to be solved.  How can the door be easily attached to or detached from the lead screw?  Additionally, there's a requirement to easily disengage the door from electronic control in the case of a power outage.  How do I make this easy?

The lead screw setup works by spinning a long threaded rod that has a nut attached to it.  The nut is trapped by a bracket that prevents it from spinning.  This converts the spinning motion of the rod into the linear motion of the trapped nut.  So, I designed a bracket that traps the nut and attaches to the door.  The bracket was made out of two parts.  One part attached to the door and allowed the threaded rod and nut to fully pass into it.  The second part snapped into the first in such a way that the threaded rod was held firmly against the bracket.  This fully captured the rod and nut while being easy to disengage.  I'm very pleased with this setup and it made installation a breeze.  I still need to design a latch to hold the door open if it is disengaged during a power outage.  In that situation, I can open and close the outer doors manually until power is restored and the door can be re-engaged.


Clockwork Coop Version 1 Mechanics First Try

Since the micro controller pin functions had been determined and DC motors selected, it was time to work on the door mechanism.  I designed a simple mount for the DC motor and a spool for it to hold a length of 20 pound test fishing line.  The door itself was made from 3/8 plywood.  I also made a wooden frame and guide rails so the door could be lifted/lowered by the motor.  I designed a mechanism to lock the door in place when it was fully lowered.

During testing, things didn't work out well.  The lift line was not precisely centered and caused the door to tilt as it was lifted and lowered.  Although, I suspect mild warping of the wood rails may also have played a role.  This meant the door would catch and stick when it was being lowered.  Similarly, the locking mechanism was often misaligned and caused multiple errors. Fortunately, I had programmed several error-detecting algorithms and it was easy to identify the problems when they occurred.

But, even though several fixes were made, the door remained unreliable.  So, I decided to see if there was a better path forward.

Clockwork Coop Version 1 Micro controller Capabilities

In order to design the mechanics, first we need to decide what sort of motors and sensors will drive the doors.  And, in order to decide on that, we need to know what capabilities our microcontroller has.  I'm using a Moteino R4 from lowpowerlabs.com.  And 5 pins on that controller are dedicated to running the transciever.  There are also 2 extra analog pins than a normal Arduino (A6 and A7) so I'll use one of those for light sensing.  This leaves 13 multipurpose pins left over (D3-D9 and A0-A5).

I decided to use two limit switches to detect each door's open and closed state.  This would require a total of 4 pins.  I considered using a single switch for each door but decided it would be too difficult to detect errors with only a single switch.  Imagine, for example, if I had used a single switch to detect open and closed.  This is easily accomplished by placing a switch near the top of the door and placing contacts on the door that would trigger the switch when it was either fully opened or fully closed.  But, what happens if the door experiences a mechanical failure while opening that causes it to drop back into the closed position?  The same switch would be triggered but the software would assume the door was now fully opened.  Even using known opening and closing times doesn't help since the door could drop into place just as it reached the point where it would indicate open.  Nope, we will need 4 pins to sense door state which means we are down to 9 available.

One of the door control requirements was to manually control the door locally.  Since I'll have 2 doors, two buttons will be used for this purpose.  This requires 2 more pins reducing the remaining count to 7.  If I had more doors, I might consider using an I2C keypad (this also requires 2 pins).

The indicator light and interior light require 2 more pins bringing us down to 5 pins.

With 5 pins, I could control a single stepper motor using the stepper.h library included with the Arduino IDE.  But that's not enough for 2 doors unfortunately.  However, if I had been clever at the time, I might have included a demultiplexer to route the 4 stepper control pins to the correct motor using the 5th available pin.  But I wasn't.  Instead, I abandoned the idea of using a stepper motor and considered using a DC motor instead.  I would control the DC motor using an L293E H-Bridge.  The Bridge required 2 input pins per motor (on/off and forward/backward) and could control up to 2 motors.  Additionally, I could get feedback about the motor performance from the sense pins.  This required 2 Analog pins and could be provided by one of the extra pins on the Moteino and one of the Analog multipurpose pins.  This was the initial plan.





Tuesday, December 6, 2016

Clockwork Coop Iterations

Finally, let's talk about versioning.  This project has a lot of requirements and I'd prefer to get things working before I get them "right".  So, I've divided the project into several iterations with explanations.  Here they are:

1)  Manual Local Control.  The gate to access the chicken run is, perhaps, not in the most convenient location.  And, while local door controls would still require more trips to the coop than I'd like, at least it's a shorter trip and doesn't involve fumbling with the gate.  Additionally, this is the version where the mechanical aspects of door control will play their biggest part and be the most time-consuming.

2)  Manual Remote Control.  Once all the mechanical bits are figured out, the next thing to attack is eliminating all those extra trips.  Remote control will do just that and will focus on the creation of the remote base station.

3)  Fully Automated Control.  Now that the coop controller and base station are talking, remotely configuring the coop controller to fully operate the doors automatically (based on the day/night cycle) is the next task.

4)  Lighting control. Establishing the length of darkness each night is really about optimizing egg production during the winter months so that will be version 4.  Additionally, if the previous versions are complete, this should just be a software update.

5)  Environment controls. This version focuses on reporting the various environmental measurements to the base station so the user can take action when needed.


A Clockwork Coop

Now that we can send information and move things, there are so many things we can do.  I decided the first project will be to free up some time and offer convenience maintaining a small flock of backyard chickens.

There are a variety of ways to keep chickens  but I have opted for a small coop with a fenced and netted area for them to roam.  This protects them from predators (including bald eagles in my area) and meets my municipality's legal requirements (chickens cannot roam freely here).  

Chickens naturally return to the coop to roost at night and they are let out to roam in their run during the day.  But, letting them out in the morning and then locking up after them at night takes time.  And, in the Puget Sound area, it rains occasionally.  Since I'd rather not fumble with locks after dark or in the early morning (or while it's wet or cold) and since I'd like to have fewer visits to the coop each day, I think an ideal first automation project is to control the opening and closing of the coop doors.

Before we dive right in, let's consider some goals.  To make things simpler, I've divided goals into 4 parts:  Door control, Lighting Control, Environment monitoring, and user interface.

Door Control
1)  Doors shall be tamper resistant when closed (so predators won't get in).  To be more specific, since the doors open like a portcullis, a predator should not simply be able to lift it open.
2)  The motors should not need to draw power in order to maintain the door in an open or closed state.
3)  A method for manually controlling the door should be available at the coop site.
4)  A method for disengaging the door from electronic control (in the case of a power outage for example) and latching it open will be available.
5)  A way of detecting when to automatically open and close the doors (at daybreak and nightfall) will be available
6) Detection of daybreak and nightfall will be robust and not influenced by temporary conditions such as shadows or bright lights.
7)  An easily visible indicator light will alert the user to the current door state.  Open, closed, transitioning, and error conditions will be indicated.

Lighting control
1)  An interior light will be provided.
2)  The light will be operated remotely (no local manual control)
3)  It should be configured to turn on some period of time after nightfall (establishing a night-length)
4)  It should turn off when the coop opens at daybreak.

Environment montioring
9)  Feed and water levels as well as temperature and humidity will be monitored and reported to the user.
10)  A heater will warm the coop if the interior temperature is too cold.
11)  Ammonia levels will be monitored and reported to the user.

User Interface
12)  A remote base station will be provided it will:
13)  Report all door and environmental conditions mentioned above.
14)  Provide manual door and light controls.
15)  Allow the user to manage configurable parameters (for example, what light level will determine daybreak and which door will open)
16)  Add timer control to the coop opening and closing.
17)  Keep time accurately (no more than a minute drift every 2 weeks.
18)  Display everything in an intuitive easy-to-read manner.



Monday, November 21, 2016

Motors are for Moving

Now that we can move information around, let's talk about moving stuff!  I'll discuss three motor types and my strategy for using them.

First, servo motors.  Servo motors can operate in at least two modes (continuous or positional) but I'll focus on the positional mode here.  A servo motor in positional mode rotates to a set position based on an input signal.  This signal is typically a 50Hz square wave (20 millisecond period) where the time spent at Vcc varies between 1 and 2 milliseconds.  If that last sentence didn't make a lot of sense, there's no need to worry.  The Arduino platform makes this very easy.  Just include servo.h in your code and write a value between 0 and 180 to rotate the motor to a position between 0 and 180 degrees.  Follow this link or this link for more details.

Next are DC motors (not the brushless kind, that's a different post).  DC motors are either on or off and run either forward or backward.  However, most motors should not be connected directly to a microcontroller for a variety of reasons including insufficient power to drive the motor and possbile damage to the controller.  Instead, the microcontroller should send signals to some sort of motor driver.  There are a variety of ways to do this.  For my purposes, I chose to write a new library that takes advantage of the L293 quadruple half-H driver chip.  Once the library is included in the code, just call methods to run the motor forward, backward, or off.

Finally Stepper motors. If you want to know more about stepper motors, check out this wikipedia article.  I use bipolar stepper motors with 4 wires and therefore, a microcontroller would need 4 outputs to control it (through some sort of driver of course) if you used the stepper.h library included with the Arduino platform.  However, there are drivers that only need 2 inputs to turn the motor and I chose the A4988 driver for my purposes.  However, I was unable to find a good control library that met all my needs so I created one with the following features:

1)  Configurable velocity and acceleration/deceleration.
2)  Interrupt driven motor steps (so the microcontroller can do other things.
3)  Methods for executing some number of steps.  These are either blocking or non-blocking (done in the background)
4)  Methods to wait for the motor to finish its current task.
5)  Continuous mode.  This allows the microcontroller to start the motor and then do other things.  During this time, the motor will not stop regardless of the number of steps it makes.  The microcontroller can stop or decelerate the motor later but the number of steps executed will likely be unknown
6)  Configurable capacity for multiple motors
7)  RPM mode.  Instead of doing some number of steps, do some number of rotations.

I used the timer 1 interrupt to control the motor (since Arduino uses timer 0 and node communications uses timer 2).

This took a fair bit to develop (particularly getting the timing for deceleration right.  I must have tried at least 3 different ways of doing that).  And, the interrupt that manages the motor takes a fairly long time unfortunately (most interrupts are short).  However, most things seem to work well in spite of the time consuming interrupt.  Here is the library.