loading...

Tweeting with Arduino Uno

danielammorais profile image Daniela Morais ・4 min read

A long time ago I bought an Ethernet ENC28J60 but I just recently tested it and, although I enjoy Java and I've used it in all of my previous projects to develop the interface between Arduino and server, it was clear to me that Python would be a much better choice in this case.

In 2014, I decided to use Panama Hitek Arduino SDK and then I sent them an email sharing my experience with their new SDK version. In 2016, I randomly met the guys from the Panama Hitek at the Fedora Latin America Meeting in IRC. Sharing your experience as a developer and be engaging in communities is very important, maybe you will meet the developers of your favorite framework in these spaces or even work with them. For me, it's one more example of the importance of sharing knowledge and ideas through articles, talks, meetings etc. So, don't be shy or scared of sharing what you know.

IoT is about being connected

IoT, embedded systems and smart devices are different concepts and there's a constant confusion when using these terms.
If your device is disconnected from Internet, it probably isn't generating the value of an IoT device. Being connected is more than reading commands remotely from an app, it's a possibility to interact in different ways with your client and other systems like Twitter and also to collect useful information that can be used to make it even smarter.

First step

Register your app in Twitter to consume their API. Access Twitter Dev to create your Twitter application and generate an access token to enable tweeting from your account ("Keys and Access Tokens" > "Create my access token")

Solutions

The Chuck Norris way

You can develop your own C program to connect with Arduino and send HTTPS requests to the Twitter API. There's a Tweet Library for Arduino available but it's deprecated and needs refactoring to work with Arduino versions higher than 1.6.4.

SpongeBob SquarePants

The easy way

Working with pointers and in a low level can be complicated if you don't have experience with C and micro-controller, registers, digital systems etc. Use a python script and it will be much easier to code and maintain the software. Python will be responsible for exposing a web server which will then be consumed by your Arduino and send the content (e.g, sensor values, commands to turn on or off the lights etc) to Twitter. Note that Arduino UNO has limitations when building HTTP requests (it was necessary to use GET method instead of POST to create a tweet) and for this reason Python doesn't expose an API.

Requirements

  • UIPEthernet
  • Python 2.7
  • pip
  • twython
  • flask

EtherShield and ETHER_28J60 are common libraries used in most of tutorials, but UIPEthernet is compatible with the original Ethernet which allows you to use the examples avaiable in the Arduino IDE (File > Examples > Ethernet) just by replacing:

#include <SPI.h>
#include <Ethernet.h> //Replace here with <UIPEthernet.h>

Download UIPEthernet and install Flask and Twython:

$ cd ~/Arduino/libraries/
$ git clone https://github.com/ntruchsess/arduino_uip UIPEthernet
$ sudo pip install flask
$ sudo pip install twython 

Create a configuration file, insert information generated by Twitter for you:

# api_config 
APP_KEY = 'your_api_key'  
APP_SECRET = 'your_api_secret'  
OAUTH_TOKEN = 'your_access_token'  
OAUTH_TOKEN_SECRET = 'your_token_secret'  

In the same folder, create tweet.py:

from twython import Twython  
from flask import Flask  
import api_config

app = Flask(__name__)

APP_KEY = api_config.APP_KEY  
APP_SECRET = api_config.APP_SECRET  
OAUTH_TOKEN = api_config.OAUTH_TOKEN  
OAUTH_TOKEN_SECRET = api_config.OAUTH_TOKEN_SECRET 

twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)

@app.route("/")
def index():  
    return "Hello world, I'm running!"

@app.route("/tweet/<message>")
def sendTweet(message):  
    twitter.update_status(status=message); 
    return "Done." 

if __name__ == '__main__':  
    #Fix here
    app.run(host="your_ip", port=8080, debug=True)

Upload to Arduino:

#include <SPI.h>
#include <UIPEthernet.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};  
char server[] = "ip_server"; //fix here  
IPAddress ip(192, 168, 1, 177); //fix here
EthernetClient client;

void setup() {  
  Serial.begin(9600);
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    Ethernet.begin(mac, ip);
  }
}

void loop() {  
  if (client.connect(server, 8080)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /sendTweet/Hello%20world%20by%20Arduino HTTP/1.1");
    client.println("Host: ip_server_with_port"); //fix here
    client.println("Connection: close");
    client.println();
    client.stop();  
  } else {
    Serial.println("connection failed");
  }

  delay(5000);
}

Give the script permission to execute:

$ chmod a+x tweet.py
$ python tweet.py

And magic.....

Observations

For some reason, I can't make requests to local servers and it was necessary to host the Python script on Digital Ocean. The server doesn't support HTTPS and some times an error about this was received.
Note that this Python script doesn't expose an API and you must always use URL Encoder/Decoder to send messages in the path param. Special characters can be a problem, try to use curl or wget if you get any errors.

Cool things

Tweetduino
IoT is eating the world
APIs for IoT devices (Brazilian Portuguese)

References

Arduino Ethernet – Pushing data to a (PHP) server http://www.tweaking4all.com/hardware/arduino/arduino-ethernet-data-push/

How to Send Tweet From Command Line using Python http://www.techplugg.com/send-tweet-command-line-python/

Originally posted on my personal blog.

Posted on by:

danielammorais profile

Daniela Morais

@danielammorais

software engineer (java☕ & spring), free software activist and computer science student

Discussion

pic
Editor guide
 

Heck yes. I need to start tinkering more with Arduino!