Python
Tweetbot … the code
You can now find the code of the twitter robot on my github at: https://github.com/pchretien/tweetbot Feel free to fork … copying is not stealing! :)
Playing With The Beaglebone
I just received my Beaglebone and started experimenting with it. The Beaglebone is a low cost, single board Linux computer with tons of IOs to interface with the physical world.
My objective is to make a Python Robot using the Beaglebone as the brain and my Makerbot to build the frame. I found an excellent series of articles on how to get started with the Beaglebone on the Dan Watts’s blog.
The most interesting feature of this board is the way used to read and write to the IOs using the file system. By using the file system, the IOs are accessible trough any language you may want to install on your Beaglebone Linux distro.
I’ll post some practical examples in the following days.
Twitter Controlled Robot
I presented this project at the 28th Montréal Python meeting. I posted the slides of the presentation in my previous post here.
The objective of this project was to demonstrate the use of pyserial and XBee to wirelessly control a robot. This project was also my first attempt at using the Tweepy library. The requirements for the project were the following:
- The communication with he robot must be wireless
- The connection to the Twitter website is made by a separate computer using the Python library Tweepy
- The robot should move according to the messages it receives
- In addition to the movement, the robot should have a servo that indicate its direction
The code running in the Arduino is a very simple program. The micro-controller read on the serial port to get a char command. The commands are text integers. The robot moves according to the command it receives. You can find the code to drive the robot in my previous post Arduino Motor Controller Using an L293D Chip. The following loop() function of the Arduino program receives commands from a computer trough the serial port. Depending on the nature of the command, the robot will perform different actions.
void loop()
{
if ( Serial.available())
{
char ch = Serial.read();
switch(ch)
{
case '1': // forward
servo.write(90);
forward();
delay(RUN_DELAY);
stop();
break;
case '2': // backward
servo.write(90);
backward();
delay(RUN_DELAY);
stop();
break;
case '3': // right
servo.write(180);
right();
delay(TURN_DELAY);
forward();
delay(RUN_DELAY);
stop();
break;
//...
}
}
}
On the computer we are running a Python that connects to Twitter.com, read it’s messages and send commands to the robot that are related to the content of the messages.
import tweepy
import time
import serial
consumer_key=""
consumer_secret=""
access_token=""
access_token_secret=""
ser = serial.Serial('COM8', 19200, timeout=0)
# Initialize the tweepy API
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
api.update_status('Start listening at ' + time.strftime("%Y-%m-%d %H:%M:%S"))
print "Start listening at " + time.strftime("%Y-%m-%d %H:%M:%S")
print
# This is where we should send the command to the robot ...
def process_text(author, text):
print author
print text
print
if text.lower().find("cmd1") > -1:
ser.write('1')
if text.lower().find("cmd2") > -1:
ser.write('2')
if text.find("#mpr-bye") > -1:
quit = True
quit = False
lastStatusProcessed = None
lastMessageProcessed = None
while True:
for status in tweepy.Cursor(api.friends_timeline, since_id=lastStatusProcessed).items(20):
if lastStatusProcessed is None:
lastStatusProcessed = status.id
break
if status.id > lastStatusProcessed:
lastStatusProcessed = status.id
process_text(status.author, status.text)
for msg in tweepy.Cursor(api.direct_messages, since_id=lastMessageProcessed).items(20):
if lastMessageProcessed is None:
lastMessageProcessed = msg.id
break
if msg.id > lastMessageProcessed:
lastMessageProcessed = msg.id
process_text(msg.sender.name, msg.text)
if quit:
break
time.sleep(15)
api.update_status('Bye! ' + time.strftime("%Y-%m-%d %H:%M:%S"))
print "Bye!"
The Twitter anti-spam filter will block you to send twice the same tweet to someone. it is then difficult to use specific commands to control the robot since you can’t send it more than once.
The solution is to use common words as commands and to incorporate it into your tweets. That way you can send multiple variations of the same command simply by decorating the command with more text.
A video of the presentation should be available on my Youtube channel soon …
Montreal Python #28

