Wenn du mehrere Badges, Monatskarten oder Tickets besitzt und die Anzahl der ungenutzten Badges automatisch in Echtzeit im Internet veröffentlichen möchtest, gibt es keine Lösung von der Stange. Dieser Beitrag beschreibt, wie du ein solches IoT-System bauen kannst.

Hintergrundgeschichte

In unserer Region ist es möglich, eine übertragbare Monatskarte für den öffentlichen Nahverkehr zu nutzen. Unser Dorfverein kauft solche Karten und bietet sie tageweise zur kostenlosen Nutzung an, was hoffentlich die Nutzung von Autos reduziert. Im Gegenzug wird man um eine freiwillige Spende gebeten, um dieses Projekt am Laufen zu halten.

Du kannst zu unserer örtlichen Bäckerei gehen und nach einer solchen Monatskarte fragen. Wenn du in der Bäckerei ankommst und feststellst, dass alle Karten bereits vergeben sind, ist das natürlich frustrierend. Und hier beginnt die Geschichte. Warum nicht ein System bauen, das die Anzahl der verbleibenden Monatskarten erkennt und dies im Internet veröffentlicht? Es gibt keine Lösung von der Stange, aber als Maker ist man natürlich in der Lage, ein solches System zu entwerfen und zu bauen.

Anforderungen

Zunächst brauchst du einen Organizer oder ein Regal, in dem die Pässe einzeln eingesteckt werden können (damit sie gezählt werden können). Dann brauchst du Sensoren, die ihre Anwesenheit überprüfen. Sobald die Anzahl der Monatskarten bekannt ist, sollte sie an einen Host-Computer übertragen werden. Schließlich muss die Zahl auf einer Webseite veröffentlicht werden.

Das alles soll mit minimalem Energieaufwand und maximaler Zuverlässigkeit geschehen, ohne die Sicherheit des drahtlosen Netzwerks des Systems oder des Webservers, der die Webseite mit den Informationen beliefert, zu gefährden.

Der Kartenhalter

Beim Bau des physischen Kartenhalters können 3D-Design und Druck hilfreich sein. Wie zuvor habe ich Tinkercad verwendet, um den Kartenhalter zu entwerfen. Das war eine ziemliche Herausforderung, die einige Iterationen erforderte (Drucken und Wegwerfen von Prototypen). Alles in allem besteht der endgültige Kartenhalter aus mehr als 60 Objekten und Löchern. Ärgerlich war, dass man oft aus Versehen etwas verändert hat, ohne es zu bemerken. Daraufhin beschloss ich, bald auf ein leistungsfähigeres CAD-Tool wie FreeCAD umzusteigen.

Zuerst habe ich versucht, die Fächer separat zu entwerfen und zu drucken und sie am Hauptkörper zu befestigen. Es blieb jedoch immer eine kleine Lücke, durch die die Monatskarte rutschen konnte. Schließlich entschied ich mich, den Halter aufrecht mit integrierten Fächern zu drucken. Das hat hervorragend funktioniert, wie man in der folgenden (3D-animierten) Skizze sehen kann. Die Druckdateien dazu findet man auf printables.com.

Das endgültige Druckergebnis, gedruckt mit meinem Prusa i3 MK3, ist in der nächsten Abbildung zu sehen. Beachte, dass es auch eine Rückseite des Kartenhalters gibt, die weder auf den Fotos noch auf der Skizze zu sehen ist.

Sensoren

