Arduino Tweet Bot – Teil 2

Wie bereits angekündigt folgt hier der zweite Teil meines kleinen Arduino-Projekts. Aufgrund einer fehlerhafter Bestellung leider mit etwas Verzögerung.
Es ist eine Schritt-für-Schritt-Anleitung für einen Arduino Twitter-Client und richtet sich an Programmierinteressierte.

Auf dem Bild ist ein “Arduino Duemilanove” zu sehen, welches um ein Ethernet-Shield erweitert wurde. Wie beim letzten Beitrag erwähnt, braucht es die Ergänzung für die Kommunikation mit dem Internet. Die beiden Teile können ohne Löten aufeinander gesteckt werden. Das Board wird nun über USB an den Laptop angeschlossen und kann mit der Arduino Software kommunizieren.

Vor einigen Tagen habe ich einen Samplesketch heruntergeladen, der das einmalige Posten eines Tweets ermöglicht. Unter dem Twitternamen „Digezzbot“ ist das Arduinoboard zu finden. Das reine Versenden von Tweets ist aber nicht besonders spannend. Ich möchte deshalb auf ein anderes Programm eingehen, welches etwas komplexer ist. Es ist Teil von Arduinos Beispielbibliothek und kann von der Arduino-Website heruntergeladen werden. Das Programm parst ein XML welches von Twitter generiert wurde, um den letzten Tweet eines Benutzers anzuzeigen. Einige mögen sich fragen, warum ich das Ganze mache. Und ganz ehrlich, das Programm selbst bringt niemandem was. Doch für mich war es sehr spannend, die Zusammenarbeit zwischen Hard- und Software zu entdecken und Basisprogramme zu analysieren.

Nun möchte ich die Funktion der Software beschreiben.

Zuerst werden die Libraries von Twitter und SPI importiert. SPI brauchen wir, um über die serielle Schnittstelle mit dem Ethernet Shield kommunizieren zu können.

#include 
#include

Danach wird MAC- und IP-Adresse definiert. In meinem normalen Klasse C Heimnetzwerk wurde die IP 192.168.1.20 noch nicht vergeben und wird dem Arduino-Board zugeteilt. Diese IP kommt aber nur zum Einsatz, wenn die Vergabe über den DHCP nicht funktioniert.

byte mac[] = {
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01 };
IPAddress ip(192,168,1,20);

Dann werden einige Variablen vergeben. Wir benötigen einen EthernetClient, die Variable dafür lautet “client”. Mittels string definieren wir eine Variable, die den Text vom Server speichert und ebenfalls eine für den Tweet. Mit einem boolean wird festgelegt, ob der Tweet gerade gelesen wird.

EthernetClient client;
//...
String currentLine = "";
String tweet = "";
boolean readingTweet = false;

Ab hier sind wir im Bereich void setup. Mit diesen Zeilen wird Platz für die strings reserviert:

void setup() {
  currentLine.reserve(256);
  tweet.reserve(150);

Danach wird die Verbindung hergestellt. Funktioniert die dynamische Vergabe der IP mittels DHCP nicht, wird auf die vorgegebene IP (192.168.1.20) zurückgegriffen.

  Serial.begin(9600);

  if (!Ethernet.begin(mac)) {
    Ethernet.begin(mac, ip);
  }
  connectToServer();
}

Die Funktion connectToServer(); wird weiter unten im Code definiert. Im Bereich void loop Fragen wir als Erstes ab, ob der Ethernet Client verbunden und verfügbar ist. Damit die Tweets gelesen werden können, weisen wir der char-Variable inChar (eingehende Daten) die Funktion read(); zu.

void loop()
{
  if (client.connected()) {
    if (client.available()) {
      char inChar = client.read();

Wenn neue Daten empfangen werden, kommen diese zu inChar dazu.

currentLine += inChar;

Wenn aber eine ganz neue Linie (sprich Tweet) empfangen wird, löschen wir den bisherigen Inhalt von inChar. Danach wird abgefragt, ob die aktuelle Linie mit Text endet. Wenn das erfüllt ist, wird die Funktion readingTweet auf true gestellt. Der Tweet beginnt.

      if (inChar == '\n') {
        currentLine = "";
      }
      if ( currentLine.endsWith("")) {
        readingTweet = true;
        tweet = "";
      }

Wenn die Daten gerade gelesen werden, werden diese dem Tweet-String hinzugefügt. Wenn das Zeichen „<“ auftaucht, ist das Ende des Tweets erreicht. Dann wird die Verbindung zum Server unterbrochen.

      if (readingTweet) {
        if (inChar != '<') {
          tweet += inChar;
        } 
        else {

          readingTweet = false;
          Serial.println(tweet);   
          client.stop(); 
        }
      }

Die Funktion connectToServer() stellt die Verbindung her und gibt die Infos auf der Konsole mittels println aus. Bei der Serververbindung wird „connecting to server…“ ausgegeben. Während die Seite mit dem XML aufgerufen wird, wird „making HTTP request…“ ausgegeben. Der Link zeigt auf https://twitter.com/statuses/user_timeline.xml?screen_name=Digezz_mmp&count=1 also auf Benutzer Digezz_mmp mit count=1 (es wird 1 Tweet angezeigt).

void connectToServer() {
  Serial.println("connecting to server...");
  if (client.connect(serverName, 80)) {
    Serial.println("making HTTP request...");
    client.println("GET /1/statuses/user_timeline.xml?screen_name=Digezz_mmp&count=1 HTTP/1.1");
    client.println("HOST: api.twitter.com");
    client.println();
  }

Und hier das Resultat in Form eines Screenshots der Konsole:

Den vollständigen Code kann man hier ansehen: Arduino Twitter Client