Einführung in die JavaScript-Programmierung des Tessel 2

Das muss (wieder) tesseln!
Keine Kommentare

Die erste Generation des Tessel (vorgestellt im Entwickler Magazin 5.15) beeindruckte die Entwicklerschaft in vielerlei Hinsicht: Die Ausführung von JavaScript auf einem Mini-Mikrocontroller der Bauart Cortex M3 war durchaus cool. Mit der zweiten Version professionalisiert Technical Machine die Architektur. Dieser Artikel zeigt, was Sie erwarten dürfen.

Tessel 1 und Tessel 2 unterscheiden sich technisch komplett: Ein Tessel der ersten Generation war im Grunde genommen eine virtuelle Maschine, die LUA-Code ausführte. Das Ausliefern von JavaScript erfolgte über eine Node Runtime, die den JavaScript-Code auf der Workstation des Entwicklers transpilierte und in Richtung des Prozessrechners schickte. Der Rest des Betriebssystems war nicht zugänglich – im Vergleich zu Unix-basierten Prozessrechnern ein durchaus signifikanter Nachteil.

Der Tessel 2 basiert auf einem Prozessor aus dem Hause MediaTek, der mit 580 Megahertz Rechenleistung und 64 Megabyte RAM durchaus genügend Rechenleistung für eine kopflose JavaScript-Umgebung anbietet. Ferner wurde der Softwarestack insofern verändert, als dass der JavaScript-Code nun direkt in V8 ausgeführt wird. Änderung Numero drei ist die Einführung eines zweiten Koprozessors, der für das eigentliche IO zuständig ist. Weitere Informationen zu den Unterschieden finden sich hier. Für uns reicht es aus, wenn wir davon ausgehen, dass unser Tessel 2 ein mit JavaScript programmierbarer Prozessrechner ist.

Installation

Die Installation der Tessel Utilities ist insofern kritisch, als sie auf diverse Hardwaremodule zugreift. Das erste wichtige Kriterium ist, dass die Node-Versionen des Superusers und des normalen Users übereinstimmen müssen. Das lässt sich in der Kommandozeile durch Eingabe der folgenden beiden Befehle überprüfen:

 
tamhan@TAMHAN14:~/.nvm$ sudo node -v
v6.10.3
tamhan@TAMHAN14:~/.nvm$ node -v
v6.10.3

Findet sich an dieser Stelle ein Mismatch zwischen den angezeigten Versionen, haben Sie ein Problem: Die Installation der Treiber wird in diesem Fall nicht gelingen. Im nächsten Schritt sind einige Module erforderlich, die Linux-Zugriff auf USB-Hardware erleichtern:

tamhan@TAMHAN14:~/.nvm$ sudo apt-get install libusb-1.0-0-dev libudev-dev

Das eigentliche Herunterladen erfolgt über den npm-Paketmanager. Wundern Sie sich aber nicht, wenn während der Installation der eine oder andere Fehler geworfen wird, denn die Tessel Runtime probiert mehrere Methoden aus, um die notwendigen Treiber zu kompilieren.

tamhan@TAMHAN14:~/.nvm$ npm install -g t2-cli