Bevor man mit der Gestaltung des Halters beginnen kann, muss man sich entscheiden, welche Art von Sensor man verwenden und wie man ihn im Inneren des Gehäuses anbringen will. Es gibt mehrere Möglichkeiten, z. B. optische und akustische Time-of-Flight-Sensoren, Sensoren zur Reflexionsmessung und NFC/RFID-Sensoren. Ich habe mich jedoch frühzeitig für den Näherungssensor ADPS9930 entschieden. Er nutzt eine IR-Reflexionsmessung, um Objekte zu erkennen, die bis zu 100 mm entfernt sind. Das Gute daran ist, dass die Fächer aus schwarzem Kunststoff bestehen und der Winkel der Wände zu einer relativ geringen Reflexion führt. Der Messwert, den man erhält, wenn sich keine Karte im Fach befindet, liegt zwischen 70 und 150. Befindet sich eine Karte im Fach, auch wenn sie aus schwarzem Papier ist, liegen die Messwerte zwischen 400 und dem Maximalwert 1023. Man kann also zuverlässig erkennen, ob sich eine Karte im Fach befindet.

Die Sensoren können so konfiguriert werden, dass sie sich die meiste Zeit in einem Stromsparmodus befinden und regelmäßig auf signifikante Veränderungen prüfen. Wenn solche Veränderungen auftreten, können die Sensoren einen Interrupt auslösen und die MCU aufwecken.

Drahtloses Netzwerk

Sobald die Sensoren die Anzahl der Badges ermittelt haben, muss man diese Information an einen Webserver senden. Die einfachste Lösung wäre natürlich Wi-Fi. Aber im Zeitalter der gehackten Netzwerke willst du die Leute nicht bitten, dir Zugang zu ihrem Netzwerk zu gewähren. Heutzutage ist die Alternative zu Wi-Fi für IoT-Anwendungen LPWAN (Low-Power Wide Area Network). LTE-M zum Beispiel ist ein sehr erschwinglicher LPWAN-Dienst, der von mobilen Datendienstleistern angeboten wird. Ich habe eine SIM-Karte für 10 € bekommen, die 10 Jahre lang gültig ist und ein Datenvolumen von 500 MB hat. Dieses Datenvolumen hört sich zwar nicht nach viel an, aber die zu erwartende Datenübertragungsrate liegt wahrscheinlich unter 100 kB/Tag, d.h. 500 MB sind mehr als genug.

Das AVR-IoT Cellular Mini Board unterstützt LTE-M. Und die MCU auf dem Board, ein AVR128DB48, ist leistungsstark genug, um das System zu implementieren. Obwohl es mit einem Preis von 80 € nicht billig ist, führt es mühelos zu funktionierenden Lösungen und man ist nicht an eine proprietäre Cloud-Lösung gebunden. Daher wurde dieses Board als Hauptkomponente gewählt.

Kommunikationsprotokoll

Sobald dein Gerät mit dem Internet verbunden ist, muss es über ein Kommunikationsprotokoll mit einem Host kommunizieren. MQTT ist oft das Protokoll der Wahl für IoT-Lösungen, da es für die Kommunikation mit Geräten gedacht ist, die nicht immer online sind. Das bedeutet aber, dass du einen MQTT-Broker betreiben (oder mieten) musst. Da der Plan ist, nur eine Zahl in einem Browserfenster anzuzeigen, ist die einfachere Lösung, diese Zahl mit einer POST-Anfrage an einen Webserver zu übermitteln, z.B. mit einem CGI-Skript. Und das ist auch die gewählte Lösung. Die Übermittlung erfolgt über das HTTPS-Protokoll, was garantiert, dass kein Man-in-the-Middle-Angriff möglich ist. Wenn der Webserver die Messung erhält, speichert er sie zusammen mit einem Zeitstempel, so dass es möglich ist, die Messung zu ignorieren, wenn sie zu alt ist (z. B. mehr als eine Stunde).

Anzeige der Anzahl

Sobald die Anzahl der ungenutzten Badges und der Zeitstempel auf einem Webserver gespeichert wurden, z. B. unter https://example.org/data/example.txt, ist es leicht möglich, sie auf einer Webseite anzuzeigen. Eine einfache Möglichkeit ist das Einbetten von PHP-Code auf der Webseite, wie unten dargestellt.

