Find all your DIY electronics in the MakerShed. 3D Printing, Kits, Arduino, Raspberry Pi, Books & more!

A really fun project sent into us by Thomas Meghe. He’s translated it all from his native French, which is a technical achievement itself. If you’d like to see the original, you can find it here.

Bored of your favorite Twitter client ? No problem, here’s the solution ! In this post we are going to explain how to control the awesome WowWee Robosapien with a wirelessly connected Arduino to trigger some actions on the robot through a specific Twitter hashtag.

Goals

  • Hack the Robosapien with Arduino
  • Deploy an app on Heroku allowing it to be available 24/24
  • Use the Twitter streaming API to watch new tweets posted on the #tweetosapien hashtag
  • Use websockets with Pusher to send events to Arduino

Steps

Step #1: Hardware

PrevNext
Tweetosapien: Hack a Robosapien With Arduino to React to TweetsTweetosapien: Hack a Robosapien With Arduino to React to TweetsTweetosapien: Hack a Robosapien With Arduino to React to Tweets
  • The Robosapien is well engineered and quite easy to hack. Documentation is easily findable on the web. Here are the steps to follow to control our robot with Arduino.
  • Unscrew the 4 screws at the back of the Robosapien (2 behind the shoulders and 2 behind the hips) to access the PCB.
  • Spot the head connector at the bottom of the PCB (above picture)
  • Remove the ribbons to disassemble the PCB.
  • Spot the black and white wires on the head connector. The black is the GND and the white is for the IR-OUT.)
  • Turn back the PCB and solder a black wire on the existing soldering point. Do the same with the white one.
  • Next, solder your brand new white wire to the central pin of a toggle switch 3-Pin then add another white wire to one of the other pin. This trick will allow us to switch the Robosapien in remote or Arduino mode.
  • Drill a hole somewhere on the robot to mount the switch on. I chose to put it on the back (bottom picture).
  • Reassemble it!

Step #2: Arduino

PrevNext
Tweetosapien: Hack a Robosapien With Arduino to React to Tweets

The original code on which is based the program to fake the remote and send data to Arduino is available on this page.

Arduino allows us to fake the remote and communicate with the robot the «serial way». Before powering on the robot, I advice you to switch the robot in remote mode. When it’s done, you can power the robot on and switch back on Arduino mode. Then, you can plug the white wire on the Arduino 6 PIN and the black one on the GND. You can optionally add a LED on the 13 PIN. Upload the code on the Arduino. If everything is working well, you should hear your Robosapien burping, the link between the controller and the robot is fine.

/*
Tweetosapien
hello@thomasmeghe.fr / May, 2013

Thanks to RobosapienRu - test Robosapien hackspace.ru
*/

include



volatile int viRobsapienCmd = -1;  // A robosapien command sent over the UART request

//////////////////////////////////////////////////////////////////
// Begin Robosapien specific variable deinitions
//////////////////////////////////////////////////////////////////


// Some but not all RS commands are defined

define RSTurnRight       0x80

define RSRightArmUp      0x81

define RSRightArmOut     0x82

define RSTiltBodyRight   0x83

define RSRightArmDown    0x84

define RSRightArmIn      0x85

define RSWalkForward     0x86

define RSWalkBackward    0x87

define RSTurnLeft        0x88

define RSLeftArmUp       0x89

define RSLeftArmOut      0x8A

define RSTiltBodyLeft    0x8B

define RSLeftArmDown     0x8C

define RSLeftArmIn       0x8D

define

RSStop            0x8E

define RSWakeUp         

0xB1

define

RSBurp            0xC2

define RSRightHandStrike 0xC0

define

RSNoOp            0xEF

//

define RSRightHandSweep  0xC1

define RSRightHandStrike2 0xC3

define

RSHigh5           0xC4

define

RSFart            0xC7

define RSLeftHandStrike  0xC8

define RSLeftHandSweep  0xC9


define RSWhistle         0xCA

define

RSRoar            0xCE

int command, buff[]={
  0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
  0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0xB1,
  0xC2, 0xC0, 0xEF, 0xC1, 0xC3, 0xC4, 0xC7, 0xC8, 0xC9};

int LedControl = 13;     // Show when control on
int IROut= 6;            // Where the echoed command will be sent from
int bitTime=516;          // Bit time (Theoretically 833 but 516)
// works for transmission and is faster
int last;                 // Previous command from IR

