Suche
preisvergleich_weiss

Recherche in 2.519.271 Produkten

Maik Schmidt 18

Einführung ins Espruino-Board

Grünes Board vor weißem Hintergrund.

Bild: Espruino

Das Espruino-Board ähnelt dem Arduino, führt allerdings JavaScript-Code aus. Wer sich mit Node.js und Co auskennt, kann leicht in die Hardware-Programmierung einsteigen – sogar direkt aus dem Browser heraus.

Eingebettete Systeme, die sich nicht nur in hardwarenahen Sprachen wie C und Assembler programmieren lassen, sind im Prinzip nichts neues. Viele PIC-Controller verstehen seit jeher Basic und auf leistungsstärkeren Geräten wie dem Raspberry Pi oder dem BeagleBone Black können Entwickler gleich aus den Vollen schöpfen und zum Beispiel Python oder JavaScript verwenden.

Gordon Williams wollte ein Mittelding schaffen und JavaScript auf stromsparenden und günstigen Mikrocontrollern zum Laufen bringen. Bereits 2012 hat er das Espruino-Projekt veröffentlicht und einen JavaScript-Interpreter angeboten, der auf ein paar populären Mikrocontroller-Boards funktionierte.

Die Software war nicht einfach zu installieren und auch nicht unter einer Open Source-Lizenz verfügbar, also nur als Binär-Download erhältlich. Dies und vermutlich die Ankündigung des Tessel-Boards standen einer weiteren Verbreitung im Weg und so startete Williams eine Kickstarter-Kampagne, in der er nicht nur ein spezielles Espruino-Board anbot, sondern auch die Freigabe des Quelltextes.

Die Hardware

Die Kampagne war erfolgreich und die handlichen Boards (54×41 mm) wurden vor wenigen Wochen ohne große Verzögerung ausgeliefert. Die Leistungsdaten des rund 30 Euro teuren Boards sind nicht üppig, erlauben aber eine große Bandbreite von Projekten.

Die Zentrale bildet eine ARM Cortex M3-CPU von STM32, die mit 72 MHz getaktet wird. Es stehen 48 KB RAM und 256 KB Flash-Speicher zur Verfügung und neben drei LEDs (rot, grün, blau) haben die Boards einen Micro-SD-Karten-Slot, zwei Drucktaster (einer dient als RESET-Schalter) und einen separaten Batterie-Anschluss (JST, 2 Pins).

Sehr erfreulich sieht die Lage auf Seiten der Ein-/Ausgabe-Pins aus, denn das Espruino-Board hat 44 GPIO-Pins. Davon eignen sich 26 zur Pulsweiten-Modulation (PWM) und 16 können analoge in digitale Signale umwandeln (ADC). Darüber hinaus gibt es drei USARTs und jeweils zwei SPI-, I2C- und DAC-Einheiten.

Der Aufbau der Platine eignet sich hervorragend für die prototypische Entwicklung von Schaltungen, denn alle Pins wurden nach außen geführt und es gibt sogar noch Platz für den Anschluss eines HC-05-Bluetooth-Moduls. Auch WLAN lässt sich mit dem TI CC3000 leicht nachrüsten.

Das Espruino-Board ist von Haus aus noch nicht sehr kontaktfreudig: Für erste Experimente empfiehlt es sich daher, Stiftleisten für die 40 GPIO-Pins an den Längsseiten des Boards anzulöten.

Ein Manko ist in der aktuellen Version die Verarbeitung des USB-Anschlusses, denn er ist nicht allzu belastbar und kann sich leicht lösen. Am besten steckt man dort einmalig ein Kabel ein und verbindet beziehungsweise trennt das Board dann nur noch auf der Seite des Host-Rechners. Das Problem ist bekannt und soll in einer überarbeiteten Version behoben werden.

Die Software

Auf dem Espruino-Board laufen ein JavaScript-Interpreter und ein ereignisgesteuertes System ähnlich dem von Node.js. Es ist sogar möglich, Node Packaged Modules auf dem Espruino zu verwenden.

