JavaScript und das Internet of Things, Teil 1: Espruino und Tessel

Seite 2: Tessel

Inhaltsverzeichnis

Das Tessel-Board (Abb. 3) interpretiert wie der Espruino von Haus aus JavaScript. Im Unterschied zum Espruino führt es den Code allerdings nicht direkt aus, sondern überführt ihn erst in Lua. Der kompilierte Quelltext wird dann in einer entsprechenden virtuellen Maschine ausgeführt. Das noch für 2015 angekündigte Tessel 2 dagegen soll eine echte Node.js/io.js-Laufzeitumgebung zur Verfügung stellen.

Das Tessel-Board zeichnet sich durch seine modulare Erweiterbarkeit aus (Abb. 3).

(Bild: https://tessel.io/press)

Das Tessel-Board (in Version 1) verfügt über einen ARM-Cortex-M3-Prozessor mit 180 MHz, 32 MByte Flash-Speicher, 32 MByte RAM, ein eingebautes WLAN-Modul, eine GPIO-Leiste, vier LEDs, zwei Drucktaster, einen Micro-USB-Port und über vier Steckplätze zum Ergänzen externer Tessel-Module (dazu gleich mehr).

Tessel 2 (Abb. 4) dagegen soll mit einem 580MHz Mediatek-MT7620n-Prozessor, über 32 MByte Flash-Speicher und 64 MByte DDR2-Arbeitsspeicher, einem Micro-USB-Port und zwei USB-Ports, einem WLAN-Modul sowie einen Ethernet-Anschluss ausgestattet auf den Markt kommen. Statt vier Steckplätzen für den Anschluss von Tessel-Modulen wird es beim Tessel 2 jedoch lediglich zwei geben.

Das Tessel-Board soll noch im September in Version 2 erscheinen (Abb. 4).

(Bild: https://tessel.io/press)


Für die Entwicklung wird das Tessel-Board per Micro-USB an den PC oder Mac angeschlossen. Bevor es mit der Entwicklung losgehen kann, ist auf dem jeweiligen Host-Rechner lediglich das Node.js-Modul tessel global über NPM zu installieren:

npm install -g tessel

Anschließend steht auf der Kommandozeile der Befehl tessel zur Verfügung, über den sich JavaScript-Programme auf dem angeschlossenen Board ausführen oder dorthin hochladen lassen (Stichwort: Deployment). Zum Starten des Programms kommt der Parameter run zum Einsatz:

tessel run index.js

Mit ihm lädt der Tessel das entsprechende Programm zwar in seinen RAM (und führt es dort aus), nicht aber in den Flash-Speicher. Um das zu erreichen, sprich ein Programm auf dem Tessel-Board zu deployen, verwendet man den Parameter push:

tessel push index.js

In beiden Fällen werden vom Programm benötigte Node.js-Module (das heißt der Ordner node_modules und dortige Unterordner) ebenfalls auf das Tessel-Board hochgeladen.

Um Letzteres innerhalb eines JavaScript-Programm ansteuern zu können, ist das entsprechende Node.js-Modul über require('tessel') einzubinden.

var tessel = require('tessel');

Mit seiner Hilfe lässt sich unter anderem auf die LEDs (über das Array tessel.led), den programmierbaren der beiden Drucktaster (über die Variable tessel.button) und die einzelnen Ports, sprich die Modul-Anschlüsse und die GPIO-Steckleiste (über die Map tessel.port) zugreifen (eine vollständige Beschreibung der API findet sich in der Tessel-Dokumentation).

Das folgende Codebeispiel zeigt – analog zum Code für das Espruino-Board – ein Programm für das alternierende An- und Ausschalten der LEDs (Anmerkung: die folgenden Beispiele beziehen sich alle auf die erste Version des Tessel-Boards). Den Zustand der LEDs speichert es über die booleschen Variablen red, green, blue und amber zwischen.

var tessel = require('tessel');
var red = true;
var green = true;
var blue = true;
var amber = true;

function toggleGreen() {
green = !green;
tessel.led[0].write(green);
}
function toggleBlue() {
blue = !blue;
tessel.led[1].write(blue);
}
function toggleRed() {
red = !red;
tessel.led[2].write(red);
}
function toggleAmber() {
amber = !amber;
tessel.led[3].write(amber);
}
setInterval(toggleRed, 400);
setInterval(toggleGreen, 420);
setInterval(toggleBlue, 440);
setInterval(toggleAmber, 460);

Alternativ dazu kann man sich die Methode toggle() zu Hilfe nehmen, die einem das umständlichere Merken des Zustands abnimmt:

var tessel = require('tessel');
var greenLED = tessel.led[0].write(0);
var blueLED = tessel.led[1].write(0);
var redLED = tessel.led[2].write(0);
var amberLED = tessel.led[3].write(0);

function toggleGreen() {
greenLED.toggle();
}
function toggleBlue() {
blueLED.toggle();
}
function toggleRed() {
redLED.toggle();
}
function toggleAmber() {
amberLED.toggle();
}
setInterval(toggleRed, 400);
setInterval(toggleGreen, 420);
setInterval(toggleBlue, 440);
setInterval(toggleAmber, 460);

Wie erwähnt verfügt das Tessel-Board über zwei Drucktaster. Einer dient dem Neustart des Tessel-Boards, der andere stellt (noch) keine spezielle Funktion bereit und lässt sich daher nach eigenen Wünschen programmieren. Das button-Objekt stellt hierfür die Methode on() zur Verfügung. Über sie können Entwickler Event-Handler für die beiden Ereignisse press und release definieren. Unten findet sich ein entsprechendes Beispiel: beim Drücken des Tasters schaltet der Nutzer die LED an, beim Loslassen wieder aus.

var tessel = require('tessel');
tessel.button.on('press', function(time, type) {
tessel.led[0].write(1);
});
tessel.button.on('release', function(time, type) {
ctessel.led[0].write(0);
});

Das besondere Kennzeichen von Tessel ist die modulare Erweiterbarkeit über die vier beziehungsweise zwei Modul-Anschlüsse. Es stehen viele Module für unterschiedliche Einsatzgebiete zur Verfügung, darunter beispielsweise ein Bluetooth-Adapter, ein Accelerometer oder eine Servo-Steuerung. Sie alle sind für die Verwendung mit einem Tessel-Board ausgelegt und dementsprechend für die Programmierung mit JavaScript optimiert (allerdings merkt man dies auch am Preis der Module, die – verglichen mit nicht-proprietären Komponenten – merklich teurer sind).

Jedes Tessel-Modul lässt sich über ein entsprechendes Node.js-Modul steuern. Der folgende Quelltextauszug zeigt exemplarisch die Verwendung eines Moduls zur Kamerasteuerung:

var tessel = require('tessel');
var camera = require('camera-vc0706').use(tessel.port['A']);
var notificationLED = tessel.led[3];
camera.on('ready', function() {
notificationLED.high();
camera.takePicture(function(err, image) {
if (err) {
console.error(err);
} else {
notificationLED.low();
var name = 'picture-' + Math.floor(Date.now()*1000)
+ '.jpg';
process.sendfile(name, image);
camera.disable();
}
});
});
camera.on('error', function(err) {
console.error(err);
});

Während das Beispiel wieder bewusst einfach gehalten ist, kann man sich bereits leicht ausmalen, was mit einem Kameramodul möglich ist: in Kombination mit einem Bewegungssensor beispielsweise wäre ein Prototyp für ein bewegungsabhängiges Überwachungssystem relativ einfach umzusetzen. Aufgenommene Fotos könnten dabei auch auf einem zentralen Server gespeichert oder direkt per Email versendet werden. Dank dem eingebauten WLAN-Modul muss das Tessel-Board dabei nicht mal per Ethernet angeschlossen sein.