//////////////////////////////////////////////////////////////////
// Begin Robosapien specific code
//////////////////////////////////////////////////////////////////
// send the command 8 bits
void RSSendCommand(int command) {
  digitalWrite(IROut,LOW);
  delayMicroseconds(8bitTime);
  for (int i=0;i<8;i++) {
    digitalWrite(IROut,HIGH); 
    delayMicroseconds(bitTime);
    if ((command & 128) !=0) delayMicroseconds(3
bitTime);
    digitalWrite(IROut,LOW);
    delayMicroseconds(bitTime);
    command <<= 1;
  }
  digitalWrite(IROut,HIGH);
  delay(250); // Give a 1/4 sec before next
}


// Set up Robosapien functionality
void RSSetup()                   
{
  pinMode(IROut, OUTPUT);
  pinMode(LedControl,OUTPUT);
  digitalWrite(IROut,HIGH);

  // Make robot burp to indicate setup is complete
  RSSendCommand(RSBurp);
}

void setup()
{
  Serial.begin(9600);
  Serial.println("RobSapien Start");

  RSSetup();
}

void loop()
{
 
}

Step #3: Deploy an app on Heroku

PrevNext
Tweetosapien: Hack a Robosapien With Arduino to React to Tweets
  • CLI, Git, SSH Keys, push, pull… Don’t panic! The aim of the next part is to explain how to deploy an app in the cloud on a PaaS like Heroku. Your app will be available 24/24 ! Go on Heroku to create an account. I don’t remember exactly what are the steps to follow but everything is well explained. When your account is ready, you need to install Heroku Toolbelt downloadable here.
  • The steps below are for an OSX / Linux terminal, further information are available on the Heroku documentation. Then, we will create a Python app. The first step is to create an Heroku folder in «My Documents» (or anywhere else !) which will contain all your future apps.
    $ cd ~/Documents $ mkdir Heroku $ cd Heroku

    Then you have to login on Heroku :
    $ heroku login Enter your Heroku credentials. Email: votre_mail@gmail.com Password: Could not find an existing public key. Would you like to generate one? [Yn] Generating new SSH public key. Uploading ssh public key /Users/votre_nom/.ssh/id_rsa.pub

    On the first login, if you have never used Git before, the CLI will generate a SSH key to secure the communication between your computer and the platform. However, if you have ever used Git, I recommend you to follow the «Password caching» section here. Before the next steps, we need to write our app!

Step #4: Twitter streaming API

PrevNext
Tweetosapien: Hack a Robosapien With Arduino to React to Tweets

Before going through the Python allowing us to interact with the Twitter streaming API painless, you need to own a Twitter account. Then you have to create a Twitter application at https://dev.twitter.com

Click on « Create a new application« , give your app a name and fill the field with your website, in this case we don’t need a callback URL. Now, you have your own Twitter app allowing you to use OAuth, the Twitter authentication protocol.

Go on your app and write down your keys :

*Consumer key *Consumer secret *Access token *Access token secret

If I remember well, the access token isn’t created yet and you should generate it. Your Twitter app is ready !

It’s now the time to write our Python app to detect the new Tweets posted on the #tweetosapien hashtag. We could dominate the world with our future army of Robosapiens ! Why Python ? Because it’s easy and fast and we can deploy it painlessly on Heroku. We suppose until the end of this post that you have a working Python dev environment on your computer. We’ll use the Tweepy library that you need to install.

from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
import os, pusher
from time import sleep
from datetime import datetime

Twitter credentials, fill with your keys


consumerkey=""
consumer
secret=""
accesstoken=""
access
tokensecret=""

class StdOutListener(StreamListener):
    """ A listener handles tweets are the received from the stream.
    This is a basic listener that just prints received tweets to stdout.

    """
    def on
data(self, data):
        print data
        return True

    def onerror(self, status):
        print status

if name == 'main':

    l = StdOutListener()
    auth = OAuthHandler(consumer
key, consumersecret)
    auth.set
accesstoken(accesstoken, accesstokensecret)

    stream = Stream(auth, l)    
    stream.filter(track=['#tweetosapien'])

You simply have to add your Twitter keys in the right place. Save the code with the name tweetosapien.py. Then you should execute the program and post a Tweet on #tweetosapien to check if everything works well.

Step #5: Pusher websockets