Today at 18:30h, I’ll make a short presentation at the 28th edition of the Montreal Python. I’ll present my PyGame Wireless Game Controller and a robot controller by the web.
More details about the presentation on the Montreal Python Website:
http://montrealpython.org/2012/03/montreal-python-28-lithographic-lobotomy/
You can get the slides of the presentation here:
https://docs.google.com/presentation/d/1KTqljkl-fSZyuhXonCrQN10HsEFdp5AsavMEvj8bdRU/edit#slide=id.p
Wireless Arduino/XBee Game Controller
For this project, I keep the same controller as in the previous post but, instead of controlling a servo motor through a second Arduino, I will use it as a game controller.
The game will be played on my desktop computer. Since I am not very good at writing games, I downloaded the PyGame library. This framework comes with tons of samples so I decided to hack one of these samples and replace the keyboard input with my controller. You move the tank left and right by turning the game controller in the vertical position. You can fire bombs by switching the controller horizontally.
The code and the circuit of the game controller are the exact same setup as in my previous post. What I’ll demonstrate here is how to implement a receiver in this Python game.
You will need to connect an XBee wireless module to your computer using a USB adapter board. This will create a new communication port, in our case COM8.
The idea is to replace the keyboard with the data coming from the controller through the serial port. To maintain compatibility with the original version, I decided to simply override the keyboard values with the wireless controller commands.
The first step is to load the proper modules and open a connection through the serial port. I will use two global variables to replace the keyboard commands: one for the firing command and the other for the tank direction.
#
# Serial port communication with the Arduino/XBee
#
import serial
import thread
arduinoFiring = 0
arduinoDirection = 0
ser = serial.Serial('COM8', 19200, timeout=0) # Change COM[number] for ttyUSB[number]
Once this is defined, we need to override the keyboard values. To replace the spacebar fire command, we override the value with:
firing = keystate[K_SPACE] firing = arduinoFiring # <-- Override the keyboard with the game controller data
To replace the arrows direction commands, we are add the following lines:
direction = keystate[K_RIGHT] - keystate[K_LEFT] direction = arduinoDirection # <-- Override the keyboard with the game controller value
Finally, we have to feed these two values with the data received from the game controller. The best way to do this is by starting a new thread to listen on the serial port, read incoming data and convert it to game usable values.
def processArduino(buffer):
global arduinoFiring
global arduinoDirection
if len(buffer) == 0:
return
if buffer[0] != '<':
return
if buffer[len(buffer)-1] != '>':
return
tokens = buffer[1:len(buffer)-1].split(':')
if len(tokens) < 4:
return
for i in range(4):
if len(tokens[i]) == 0:
return
#print(buffer)
c = int(tokens[0])
x = int(tokens[1])
y = int(tokens[2])
z = int(tokens[3])
if y > 550:
arduinoDirection = 1
elif y < 450:
arduinoDirection = -1
else:
arduinoDirection = 0
if z > 575:
arduinoFiring = 1
else:
arduinoFiring = 0
def readArduino():
buffer = ''
while 1:
b = ser.read()
while b:
if b == '<':
buffer = ''
buffer += b
if b == '>':
processArduino(buffer)
b = ser.read();
def main(winstyle = 0):
...
thread.start_new_thread(readArduino, ())
We have two functions here. The readArduino() function is the thread entry point that contains the code reading on the serial port. A buffer is built of bytes received from the game controller. When the ‘<’ character is read, the buffer is cleared to receive a new command. When the character ‘>’ is received, the command stored in the buffer is processed.
The data is processed in the function processArduino(buffer). The data buffer is received as a parameter. The function reads the three axis and the compass values. Then, it determines if the direction is -1, 0 or 1 and if the tank fires a bomb. The values of the axis range from 400 to 600. The constants used in the function to determine the position of the controller can be adjusted to match your game requirements.





