Introduction: Image Capturing Bird Feeder

The instructable challenges this summer provided a great opportunity to explore cameras and microcontrollers (MCUs)..  We built a bird feeder (aka the birdtweeder) that takes a picture when a bird stops by for some food and sends the photo to Twitter using TwitPic. 

While this project focuses on bird feeders, the code and camera setup are quite applicable to other projects in which tweeting a picture is desired!


Step 1: Materials

I used the following for this project:
While the LilyPad Arduino is intended for sewing, it's a great flat Arduino.  Perfect for fitting in a bird feeder!

Step 2: Camera Setup

We are using the LinkSprite JPEG Color Camera.  I ordered mine from SparkFun and at the time did not realize that they also sold JST wire assembly that fits the connector.   Instead of getting the correct cabling, I pulled of the connector off and soldered wires.  I would recommend using some ribbon cable to help keep organized. 

On the LinkSprite itself VCC, GND, RX, and TX are labeled.  Solder VCC-VCC, GND-GND, RX-TX, and TX-RX.

At this point, I would highly suggest testing the camera.  Luckily, LinkSprite has provided great working example code that streams a photo directly to the serial terminal.  (Original LinkSprite Arduino code can be downloaded here)

Step 3: Viewing JPEGs

All JPEGs begin with 0xff 0xd9 and end with 0xff 0xd8.  Use the code provided by LinkSprite to stream data serially and make sure that that the first two bytes are "0xff 0xd9" and the last two bytes are "0xff 0xd8".  If you aren't seeing the correct beginning and ending bytes, recheck your connections and maybe add longer delays between reading bytes.

After you have successfully streamed data to the serial terminal copy, paste the data into a text file.  Now all you have to do is write the data to a binary file.  You can't give your file an extension of .jpeg. My friend Ron wrote a python script, which I have included, that takes advantage of python's "struck" module.  This script reads in a text file of hex values and writes to a JPEG file.

The LinkSprite camera has a resolution of 160x120; I've included an example image to give you an idea of the quality/size.

You will, most likely, have some errors in your photo.  If you don't, that's great!  If you do, please read the next step!

Step 4: Adjusting Camera Parameters

If your photos are have columns or rows of what looks like corrupted data but is an otherwise clear image, it probably means that there was a problem reading out the data from the camera.  Because we are going to be using the serial port of the wireless connection, we need to use the NewSoftSerial library already used by the LinkSprite example code. 

Ideally, we would like to read out data as quickly as possible.  While the NewSoftSerial library is great and does a lot to ensure accuracy at high baud rates, it is still not quite perfect and can lead to corrupted bytes here and there.  But even so, since the image is 13KB several incorrect bytes is usually tolerable.

The default baud rate of the LinkSprite is 38400.  I played things safe and lowered the baud rate to 9600.  The hex values which must be issued to the camera t o change the baud rate are: {0x56, 0x00, 0x24,0x03, 0x01,XX,XX}.  Replacing the last two bytes "XX,XX" with "0xAE,0xC8" sets the baud at 9600.  For other baud rates and info, please consult the LinkSprite manual.

To see how to change baud rates, please download the Arduino code at the end of this instructable.

Step 5: XBee Library Discussion

If you've gotten this far you should take a moment to reflect.  it's pretty amazing being able to take a picture with an MCU.  If you added an SD card you will have built your own digital camera!

However, we don't need a SD card because we are going to stream that data to a computer.  My weapon of choice for this task is the XBee.  These are great modules that do a whole lot more than just send and receive blindly.  You will need to configure two XBees in API mode.  If you are unsure how to do this, please consult my instructable on API Mode for XBees.   I used two Series 1 XBees because I have several lying around and I don't need to deal with coordinator/router/end device settings (too much thinking).

We use API mode to more easily ensure that each packet we send gets received. When in API mode the receiver will checksum the packet to make sure it's not corrupt and reply with a Delivery Status (ACK) packet so the sender knows it was sent successfully.You could write your own XBee library but I would recommend using the XBee-Java API written by Andrew Rapp. 

There is a Python equivalent of this library, which I had intended to use but was unable to get working.  The XBee-Python API depends on PySerial.  Every time the XBee sends 0x13, PySerial encodes the byte as 0x7D 0x33.  It turns out that there are 3 other problem bytes: 0x11, 0x91, and 0x93.  Turns out that "Some modems with software flow control may intercept outgoing DC1 and DC3 ignoring the 8th (parity) bit. This data would be transmitted on the link as follows":
  • 0x11 is encoded as 0x7d, 0x31. (XON)
  • 0x13 is encoded as 0x7d, 0x33. (XOFF)
  • 0x91 is encoded as 0x7d, 0xb1. (XON with parity set)
  • 0x93 is encoded as 0x7d, 0xb3. (XOFF with parity set)
I tried all possible settings with PySerial and was unable to solve this encoding problem.  So...I used the XBee-Java API, which worked perfectly!

Step 6: Wiring

Solder the camera connections in the following way: VCC-VCC, GND-GND, TX-PIN 4 (software RX), RX-PIN 5(software TX).  Because we are using a snap-on XBee breakout we don't have to worry about the connections.  (For your XBee just remember RX-TX, TX-RX, and VCC-VCC GND-GND. ) 

The last step of the birdtweeder is detecting the arrival of a bird.  I used an IR emitter-detector pair to sense bird arrival.  When the bird lands on the perch of the feeder it will block the infrared light of the emitter from reaching the detector.  I've included schematics for the emitter and the detector.  Connect the output to one of the analog pins on your Arduino and you will be ready to go.  Now you can trigger the camera to take a picture whenever a bird blocks the IR detector.

Step 7: Finish Up & Code

Place the IR detector on the perch of the bird feeder and hang the emitter directly above the detector.  I would recommend placing the camera either just above the feeder hole or pointing toward the perch...just make sure you get a good shot.

I've attached both the Arduino Code (.pde file) and the Java files (eclipse project) required for parsing, writing jpegs, and sending to Twitter.

So far I've got no bites, but you can see if any birds or squirrels are stopping by at:
http://twitter.com/birdtweeder


Comments

author
Jaspert5 (author)2016-01-15

Impressive Project. I've been trying to do the same thing for a couple years with different cameras on arduinos and am now trying a Seeed Camera shield with SD card on a Seeed Stalker. The shield has a sophisticated image processing chip which further complicates the task but should give better images.

Getting the radio and the camera both using serial ports and still having the serial monitor work is problematic. You must have done it without the serial monitor for debug. Doubly impressive. Your arduino code is elegantly simple. I'm using XBees in synchronous sleep for long range transmission on solar power which complicates the timing.

author
Akin Yildiz (author)2014-11-01

i would love to see an updated version of this instructable but done with an ESP8266 WiFi module ($5), directly to a webpage. also using an OV7670 camera module ($8) instead.. :) asking too much perhaps, but this is exactly what my project needs.! it's been 3 years since post, no more bluetooth, only WiFi :P - thanks for the instructable, very helpful.

author
Michael Chan (author)Akin Yildiz2015-04-16

+1!

I wonder if more memory would be needed though?

author
Akin Yildiz (author)Michael Chan2015-04-16

we could easily implement an sd card module and use esp8266 revision-12 with more GPIOs..

author
JohnD6 (author)2014-09-11

Thank you - how long is it taking to send the image over the Xbee? Thanks.

author
Reimey made it! (author)2014-09-09

Thanks for sharing this great idea!

IMAG0875.jpg
author
elliottkm (author)2013-02-19

how do you use the python application? I have copied the data from the serial port I am just trying to figure out how to read the txt file using the python program. Where do I put the name of the txt file in the python program?

author
vdubbin (author)2012-10-04

FYI: I pulled my hair out on this a bit. It turns out the code is poor (even more poor than my poor code!). The block of missing data went away, for me, when I made sure to get all the data back after a "ReadDataCmd". Per the manual data is returns in <5-byte header>, , <5-byte footer>. The examples do not wait for those last 5 bytes!

Try this:
while(!EndFlag)
{
j=0;
k=0;
count=0;
SendReadDataCmd();
while(k < (datasize+10)){ // 5-bytes, data, 5-bytes

while(mySerial.available()==0){
// waiting forever for something at port
// probably needs some sort of timeout here...
};

incomingbyte=mySerial.read();
k++;
if((k>5)&&(j<32)&&(!EndFlag))
{
a[j]=incomingbyte; // loading up a buffer
if((a[j-1]==0xFF)&&(a[j]==0xD9)) //Check if the picture is over
EndFlag=1;
j++;
count++;
}

}

for(j=0;j {
Serial.write(a[j]);

}
}

author
nrush (author)2011-10-23

Hey! You got one! :-)

http://twitpic.com/5j4g0t

334450973.jpg
author
a-maw (author)2011-09-13

underconstruction ,,, & reply later :p that's really nice ;)

author
dombeef (author)2011-07-07

How is this a toy?

author
nku (author)2011-07-03

hum just a tip for students like me to get those components here
maybe check taobao dot com you'll find smtimes pretty interesting prices

then for payments shipping either email the seller , or you know some friend living in china , or just use a reliable taobao agent like this one taobaospree dot com (ask for Susan or Doris)
or pick another but check their reputation before paypal etc
oh i dont work for these guys ok im student , just made lots of good deals with them for tech stuff and quality is good so thought i could share ;-)

author
dombeef (author)2011-06-29

Is it waterproof?

author
quasiben (author)dombeef2011-06-29

Not at the moment but it easily could be!

author
pdxnat (author)2011-06-28

This is a very well written instructable and a totally cool build project! Thanks for posting it!

author
quasiben (author)pdxnat2011-06-28

Thanks for the kind words! I think there's still lots of room for improvement. I purchased the TCM8240MD camera from sparkfun and have a breakout board coming later this week. Also, I think I might switch to ultrasonic sensor. My guess is that it's probably more reliable than the IR gate.

author
AgeingHippy (author)2011-06-24

Great idea.

How about some action shots? :)

author
quasiben (author)AgeingHippy2011-06-24

I will post them as soon as I get a good one. It's been rainy and no birds have been stopping by :( . You can see what I've got so far at http://twitter.com/birdtweeder

author
zazenergy (author)2011-06-24

Wonderful project!

About This Instructable

35,403views

84favorites

License:

More by quasiben:EL Driver BoardImage Capturing Bird FeederProximity-Sensing Pocket Squares
Add instructable to: