Meow you doing

So for my birthday last year, I was pleasantly surprised to receive a Lucky Cat, traditionally refered to as a Maneki-nek in Japanese. You typically see them in businesses, beckoning you to come inside. The cat, powered by two AA batteries, slowly waves its hand at you. That is, until it runs out of batteries.

Annoyed at having to change the batteries, even with rechargeables, I ventured a little outside my comfort zone, and splashed out on an Arduino Uno which can be wired up to operate various electronics. It’s a bridge between the hardware and the software worlds. I like a good bridge.

Arduino & Sketch

Knowing almost nothing about circuitry, I hacked in a design that came within the Sparkfun Inventors Kit documentation. After spending ages tinkering with the wiring, and a bit of Macgyver style blue tacking, I was able to get the Arduino to power the beckoning hand.

The Arduino takes has its own special language, which you use to write “sketches”, which are then uploaded to the device. My sketch, which is rather primitive, is as follows:

/*
  Cat.sketch
Sketch is used to read in an integer value from a serial connection,
  and then enable PIN 9 for the supplied amount of time.
*/

// Port 9 is being used to control the cat
const int CAT_PIN_OUT = 9;
/*
  Sketch initialisation.
*/
void setup()
{
  pinMode(CAT_PIN_OUT, OUTPUT);
  //Sets up serial connection
  Serial.begin(9600);
}

/*

*/
void loop()
{
  //The duration, in milliseconds to elave the cat arm running for
  int timeout = 0;

/*
    Puts the code into a never ending loop
  */
  while(true)  // "true" is always true, so this will loop forever.
  {
      // First we check to see if incoming data is available:
      while (Serial.available() > 0)
      {
        timeout = 0;
//Read in the timeout value from the serial input.
        timeout =  Serial.parseInt();
        Serial.print("Timeout ");
        Serial.print(timeout);
        Serial.println();
        //Turn the power on, wait the "timeout" of time, and then turn it off
        if(timeout > 0)
        {
          analogWrite(CAT_PIN_OUT, 255);  // turns arm On. 255 means full power
          delay(timeout);   //leaves cat arm running for as long as the timeout  millisecconds          analogWrite(CAT_PIN_OUT, 0);  // turns arm off
        }
}
//Short delay before trying to re-read the serial connection
      delay(50);
  }
}

So this code basically just reads in an integer value from the serial connection, and then turns the cat’s arm on for the supplied amount of time. The next step is to invoke the code from the computer.

Python & Twitter

Communication from your computer (in this case, my mac), to the Arduino is relatively simple. All you need is a library called pySerial (http://pyserial.sourceforge.net/) and you’re ready to go. So I grabbed the library, and I enjoyed stopping and starting my cat, but I wanted a little more from it. And that ‘more’ manifested itself in the twitter streaming API(https://dev.twitter.com/docs/streaming-apis). The streaming API offers a tiny, miniscule sample of twitter;’s global stream of tweets, which you can filter on. So after a bit of searching I stumbled across tweepy (https://github.com/tweepy/tweepy), a python API that has access to the streaming API. Without further ado:

import serial
import time
import sys
import inspect
from Queue import Queue
from threading import Thread
import time
import tweepy
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
# Twitter consumer and access keys
consumer_key="<INSERT_HERE>"
consumer_secret="<INSERT_HERE>"
access_key = "<INSERT_HERE>"
access_secret = "<INSERT_HERE>"
# Wave duration
WAVE_DURATION = '3000' # in milliseconds
SLEEP_TIME = 3 # in seconds
#List of twitter terms
STREAM_FILTER='#cat,#cats'
# Establish authentication information
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth)
# serial connection to the arduino
s = serial.Serial(port='/dev/tty.usbmodem1d21', baudrate=9600,timeout=4)
# Queue for work thread. We only want the thread handling one "wave"
# item at a time.
q = Queue(maxsize=1)
# Thread which handles the cat's arm waving
def worker():
    # Loop forever. Retrieve item from queue, and then sleep
 while True:
     item = q.get()
      time.sleep(SLEEP_TIME)
      s.write(WAVE_DURATION)
      s.write('')
#starting cat thread
t = Thread(target=worker)
t.daemon = True
t.start()
# Tweepy sample based on Based on this:
# http://answers.oreilly.com/topic/2605-how-to-capture-tweets-in-real-time-with-twitters-streaming-api/
#
class StreamListener(tweepy.StreamListener):
    def on_status(self, status):
        print status.text
         # Adds the wave request to the queue.
       # Will throw an error if there is already a request
         # in the queue
        try:
              q.put_nowait('cat')
         except:
             print ''
def on_error(self, status_code):
        print >> sys.stderr, 'Encountered error with status code:', status_code
        return True # Don't kill the stream
def on_timeout(self):
        print >> sys.stderr, 'Timeout...'
        return True # Don't kill the stream
# Start the stream
sapi = tweepy.streaming.Stream(auth, StreamListener())
sapi.filter(track=[STREAM_FILTER] )

I ran into some threading issues combining the two APIs. By setting up a processing thread, and queue with a maximum depth of 1, I was able to ensure the Arduino was only handling one request at a time.

So here we go, the cat in action:

The next step is to get myself an Ethernet shield for the Arduino, and maybe a web-cam.