Brücken bauen – die Bridge-Bibliothek des Arduino Yún

Send to Kindle

Wer schnell Sensoren oder Aktoren ins Netz bringen möchte, verwendet dafür häufig “normale” AVR-Microcontroller und kombiniert diese mit Ethernet- oder Wifi-Shields. Das ist relativ günstig – ein Pro Mini Klon plus Ethernetmodul kostet etwa 10 Euro, verlangt den kleinen Microcontrollern aber einiges ab – an moderne Sicherheitsfeatures wie HTTPS oder auch nur HTTP-Authentifizierung ist nicht zu denken. Andererseits haben Einplatinencomputer wie der Raspberry Pi oder Banana Pi meist keinen Analog-Digital-Wandler und fordern von Arduino-Nutzern, dass sie sich an neue Programmiersprachen gewöhnen müssen – Zudem bedeutet der Wechsel zu Banana Pi oder Raspberry Pi, dass alte Arduino-Sketches nicht weiterverwendet werden können.

Diesem Problem hat sich das Arduino-Projekt seit Mitte 2013 angenommen, herausgekommen ist eine Platine im Arduino-Format, die den ATmega32u4 des Leonardo mit einem MIPS-Prozessor, WLAN und Ethernet kombiniert. Die MIPS-Seite kennt man von DSL-Routern. Der Clou: Zur Kommunikation zwischen der Arduino-Seite und der Linux-Seite dient eine Bibliothek, die “Bridge” heisst. Diese erlaubt es, per REST API ansprechbare Sensoren oder Aktoren zu bauen, ganz ohne auf der Linux-Seite programmieren zu müssen.

Der Yún nutzt Grundfläche und Pin-Layout des Leonardo, bringt aber neben dem Atmega-Microcontroller einen MIPS-Prozessor unter, der unter Linux läuft

Der Yún nutzt Grundfläche und Pin-Layout des Leonardo, bringt aber neben dem Atmega-Microcontroller einen MIPS-Prozessor unter, der unter Linux läuft

In diesem Beitrag stelle ich das Konzept und einfache, sinnvolle Anwendungen vor. Im nächsten Beitrag zeige ich Anwendungen – auch aus den offiziellen Beispielen -, die nicht ideal umgesetzt sind, nenne die technischen Hintergründe und zeige Vor- und Nachteile anderer Kommunikationsformen zwischen Linux-Single-Board-Computer und Microcontroller. In einem dritten Beitrag werde ich mich mit Details der Implementierung und die Portierbarkeit auf andere Platinen auseinandersetzen.

Inbetriebnahme des Yún

Das Linux-System des Yún besiert auf OpenWRT, der freien Distribution für Router und Accesspoints. Beim ersten Start spannt der noch unkonfiguierte Yún einen WLAN Accesspoint auf. Sein Name lautet “Yun” gefolgt von der MAC-Adresse. Verbinden Sie sich mit diesem Accesspoint und rufen Sie dann im Browser http://192.168.240.1/. Sie befinden sich nun in der Erstkonfiguration. Führen Sie die folgenden Schritte durch:

  1. Verbinden Sie den Yún mit Ihrem WLAN
  2. Vergeben Sie ein Root-Passwort
  3. Öffnen Sie den Zugang zum REST API (nur in vertrauensvollen Umgebungen)

Im Prinzip können Sie den Yún auch als WLAN-Bridge oder Access-Point konfigurieren. Sogar die Verwendung als DSL-Router (dann nur mit WLAN und ohne interne LAN-Ports) ist möglich. Doch dazu an anderer Stelle.

Erstkonfiguarion des Yún: Typische Einstellung ist die Nutzung als WLAN- oder LAN-Client

Erstkonfiguarion des Yún: Typische Einstellung ist die Nutzung als WLAN- oder LAN-Client

Der erste Sketch

Um Sketches zum Yún hochzuladen wird keine USB-Verbindung benötigt. Der Yún kann an seinem Einsatzort verbleiben. Öffnen Sie im Menu der Arduino-IDE die Ports-Liste: Spätestens eine Minute nach dem Start sollte der Yún hier auftauchen. Der Trick? Broadcasts, die der Yún aussendet und auf die die IDE reagieren kann. Taucht der Yún nicht auf, sind möglicherweise die Firewall-Einstellungen zu strikt gesetzt. Nach Auswahl des Yún im Board Menüs und im Port-Menü können Sie eine einfachen Sketch zum Yún hochladen – starten Sie mit dem Blink-Beispiel. Beim Hochladen wird das soeben vergebene Root-Passwort des Yún abgefragt und bis zur Ende dieser Sitzung in der Arduino-IDE gespeichert.