<!DOCTYPE html>
<html>
    <head>
        <title>cardRack-Test</title>
    </head>
    <body>
      <?php
        function read_card_num($url) {
                $headers = @get_headers($url);
		if($headers && strpos( $headers[0], '200')) { // web page exists
		  $data = explode("\n",file_get_contents($url)); // 1st line data, 2nd timestamp
		} else { 
		  return "no info"; // if webpage does not exist
		} 

		if (time()-$data[1] > 3600+300 ) { // data is too old
		  return "no info";
		} else {
                  return $data[0];
		}
         }
      ?>
      <b>Available cards: <?php echo read_card_num("https://example.org/data/example.txt") ?></b>
    </body>
</html>

Wenn du den Text auf einer WordPress-Website wiedergeben willst, kannst du einen Shortcode definieren, der die oben genannte PHP-Funktion verwendet. Shortcodes können z. B. mit dem CodeSnippet Plugin definiert werden.

Sicherheit

Wie könnten böse Buben einem jetzt das Leben schwer machen? Sie könnten versuchen, das CGI-Skript zu benutzen, um beliebige Dateien hochzuladen, oder sie könnten versuchen, gefälschte Daten hochzuladen. Das Skript schreibt Daten nur in eine bestimmte Datei, und man braucht ein Passwort, das vor dem Schreiben von Daten überprüft wird. Es scheint also äußerst unwahrscheinlich, dass jemand das CGI-Skript missbrauchen kann, solange das Passwort geheim gehalten wird. Und der einzige Ort, an dem das Passwort im Klartext gespeichert wird, ist der Arduino-Sketch. Auf dem Webserver wird nur ein kryptografischer Hash gespeichert, der zur Überprüfung des übermittelten Passworts verwendet wird. Schließlich wird die Übertragung des Passworts, wie weiter oben erwähnt, durch das HTTPS-Protokoll kryptograpisch geschützt.

Benutzer-Interface

Das Benutzer-Interface des Kartenhalters ist simpel. Du steckst eine Karte in ein Fach oder nimmst eine Karte aus einem Fach. Im Prinzip ist es möglich, mehr als eine Karte in ein Fach zu stecken. Ich habe jedoch keine Idee, wie man das verhindern oder erkennen kann. Das sollte man einfach nicht tun!

Es gibt eine LED, die einen Überblick über den Zustand des Geräts gibt. Wenn die LED konstant leuchtet, signalisiert sie, dass das Gerät funktioniert. Wenn eine Karte hinzugefügt oder entfernt wird, wird dies nach 3 Sekunden erkannt und dann blinkt die LED einige Sekunden lang langsam, um zu signalisieren, dass sie die Daten überträgt. Falls etwas schiefgeht, blinkt die LED dauerhaft. Man kann dann versuchen, das System aus und wieder einzuschalten. Wenn das nicht hilft, ist eine Wartung erforderlich.

Im folgenden kurzen Video kannst du das System bei der Arbeit sehen. Anfänglich steckt keine Karte in den Fächern, was im Browserfenster angezeigt wird. Dann werden zwei Karten hineingesteckt, nach kurzer Zeit blinkt die LED, und nach Neuladen der Webseite wird dies auch angezeigt.

Arduino-Sketch

Obwohl der Arduino-Sketch selbst immerhin 400 Zeilen lang ist, ist er nicht sehr kompliziert. Das meiste betrifft die Erkennung von abnormalen Zuständen und deren Meldung. Das Wesentliche des Sketches ist im folgenden Pseudocode dargestellt.

void setup() {
  init_lte_modem();
  init_sensors();
  init_blink_irq_routine(); // blinkt so lange, wie das System wach ist
}

void loop() {
  int numberOfCards;

  numberOfCards = gather_sensor_readings();
  send_number(numberOfCards);
  sleep_until_wakeup(); // wenn sich ein Sensorwert ändert oder nach einer Stunde wacht das System auf
}

