Thursday, April 11, 2013

Hand of PI (Twitter controlled Robot Hand)

OBJECTIVE: Use the Raspberry PI to monitor a Twitter feed and control a mechanical device.

If you are not interested in the details of the build and just want to see the result you can watch the vid below.

-----

RESULT: Success!!! You can control the "The Hand of PI" by sending a tweet to @OurCatDoor. If your tweet includes any of the text below, the "Hand of PI" obeys your command. Valid commands are (lowercase):

one (holds up one finger)

peace (shows the two finger peace sign)

three (three fingers up)

hookem (if you are a Texas Longhorn fan this one makes sense)

fist (the Hand of PI gets ready to fight)

open (ready for a 'high five')

finger (well... this will be the most tweeted command)

Go ahead, try it!!! Send a tweet command to @OurCatDoor to let us know you were here.
-----
Basically what you are seeing is the Raspberry PI running a Python script searching any tweet sent to @OurCatDoor. In the video, an iPad sends a tweet to @OurCatDoor that has the command "finger" in it. It takes a few seconds, but the Raspberry PI finds the tweet, parses it, and find the "finger" command. The Python script then sets the PI's GPIO ports High/Low. The PI GPIO is connected to a PICAXE 18M2 (via a HC7404 buffer). The PICAXE 18M2 reads the PI's GPIO to control five servo motors. "Hand of PI" reacts with the appropriate gesture. Watch closely and you can see the text on the screen update as the "finger" command is found and the "Hand of PI" gestures. There's a lot going on here. Confused? This diagram should help (click to see full size):

Of course this isn't full schematic, but it lays out all the I/O to align with the source code you see below. Really, the interconnects and 5VDC to the servos, PI, PICAXE, and HC7404 is something anyone wanting to duplicate the project should easily understand given the block diagram and source code.
-----
Let's show a few more pics and action videos of the rig before we get into the source code:

-----
This video is a bit long but demonstrates all the gestures of the "Hand of PI". The screen in the background shows output from the Python script. The screen is not needed, but I included it in the video to show the tweets as they are captured. Note the "Hand of PI" reacts when a new tweet command is found.
Everyone wants to see the "Hand of PI" flip the bird; that is the last gesture if you want to skip to the end...

----
If you are still with us, enjoy some source code for your reading pleasure.

First the program that is running on the PICAXE 18M2. It's job is to read the Raspberry PI's GPIO output and control the five servo motors on the "Hand of PI".

servopos 0, Ex_Thumb
pause 70
servopos 1, Ex_Pointer
pause 70
servopos 2, Ex_Middle
pause 70
servopos 3, Ex_Ring
pause 70
servopos 4, Ex_Pink
return 'Wave
----
Now for the Python script running on the Raspberry PI. It's job is to search any tweet sent to @OurCatDoor and parse it for a "Hand of PI" command, then set the PI's GPIO for input to the PICAXE 18M2.

# WhiskeyTangoHotel.com - APRIL 2013 (special thanks to @Rob_Bishop)
# Error traps entered due to json hitting web site that was down etc.
# For next added to end of prog to blink LED to show program is running.

# Import the urllib library to read data from webpages
import urllib

# Import the simplejson library to decode the data read from the webpage
import simplejson

# Import the time library for delay and lepse time tracking
import time
CurrentTime = time.time()

# Import the Raspberry Pi GPIO libraries
import RPi.GPIO as GPIO

# Set-up the GPIO pins
# Clear the current set-up
GPIO.cleanup()

# Set up the GPIO library to use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BOARD)

# Function to take Twitter handle (e.g. @Raspberry_Pi) as an argument and return the most recent tweet

# Define the function name and show the arguments
def Latest_Tweet_to_Twitter_Handle(twitter_handle):try:# Get the results of a search on Twitter for tweets containing the given hand$Twitter_search_results = urllib.urlopen("http://search.twitter.com/search.json?q="+twitter_handle)

# Decode the data that we got from the webpage to form a list of tweetsresult_list = simplejson.loads(Twitter_search_results.read())

# The function returns the first result in the listreturn result_list["results"][0]["text"]except:pass

# Main body of the program - Get the latest tweet and check if it contains certain words
# Loop to run forever

while(True):try:#Time since program start in secondsDeltaTime = int(time.time() - CurrentTime)

# Function gets the latest tweet mentioning the handle given in next line Tweet=Latest_Tweet_to_Twitter_Handle("@OurCatDoor")

# START TEST(open): Check if tweet contains the word given in quotation marksif "open" in Tweet: # and Last_gesture != "open":Last_gesture = "open"# If it did contain the word then print out the tweet along with a messageprint DeltaTime,"seconds:",Tweet," - Gesture OPEN HAND","\n"# Turn on the LEDGPIO.output(11,GPIO.LOW)GPIO.output(13,GPIO.LOW)GPIO.output(15,GPIO.LOW)#---END TEST(open)---

# START TEST(one): Check if tweet contains the word given in quotation marksif "one" in Tweet: # and Last_gesture != "one":Last_gesture = "one"# If it did contain the word then print out the tweet along with a messageprint DeltaTime,"seconds:",Tweet," - Gesture ONE","\n"# Set the PICAXE inputsGPIO.output(11,GPIO.HIGH)GPIO.output(13,GPIO.LOW) GPIO.output(15,GPIO.LOW) #---END TEST(one)---

# START TEST(peace): Check if tweet contains the word given in quotation marksif "peace" in Tweet: # and Last_gesture != "peace":Last_gesture = "peace"# If it did contain the word then print out the tweet along with a messageprint DeltaTime,"seconds:",Tweet," - Gesture PEACE","\n"# Set the PICAXE inputsGPIO.output(11,GPIO.LOW) GPIO.output(13,GPIO.HIGH)GPIO.output(15,GPIO.LOW) #---END TEST(peace)---

# START TEST(three): Check if tweet contains the word given in quotation mar$if "three" in Tweet: # and Last_gesture != "three":Last_gesture = "three"# If it did contain the word then print out the tweet along with a messageprint DeltaTime,"seconds:",Tweet," - Gesture THREE","\n"# Set the PICAXE inputsGPIO.output(11,GPIO.HIGH) GPIO.output(13,GPIO.HIGH) GPIO.output(15,GPIO.LOW) #---END TEST(three)---

# START TEST(hookem): Check if tweet contains the word given in quotation mar$if "hookem" in Tweet: # and Last_gesture != "hookem":Last_gesture = "hookem"# If it did contain the word then print out the tweet along with a messageprint DeltaTime,"seconds:",Tweet," - Gesture HOOK EM HORNS","\n"# Set the PICAXE inputsGPIO.output(11,GPIO.LOW)GPIO.output(13,GPIO.LOW)GPIO.output(15,GPIO.HIGH)#---END TEST(hookem)---

# START TEST(fist): Check if tweet contains the word given in quotation mar$if "fist" in Tweet: # and Last_gesture != "fist":Last_gesture = "fist"# If it did contain the word then print out the tweet along with a messageprint DeltaTime,"seconds:",Tweet," - Gesture FIST","\n"# Set the PICAXE inputsGPIO.output(11,GPIO.HIGH)GPIO.output(13,GPIO.LOW)GPIO.output(15,GPIO.HIGH)#---END TEST(fist)---

# START TEST(finger): Check if tweet contains the word given in quotation mar$if "finger" in Tweet: # and Last_gesture != "finger":Last_gesture = "finger"# If it did contain the word then print out the tweet along with a messageprint DeltaTime,"seconds:",Tweet," - Gesture FINGER F_YOU","\n"# TSet the PICAXE inputsGPIO.output(11,GPIO.LOW)GPIO.output(13,GPIO.HIGH)GPIO.output(15,GPIO.HIGH)#---END TEST(finger)---

# START TEST(wavewave): Check if tweet contains the word given in quotation mar$if "wavewave" in Tweet: # and Last_gesture != "wave":Last_gesture = "wavewave"# If it did contain the word then print out the tweet along with a messageprint DeltaTime,"seconds:",Tweet," - Gesture WAVE","\n"# Set the PICAXE inputsGPIO.output(11,GPIO.HIGH)GPIO.output(13,GPIO.HIGH)GPIO.output(15,GPIO.HIGH)#---END TEST(wavewave)---

for x in range(0, 10):# Wait for xx seconds before repeating# Blinkie LED to let us know the program is runningGPIO.output(7,GPIO.HIGH)time.sleep(.1)GPIO.output(7,GPIO.LOW)time.sleep(1)except:pass

-----
If you are still awake, thanks for checking out the build. Send a tweet to @OurCatDoor to let us know you were here.
-----