Zweimal Yún? Ja, dieser Yún ist gerade auch per Ethernet mit dem gleichen Netz verbunden

Zweimal Yún? Ja, dieser Yún ist gerade auch per Ethernet mit dem gleichen Netz verbunden

Die Bridge: Sensorwerte per REST-API bereitstellen

Die Bridge bietet mit Bridge.put() und Bridge.get() zwei Funktionen für den Zugriff auf den gemeinsamen Schlüssel-Wert-Speicher. Die tatsächliche Speicherung findet im Microcontroller statt, werden Sie sich also bewusst, dass spätestens nach ein paar Dutzend hier abgelegten Werten Schluss ist. Warum das gut und schlecht ist, später…

An den Yún wird ein Potentiometer angeschlossen: Mittleres Beinchen auf A0, linkes auf Masse und rechtes auf VCC. Der folgende Sketch liest alle 100ms den Sensor aus und schreibt den erhaltenen Wert in den Schlüssel-Wert-Speicher:

#include <Bridge.h>

void setup() {
  pinMode(A0, INPUT); 
  Bridge.begin();
}

void loop() {
  int val = analogRead(A0);
  Bridge.put("analog0", String(val, DEC));
  delay(100);
}

Bei der Verwendung der Bridge sollte lediglich klar sein, dass diese von seriellen Lese- und Schreibzugriffen abstrahiert. Der Lesezugriff von Linux-Seite aus erfolgt schließlich über den Webserver des Yún. Dieser bietet zwei Möglichkeiten des Zugriffs: Ein Webformular, in dem Sie Werte auslesen, aber auch setzen können. Sie erreichen es unter http://12.34.56.78/keystore_manager_example/. Zudem ist REST-Zugriff über den Pfad /data/get möglich. Dafür muss der HTTP-Client jedoch den Variablennamen kennen: http://12.34.56.78/data/get/analog0. Die Rückgabe ist ein kleine JSON-Schnippsel, der leicht zu parsen ist.

Über ein Webformular oder per REST-API haben Sie Zugriff auf Daten im gemeinsamen Schlüssel-Wert-Speicher

Über ein Webformular oder per REST-API haben Sie Zugriff auf Daten im gemeinsamen Schlüssel-Wert-Speicher

Das war fast zu einfach: Ein analoger oder digitaler Sensor ist damit in fünf Minuten im Netz. Schauen wir uns einmal an, wie Aktoren geschaltet werden können.

Aktoren über HTTP steuern

Dieses Beispiel ist komplexer, es nutzt YunServer und YunClient, hier werden tatsächlich Anfragen des HTTP-Servers der Linux-Seite an den Yún durchgereicht, der verarbeitet sie und schickt einen String zurück. Bei eingehenden HTTP-Anfragen wird hier die Callback-Methode process() aufgerufen, in dieser Aktionen durchgeführt und schließlich mit client.print() eine Ausgabe zurückgeliefert.

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

YunServer server;
YunClient client;

void setup() {
  pinMode(13,OUTPUT);
  digitalWrite(13, LOW);
  Bridge.begin();
  digitalWrite(13, HIGH);
  server.listenOnLocalhost();
  server.begin();
}

void loop() {
  YunClient client = server.accept();
  if (client) {
    process(client);
    client.stop();
  }
  delay(50);
}

void process(YunClient client) {
  String command = client.readString();
  command.trim();
  if (command == "high") {
    digitalWrite(13, HIGH);
    Bridge.put("ledhigh", "0");
  }
  if (command == "low") {
    digitalWrite(13, LOW);
    Bridge.put("ledhigh", "1");
  }
  client.print(command);
}

Ruft man dieses Beispiel mit http://12.34.56.78/arduino/high oder http://12.34.56.78/arduino/high, so wird die LED an- bzw. ausgeschaltet und eine ganz simple Webseite mit dem Text high oder low zurückgeliefert. Dieses Beispiel ist in vielen Fällen sehr pragmatisch, beispielsweise bei Sensoren, die nicht kontinuierlich ausgelesen werden sollen. Bei komplexeren Aufgaben oder gar für die Implementierung eines kompletten REST-APIs stößt diese Methode jedoch schnell an ihre Grenzen.

Besser: Schreiben in den Schlüssel-Wert-Speicher

Ein besserer Weg ist es, über die Bridge Werte oder Befehle in den Key-Value-Storage zu schreiben und diese dann auf Arduino-Seite abzufragen. Gesetzt wird über die URL http://12.34.56.78/data/put/ledhigh/1 bzw. http://12.34.56.78/data/put/ledhigh/0:

#include <Bridge.h>

char buffer[16];

void setup() {
  pinMode(13, OUTPUT);
  Bridge.begin();
}

void loop() {
  Bridge.get("ledhigh", buffer, 1);
  if (buffer[0] == '1') {
    digitalWrite(13, HIGH);
  } else {
    digitalWrite(13, LOW);
  }
}

Das Beispiel sieht aus, als würde der Microcontroller ständig pollen, tatsächlich schiebt die Linux-Seite nur bei Änderungen das Schlüssel-Wert-Paar über die serielle Schnittstelle, gespeichert werden die Daten ja im Microcontroller. Im loop() wird tatsächlich ständig der Speicher durchsucht – bei vielen Variablen leidet die Effizienz.

Immerhin ist diese Lösung ein passabler Kompromiss zwischen einfacher Umsetzung und ausreichender Effizienz. Soll beispielsweise ein Sensor nicht ständig ausgelesen werden, können Sie einen Schlüssel “reread” verwenden, der per REST-Zugriff auf “1” gesetzt wird, wenn Sensordaten angefordert werden. Einen Augenblick später lesen Sie dann per REST aus, welchen Wert der Sensor hat.

Auch fein: Die Netzwerkkonsole

Bei “normalen” Arduinos verwenden wir gerne die serielle Konsole zum Debuggen. Ein an sich archaischer Mechanismus, der auch nicht immer funktioniert, wenn viele Interrupts eintreffen. Aber meistens gut genug. Bekanntlich ist die Brücke zwischen Linux- und Arduino-Seite über eine der beiden seriellen Schittstellen des Atmega32u4 implementiert. Darüber legt Console.h eine dünne Softwareschicht, mit der es möglich ist, ganz wie mittels Serial Debug-Ausgaben weiterzugeben. Der Zugriff gelingt auch über das Netzwerk aus der Arduino IDE heraus:

#include <Bridge.h>
#include <Console.h>

void setup() {
  Bridge.begin();
  Console.begin();
  while (!Console){ }
}

void loop() {
  Console.println("Hallo Welt!"); 
  delay(1000);
}
Achten Sie auf den Fenstertitel: Die "Console" des Yún verhält sich wie die serielle Schnittstelle "normaler" Arduinos

Achten Sie auf den Fenstertitel: Die “Console” des Yún verhält sich wie die serielle Schnittstelle “normaler” Arduinos

Zwischenfazit

Einfache vernetzte Sensoren sind mit dem Arduino Yún tatsächlich möglich, ohne sich näher mit der Linux-Seite beschäftigen zu müssen. Das Setzen und Lesen von Schlüssel-Wert-Pärchen ist absolut transparent. Das erleichtert die Portierung bestehender Projekte auf den Arduino Yún. Allerdings verleitet es auch dazu, möglicherweise unnötige Berechnungen auf dem Microcontroller vorzunehmen, die auf der nun bereitstehenden Linux-Seite besser aufgehoben wären. Aber: Bereits einige Beispiele dieses Beitrags weisen darauf hin, dass stellenweise die Performance der einfachen Handhabung geopfert wurde. Mehr dazu demnächst.

Weiter geht’s

  • Problematische Umsetzungen von (Beispiel-) Sketches und Lösungsvorschläge, welche die Linux-Seite einbeziehen (demnächst)
  • Die Implementierung der Bridge und die Portierbarkeit auf andere Single Board Computer (demnächst)

Kommetare bitte unter meinem G+ Beitrag:

Einstiegsbild: Sidney Harbour Bridge von Wikipedia User Adam.J.C.W This file is licensed under the Creative Commons Attribution 3.0 Unported license.