Introduction: Tweeting Cat Door

Code, schematic:

https://github.com/e1ioan/Tweeting-Cat-Door

After receiving many emails requesting Instructions and Kits for building the Tweeting Cat Door, I decided to make a version that is stand-alone and doesn't need a computer to be run and that is easy to be put together by anyone with a soldering iron and a little time on hand. All the software is available to download, but feel free to modify it to make it better or to better suit your needs.

The Tweeting Cat Door works as follows:

When a pet tries to enter the pet door, a RFID reader will read the RFID tag that your pet has on the collar. If the tag is authorized , the latch of the pet door will open, a picture is taken of the pet, and uploaded to Twitter along with a funny random message, for example: "Penny is in playing with a ball of yarn."

The pet door works in the same way when the pet tries to go out. A picture is taken and uploaded to Twitter along with a message, for example: "Gus is out to play poker with the fellas."

The messages are chosen at random from a list of possible messages.
Here are some examples:
http://twitpic.com/2a7q32
http://twitpic.com/2uehbs
http://twitpic.com/2uc1ry
http://twitpic.com/29jcd2

Here is @GusAndPenny Sadly, there are no recent updates @gusandpenny. Gus died a while back (probably a fight with a raccoon or other cats?) and not long after, Penny followed.

Note: The twitter part of the project is optional. You can just build the Arduino controller, the latch to lock/unlock the pet door, mount the RFID reader and the latch on the door and you are ready to go. Your pets would be "sorted" by the RFID tag they are waring.

Here you'll find detailed step by step instructions and kits with all the components (you can buy kits, PCB, preprogrammed Arduino chip, etc, by contacting me). By following the instructions on this page, you will have - in no time - your own RFID enabled, twitting pet door, just like the original Tweeting Cat Door.

How does the RFID (Radio-frequency identification) enabled pet door works?

Each pet will have a small RFID tag on the collar and the pet door will open ONLY for your pet for entering the house.

The RFID enabled pet door has 3 settings that can be controlled by pressing a button. For each setting a LED will light in a different color:
GREEN - Open, your pet is allowed to exit the door and to enter the door.
BLUE - In-only, your pet is allowed to only enter the door (for example at night when you want your pet inside)
RED - Locked, the door will stay locked and no exit or entering is allowed.

Note: The entering through the door is controlled by RFID, exiting is controlled by a infrared beam.

Step 1: Make Your Own!

The pet door controller  is based on ATmege328 chip with Arduino bootloader. In this tutorial we won't use an already made Arduino board, we will build our own customized one to fit just our needs.

Note: You are welcome to use your own Arduino board. If you look at the schematic it would be very easy to build it around a standard Arduino board, but we won't cover it in this article.

Here is the schematic for the pet door controller we will use (click on the image to zoom in).

And if you want to see the PCB board design, click on following links:
The schematic
Top Layer with Silkscreen
Top Layer
Bottom Layer

(if you want to make your own PCB board, check out this)

You can also download the Eagle files at the bottom of this page.

On the schematic, you will see a bunch of header connectors, here is the description for each of them:

VCC1 : connect the power supply here
ICSP : you will use this for uploading your software to the Arduino chip.
IRT : the Infrared transmiter LED goes here
IRD : the infrared detector
WIFI : serial connection that goes to the OpenWrt router
RFID : your RFID reader (the software supports both ID12 and Parallax readers, selectable from RJP)
BTN : button to control the way the door operates (open, in only, locked)
RGB : RGB LED (common anode, common cathode, both work, selectable from JP1) 
SERVO : the servo that will open/close the pet door latch

SETSERVO button : when pressed you are going to be able to set the max values the servo goes to right or left. The settings are made using the trimpots TPR (max right) and TPL (max left).

PROGTAG button : when pressed, arduino will switch in "learning mode" and you can program new RFID tags. The tags are "learned" by passing them in front of the reader.