Ein interessantes Detail ist, wie die I2C-Sensoren eingebunden werden. Da das Board über zwei I2C-Busse mit unterschiedlichen Spannungspegeln verfügt und diese für die Kommunikation mit anderen Peripheriegeräten verwendet werden, habe ich eine zusätzliche Software-I2C-Bibliothek eingesetzt, nämlich FlexWire. Diese Bibliothek kann die Wire-Bibliothek vollständig ersetzen. Ich wollte aber nicht mit den bestehenden Bibliotheken des Boards interferieren. Also habe ich eine Kopie der FlexWire-Bibliothek in den src-Unterordner des Arduino-Sketches gelegt. Außerdem habe ich die APDS9930-Bibliothek in diesen Unterordner kopiert und so abgeänderte, dass sie mit FlexWire anstelle von Wire funktioniert. Mit dem Software-I2C-Multiplexer-Trick kann ich jetzt mit allen drei Sensoren kommunizieren, ohne einen zusätzlichen Hardware-Multiplexer zu verwenden.

Hardware-Konfiguration

Die Hardware-Konfiguration ist nach den obigen Ausführungen fast schon kanonisch. Die Fritzing-Skizze unten zeigt, wie die drei Sensoren und die System-LED mit der Hauptplatine verbunden werden, die einen Feather-Footprint hat. Ich habe in der Fritzing-Skizze ein M328-Feather-Board verwendet. In Wirklichkeit handelt es sich aber natürlich um das AVR-IoT Cellular Mini Board.

Wie du auf dem Bild am Anfang dieses Blog Posts sehen kannst, habe ich keine fliegenden Kabel verwendet, wie in der Fritzing-Skizze vorgeschlagen. Stattdessen habe ich Dupont-Kabel verwendet, um die Sensoren und die LED mit der Hauptplatine zu verbinden, die ein Prototyping Board namens FeatherWing Doubler ist. Ich habe die Stifte für die Dupont-Stecker auf dieser Platine verlötet, aber der Platz war sehr begrenzt, so dass die eigentliche Lötung hässlich aussieht. Ich werde auf jeden Fall eine Leiterplatte für diesen Zweck entwerfen.

Zusammenfassung & Ausblick

Die Anzahl von ungenutzten Badges, Monatskarten, Tickets oder Pässe auf einer Webseite zu veröffentlichen, klingt nicht besonders kompliziert. Leider gibt es dafür keine Lösungen von der Stange. Aber mit 3D-Druck, dem AVR-IoT Cellular Mini Board, APDS9930 Näherungssensoren und ein bisschen Arduino-Programmierung kann man eine robuste und sichere Lösung entwickeln. Auch wenn es sich nicht übermäßig komplex anhört, musste ich dennoch ein paar Arbeitstage mit dem 3D-Design verbringen, mich mit dem Board vertraut machen und die notwendigen Skripte und Skizzen erstellen. Die Informationen über das fertige System findest du im GitHub-Repository des Projekts.

Obwohl ich das Projekt als nahezu fertig betrachte, gibt es noch ein paar Dinge, die man tun könnte. Eine davon ist, alle Log-Meldungen in den EEPROM zu schreiben, der eine Kapazität von 250 kB hat. Meine ersten Versuche, das EEPROM zu nutzen, waren bisher nicht erfolgreich.

Eine weitere wertvolle Ergänzung auf der Softwareseite wäre, alle Sensormesswerte in einer Datenbank auf dem Webserver zu protokollieren. Daraus könnte man später Statistiken über die Nutzung der Pässe erstellen und u.U. Ausfälle bei der Sensorik sehen. Dann gibt es noch die Möglichkeit, eine Leiterplatte zu entwerfen, die auch die Möglichkeit eröffnet, mehr Fächer zu unterstützen. Schließlich könnte das 3D-Design erweitert werden, um mehr Fächer zu ermöglichen. Das würde wahrscheinlich bedeuten, dass man zwei Kartenhalter drucken muss, die miteinander verbunden werden können.

UPDATE: Das System ist mittlerweile live und man kann die Anzahl der ausleihbaren Regiokarten auf dieser Webseite in Echtzeit verfolgen.

Views: 40