Williams hat einen eigenen Interpreter namens TinyJS entwickelt, der mittlerweile Espruino JavaScript heißt. Die Implementierung ist minimalistisch, deckt aber so gut wie alle Aspekte des aktuellen Sprachumfangs ab. Auf der Webseite des Projekts gibt es eine vollständige Referenz aller Funktionen.

Das System ist auf möglichst geringe Speichernutzung ausgelegt und basiert nicht auf einer virtuellen Maschine, sondern auf einem rekursiv-absteigenden Parser. Somit wird Code, der innerhalb von Schleifen ausgeführt wird, automatisch etwas langsamer.

Installation und erster Code

Installation

Nur wer Windows XP oder Windows 8.1 nutzt, muss separate Treiber herunterladen und installieren. Linux-Freunde müssen lediglich ihren Nutzer in die Gruppe dialout eintragen und sich anschließend ab- und wieder anmelden:

$ sudo adduser $USER dialout

Unter Mac OS X ist gar nichts zu tun.

Nachdem man das Board über ein Micro-USB-Kabel mit dem PC oder Mac verbunden hat, wartet es an der seriellen Schnittstelle auf Kommandos. Zur Kommunikation eignet sich jede serielle Monitor-Software, also zum Beispiel HyperTerminal oder PuTTY unter Windows, picocom oder minicom unter Linux und screen unter Mac OS X. Die Projekt-Webseite erklärt die Verwendung der bekanntesten Werkzeuge.

Mal rantasten

Verbindet man sich mit dem Espruino-Board, wird man mit einem Espruino-Logo und einer Eingabeaufforderung begrüßt:

Hier lassen sich beliebige JavaScript-Anweisungen eingeben und auswerten:

>2 + 3 * 4
=14

Espruino stellt neben vielen gewohnten JavaScript-Funktionen auch spezielle Hilfsmittel für den direkten Zugriff auf die Hardware bereit. Mithilfe des globalen Objekts process kann man sich zum Beispiel schnell einen Überblick über die Eigenschaften des Boards verschaffen.

>process.env
={ "VERSION": "1v52",
"BUILD_DATE": "Feb 21 2014",
"BUILD_TIME": "15:28:41",
"BOARD": "ESPRUINOBOARD",
"CHIP": "STM32F103RCT6",
"CHIP_FAMILY": "STM32F1",
"FLASH": 262144,
"RAM": 49152,
"SERIAL": "33FFD705-41573033-24790743",
"CONSOLE": "USB"}

Auch die GPIO-Pins steuert man sehr einfach an. Die JavaScript-Umgebung definiert eine Pin-Klasse und erzeugt automatisch Instanzen mit sprechenden Namen für jeden GPIO-Pin. Beispielsweise gibt es ein Objekt namens LED1, mit dem sich die rote LED des Boards steuern lässt. Das folgende Beispiel schaltet die rote LED ein, liest ihren Zustand aus und schaltet sie dann wieder ab.

>pinMode(LED1, 'output')
=undefined
>LED1.set()
=undefined
>LED1.read()
=true
>LED1.reset()
=undefined

Zusätzlich zu den Methoden der Pin-Klasse enthält die Espruino-Umgebung aber auch Funktionen, wie sie aus dem Wiring- beziehungsweise dem Arduino-Projekt bekannt sind. Zum Beispiel liest die folgende Anweisung den aktuellen Wert des analogen Pins A2 aus.

>analogRead(A2)
=0.309330891889829873164

Entsprechend gibt es weitere Funktionen wie analogWrite, digitalRead, digitalWrite und digitalPulse. Analog zur Pin-Klasse gibt es auch Klassen für den Zugriff auf SPI, I2C und USART (Serial).

Eigene Funktionen schreiben

Eigene Funktionen schreiben

