How does it work?
You write words on blocks, and stick a qr code equivalent on the bottoms. You place them on a transparent acrylic table, and a webcam underneath decodes the qr codes as they slide over it. The computer attached to this webcam then looks at the sentence you have made, and finds sentences with matching words in a free book from project Gutenberg. The computer then displays the sentence it found.
Step 1: Materials and Tools
USB Webcam -- we happened to use a Logitech QuickCam Pro 9000, but you should be able to use any webcam
12'' x 24'' x 1/8'' transparent acrylic (plexiglass)
Fourteen 2'' long wood screws
Two 1'' long wood screws
Three 8' long pieces of 1x3 pine lumber (These are not the final sizes. I just used these because they were the standard lengths available at Home Depot. You'll need to cut these down into four 4' long pieces and three 1' long boards.)
One 6' long piece of 1x3 pine lumber
Thin drill bit for pre-drilling screw holes
Phillips drill bit for drilling in screws
Straight edge ruler
Square for measuring right angles
Step 2: Software Pre-Requisites
(1) Install all the necessary dependencies: you'll need Python 2 (including python-devel and python-imaging), OpenJDK 1.6, and most importantly, JCC.
(2) Since JCC likely doesn't come with your distro, follow along and install PIP if you haven't already (you may have to set JCC_JDK to your JDK installation). A sample command might look as follows: sudo JCC_JDK=/usr/lib/jvm/java-1.6.0-openjdk pip-python install jcc
(3) You'll likely be asked to apply a patch, so you should do so (feel free to ignore warnings for now): sudo patch -d /usr/lib/python2.7/site-packages -Nup0 < /home/sebastian/build/jcc/jcc/patches/patch.43.0.6c11
(4) At this point, you should be good to go. Call: make followed by sudo make install
(5) There's one minor issue, where you have to change one line in a python file. Call sudo vim /usr/lib/python2.7/site-packages/qrcode-0.2.1-py2.7-linux-i686.egg/qrcode/__init__.py and change _setExceptionTypes to _set_exception_types
Now that this is done, you might want to setup the Arduino IDE. We're using an Arduino Uno, but feel free to use whatever you like. In short, go to arduino.cc and install the IDE, as well as the python module pyserial.
Lastly, there's the code that we wrote to decode the qrcode and parse it with the contents of the book. You can download it here (https://gist.github.com/2629901). That's it. Rock on.
Step 3: Code
There's a function called parse_book that takes a text file, opens it and parses it by creating a single long string without line breaks and calls a function called splitParagraphIntoSentences from there. This function, credit to Pythonic Prose here, breaks paragraphs into sentences and populates a list with them using a regular expression. The parse_book function then returns that list in question.
Of course, we also need to scan the table for the words, which is what the function grab_words is responsible for. It opens the connection to the Arduino using the pyserial module. At this point, we also initialize the pyqrcode module and reset the counters. Then, we have the script read the serial communication from the Arduino which represents the values from the photo diode. A value below 55 gives us a reasonably good idea that a block might be in the way; whereas one above 60 usually means that the laser is pointing directly at the diode, in which case we just want to wait until a block appears.
Once that is the case, we continuously take pictures from the webcam using the streamer command and convert the resulting .jpeg images to .png files. The function then passes the resulting file on to the pyqrcode library which repeats the process above until it successfully decodes a word and produces a list of words.
The function parse_words then takes both lists and uses a regular expression to match the first word in the list of the blocks to the list of sentences and returns a list with the matching sentences. It then continues to parse the next word against that list of matching sentences, until it finds a sentence that contains all words in question (or returns the previous list of sentences). Finally, it prints the sentence in question, together with the sentence before and after for context.
Step 4: Constructing the Table
Assemble your 1x3 boards, your saw, screws, drill, pencil, square, and measuring tape.
You'll need four 4 ft long boards. Cut two of your 8' long boards in half.
You'll need two 12 inch long boards and one 13.5 inch board. Cut these from your other 8' board.
You'll need six table legs about 7.5 inches long. Cut these from your 6' board.
The extra wood you can chop into 2.5 x 2.5 inch blocks to use as your word blocks.
We pre-drilled our screw holes to avoid splitting the wood.
First, drill the holes to attach the sides of the table to the rails that the plexiglass will slide along (Photo 1 and 2). For this, we need the four 4' long pieces of wood. They will fit together to form corners as in Photo 1. We'll attach them using 2 screws in each. Simply clamp them together as seen in the Photo 1, then flip them over, drill holes in as seen in Photo 2, and then screw them together.
Next (Photo 3) we attached these two sides together using 12'' long pieces. We screwed them in as seen in Photo 4. The bottom view (Photo 5) gives a better idea of the exact position of these screws.
Next (Photo 6) we attached six 7.5'' long legs. The legs on the end we attached using 2 screws each. The middle legs we used one screw each. The exact placement of these screws is up to you, but I recommend that you screw the end legs into the long edges of the table using 2'' screws. You'll need to save the 1'' screws to attach the center legs, which are screwed into the sides where the wood is only 3/4'' wide.
Next, we screwed the 13.5'' piece of wood between the middle legs. This acts as the mount for the camera and we found that it was good to keep our camera about 5'' from the qr codes. Your camera may differ. We ended up cutting a nice little hole for our camera so didn't wiggle around.
We drilled a hole in either side of the table right in the middle, through the center legs. These holes were for our photodiode and our laser pointer. We had to pick our drill bits to fit the size of our photodiode and laser pointer, but the hole for the laser pointer ended up being a bit loose. We ended up sticking it in place using modeling clay.
Step 5: Attaching Laser, Photodiode, Arduino & Camera
Photodiode and arduino:
Solder two long wires to the two ends of the photodiode. Remember, long leg is typically positive and the flat edge is typically on the negative side. Stick the positive wire into A0 of the arduino, and the negative wire into GND. Push the photodiode into the hole you drilled in the side of the frame (Photo 1).
Push the laser pointer through the hole. It should shine directly into the spot where the photodiode is on the other side of the frame. The point of the laser and photodiode is to recognize when there is a word block above the camera (it should interrupt the beam of the laser to the photodiode). Make sure the laser is pointing into the photodiode. If it is not, re-drill the holes to work out. Use modeling clay to hold the laser in place (Photo 2).
We cut a hole in the shape of our camera in the bottom (Photo 3) so we wouldn't have to worry about it moving around. You're on your own here. I don't know what shape your camera is.
Step 6: Making Word Blocks
We used libqrencode. http://fukuchi.org/works/qrencode/index.html.en
You can probably get a package for common linux distros, or you could compile it. After that, the command structure is really simple.
qrencode -o hello.png -s 3 'Hello, World!'
The -o flag tells it what file to output to and the -s flag tells it the size of individual pixels in the qrcode. Print the resulting image as a 2.5 x 2.5'' square, and you're set to go!
Cutting word blocks
You can cut 2.5x2.5'' square blocks easily out of your extra 1x3 lumber.
To make the Human Readable Words (HRW, as they are known in the lab) we attached pieces of transparency on the top of these blocks with some tape. The HRW were then carefully handwritten on using dry erase markers. We taped the corresponding qrcode onto the bottom of the block. In the future, we will try engraving, laser etching, or printing custom stickers for our words.