Zu guter Letzt müssen die Treiber auf der Workstation installiert werden. Das erfolgt durch Eingabe des folgenden Befehls:

 
tamhan@TAMHAN14:~/.nvm$ sudo t2 install drivers
*** Error in `node': free(): invalid pointer: 0x0000000003b66eff ***

Kommt es bei der Ausführung des Installationsbefehls zum oben erwähnten Fehler, so müssen Sie die Tessel-Programmierumgebung – gegen die expliziten Empfehlungen des Entwicklerteams – als Root „nachinstallieren“, um danach die Installation zum erfolgreichen Durchlaufen zu bringen:

 
tamhan@TAMHAN14:~/.nvm$ sudo npm install -g t2-cli
tamhan@TAMHAN14:~/.nvm$ sudo t2 install drivers
INFO udev rules installed to /etc/udev/rules.d/85-tessel.rules
INFO Done. Unplug and re-plug Tessel to update permissions.

Tessel hoch!

Unsere nächste Aufgabe ist das Testen der korrekten Funktion. Hierzu ist natürlich ein Tessel-2-Prozessrechner erforderlich. Das Board ist beispielsweise bei Mouser erhältlich. Um sich für eine kostenlose Lieferung zu qualifizieren, bietet es sich an, Zubehörteile oder sonstige Komponenten mitzubestellen. Für die folgenden Schritte benötigen wir z. B. ein RFID-Modul, das Sie an dieser Stelle samt Zenerdiode und Widerstand mitbestellen könnten.

Verbinden Sie den Prozessrechner per Micro-USB-Kabel mit einer Workstation. Die blaue LED zwischen den beiden Erweiterungsports wird kontinuierlich pulsieren. Der Bootprozess des Linux-Betriebssystems kann bis zu dreißig Sekunden in Anspruch nehmen. Lassen Sie dem Prozessrechner etwas Zeit, bevor Sie ihn mit folgendem Kommando zu identifizieren suchen:

 
tamhan@TAMHAN14:~$ t2 list
INFO Searching for nearby Tessels
USB Tessel-02A3457FFA5E

t2 list lässt sich insofern etwas Zeit, als es nicht nur nach per USB verbundenen Prozessrechnern sucht: Ein Tessel wird auch dann gefunden, wenn er im selben Netzwerk wie die Workstation residiert.

Nach dem erstmaligen Anstecken ist es empfehlenswert, eine Aktualisierung der Firmware durchzuführen. Hierzu müssen Sie folgenden Befehl eingeben:

tamhan@TAMHAN14:~$ t2 update
INFO Looking for your Tessel...
INFO Connected to Tessel-02A3457FFA5E.
INFO New firmware version found...0.0.16
. . .
INFO Updated Tessel-02A3457FFA5E from 0.0.13 to 0.0.16

Wundern Sie sich nicht, wenn der Aktualisierungsprozess einige Zeit in Anspruch nimmt. Der Tessel des Autors genehmigte sich fünf Minuten. Achten Sie zudem darauf, dass es während dieser Zeit nicht zu Stromausfällen oder sonstigem Blödsinn kommt.

Erstes Projekt: ein Cardreader

Nach diesen einführenden Überlegungen wollen wir uns mit der Erzeugung eines ersten Testprojekts auseinandersetzen. Die schwarzen Konnektoren auf der Seite des Boards erlauben das Anstecken von dedizierter Hardware. Zum Zeitpunkt der Drucklegung gibt es rund ein Dutzend geschiedener Module.

Als erste Aufgabe – sowohl zur Nutzung von vorgefertigten als auch von eigenen Erweiterungen – müssen wir ein Projektskelett anlegen, das später auf den Tessel geschoben werden kann. Hierzu ist unter Unix die folgende Kommandofolge erforderlich:

tamhan@TAMHAN14:~/tesselspace$ mkdir blinker

tamhan@TAMHAN14:~/tesselspace$ cd blinker

tamhan@TAMHAN14:~/tesselspace/blinker$ t2 init

Tessel-Projekte leben normalerweise in einem eigenen Verzeichnis. Die Eingabe des Befehls T2 Init sorgt sogar dafür, dass der Client die nötige Projektstruktur im gerade aktuellen Arbeitsverzeichnis errichtet. Nach dem erfolgreichen Durchlaufen des Kommandos stellen Sie fest, dass das Projekt ein gewöhnliches Node.js-Projekt darstellt, das um einige Bibliotheken für den Tessel erweitert wurde. Öffnen Sie sodann Datei index.js, um Ihren von Tessel vorgegebenen Inhalt durch ein hauseigenes Testprogramm zu ersetzen (Listing 1).

var tessel = require('tessel');
tessel.led[1].on();
tessel.led[0].on();
while(1==1) {
tessel.led[1].off();
console.log("Rennt!");

Aus technischer Sicht gibt es hier nicht besonders viel zu sehen. Wir laden im ersten Schritt die Tessel-Bibliothek und schalten danach zwei der vier auf der Platine befindlichen Leuchtdioden ein. Danach rufen wir in einer Endlosschleife die Funktion off auf, um die zweite LED auszuschalten. Zudem findet sich ein Aufruf von console.log, der eine Meldung in die Kommandozeile emittiert. Das Ausliefern des Codes erfolgt sodann mit folgendem Kommando:

tamhan@TAMHAN14:~/tesselspace/blinker$ t2 run index.js
. . .
INFO Running index.js...

Nach der erfolgreichen Auslieferung des Programms stellen Sie fest, dass sich die Konsole des Terminalfensters mit der Ausgabe von console.lok füllt. Zudem leuchten am Tessel eine blaue und zwei grüne Leuchtdioden auf. Dabei handelt es sich allerdings um eine Fehlanzeige: Der Tessel 2 ist in der Lage, die Energieversorgung seiner beiden Erweiterungsanschlüsse bei Bedarf abzuschalten, um so durch Deaktivierung der angeschlossenen Hardware Energie zu sparen. Das Aufleuchten der beiden grünen LEDs bedeutet, dass die Ports aktiv sind – mit den im LED-Array befindlichen Leuchtdioden haben diese nichts zu tun.

Abb. 1: Die beiden Leuchtdioden aktivieren sich wie erwartet

Abb. 1: Die beiden Leuchtdioden aktivieren sich wie erwartet

Probieren Sie im nächsten Schritt folgende Version des Codes, die zum in Abbildung 1 gezeigten Verhalten führt:

var tessel = require('tessel');
tessel.led[1].on();
tessel.led[0].on();
 

Das Betriebssystem des Tessel weist eine kleine Besonderheit auf: Befehle, die zur Ansteuerung von Hardware vorgesehen sind, werden normalerweise asynchron ausgeführt. Der Tessel sammelt sie während der Ausführung von Nutzercode, um sie danach in einer „Ruhepause“ zur Abarbeitung zu bringen. Die Endlosschleife des vorhergehenden Beispiels würde die Runtime also mit diversen Ausschaltbefehlen fühlen, die sich aber nicht weiter auf die Hardware auswirken.

General Purpose Input Output

Die vier Leuchtdioden nehmen bis zu einem gewissen Grad aus schaltungstechnischer Sicht eine Sonderstellung ein, weil sie, wie in der Schaltung in Abbildung 2 gezeigt, vom MediaTek-Prozessor angesteuert werden.

Abb. 2: Die Macher des Tessel setzen auf Labels; die eigentlichen Leuchtdioden finden sich auf einer anderen Seite des Schaltplans

Abb. 2: Die Macher des Tessel setzen auf Labels; die eigentlichen Leuchtdioden finden sich auf einer anderen Seite des Schaltplans

Die eigentliche Kommunikation mit der Außenwelt erfolgt beim Tessel 2 stattdessen über den Atmel-Koprozessor.

Modu-was?

Die Modulationsdomänenanalyse ist ein interessantes Verfahren zur Qualifikation von Wellenformstabilität. Weitere Informationen hierzu finden sich in einem hier  zugänglichen Video.

Eine Frage der Stabilität

Als erste Aufgabe wollen wir – wie immer bei der Qualifikation eines Prozessrechners – mit der Ausgabe einer charakteristischen Wellenform beginnen, um diese danach sowohl auf einem Digitalspeicheroszillograph als auch in der Modulationsdomäne näher zu betrachten (siehe auch Infokasten „Modu-was?“).

Wie im vorigen Fall beginnt unser Programm auch diesmal mit der Inklusion des Tessel-Moduls. Im nächsten Schritt wird das Modul um eine Referenz auf einen GPIO-Pin des Ports A erleichtert: Wer die Planare aus dem in Abbildung 3 gezeigten Winkel betrachtet, stellt fest, dass die beiden Ports beschriftet sind.

Abb. 3: Die kleinen Zahlen informieren Sie über die Rolle der einzelnen Pins

Abb. 3: Die kleinen Zahlen informieren Sie über die Rolle der einzelnen Pins

Ein erster naiver Versuch der Erzeugung einer Wellenform würde wie in Listing 2 aussehen.

  

var tessel = require('tessel');
var pin = tessel.port.A.pin[2];
while(1==1) {
  pin.write(1, (error, buffer) => {});
  pin.write(0, (error, buffer) => {});
  pin.write(1, (error, buffer) => {});
 pin.write(0, (error, buffer) => {});
}

Die Write-Funktion des Pin-Objekts nimmt neben dem zu schreibenden Objekt auch einen Verweis auf einen eigenen Handler entgegen, der beim nicht erfolgreichen Setzen des Pins aufgerufen wird.

Rein theoretisch könnten wir unser Programm an dieser Stelle auch schon zur Ausführung freigegeben. Der hierzu vorgesehene Befehl wurde weiter oben schon einmal angesprochen und liefert nun (nach einiger Zeit) eine sehr interessante Fehlermeldung:

 
tamhan@TAMHAN14:~/tesselspace/blinker$ t2 run index.js
INFO Looking for your Tessel...
. . .
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

Nach der erfolgreichen Auslieferung des Codes fällt sofort auf, dass die beiden Port-LEDs nicht aufleuchten. Einige Zeit später erscheint die weiter oben abgedruckte Fehlermeldung am Bildschirm. Auch beim Zugriff auf GPIO-Pins gilt also, dass der Prozessrechner die Befehle nur im „Leerlauf“ in Richtung des Hardware-Koprozessors weiterleitet.

Als Nächstes modifizieren wir die Funktion, um die Ausgabe der charakteristischen Wellenform auf eine Tessel-kompatible Art und Weise auszugeben. Hierzu müssen wir den Ausgabecode im ersten Schritt in eine Payload Closure verpacken, die im zweiten Schritt über die setInterval-Funktion periodisch angefeuert wird (Listing 3).

setInterval(function(){
  pin.write(1, (error, buffer) => {});
  pin.write(0, (error, buffer) => {});
pin.write(1, (error, buffer) => {});
  pin.write(0, (error, buffer) => {});
}, 1);

JavaScript-Kenner merken an dieser Stelle, dass der Echtzeitleistung des Tessel durch sein Betriebssystem engste Grenzen auferlegt sind. Der minimale Zykluswert von setInterval beträgt nun mal eine Millisekunde, was in Informatikkreisen eine immens lange Zeit ist. Auch auf Oszillographen lässt sich diese Tatsache nachvollziehen. Die Wellenform präsentiert sich – bei längerer Zeitbasis – entsprechend und zeigt, wie der Tessel 2 bei der Programmausführung „stottert“.

Interessant ist, dass der Tessel zwei Programmierungszustände kennt. Ein mit run in den Prozessrechner geschriebener Code ist nur so lange geladen, wie der Tessel mit Energie versorgt wird. Abstecken genügt, um den Code nach Astoria zu schicken. Diese auf den ersten Blick wenig sinnvolle Vorgehensweise ist insofern vernünftig, als Sie Code so ausprobieren können, ohne den Flash-Speicher des Prozessrechners mit einem Schreibzyklus zu belasten.

Aus Gründen der Komplixität – USB-Verbindungen können auf diverse Arten für Ärger sorgen – wollen wir unseren kleinen Benchmarkcode noch in den Flash-Speicher des Prozessrechners schreiben. Hierzu ist folgendes Kommando erforderlich:

tamhan@TAMHAN14:~/tesselspace/blinker$ t2 push index.js
INFO Looking for your Tessel...
INFO Connected to Tessel-02A3457FFA5E.
INFO Building project.

Nach dem erfolgreichen Durchlaufen des push-Kommandos können wir den Prozessrechner mit einem beliebigen Handynetzteil versorgen. Leider sehen die Wellenformen auch in diesem Betriebszustand instabil aus. Die enorme Langsamkeit der JavaScript Runtime zeigt sich auch am Oszillograph. Der erste Teil eines „stabilen“ Durchlaufs nimmt 2.55 ms in Anspruch, während im zweiten Durchlauf 13.72 ms verbraucht werden.

Zur Erklärung: Die weiter oben an setInterval übergebene Payload schaltete den GPIO-Pin zweimal hintereinander ein und aus, bevor die Programmausführung an das Betriebssystem zurückgegeben wurde. Auf diese Art und Weise können wir feststellen, wie viel Zeit für Housekeeping-Aufgaben verbraucht wird.

Wer den in seinem Prozessrechner befindlichen Code nicht mehr benötigt, kann ihn durch Eingabe folgender Kommandos löschen (das ist insofern interessant, als ein unprogrammierter Tessel mit komplett „inerten“ Eingabepins startet):

tamhan@TAMHAN14:~/tesselspace/blinker$ t2 erase
. . .
INFO Files erased.

Mit Hardwarebeschleunigung an die Spitze

Wer mit Bit Banging nicht zum Ziel kommt, weicht normalerweise auf hardwarebeschleunigte Protokolle aus. Sie unterscheiden sich von per GPIO realisierten Kommunikationsstandards insofern, als das Betriebssystem in die Rolle des „Beobachters“ delegiert wird. Die eigentliche Generierung der Wellenformen erfolgt in dedizierten Hardwarekomponenten – das Betriebssystem beschränkt sich darauf, von Zeit zu Zeit Daten abzuernten.

Zum Zeitpunkt der Drucklegung unterstützt der Tessel die Bussysteme I2C, SPI und gewöhnliche serielle Verbindungen auf Basis eines UART. I2C ist hierbei für die Kommunikation mit mehreren Endgeräten geeignet, während UART und SPI für schnelle Datenaustäusche mit Einzelgeräten vorgesehen sind.

Wir wollen diesmal – Experimente mit I2C-Gyroskopen und SPI-Displays werden irgendwann einmal langweilig – auf den UART setzen. Es handelt sich hierbei um ein an RS232 erinnerndes serielles Kommunikationsverfahren, das allerdings um einige Datenleitungen erleichtert wurde und zudem mit anderen Signalisierungsspannungen arbeitet.

Als Gegenstelle wollen wir auf einen preiswerten RFID-Scanner (sprich Cardreader) setzen, der im 125-kHz-Bereich arbeitende, passive RFID-Tags auslesen kann. Die kleinen Biester sind in China extrem preiswert erhältlich und schaffen Scanreichweiten von bis zu drei Zentimeter. Wer sie an einem ausziehbaren Band befestigt, kann sie zur Authentifizierung von Personen oder Gütern einsetzen. Im Unternehmen des Autors werden die Dinger beispielsweise an Kisten montiert, die in den Tiefenspeicher wandern. Die in Fitnessstudios, Privatbanken und öffentlichen Verkehrsunternehmen verwendeten RFID-Tags in Karten arbeiten hingegen normalerweise nicht im 125-kHz-Bereich, sondern in einem anderen Frequenzbereich. Es gibt auch für sie ebenfalls passende Lesegeräte, auf die wir an dieser Stelle aber nicht weiter eingehen wollen.

Die auf den ersten Blick einfach klingende Verbindungsaufgabe wird dadurch erschwert, dass das von SeedStudio entwickelte und bei Mouser hier erhältliche Element ausschließlich mit 5V-Signalspannung arbeitet und auch eine 5V-Versorgung voraussetzt. Für Besitzer eines Tessel ist das insofern zweifach kritisch, als der Tessel erstens ein reines 3,3V-System ist und anders als der Rasberry Pi 3 beim Anlegen von 5V massiven Schaden nimmt.

Ärgernis Nummer zwei ist, dass der Tessel von Haus aus keine 5V-Spannungsquelle bereitstellt. Es gibt zwar neben dem Ethernet-Port eine Möglichkeit, weitere Pins einzulösen – dies setzt allerdings grundlegende mechanische Fertigkeiten voraus und sollte nicht als erste Einführung in die Welt des Lötens angegangen werden. Im Interesse des einfachen Handlings nutzen wir stattdessen die in Abbildung 4 gezeigte Schaltung mit einem zweiten Netzgerät.

Abb. 4: Der Lötkolben kann dem empfindlichen Prozessrechner fernbleiben - auch wenn ein Netzgerät wie das HP 6624A an dieser Stelle Overkill ist

Abb. 4: Der Lötkolben kann dem empfindlichen Prozessrechner fernbleiben – auch wenn ein Netzgerät wie das HP 6624A an dieser Stelle Overkill ist

Der Code des RFID-Readers beginnt ebenfalls mit der Inklusion des Testmoduls und der Bereitstellung einer Instanz der Portklasse, die den Zugriff auf Port A und die mit ihm verbundenen Hardwaremodule ermöglicht. Im nächsten Schritt wird ein neues UART-Objekt generiert. Bei dessen Erzeugung muss die zur Kommunikation zu verwendende Baudrate angegeben werden.

SeedStudio arbeitet mit gemächlichen 9 600 Baud und lässt auch keine Beschleunigung des Kommunikationsprotokolls zu. Das ist ob der sehr kurzen Wellenlänge der in RFID-Karten enthaltenen Informationen in der Praxis allerdings kein Problem, da der Cardreader das erfolgreiche Scannen der Karten sowieso durch Aufblinken der grünen LED quittiert. Anzumerken sei, dass der Test allerdings auch mit höheren Baudraten durchaus gut zurechtkommt – bei der Kommunikation mit schnelleren Gegenstellen spart das wertvolle Zeit (Listing 4).

 

var tessel = require('tessel');
var port = tessel.port.A;
var uart = new port.UART({
  baudrate: 9600
});
uart.on('data', function (data) {
  console.log('received:', data);
})

Im nächsten Schritt findet sich der eigentliche Korpus des Cardreaders: Die On-Methode des UARTs wird genutzt, um einen Event Handler einzuschreiben, der beim Eintreffen von Informationen von der Runtime aktiviert wird. Damit sind wir eigentlich auch schon zur Programmausführung bereit. Das CLI sollte uns nun zeigen, wie der Tessel-basierte Kartenleser verschiedene Karten mit dem NFC-Lesesystem erkennt (Abb. 5). Vorausgesetzt natürlich, die von Ihnen getesteten Karten sind bereits programmiert. Insbesondere beim Kauf von Karten aus China sollte man wissen, dass die Händler ihre Karten oft nicht programmiert ausliefern. Der Seeed-Cardreader kann diese nicht erkennen.

Abb. 5: Der Tessel-basierte Kartenleser funktioniert

Abb. 5: Der Tessel-basierte Kartenleser funktioniert

Ab ins Netz

Als nächste Aufgabe wollen wir die Daten unseres kleinen Cardreaders über das Internet ansprechbar machen. Hierzu ist der WLAN-Transmitter des Tessel geradezu ideal geeignet: Der Prozessrechner bringt neben dem Ethernet-Modul nämlich auch ein vollwertiges WLAN-Modul mit, das dank einer in die PCB integrierten Antenne komplett autonom agieren kann.
Zur Nutzung des WLAN-Transmitters müssen wir im ersten Schritt den Namen des Netzwerks ermitteln, zu dem der Prozessrechner eine Verbindung aufnehmen soll. Das lässt sich am einfachsten über das t2 wifi-Kommando bewerkstelligen. Im ersten Schritt müssen Sie hierbei das Funkmodul einschalten, um weitergehende Operationen durchführen zu können:

 

tamhan@TAMHAN14:~/tesselspace/reader$ t2 wifi --on
. . .
WARN Unable to verify connection. Please ensure you have entered the correct network credentials.

Die Ausgabe des Fehlers bezüglich des Nichtaufbaus einer Verbindung ist in diesem Zusammenhang übrigens irrelevant. Der Tessel beklagt sich darüber, dass in seinem Remanentspeicher derzeit kein WLAN angemeldet ist. Die Ermittlung der verschiedenen in der Umgebung befindlichen Netzwerke erfolgt sodann über das Kommando wifi -l, dessen Aufgabe wir an dieser Stelle stark gekürzt abdrucken:

 
tamhan@TAMHAN14:~/tesselspace/reader$ t2 wifi -l
. . .
INFO Found 10 networks visible to Tessel-02A3457FFA5E:
  Tamoggemon Holding k.s. BA EXTtp (51/70)
. . .

Nach den Erlebnissen mit dem nicht besonders zuverlässigen WLAN-Modul des Raspberry Pi 3 sind Prozessrechnernutzer mitunter etwas paranoid, wenn es um die Verwendung von WLAN geht. Das l-Kommando informiert Sie über die Signalstärke des jeweiligen Netzwerks: Der in der Klammer befindliche Wert gibt die Signalstärke in Teilen von 70 an.
Unsere nächste Aufgabe ist der Aufbau einer Verbindung zum Netzwerk. Hierzu dient das Codesnippet aus Listing 5.

tessel.network.wifi.connect({
  ssid: 'Tamoggemon Holding k.s. BA EXTtp',
  password: 'XXX',
  security: 'psk2'
}, . . .

tessel.network.wifi.connect nimmt ein JSON-Objekt entgegen, das das anzusprechende Netzwerk vollständig beschreibt. Achten Sie darauf, dass das Kommando wifi -l am Ende jedes Netzwerknamens ein zusätzliches Leerzeichen anfügt, dass nicht im finalen Code sein darf. Der an Security übergebene String legt das Verschlüsselungsverfahren des jeweiligen Netzwerks fest. Zum Zeitpunkt der Drucklegung unterstützt der Tessel hierbei folgende Methoden:

  • none
  • wep
  • psk
  • psk2
  • wpa
  • wpa2

Erfolg und/oder Misserfolg werden über ein Callback angemeldet. Fürs Erste reicht es aus, wenn wir eine Statusmeldung in die Konsole emittieren:

. . .function (error, settings) {
  if (error) {
    console.log(error);
  }
  console.log ("WiFi up!");
  console.log(settings);
});

An dieser Stelle ist unser Programm zur Ausführung bereit. Jagen Sie es auf den Prozessrechner und der Tessel nimmt Kontakt zum Netzwerk auf, um sich am in Abbildung 6 gezeigten Ergebnis zu erfreuen.

Abb. 6: Der Tessel hat Kontakt zum Netzwerk aufgenommen

Abb. 6: Der Tessel hat Kontakt zum Netzwerk aufgenommen

Da das permanente Herumhantieren mit Router-Backends alles andere als komfortabel ist, empfiehlt es sich, die IP-Adresse des Tessel in die Kommandozeile auszugeben. Das ist insofern etwas haarig, als der Prozessrechner trotz mehrerer Nachfragen diverser Entwickler bisher kein dafür vorgesehenes API besitzt. Stattdessen müssen Sie auf das etwas komplexe Statement in Listing 6 zurückgreifen.

console.log ("WiFi up!");
setInterval(function(){
var os = require('os');
var interfaces = os.networkInterfaces();
var addresses = [];
for (var k in interfaces) {
  for (var k2 in interfaces[k]) {
    var address = interfaces[k][k2];
    if (address.family === 'IPv4' && !address.internal) {
      addresses.push(address.address);
    }
  }
}
console.log(addresses);  },1000);

Beachten Sie zudem, dass die IP-Adresse erst einige Zeit nach dem Verbindungsaufbau zur Verfügung gestellt wird. Es ist völlig normal, wenn Sie anfangs „leere“ Resultate erhalten.
Zur Interaktion mit HTTP ist sodann die Inklusion des in Node enthaltenen Moduls erforderlich:

var tessel = require('tessel');
var http = require("http");
var server = null;

Als nächste Aufgabe müssen wir nach dem erfolgreichen Aufbau einer WLAN-Verbindung einen Server starten und mit einem Request Handler ausstatten, der für das Zurückgeben von Inhalten verantwortlich ist (Listing 7).

server = http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/html"});
response.write("");
  response.write("Hello World Page");
  response.write("");
  response.end();
});
server.listen(80);

Wer das Programm in der vorliegenden Version ausführt und die betreffende IP-Adresse in einem Browser seiner Wahl öffnet, stellt fest, dass die Seite ordnungsgemäß ausgeliefert wird.
Zur Fertigstellung unseres Cardreaders müssen Sie den zuletzt eingelesenen String in einer globalen Variable zwischenspeichern und sodann in der response-Funktion an den Client zurückgeben. Eine Aufgabe, die erfahrene JavaScript-Programmierer mit Sicherheit nicht sonderlich fordern wird.

Fazit

Außer Frage steht, dass der Tessel kein Prozessrechner für jedermann ist. Die Echtzeitperformance von Achtbittern ist höher, während Nutzer von OrangePi und Co. wesentlich mehr Rechenleistung zur Hand haben. Die Stunde von Technical Machine schlägt allerdings immer dann, wenn große Mengen von JavaScript-Code auf eine effiziente Art und Weise in eine Steuerung wandern müssen – das Entwickeln eigener Node Bindings artet in der Praxis zu schnell in Arbeit aus …

Entwickler Magazin

Entwickler Magazin abonnierenDieser Artikel ist im Entwickler Magazin erschienen.

Natürlich können Sie das Entwickler Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -