Introduction: Image Capturing Bird Feeder
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
- Adafruit XBee Adapter ($10)
- LilyPad Arduino ($20)
- XBee Series 1 ($22) x2
- LinkSprite JPEG Camera ($50)
- LiPo Battery ($9)
- Infrared Emitter Detector Pair ($2)
- Snap-On XBee Breakout ($10)
- 100 Ohm and 10K Ohm Resistor
- Wire
- Bird Feeder
- Bird Seed
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!
Attachments
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
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)
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

Runner Up in the
Adafruit Make It Tweet Challenge

Participated in the
Toy Challenge

Participated in the
Microcontroller Contest
19 Comments
7 years ago
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.
8 years ago on Introduction
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.
Reply 8 years ago on Introduction
+1!
I wonder if more memory would be needed though?
Reply 8 years ago on Introduction
we could easily implement an sd card module and use esp8266 revision-12 with more GPIOs..
Reply 8 years ago on Introduction
https://www.instructables.com/community/arduino-wif...
8 years ago on Introduction
Thank you - how long is it taking to send the image over the Xbee? Thanks.
10 years ago on Step 3
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?
10 years ago on Step 4
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]);
}
}
11 years ago on Step 7
Hey! You got one! :-)
http://twitpic.com/5j4g0t
11 years ago on Introduction
underconstruction ,,, & reply later :p that's really nice ;)
11 years ago on Introduction
How is this a toy?
11 years ago on Introduction
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 ;-)
11 years ago on Introduction
Is it waterproof?
Reply 11 years ago on Introduction
Not at the moment but it easily could be!
11 years ago on Introduction
This is a very well written instructable and a totally cool build project! Thanks for posting it!
Reply 11 years ago on Introduction
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.
11 years ago on Introduction
Great idea.
How about some action shots? :)
Reply 11 years ago on Introduction
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
11 years ago on Introduction
Wonderful project!