PrevNext
Tweetosapien: Hack a Robosapien With Arduino to React to Tweets
  • Pusher is a great websockets service. You need to create an account on http://pusher.com and write down your access tokens. Then we’ll use the updated ArduinoPusherClient of Marco Altomonte available here. You have to copy the lib in your libraries sketchbook folder. You also need to install the Pusher Python library with easy_install or pip (pip install pusher). We will now complete the Arduino and Python code and do our little Pusher thing. Then we will deploy the app on Heroku and upload the Arduino code on the board. Leave your terminal open, we will use it later.
  • Pusher Python Go back to our Python app and let’s add the final part. Now, each new Tweets posted on the #tweetosapien hashtag will send an event to Pusher on the private channel private-twitter.
    from tweepy.streaming import StreamListener
    from tweepy import OAuthHandler
    from tweepy import Stream
    import os
    import pusher
    from time import sleep
    from datetime import datetime

    #Pusher credentials

    pusher.app_id = ''
    pusher.key = ''
    pusher.secret = ''

    #Twitter credentials, fill with your keys

    consumer_key=""
    consumer_secret=""
    access_token=""
    access_token_secret=""

    p = pusher.Pusher()

    class StdOutListener(StreamListener):
        """ A listener handles tweets are the received from the stream.
        This is a basic listener that just prints received tweets to stdout.

        """
        def on_data(self, data):
            print data
            p['private-twitter'].trigger('hashtag-newtweet', {'some': 'data'})
            return True

        def on_error(self, status):
            print status

    if __name__ == '__main__':

        l = StdOutListener()
        auth = OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)

        stream = Stream(auth, l)    
        stream.filter(track=['#tweetosapien'])
    To ensure that the code works well, run the Python app and go on the Pusher’s «Debug Console», then Tweet something on #tweetosapien. If everything goes well, you should have a new event in the Pusher console.
  • Pusher Arduino The first step is to fill-in your Pusher credentials (App ID, App Key, Key secret) in the PusherClient.cpp file of the library (on lines 35, 36, 37). Then, you have to replace in WebSocketClient.h the line “#include ” by “#include ” Go on the line 58 to replace « EthernetClient _client; » by « WiFiClient _client; » We’re done for the lib configuration. However, the following code is designed to work with an official Arduino WiFi shield. Some changes may be necessary to make it work with a classic Ethernet shield. Here is the Arduino code to upload on the board :
    /*
    Tweetosapien
    hello@thomasmeghe.fr / May, 2013

    Thanks to RobosapienRu - test Robosapien hackspace.ru
    */

    #include
    #include
    #include

    char ssid[] = "yourssid";     //  your network SSID (name)
    char pass[] = "yourwpakey";  // your network password
    int status = WL_IDLE_STATUS;     // the Wifi radio's status

    volatile int viRobsapienCmd = -1;  // A robosapien command sent over the UART request

    //////////////////////////////////////////////////////////////////
    // Begin Robosapien specific variable deinitions
    //////////////////////////////////////////////////////////////////


    // Some but not all RS commands are defined
    #define RSTurnRight       0x80
    #define RSRightArmUp      0x81
    #define RSRightArmOut     0x82
    #define RSTiltBodyRight   0x83
    #define RSRightArmDown    0x84
    #define RSRightArmIn      0x85
    #define RSWalkForward     0x86
    #define RSWalkBackward    0x87
    #define RSTurnLeft        0x88
    #define RSLeftArmUp       0x89
    #define RSLeftArmOut      0x8A
    #define RSTiltBodyLeft    0x8B
    #define RSLeftArmDown     0x8C
    #define RSLeftArmIn       0x8D
    #define RSStop            0x8E
    #define RSWakeUp          0xB1
    #define RSBurp            0xC2
    #define RSRightHandStrike 0xC0
    #define RSNoOp            0xEF

    //
    #define RSRightHandSweep  0xC1
    #define RSRightHandStrike2 0xC3
    #define RSHigh5           0xC4
    #define RSFart            0xC7
    #define RSLeftHandStrike  0xC8
    #define RSLeftHandSweep  0xC9

    #define RSWhistle         0xCA
    #define RSRoar            0xCE

    int command, buff[]={
      0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
      0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0xB1,
      0xC2, 0xC0, 0xEF, 0xC1, 0xC3, 0xC4, 0xC7, 0xC8, 0xC9};

    int LedControl = 13;     // Show when control on
    int IROut= 6;            // Where the echoed command will be sent from
    int bitTime=516;          // Bit time (Theoretically 833 but 516)
    // works for transmission and is faster
    int last;                 // Previous command from IR

    //////////////////////////////////////////////////////////////////
    // Begin Robosapien specific code
    //////////////////////////////////////////////////////////////////
    // send the command 8 bits
    void RSSendCommand(int command) {
      digitalWrite(IROut,LOW);
      delayMicroseconds(8*bitTime);
      for (int i=0;i<8;i++) {
        digitalWrite(IROut,HIGH);  
        delayMicroseconds(bitTime);
        if ((command & 128) !=0) delayMicroseconds(3*bitTime);
        digitalWrite(IROut,LOW);
        delayMicroseconds(bitTime);
        command <<= 1;
      }
      digitalWrite(IROut,HIGH);
      delay(250); // Give a 1/4 sec before next
    }


    // Set up RoboSpapien functionality
    void RSSetup()                    
    {
      pinMode(IROut, OUTPUT);
      pinMode(LedControl,OUTPUT);
      digitalWrite(IROut,HIGH);

      // Make robot burp to indicate setup is complete
      RSSendCommand(RSBurp);
    }

    void setup()
    {
      Serial.begin(9600);
      Serial.println("RobSapien Start");

      // attempt to connect using WPA2 encryption:
      Serial.println("Attempting to connect to WPA network...");
      status = WiFi.begin(ssid, pass);

      // if you're not connected, stop here:
      if ( status != WL_CONNECTED) {
        Serial.println("Couldn't get a wifi connection");
        while(true);
      }
      // if you are connected, print out info about the connection:
      else {
        Serial.println("Connected to network");
      }

      // wait 10 seconds for connection:
      delay(3000);

      if (!Pusher.connect())
      {
        for(;;);
      }

      Pusher.subscribePrivate("private-twitter"); //Subscribe to the channel
      Pusher.bind("hashtag-newtweet", twitter); //Bind the function to handle the event

      RSSetup();
    }

    void loop()
    {
      Pusher.monitor();
    }

    void twitter(const String& eventName, const String& eventData)
    {
      //Handling event :
      RSSendCommand(RSHigh5);
      Serial.println("New Tweet on the hashtag");
    }
  • Pusher Python We are going to add to our Python app the things needed to trigger a Pusher event when new Tweets are detected.
    from tweepy.streaming import StreamListener from tweepy import OAuthHandler from tweepy import Stream import os import pusher from time import sleep from datetime import datetime #Pusher credentials pusher.app_id = '' pusher.key = '' pusher.secret = '' #Twitter credentials consumer_key="" consumer_secret="" access_token="" access_token_secret="" p = pusher.Pusher() class StdOutListener(StreamListener): """ A listener handles tweets are the received from the stream. This is a basic listener that just prints received tweets to stdout. """ def on_data(self, data): print data p['private-twitter'].trigger('hashtag-newtweet', {'some': 'data'}) return True def on_error(self, status): print status if __name__ == '__main__': l = StdOutListener() auth = OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) stream = Stream(auth, l) stream.filter(track=['#tweetosapien'])
    Don’t forget to fill your Pusher credentials to allow the app works well. You are now ready to deploy your app on Heroku !