Eigene Funktionen definiert man ebenfalls wie gewohnt. Die folgende Funktion invertiert zum Beispiel bei jedem Aufruf den Status der grünen LED:

>function toggle() {
: on = !on;
: digitalWrite(LED2, on);
:}
=function () {
on = !on;
digitalWrite(LED2, on);
}

Ruft man toogle auf, wenn die grüne LED aus ist, dann wird die LED eingeschaltet. Andernfalls wird sie ausgeschaltet. Die Variable on ist eine globale Variable, die vom Interpreter bei der ersten Verwendung automatisch erzeugt wird. Sie hat zuerst einmal den Wert undefined. Weil in JavaScript der Ausdruck !undefined aber zu true wird, kann man on ohne Deklaration bequem als Boolesches Flag verwenden.

Mehr Dynamik

Um die LED in einem festen Intervall blinken zu lassen, kann man die Funktion setInterval verwenden:

>var toggler = setInterval(toggle, 1000)
=1

Danach blinkt die LED im Sekundentakt (1000 Millisekunden) und die Variable toggler enthält eine Referenz auf das Intervall-Objekt. Damit lässt sich das Blinken jederzeit wieder abbrechen:

>clearInterval(toggler)
=undefined

Mehr Interaktion

Feste Zeitintervalle zur Steuerung von Aktionen sind in vielen Fällen hilfreich. Genauso hilfreich ist es aber, Aktionen an Ereignisse zu knüpfen, wie zum Beispiel an die Zustandsänderung eines GPIO-Pins.

Das folgende Programm verwendet die Funktion setWatch, um den Status des frei programmierbaren Druckschalters auf dem Espruino-Board zu überwachen (das ist der Drucktaster, der am weitesten vom USB-Anschluss entfernt ist):

setWatch(function() {
LED1.set();
setTimeout("LED1.reset(); LED2.set();", 500);
setTimeout("LED2.reset(); LED3.set();", 1000);
setTimeout("LED3.reset()", 1500);
}, BTN, { repeat: true, edge: "rising" });

Wann immer man den Taster drückt, leuchten die drei LEDs in der Reihenfolge rot, grün und blau.

Die setWatch-Funktion erwartet eine Funktion, die im Falle einer Zustandsänderung eines Pins auszuführen ist und sie erwartet den zu überwachenden Pin. Im obigen Beispiel repräsentiert die globale Konstante BTN, die von der Laufzeit-Umgebung automatisch angelegt wird, den Pin. Darüber hinaus akzeptiert setWatch eine Reihe von Optionen, mit denen sich das Überwachungsverhalten steuern lässt.

Schon bei einem solch kleinen Beispiel muss man sich Gedanken über die beschränkten Ressourcen des Boards machen. Betätigt man den Taster ausreichend oft, wird die Laufzeitumgebung irgendwann die Fehlermeldung “Out of memory” ausgeben. Das Problem sind vermutlich die Timeout-Objekte, die bei jedem Aufruf von setTimeout erzeugt, aber nie mit der Funktion clearTimeout zerstört werden. In einer Produktionslösung muss man also deutlich mehr Sorgfalt walten lassen.

Nichts ist für die Ewigkeit

Wenn man etwas länger in der Shell des Interpreters gearbeitet hat, wird man die bisherigen Erfolge irgendwann sichern wollen. Dazu gibt es mehrere Möglichkeiten.

>dump()
function toggle() {
on = !on;
digitalWrite(LED2, on);
}
var on = false;
=undefined

dump gibt den aktuellen Zustand des Interpreters als Text aus, so dass man durch simples Kopieren denselben Zustand in einer weiteren Interpreter-Instanz erzeugen kann. Zurücksetzen kann man den Interpreter mit der Funktion reset. Die save-Funktion dient dazu, den aktuellen Zustand im Flash-Speicher zu hinterlegen und beim nächsten Start automatisch zu laden.

>save()
=undefined
Erasing Flash.....................
Programming 36000 Bytes.......................................
Checking...
Done!
>>