JP2: disconnects the RFID reader from the serial, and this way the ICSP can be used to reprogram arduino chip. 

Step 2: Parts List

Here is the list of all the parts you are going to need for this project:

Semiconductors:
 1x ATMEGA328P-PU 28 pin DIP package with Arduino bootloader
 1x LM7805 LDO TO-220 package
 1x 1N400x Diode
 1x 3mm LED (red or green)
 1x 16 MHZ ceramic resonator (built-in capacitors)
 1x RGB LED
 1x PNA4602M 38KHz Infrared Detector

Capacitors:
 3x 0.1uF (104) Ceramic Capacitor, 25 V (not polarized)
 2x 47uF Electrolytic Capacitors, 25V (polarized)
 1x 330uF Electrolytic Capacitors, 25V (polarized)

Resistors:
 1x 1K 1/4 watt Resistor
 3x 10K 1/4 watt Resistor
 3x 20K 1/4 watt Resistor
 3x 10K Trimpots

Hardware:
 1x PCB (you can contact me for the custom PCB here)
 1x 28 pin DIP Socket
 2x Pushbutton Switch
 4x 2 pin male & female header connection polarized
 3x 3 pin male & female header connection polarized
 1x 4 pin male & female header connection polarized
 1x 6 pin male header

Miscellaneous:
 1x 125 kHz RFID Reader Serial (Parallax or ID-12/ID-20)
 3x 125 kHz RFID Tag (for 3 pets)
 1x Micro Servo (latch control)

You will need a flap pet door similar to the one in picture.

Also a router that is supported by OpenWrt is necessary for enabling the twitting part of the project.

A webcam (for automatically taking pictures of your pet and uploading them on twitter) is optional.

Step 3:

Here is a picture with all the parts that you need to build your arduino, including the RFID reader (parallax in the picture).

For Internet enabling the cat door you would need a wireless router that accepts OpenWRT.
For a list of routers supported by OpenWRT, please see the OpenWRT website.

In my example I'm using an ASUS WL-520gU (it has a USB port that can be used for a Webcam).

Step 4: Software for the Controller

Build you pet door controller just like the schematic in Step 1.
You can use the Eagle files to create your own PCB, or, you can contact me if you want to buy an already made PCB.

Before being able to test your twitting pet door, you need to program you arduino chip. You can download tweetingcatdor.pde here  (also at the bottom of this page).

I included many comments in the file, but if you have any questions about portions of the code, do not hesitate to ask.

You are going to need a  USB FTDI TTL-232 cable for this.

Connect your FTDI cable to the ICSP pins, disconnect JP2 jumper, load tweetingcatdoor.pde in the Arduino IDE and write it to the chip.

If you only want to control your pet door and don't care too much about posting to Twitter, you should jump at the step "building a latch for the cat door". The "pet door" controller is done now and fully functional.

Step 5: Putting It Together

Step 6: Building OpenWrt for the Router

Like we decided in previous steps, we will need OpenWrt on the router. We are going to build our own openwrt firmware that includes everything we need. For this you need a linux machine (or linux running in vmware player).

You can download the firmware already made by me from here  or you can download it from this page (openwrt-brcm-2.4-squashfs-spca5xx-curl-stty).

I'm using vmware image of ubuntu on a windows machine with vmware player installed.

Open a console and type:

sudo apt-get install build-essential subversion libncurses5-dev zlib1g-dev gawk bison gcc
mkdir ~/kamikaze
cd ~/kamikaze
svn co svn://svn.openwrt.org/openwrt/branches/8.09/  . 
./scripts/feeds update -a
make menuconfig


Select the following options:

Target System (Broadcom BCM947xx/953xx [2.4])
Target Profile (Generic, Broadcom WiFi (default))
Select all packages by default
Image configuration —>
     Base system
         busybox (press enter to open hidden menu)
               Configuration
                     Coreutils
                           [*] stty 
Kernel modules
           USB support
               kmod-usb-core [*]
               kmod-usb-ohci [*]
Video Support
      kmod-video-core [*]


Save the configuration and then type in console:

make world V=99

This will take a while...
When is done, type this in console:

wget http://mxhaard.free.fr/spca50x/embedded/KernelPatch/usb-2.4.31LE06.patch.tar.gz
tar xvfz usb-2.4.31LE06.patch.tar.gz
mv usb-2.4.31LE06.patch ~/kamikaze/build_dir/linux-brcm-2.4/linux-2.4*/drivers/usb
cd ~/kamikaze/build_dir/linux-brcm-2.4/linux-2.4*/drivers/usb
patch -p1 < usb-2.4.31LE06.patch


Now we have to modify usb.mk. Open with a text editor ~/kamikaze/package/kernel/modules/usb.mk and add the following code to it:

define KernelPackage/usb-spca5xx
$(call usbdep,)
TITLE:=spca5xx WebCam driver
#KCONFIG:=$(CONFIG_USB_SPCA5XX)
FILES:=$(LINUX_DIR)/drivers/usb/spca5xx/spca5xx.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoLoad,70,spca5xx)
endef

$(eval $(call KernelPackage,usb-spca5xx))


Save usb.mk with the new settings.

Now we have to build the image again. In Kernel->modules->USB Supoprt you'll have a new line "kmod-usb-spca5xx", make sure is marked as [M].

cd ~/kamikaze
make menuconfig
Target System (Broadcom BCM947xx/953xx [2.4])
Target Profile (Generic, Broadcom WiFi (default))
Select all packages by default
Image configuration —>
     Base system
         busybox (press enter to open hidden menu)
               Configuration
                     Coreutils
                           [*] stty 
Kernel modules
           USB support
               kmod-usb-core [*]
              kmod-usb-ohci [*]
              kmod-usb-spca5xx [M]
Video Support
      kmod-video-core [*]


Save the new config, and then:

make world V=99

The compiling stopped twice to ask me to to select an option, I selected "m".

When is done, you'll have in ~/kamikaze/bin/brcm-2.4/ the new firmware:
openwrt-brcm-2.4-squashfs.trx

and in ~/kamikaze/bin/brcm-2.4/packages/ the compiled spca5xx package:
kmod-usb-spca5xx_2.4.37.5-1_brcm-2.4.ipk

Let me know if you have questions or if something is not clear. 

Now replace the old firmware with the new built one:
 (I used window for this, for linux or mac follow the instructions on openwrt.org http://wiki.openwrt.org/toh/asus/wl520gu)
Download: http://www.shadowsoftware.net/shadowgameworld/downloads/tftp2.exe

Change the IP on the windows machine to 192.168.1.8.
Connect the computer's LAN port to one of router's LAN ports.

Run the application prev. downloaded: tftp2.exe

In the Server field put 192.168.1.1, leave password empty, and in the File field, select the openwrt-brcm-2.4-squashfs-spca5xx-curl-stty.trx file. Set the retry to 99.

DO NOT press Upgrade button yet.

With the unit powered on, press and hold the reset button on back of unit for 30 seconds
Without releasing the reset button, unplug the unit and hold reset for another 30 seconds
Plug the unit back in STILL holding the reset button a final 30 seconds (please note that this step can put Asus devices into recovery mode)

NOW press Upgrade button.

Wait 5 full minutes and then reboot the router.

Wait a minute for it to boot, then:
telnet 192.168.1.1

Now the router is ready to be configured to connect to your WiFi network.

Step 7: Configuring the Router for WiFi

Telnet into your router and then change the router's default password:
telnet 192.168.1.1
passwd

After selecting a new password, you will only be able to connect to the router using ssh. A ssh client for windows is putty .

Now you will have to edit the network configuration to make your router be able to connect to the internet.
(From this point on you can think of your router as a small computer that runs linux and the only "screen" that you have to see what's going on in the router is telnet or ssh).

Using putty, ssh in your router and then:
vi /etc/config/network

edit it to make it look like this:
(Note: if you don't know how to use vi editor under Linux, here is a cheat sheet )

#### VLAN configuration
config switch eth0
option enable 1

config switch_vlan eth0_0
option device "eth0"
option vlan 0
option ports "1 2 3 4 5*"

config switch_vlan eth0_1
option device "eth0"
option vlan 1
option ports "0 5"

#### Loopback configuration
config interface loopback
option ifname "lo"
option proto static
option ipaddr 127.0.0.1
option netmask 255.0.0.0


#### LAN configuration
config interface lan
option type bridge
option ifname "eth0.0"
option proto static
option ipaddr 192.168.1.7
option netmask 255.255.255.0
option gateway 192.168.1.1
option dns 192.168.1.1


#### WAN configuration
config interface wan
option ifname "eth0.1"
option proto dhcp


save and exit vi editor, then:

vi /etc/config/wireless

make this file look like this:

config wifi-device wl0
option type broadcom
option channel 11 # the channel your wireless network is on

 # REMOVE THIS LINE TO ENABLE WIFI:
# option disabled 1 (comment out or remove this line)

config wifi-iface
   option device wl0
   option network lan

option mode sta # tell router to connect to your network as a client
option ssid MySSID # the SSID of your network
option encryption wep # the encryption mode of your network (none, wep, psk)
option key xxx # replace xxx with your network key

save and exit the vi editor and then:
reboot

Wait for the router to boot and then ssh back in now using the new IP (192.168.1.7 in our example).

Now your router should be connected to the internet, you could try to ping google.com to try the connection.

ping www.google.com

Congratulations! your router is a small linux computer now. 

Step 8: Getting Router's Serial Port Ready

Open your router:
On the back of the router you will find 4 screws (two of them are under the rubber feet). Unscrew the four screws and open the plastic box. You will find a circuit board that looks like the one in the picture.

Remove the PCB from the plastic enclosure by gently pulling it up and towards you (ethernet ports facing away).

Just to the left of the ASUS logo you will see four solder filled vias in a row. Solder 4 pins to the vias. From Left to right you will have:
GND, TX, RX, 3.3V

For this project we are going to use only the GND and RX pin (the router just receives instructions from the Arduino board).

After the 4 pins are in place, connect two wires, one to the GND pin (black wire), one to RX pin (a red wire). Make a small hole in the plastic enclosure for the two wires and now you can close the router back up. Screw the 4 screws back, and put the 2 rubber feet back in place.

Now the router is ready to communicate with the pet door controller.

Step 9: Serial Communication

To make the pet door controller communicate with the OpenWrt router you must connect the controller's TX pin to the router's RX pin and the controller's GND to router's GND (In our situation the communication is one way, from the controller to the router).

First of all, comment (add # in front of them) the lines in /etc/inittab :

tts/0::askfirst:/bin/ash --login
ttyS0::askfirst:/bin/ash --login
tty1::askfirst:/bin/ash --login


this will disable login console terminal on serial port, so we can use it for back and forth communication with the arduino based controller.

Both the router's serial port and controller's serial port must have same speed to be able to communicate. The router's serial speed to is set to 9600 by executing:

root@OpenWrt:~# stty 9600 < /dev/tts/0

For each RFID tag read by the pet dor controller, the controller will write to the serial the RFID tag with .txt at the end of line, for example, if the tag is 01068E2081, and the pet went out the door (breaking the IR beam) the controller is going to write to the serial 01068E2081-out.txt and if the pet went in the door (door opened by the RFID tag), the controller is going to send over the serial 01068E2081-in.txt


On the router, to read what's coming over serial communication from the controller, your code should look something like this:

# Tell the AVR we're ready to start doing stuff
echo "start" > /dev/tts/0
while true # loop forever
do
  inputline="" # clear input
  # Loop until we get a valid command from arduino
  # the line should be the text file we have to open to get
  # a random message
  until inputline=$(echo $inputline | grep -e ".txt")
  do
     inputline=$(head -n 1 < /dev/tts/0)
  done
[...]


by looking for .txt we will know when we got a new command from the pet door controller.

After we got a new command, for example 01068E2081-out.txt, we are going to read a random line from the file with the same name:

LINES=`wc -l $inputline | awk '{ print ($inputline + 1) }'`
RANDSEED=`date '+%S%M%I'`
LINE=`cat $inputline | awk -v COUNT=$LINES -v SEED=$RANDSEED 'BEGIN { srand(SEED); i=int(rand()*COUNT) } FNR==i { print $0 }'`


take a picture from the Webcam:

ln -s /dev/v4l/video1 /dev/video1 # create /dev/video1
spcacat -d /dev/video1 -g -f jpg -p 10000 -o > /dev/zero # take a picture every 3 sec


and upload them to twitter (twitpic):

# tell curl to send a multipart form to twitpic
# save returned XML in a variable
RET=$(curl -s -S -F "$myname" -F "$pword" -F "$cargo" -F "$tweet" $target)
echo "$RET"


Note: In this project the communication is just one way, the OpenWrt router just receives messages from arduino based controller. If you want to communicate both ways, in your bash script on the router use following command to send messages to arduino based conntroller:

echo "test message sent from OpenWrt router to arduino" > /dev/tts/0

Step 10: OpenWrt Scripts

Basically on the OpenWrt router you will have 2 scripts, one that starts the webcam capture and one that handles the communication with the pet door controller and uploads the messages and pictures to twitter.

On the router, create a dir in ~/ called catdoor:

mkdir ~/catdoor

then, in this directory put the following script:

tp.sh

#!/bin/sh -

# store some paths in handy variables
picsdir=/www/
pic=SpcaPict.jpg
TNAME=your_twitter_username
TWORD=your_twitter_password

# set serial port to 9600 baud
# so we can talk to the AVR
# turn off local echo to make TX/RX directions
# completely separate from each other
stty 9600 -echo < /dev/tts/0

# Tell the AVR we're ready to start doing stuff
echo "start" > /dev/tts/0
while true # loop forever
do
  inputline="" # clear input
  # Loop until we get a valid command from arduino
  # the line should be the text file we have to open to get
  # a random message
until inputline=$(echo $inputline | grep -e ".txt")
do
inputline=$(head -n 1 < /dev/tts/0)
done
# got a valid line - text file name - from arduino
# example: gus-out.txt
# now open the file and get a random line from the file
if [ -f $inputline ];
then
LINES=`wc -l $inputline | awk '{ print ($inputline + 1) }'`
RANDSEED=`date '+%S%M%I'`
LINE=`cat $inputline | awk -v COUNT=$LINES -v SEED=$RANDSEED 'BEGIN { srand(SEED); i=int(rand()*COUNT) } FNR==i { print $0 }'`

# got the random line
# create the twitpic message and send it
# store everything in vars to make
# curl opts for multipart form a bit more manageable
picfile=$picsdir$pic
cargo="media=@$picfile"
myname="username=$TNAME"
pword="password=$TWORD"
tweet="message=$LINE"
target="http://twitpic.com/api/uploadAndPost"

# make sure the file exists and is readable
while [ ! -r $picfile ];
do
picfile=$picsdir$pic
done

# tell curl to send a multipart form to twitpic
# save returned XML in a variable

RET=$(curl -s -S -F "$myname" -F "$pword" -F "$cargo" -F "$tweet" $target)
echo "$RET"
fi
done


in /www dir create the file pic.sh:

#/bin/sh
sleep 10
#cd /www
ln -s /dev/v4l/video0 /dev/video0 # create /dev/video0
spcacat -d /dev/video0 -g -f jpg -p 3000 -o > /dev/zero # take a picture every 3 sec



 in /etc/init.d create a file called webcam (this is going to start every time the router boots):

#!/bin/sh /etc/rc.common
# webcam script
# Copyright (C) 2007 OpenWrt.org

START=10
STOP=15

start()
{
  echo start
  # commands to launch application
  /www/pic.sh &
}

stop()
{
echo stop
# commands to kill application
}

Step 11: Twitter Messages

In ~/catdoor dir create two files for each RFID tag your pets are using. Name the files _the_tag_-in.txt and _the_tag_-out.txt (replace _the_tag_ with tag's code, for example 01068E2081-in.txt and 01068E2081-out.txt). Put some funny messages in those files. Here are some examples that I used:

Gus is in to drink from the faucet.
Gus is in to smoke a catnip cigar.
Gus is in to take a nap.
Gus is in to eat.
Gus is in because he is thirsty.
Gus is in to take a leak.
Gus is in to vomit in owners shoes.
Gus is in to take a nap.
Gus is in to take a crap.
Gus is in to lick his ass.
Gus is in to annoy Penny.
Gus is in to take a nap.
Gus is in for no reason.
Gus is in because he is bored.
Gus asks: Any followers willing to host our owners for a short vacation? The farther from Oregon the better. BTW, I'm in.
Gus is in. My Zen Garden is up and running: @GusAndPennyZen



Gus is out to behave badly.
Gus is out to see where the baked chicken smell comes from.
Gus is out to play poker with the fellas.
Gus is out for a beer.
Gus asks: Any followers willing to host our owners for a short vacation? The farther from Oregon the better. BTW, I'm out.
Gus is out to annoy the dog next door.
Gus is out to play poker with the fellas.
In and out again Finnegan.
Gus is out for a beer.
Gus is out to spray the house across the road.
Gus is out to sit on the porch.
Gus is out to play poker with the fellas.
Gus is out for a beer.
Gus is out to enjoy the weather.
Gus is out to check out the neighborhood.
Gus is out to meow at some door.
Gus is out for no reason
Gus is out to check out a noise.
Gus is out to play poker with the fellas.
In and out again Finnegan.
Gus is out for a beer.
Gus is out to chat with another cat.
Gus is out to get rid of a hairball.
Gus is out to play poker with the fellas.
Gus is out for a beer.
Gus is out to sleep under the car.
Gus is out to sniff catnip.
Gus is out to buy catnip from the dealer.
Gus is out to play poker with the fellas.
Gus is out for a beer.
Gus is out being a voyer in neighbors windows.
Our Zen Garden is up and running: @GusAndPennyZen


Step 12: New Way to Post to Twitter and Twitpic

Twitter and Twitpic changed a while back the way you can upload pictures and messages. For this, you have to register with Twitpic an application to get a key, here: http://dev.twitpic.com/apps/new

To register you application with Twitter go here: http://dev.twitter.com/

After registering, you will get the keys that are necessary to upload a picture to Twitpic and a message to Twitter. 

Here is the modified curl line that you have to use in your linux scripts to upload the pictures and messages (replace the keys with the ones you got from Twitter and Twitpic).

# tell curl to send a multipart form to twitpic
# save returned XML in a variable

RET=$(curl -v -F "consumer_token=I1dEkTPQJhAB1hHA" -F "consumer_secret=QTemkqHY4p6r4L5InSWKqsvxLc" -F "oauth_token=325134851-k6H2S05H8BKzesDKCQDN3WQ6yWaN" -F "oauth_secret=tQeHhLszyzYSjCNb11qmUEsREVb1s" -F "message=ALERTA" -F "key=96ef4b095809a3fad97b" -F "media=@/www/SpcaPict.jpg" http://api.twitpic.com/1/uploadAndPost.json)
echo "$RET"



Adafruit Make It Tweet Challenge

First Prize in the
Adafruit Make It Tweet Challenge

Microcontroller Contest

Participated in the
Microcontroller Contest