Erstellt am 26.11.2015
Ab in den Äther
Das ganz heiße Thema zur Zeit ist ja IoT - Internet of Things - und angefeuert wird das ganze noch durch das ESP8266-Modul (ESP8266 im Mikrocontroller.net-Wiki). Dabei handelt es sich um eine etwa daumengroße Platine mit einem Mikrocontroller, einigen kB bis MB Flash-Speicher und einer WLAN-Antenne. Dieser Mikrocontroller hat also einen kompletten WLAN-Stack an Board mit dem man sich in jedes handelsübliche WLAN einklinken kann. Wer davon noch nichts gehört hat, der sollte spätestens jetzt einen Blick darauf werfen! Denn es kommt noch besser: Mit der Standardfirmware kann das Gerät über AT-Befehle programmiert werden und stellt zunächst einmal nur eine Brücke zwischen seiner seriellen Schnittstelle und dem WLAN her. Damit lassen sich also prinzipiell andere Mikrocontroller super einfach in ein WLAN (bzw. eben ein Netzwerk) integrieren.
Was dieses Platinchen aber für mich richtig interessant macht, ist die Möglichkeit eine Firmware zu flashen, die einen Lua-Interpreter beinhaltet und schon viele Basisfunktionen für das Verbinden mit dem Funknetzwerk, zum Arbeiten mit der seriellen Schnittstelle und vorallem zum Arbeiten mit TCP- und UDP-Verbindungen mit bringt. Damit kann man also diesen Chip stand-alone betreiben und beispielsweise einen Webserver implementieren, der Sensorwerte bereit stellt - und das alles auf nur 2,4 x 1,6 cm Platinengröße.
RFID + Wifi
Den RFID-Reader hatte ich euch bereits in meinem Artikel RFID-Türöffner vorgestellt. Damals hatte ich das Reader-Modul, welches die ausgelesene Tag-ID der RFID-Tokens einfach auf seiner seriellen Schnittstelle ausgibt mit einem Attiny 2313 gekoppelt, der die IDs mit einer Liste auf seinem EEPROM abgleicht und entsprechend einen Relaisausgang schaltet. Der RFID-Reader ist inzwischen hinter ein noch freies Lautsprechergitter (aus Plastik, sonst würde das wohl nicht funktionieren) an der Sprechanlage am Gartentor gewandert. Dort hält man einfach seinen RFID-Tag hin, die ID wird an den Mikrocontroller gesendet, welcher dann den Torsummer aktiviert. Ich weiß aber somit nicht, welchem Tag gerade die Tür geöffnet wird. Auch das Einprogrammieren neuer IDs gestaltet sich schwierig. Dazu muss ich immer erst das Gehäuse öffnen, welches den Mikrocontroller beherrbergt, die Jumper zum Programmieren umstellen und mich mit einem Laptop verbinden. Viel schöner wäre es da doch, wenn man die IDs in einer Datenbank auf einem Server vorhalten und abgleichen könnte.
Jetzt sagt ihr sicher, na dann verbinde doch einfach den RFID-Reader direkt mit dem Server. Genau das hätte ich gerne gemacht, nur leider sind keine freien Kabel mehr verfügbar, über die das Signal in den Keller gelangen könnte. Genau hier kommt also das ESP-WLAN-Modul in's Spiel. Es empfängt die IDs vom RFID-Reader und sendet einen GET-Request an den Webserver. Dieser sieht in der Datenbank nach, ob er die ID kennt und quittiert mit "OK" oder "NO". Zusätzlich lauscht das ESP-Modul auf UDP Port 18. Sendet man hier den String "on", wird ebenfalls der Relaiskontakt betätigt. Ihr seht, dem Gartentorsummer im Internet sind somit keine Grenzen mehr gesetzt - außer vielleicht durch die fehlenden Buzzwords, wie "Doorbuzzer as a service" oder "Internet of Doors"
Die Hardware
Für die Realisierung habe ich mich für das ESP-12-Modul entschieden. Es gibt inzwischen für fast jeden Geschmack Module, das 12er hat aber mit die meisten IO-Ports. Sogar ein AD-Wandler ist mit von der Partie. Als RFID-Reader kommt das bereits beschriebene Modell RDM6300 zum Einsatz. Außerdem benötigt ihr noch ein paar Spannungswandler: einen mit 3,3 V Ausgang für das ESP-Modul (hier sollten schon 700 mA verfügbar sein, da das Modul zum Senden recht viel Leistung braucht) und einen mit 5 V Ausgang für den RFID-Reader. Dann alles nach diesem Vorbild zusammen braten:
Schaltplan für EAGLE
ESP-Library für EAGLE
Über einen Spannungsteiler wird das TTL-Signal vom RFID-Reader auf ein erträgliches Maß für den ESP herunter gespannt, denn das ESP-Modul ist nicht 5 V tolerant! Der DIP-Schalter an GPIO0 ist zum Flashen. Zieht man ihn auf GND und drückt den Resettaster, kann über die serielle Schnittstelle eine neue Software aufgespielt werden. Das fertige Platinchen sieht bei mir dann so aus - hier erstmal auf dem Steckbrett:
Statt DIP-Schalter und Taster habe ich einfach zwei Jumper-Pins eingelötet.
Die Software
Läuft die Hardware soweit, brauchen wir jetzt etwas Software damit der Prozessor tut, was wir wollen. Dazu ladet ihr euch am Besten erstmal die neue Firmware sowie den Firmware-Flasher herunter. Als Firmware kommt NodeMCU zum Einsatz. Um eine Firmware zu flashen gibt es einige Tools. Meine Versuche starteten zunächst mit dem esptool, da das einfach als python-Script unter Linux läuft. Leider brach damit der Flashvorgang immer nach wenigen Prozent mit der Meldung "A fatal error occurred: Invalid head of packet" ab. Langwieriges Suchen im Internet brachte leider keine Lösung, also habe ich mein gutes altes Windows wieder mal heraus gekramt und dort mit dem offiziellen NodeMCU Flasher die Firmware auf das Modul spielen können.
Die Firmware müsst ihr euch über ein "Custom Build" holen, da soweit ich das verstanden habe, das bit-Modul in den fertigen FW-Images fehlt. Aber das alles ist super easy, ihr braucht keine Toolchain, sondern ruft einfach folgende Seite auf: nodemcu-build.com. Dort einfach die Standardeinstellungen übernehmen und zusätzlich noch die Module bit und http auswählen. Als E-Mail-Adresse könnt ihr auch irgend eine Trash-E-Mail verwenden, hauptsache ihr könnt auf ihr den Link zum Download empfangen.
Wenn ihr also Firmware und Flasher habt, dann braucht ihr noch einen USB-Seriell-Adapter mit 3,3 V. Wie gesagt, die Eingänge des ESP-Moduls sind nicht 5 V tolerant! Wenn ihr da mit 5 V rein geht, dann ist das Teil kaputt. Nach einem kleinen Kampf mit dem Treiber für meinen Adapter kann man in der Software den COM-Port und die Firmware wählen. RX- und TX-Leitungen vom Modul und dem Adapter verbinden, danach das ESP-Modul in den Flash-Modus versetzen (GPIO0 über den Schalter oder Jumper auf GND legen und Reset auslösen). Dann nur noch auf Flash klicken und warten.
Nach erfolgreichem Flashvorgang, GPIO0 wieder floaten lassen (also einfach nix anschließen) und einen weiteren Reset ausführen. Mit einem Terminalprogramm alla putty oder minicom lässt sich jetzt eine Verbindung zum Lua-Interpreter auf dem Chip aufbauen. Dazu die Schnittstelle auf 9600 Baud (in neueren Versionen die Baudrate auf 115200 erhöht worden), 8 N 1 stellen und ihr bekommt einen command-prompt. Hier können jetzt direkt Lua-Befehle eingegeben werden, z.B. print(wifi.sta.getmac()) um die MAC-Adresse des Moduls anzuzeigen. Die Firmware ist so aufgebaut, dass sie am Anfang das init.lua-Script startet. Diese habe ich quasi wie einen Bootloader gestaltet. Wenn ihr nichts macht, wird per dofile() die rfid.lua gestartet, die das eigentliche Programm beinhaltet. Wenn ihr die Enter-Taste drückt landet ihr in der NodeMCU-Konsole. Nachfolgend habe ich euch meine init.lua sowie meine rfid.lua verlinkt. Die rfid.lua müsst ihr natürlich mit eurer SSID und dem PSK für euer WLAN bestücken, sowie der Adresse für den Server welcher die check.php ausführt. Diese liefert eine Variable per JSON zurück, die entweder OK oder NO beinhaltet. Je nachdem wird der Torsummer betätigt oder nicht.
- init.lua WLAN initialisieren und main.lua starten
- rfid.lua Hauptprogramm
- check.php PHP-Script welches RFID-IDs abgleicht
Und wie kommen die Dateien jetzt auf das Modul? Ganz einfach, dafür gibt es noch ein nettes Programm: luatool. Das benötigt Python und das pyserial-Modul. Dann lassen sich die Dateien im Handumdrehen auf das Modul übertragen:
python luatool.py --port /dev/ttyUSB0 --src init.lua --dest init.lua --verbose python luatool.py --port /dev/ttyUSB0 --src rfid.lua --dest rfid.lua --verbose python luatool.py --port /dev/ttyUSB0 --restart
Damit wäre das Modul einsatzbereit.
Der erste Test
- Der neue Torsummer wird verkabelt
Jetzt kommt also der erste Test. Den RFID-Reader über die zwei Spannungsteilerwiderstände mit dem ESP-Modul verbinden, alles mit Strom versorgen und wenn ihr jetzt einen RFID-Tag an den Reader haltet, sollte in eurem Serverlog ein Eintrag wie folgt erscheinen:
192.168.XX.YY - - [25/Nov/2015:00:58:36 +0100] "GET /rfid/check.php?id=0123456789 HTTP/1.1" 200 160 "-" "NodeMCU-12345432"
Außerdem könnt ihr noch schauen, ob der UDP-Dienst funktioniert. Mit netcat lassen sich z.B. UDP-Pakete von der Kommandozeile aus verschicken:
echo -n "on" | nc -4u -w1 192.168.XX.YY 18
Dies sollte ebenfalls in einem Klick vom Relais münden. Etwas PHP-Code zum Senden der Daten über UDP habe ich auch noch für euch: sendudp.php
Damit habt ihr jetzt eure Garten- oder Haustür erfolgreich in das Internet der Dinge befördert und könnt jetzt auch aus Sibirien mit Satteliteninternet euere vier Wände fernsteuern.
Manchmal kann es nützlich sein, für Testzwecke das main.lua zu beenden. Dafür habe ich eine kleine Datei erstellt, welche die Steuerzeichen STX (start of text), quit und ETX (end of text) enthält. Schickt man dies an das ESP-Modul wird das main.lua-Script beendet und ihr könnt z.B. mit dem luatool eine neue Version aufspielen. Auch habe ich ein Testfile erstellt, mit dem man den RFID-Reader simulieren kann. Einmal mit gültiger Checksum, einmal mit ungültiger*. Die Dateien lassen sich ganz einfach an die Schnittstelle schicken, sobald diese auf 9600 Baud initialisiert ist:
cat quit.rfid > /dev/ttyUSB0
- quit.rfid
- example.rfid (gültige checksum)
- example2.rfid (ungültige checksum)
* Leider sendet mein RFID-Reader selber immer unpassende Checksummen, daher habe ich diese Routine im Code auskommentiert. Laut Datenblatt werden die 5 Bytes der Token-ID ver-Xoder-t. Also bei einer ID von 0123456789 wird bitXor( 0x01, 0x23, 0x45, 0x67, 0x89 ) ausgeführt. Bei meinem Reader wurde aber eine andere checksum übertragen. Letztlich äußert sich aber ein Übertragungsfehler eh in einer ungültigen ID, von daher ist es nicht so schlimm, dass die Checksum-Funktion nicht klappt. Wenn ihr noch zielführende Hinweise habt, was da schief laufen könnte, immer gerne her damit.