In meinem letzten Beitrag habe ich ein LCD/LED-Gerät gebastelt. In diesem Artikel geht es um einen möglichen Anwendungsfall: Das Lesen von RSS-Feeds und deren Anzeige auf dem LCD-Bildschirm.

Die Bauanleitung für das LCD/LED-Gadget habe ich im letzten Artikel vorgestellt. Eigentlich wollte ich ein Tool zum Abrufen von E-Mails schreiben, leider führte ein Testskript von mir zu einem schweren Fehler (Segfault), da das Perl-Modul Mail::POP3Client im verschlüsselten Betrieb wiederum auf das SSL-Modul von Perl zurückgreift, welches offenbar irgendwo einen Null-Pointer verwendet (in seiner Verbindung zu openssl). Aus diesem Grund habe ich einen Newsreader  in Perl implementiert, den Mail-Leser werde ich mit Java umsetzen.

Vorbereitungen

Die D2XX-Treiber und die entsprechenden Perl-Bindings müssen installiert sein, damit das Perl-Skript unten funktioniert. Eine detaillierte Anleitung findet man in meinem Artikel LED am USB-Port: Neue E-Mails anzeigen lassen unter den Überschriften „D2XX-Treiber installieren” und „FTD2XX-Bindings für Perl installieren”.

Ansonsten benötigt man eigentlich lediglich das unten stehende Skript. Individuelle Einstellungen lassen sich jederzeit im Kopfbereich (Zeilen 22–56) des Skripts vornehmen.

Aufruf und Ergebnis

Mann muss das Skript ausführbar machen (unter Linux z.B. mit chmod +x feedreader.pl). Einen beispielhaften Aufruf des Skripts sieht man in folgendem Video:

Erläuterungen zum Skript

Das Skript ruft eine Server-Subroutine auf, welche zwei weitere Threads startet: Einem für die LED und einen für die LCD-Anzeige. Der Hauptthread kümmert sich selbst um die Abfrage des Feeds.

Demzufolge teilt sich das Skript in mehrere logische Teile:

  1. FTDI-Steuerung allgemein (Zeilen 61–112): Hier wird der FTDI-Kontext geladen bzw. geschlossen.
  2. LED-Funktionen (Zeilen 118–124): Diese kapseln die FTDI-Aufrufe in einfache Subroutinen.
  3. LCD-Routinen (Zeilen 130–248): Bei diesen handelt es sich um allgemeine Routinen zum Ansprechen des LCDs. Bei den Routinen habe ich mich von jenen im Arduino-Playground inspirieren lassen.
  4. Blink-Thread (Zeilen 254–275): Der Blink-Thread kümmert sich um die LED im Gerät. Es gibt zwei globale Variablen, die gesetzt werden können: blinkLED lässt die Diode immer blinken. blinkUntil kann auf einen Unix-Timestamp (Anzahl der Sekunden seit 1.1.1970) gesetzt werden, um das Blinken an einem bestimmten Zeitpunkt einzustellen. blinkLED besitzt Priorität gegenüber blinkUntil.
  5. LCD-Thread (Zeilen 281–348): Der Thread kümmert sich um die Anzeige im Gerät. Als wichtigste globale Variable dient der Array @content, in dem die Titelüberschriften des Feeds gespeichert werden. Weitere globale Variablen verhindern konkurrente Zugriffe von Threads auf diese Variable und steuern die Beleuchtung der Anzeige (ähnlich wie für die LED). Der Thread selbst initialisiert zuerst die LCD-Anzeige und fährt einen Test, um Fehler zu prüfen. Dann geht es in die Hauptschleife. Falls Nachrichten vorliegen, wird zunächst geprüft, ob es neue Nachrichten gab, indem der erste Eintrag des Arrays mit einer gespeicherten Variable verglichen wird. Falls es neue Beiträge gab, wird das Blinken gesetzt und die LCD-Anzeige beleuchtet. Die restlichen Aufrufe im Thread kümmern sich um die Hintergrundbeleuchtung, die Position der Anzeige und schließlich die Anzeige selbst. Der Titel wird dabei abgeschnitten und ins ASCII-Format transformiert, damit die Anzeige keine fehlerhaften Zeichen darstellt. Die Schleife zählt am Ende immer einen Positionsanzeiger hoch und wartet eine Weile. Es werden also die Nachrichten hintereinander auf der LCD-Anzeige dargestellt.
  6. Server-Thread (Zeilen 354–454): Der Server initialisiert anfangs den FTDI-Kontext und startet die beiden anderen Threads. Dann ruft er in regelmäßigen Abständen die Routine getRSS auf. Diese lädt den Feed aus dem Internet und parst ihn mit Hilfe des Perl-Moduls XML::RSS. Falls keine Fehler auftreten, wird der globale Array @content mit den Titelzeilen des Feeds überschrieben.
  7. Hilfsfunktionen und Start (Zeilen 460–551): Am Ende folgen einige Hilfsfunktionen und der Start des eigentlichen Servers.

Es ist im Übrigen recht einfach, das Skript in Linux beim Laden des Systems als Daemon zu starten. Als Basis dient in der Regel eine „leere” Daemon-Datei namens /etc/init.d/skeleton.

Ansonsten wünsche ich viel Spaß mit dem Skript!