Step #6: Heroku app deployment : the end

PrevNext
Tweetosapien: Hack a Robosapien With Arduino to React to Tweets

Here is the great thing : app deployment in the cloud. Follow the steps bellow. You have to create a new app on Heroku, but before, you have to create the tweetosapien folder in which you will save your app in the Heroku folder :

$ mkdir tweetosapien $ cd tweetosapien
Then, move your tweetosapien.py file in this folder. We have to create two more files needed by Heroku to work well. The first one is Procfile where is specified the process which will be launched by Heroku, here’s is it’s content :
worker: python tweetosapien.py
You have to create a second file, requirements.txt where are specified the Python dependencies used by your app :
tweepy pusher
At this moment, your app folder contain at least three files : tweetosapien.py, Procfile and requirements.txt. The you can create a Git repository with the following commands :
$ git init $ git add . $ git commit -m "init"
The next step is to push your app on Heroku, but before, you have to create the Heroku app. The URL is randomly generated by the service :
$ heroku create Creating stark-window-524... done, stack is cedar http://stark-window-524.herokuapp.com/ | git@heroku.com:stark-window-524.git Git remote heroku added

Then, push the code on Heroku :
$ git push heroku master
To finish, we have to tell Heroku which type of Dyno we need (a Dyno is a container allowing us to run an instance of an app, for more information, check the documentation here)
$ heroku ps:scale worker=1
That’s it ! You’re now ready to use your Tweetosapien. We made the thing to monitor a specific hashtag. However, it’s possible (with some changes) to trigger events when you receive a new Tweet or a mention. This code can also be used to connect almost anything to Twitter, it’s up to you! I would like to thanks a lot my friend @hugobiwan helped me a lot to hack the Robosapien and folks of the local Rennes (France) LabFab.