Tweeting from the ESP8266

Other blogs have covered how to send data from the ESP8266 to a web server.  Sparkfun suggest a few services (here).  I've started playing around with ThinkSpeak.  The platform is great, and allows you to react to and visualise your data.  I have been looking for a way to post to Twitter from the ESP8266 for a project I've started working on and found that there wasn't a wealth of information.


Firstly, I had to register at ThinkSpeak, then link my Twitter account to my ThinkSpeak account.  Go to ThinkSpeak-->Apps--> ThinkTweet then click on "Link Twitter Account".  This generates an API key that is used in the code to authenticate the post.  For posting from the ESP8266, I used the code here as a start template.

The first time I tried to send a tweet using the code, only the first word of the string was sent.  The problem is that strings containing "special" characters such as space non-alphanumerical characters need to be percent-encoded.  Thankfully this is trivial to do.  I couldn't find a standard function to do this, so I wrote my own:
String encodeURL(char *src)
{
  String encoded="";
  char *hex = "0123456789ABCDEF"; 
  char *ptr = src;
  char c=0;

  while (c!='\n')
  {
    c = *ptr;
      if( ('a' <= c && c <= 'z')
          || ('A' <= c && c <= 'Z')
          || ('0' <= c && c <= '9') )
          {
            encoded+=c;
          }
          else
          {
            encoded+="%";
            encoded+=hex[c >> 4];
            encoded+=hex[c & 15];
          }
    ptr++;
  }
  return encoded;
}
In the above code, the address of the string is passed to the function.  The string is parsed - if the character is 0-9, a-z or A-Z it is appended unchanged, otherwise the percent sign is appended, followed by the hexidecimal value of the character.  The encoded string is returned and is called like so:
char tweet[] = "This is my tweet, with spaces and characters!! :)\n";
.
.
.
Serial.println(encodeURL(&tweet[0]);
Confusingly, using a String object to hold the tweet string caused problems with some characters - in particular the '?' character was reported as '|'.  I never got to the bottom of this, but using a character array as above worked.  I found I needed to explicitly add the end of line character '\n' though, as the compiler didn't add it automatically.  It is then simply a matter of calling the below SendTweet function to send the tweet!
String API = "XXXXXXXXXXXXXXX"; // Your ThingSpeak-Twitter API key goes here
.
.
.
void SendTweet(void)
{
if (client.connect("184.106.153.149", 80))
{
  client.print("GET /apps/thingtweet/1/statuses/update?key=" + API + "&status=" + encodeURL(&tweet[0]) + " HTTP/1.1\r\n");
  client.print("Host: api.thingspeak.com\r\n");
  client.print("Accept: */*\r\n");
  client.print("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n");
  client.print("\r\n");
  Serial.println("Success!");
}
else Serial.println("Could not connect to ThingSpeak!");
}
Note, that it seems you can't send the same tweet twice.  Happy tweeting from your sensors!

Comments

Popular posts from this blog

Getting started with the Pro Micro Arduino Board

Arduino and Raspberry Pi serial communciation