This is a follow up to my initial post about using the Parallax RFID reader with the Arduino microcontroller. We’re going to spice things up by making your computer yell at intruders! With Python! I’ve opened the whole project up on GitHub at http://github.com/mattwilliamson/Arduino-RFID.
This is an RFID authentication system. It allows a person to place an RFID tag within proximity of the reader device (usually 5-6 inches with this reader) and it will look up the tag in an SQLite database to check if it should grant access. If authorization is granted, the hardware device will turn a servo motor into a second position. The primary application of this being the unlocking of a door. This implementation also speaks aloud “Access Granted” or “Access Denied” if you are running the server on OS X. You can modify the source to use something like flite on other OSes. This project is very easily modified to do any sort of task. Some ideas are:
To make this RFID system, you’ll need the following hardware:
You can use the image schematic/reader_breadboard.png to reference the wiring diagram. Basically you just need to wire the pins as follows:

You should end up with something like this.


Download the project here: http://github.com/mattwilliamson/Arduino-RFID
First you need to install the NewSoftSerial library for Arduino. Read the Arduino docs on how to install a library.
Plug the Arduino into your computer and open the sketch sketch/rfid_sketch.pde with the Arduino IDE. Select which serial port to use for the Arduino (Tools->Serial Port on OS X). Click the upload button to write the sketch to your Arduino. You may need to try a few different ports before it works. Write down the port name, we’ll need it later. It should look something like /dev/tty.usbserial-A70064Mh or COM3. It will probably be different for your machine.
Install the pySerial serial library for python. If you have setuptools installed, you can just run easy_install pyserial.
Open rfid.py with a text editor and look for this line: serial_port = '/dev/tty.usbserial-A70064Mh'. Change the /dev/tty.usbserial-A70064Mh to the serial port you wrote down in the previous step.
First, we’ll run the server to watch for the RFID tags we want to allow. Open a terminal and cd to the project directory. Then run python rfid.py serve. This tells the python server to listen to the serial device for RFID tags. It will print debug information into the console.
wraith:rfid mwilliamson$ python rfid.py serve Starting serial server... Connected to arduino. Awaiting RFID scans. Checking tag: 0F03042E80 Tag access denied. ^C
Hit ctrl-c to kill the program. Now we have a tag we can enable: 0F03042E80. We’ll use the enable command to enable it.
wraith:rfid mwilliamson$ python rfid.py enable 0F03042E80 Added tag with access ENABLED
Now that we’ve added the tag, we can scan it successfully. You should see the servo spin, or a least the built in LED on pin 13 of the arduino will light up.
wraith:rfid mwilliamson$ python rfid.py serve Starting serial server... Connected to arduino. Awaiting RFID scans. Checking tag: 0F03042E80 Tag access granted.
You can revoke access to a particular tag by running the disable command
wraith:rfid mwilliamson$ python rfid.py disable 0F03042E80 disabled access for tag
If you see the following, make sure your Arduino is plugged into your computer and you correctly set up the serial port in rfid.py
wraith:rfid mwilliamson$ python rfid.py serve Starting serial server... *ERROR* Could not open serial port. Edit rfid.py and make sure you define serial_port properly.
Download or view code at: http://github.com/mattwilliamson/Arduino-RFID
I used Python and OpenCV to get a simple app together that tracks movement using a webcam. It currently averages all of the movements’ locations to determine a single point for targeting. This will not work for multiple targets, with a little modification.
Here's the code from http://github.com/mattwilliamson/Motion-Tracker/blob/master/track.py:
# Derived from http://sundararajana.blogspot.com/2007/05/motion-detection-using-opencv.html import cv class Target: def __init__(self): self.capture = cv.CaptureFromCAM(0) cv.NamedWindow("Target", 1) def run(self): # Capture first frame to get size frame = cv.QueryFrame(self.capture) frame_size = cv.GetSize(frame) grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1) moving_average = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_32F, 3) difference = None while True: # Capture frame from webcam color_image = cv.QueryFrame(self.capture) # Smooth to get rid of false positives cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0) if not difference: # Initialize difference = cv.CloneImage(color_image) temp = cv.CloneImage(color_image) cv.ConvertScale(color_image, moving_average, 1.0, 0.0) else: cv.RunningAvg(color_image, moving_average, 0.020, None) # Convert the scale of the moving average. cv.ConvertScale(moving_average, temp, 1.0, 0.0) # Minus the current frame from the moving average. cv.AbsDiff(color_image, temp, difference) # Convert the image to grayscale. cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY) # Convert the image to black and white. cv.Threshold(grey_image, grey_image, 70, 255, cv.CV_THRESH_BINARY) # Dilate and erode to get object blobs cv.Dilate(grey_image, grey_image, None, 18) cv.Erode(grey_image, grey_image, None, 10) # Calculate movements storage = cv.CreateMemStorage(0) contour = cv.FindContours(grey_image, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) points = [] while contour: # Draw rectangles bound_rect = cv.BoundingRect(list(contour)) contour = contour.h_next() pt1 = (bound_rect[0], bound_rect[1]) pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) points.append(pt1) points.append(pt2) cv.Rectangle(color_image, pt1, pt2, cv.CV_RGB(255,0,0), 1) num_points = len(points) if num_points: # Draw bullseye in midpoint of all movements x = y = 0 for point in points: x += point[0] y += point[1] x /= num_points y /= num_points center_point = (x, y) cv.Circle(color_image, center_point, 40, cv.CV_RGB(255, 255, 255), 1) cv.Circle(color_image, center_point, 30, cv.CV_RGB(255, 100, 0), 1) cv.Circle(color_image, center_point, 20, cv.CV_RGB(255, 255, 255), 1) cv.Circle(color_image, center_point, 10, cv.CV_RGB(255, 100, 0), 5) # Display frame to user cv.ShowImage("Target", color_image) # Listen for ESC or ENTER key c = cv.WaitKey(7) % 0x100 if c == 27 or c == 10: break if __name__=="__main__": t = Target() t.run()
What if you could offload some of your computational work onto the visitors of your site? We thought it would be pretty cool to make a quick little app to test the theory out using Google App Engine.
We opted to use the MapReduce paradigm as made famous by Google. The workflow is like this:
<script src="http://bbmapreduce.appspot.com/client/wrapper/"></script>
It should be noted that was not written with security in mind and you can never trust the data that gets sent back from your visitors, but there are ways to make it more reliable, such as executing one function on multiple clients and checking the data returned against the rest which is not currently implemented. The other issue is that the jobs being submitted on this test site is completely open and thus prone to spam alert calls.
I am not responsible for any harm this causes you, your computer, or anyone who visits the URLs provided. This is simply for educational purposes.
Page 1 / 1
Try out Pocket Sentry, our iPhone motion-activated camera app and get emails when your pet enters the bathroom.
Matt Williamson
President, App Delegate Inc
Copyright © 2011 - App Delegate Inc - All rights reserved.