Alternative: Die Web-IDE

Etwas Komfort

Die Shell des Espruino-Boards bietet ein Mindestmaß an Komfort. Beispielsweise speichert es die bisher eingegebenen Befehle wie eine moderne Unix-Shell. Mit den Cursor-Up- und -Down-Tasten kann man sich durch diese Historie bewegen und zuvor eingegebene Kommandos erneut ausführen.

Darüber hinaus kann man mit der edit-Funktion die Definition von Funktionen bearbeiten. Um zum Beispiel die toggle-Funktion zu verändern, muss man lediglich folgendes eingeben:

>edit(toggle)

Der “Komfort-Modus” ist etwas gewöhnungsbedürftig, weil man nach Änderungen, die man aus der Historie geholt hat, den Cursor erst immer bis zum Ende der Zeile bringen muss, um das neu geschriebene Kommando auszuführen. Tut man das nicht, fügt die Shell an der aktuellen Cursor-Position ein Zeilenende-Zeichen ein.

Dieses Verhalten wirkt sich auch auf die Definition von Funktionen aus. Eine Funktion wie die folgende einzugeben, ist zum Beispiel kein Problem:

function foo() {
}

Anders sieht es für Anhänger alternativer Formatierungen aus:

function foo()
{
}

Gibt man nur “function foo()” ein und drückt dann die Return-Taste, führt das zu einer Fehlermeldung:

ERROR: Got EOF expected ‘{‘ at line 1 col 15

Web-IDE

Alternativ zur spartanischen Schnittstelle eines seriellen Monitors bieten die Entwickler eine Web-IDE an, die zurzeit nur in Googles Chrome-Browser läuft. Sie kann per Mausklick über den Google Chrome Store installiert werden.

Die IDE ist in der Mitte geteilt. Auf der linken Seite gibt es ein Fenster mit einem seriellen Monitor und auf der rechten Seite einen Editor für JavaScript-Code. Über Buttons und Menüs in der Toolbar kann man eine serielle Schnittstelle aussuchen und sich mit dem daran angeschlossenen Espruino-Board verbinden. Dann kann man JavaScript-Code auf der rechten Seite editieren und per Knopfdruck nach links verschieben.

Das Ganze funktioniert sogar “graphisch”, das heißt, Code lässt sich auch mit der Maus visuell modellieren. Sonderlich praktisch ist das im täglichen Gebrauch allerdings nicht.

Prinzipiell ist die IDE eine nette Idee, aber sie ist in vielen Belangen noch recht wackelig, so dass halbwegs erfahrene Benutzer mit einem guten Text-Editor und einem seriellen Monitor deutlich besser bedient sein dürfen.

Eine wichtige Option bietet die IDE aber: Sie ermöglicht ein komfortables Upgrade auf die aktuelle Firmware-Version.

Fazit

Espruino hat prinzipiell das Zeug zu einem ernsthaften Arduino-Konkurrenten, denn JavaScript ist allemal einsteigerfreundlicher als C/C++ und auch die Hardware bietet deutlich mehr. Allerdings steckt die IDE noch in den Kinderschuhen und mit der Unzahl an Arduino-Bibliotheken und -Shields kann das Projekt lange nicht konkurrieren. Darüber hinaus macht Espruino den Sprung von JavaScript zu C nicht ganz einfach und ab einer gewissen Komplexität der Anwendung wird dieser unvermeidlich sein.

Gemessen an der direkten Konkurrenz, wie zum Beispiel dem Tessel-Projekt, schneidet Espruino hervorragend ab. Das Board ist deutlich preiswerter und bereits jetzt verfügbar. Die Software läuft sogar auf einigen anderen Mikrocontroller-Boards und die Portierung auf weitere Plattformen sollte kein großes Problem darstellen. Insgesamt bildet es eine hervorragende Grundlage für die iterative und prototypische Entwicklung von Elektronik-Projekten.

18 Kommentare

Themen: