Table of Contents

Under Development

Dieser Review ist noch in Bearbeitung

electric Imp Review

Der electric Imp ist ein kleiner Microcontroller mit eingebautem WLAN Adapter auf der Größe einer normalen SD Karte, wie man sie von Digitalkameras her kennt:

electric Imp Als SD Karte ist der electric Imp alleine zu Nichts zu gebrauchen, man sollte ihn auch nicht in einen normalen SD Kartenslot stecken. Im besten Fall geht nichts kaputt, im schlimmsten Fall ist der electric Imp nachhaltig beschädigt. Zusätzlich zum electric Imp (eImp) bedarf es eines Breakouts oder eines anderen sogenannten “Impee”, wie die Entwickler des eImp ein Gerät nennen, welches einen eImp aufnehmen kann. Für diesen Review wurde ein Arduino Shield für den eImp gewählt, welches von Sparkfun stammt.

In den Beispielcodes wird im WIki von eImp immer wieder von “April” und “Hannah” gesprochen. Es handelt sich dabei um Impees, welche von eImp designed worden sind und an Betatester vergeben wurden. Ich habe bislang keine Quelle gesehen, welche das Impee Hannah anbietet. Man kann sie aus den angebotenen Dateien aber selbst herstellen, was beim Hannah vielleicht sogar sehr interessant wäre.

Erste Schritte - Das Shield

Als erstes wurde das Shield mit Headern versehen, die getrennt gekauft werden müssen. Sparkfun begründet dies damit, dass das Shield die freie Wahl des Headers ermöglichen soll, was bei den geringen Kosten der Header keine schlechte Idee ist. So kann man sich entscheiden, stackable Headers oder eine Stiftleiste einzubauen. Empfehlenswert ist es, die innen gelegene Spiegelung der Kontakte mit einer Buchsenleiste zu bestücken.

Arduino Shield

Schaut man sich die Beschreibung des Shields and, dan sieht man, dass das Shield bis auf RX/TX keine Verbindung zu den Arduino-Pins herstellt, es also lediglich eine Aufnahme für den eImp darstellt. Das ist auch sehr wichtig, denn das eImp ist auf 3.3 Volt ausgelegt und wird beschädigt, wenn man auf seine Eingänge ein 5 Volt Signal legt. Hier muss ein Levelshifter zwischengeschaltet werden oder man steckt das Shield auf ein 3.3 Vol Board, wie es der neue Arduino Due darstellt (alternativ chipKit).

Dem Schaltplan kann man auch entnehmen, dass die serielle Kommunikationsleitung (RX/TX) über einen Levelshifter Mosfet 5 Volt tolerant ausgelegt sind. RX und TX sind auf D8 und D9 gelegt und können mit Brücken auf D0 und D1 umgestellt werden. Diese befinden sich auf der Unterseite des Shields als Lötbrücken.

Zusätzlich befinden sich auf dem Shield zwei LED, welche auf P8 und P9 des eImp mit Vorwiederstand geschaltet sind, ähnlich wie die LED auf dem Arduino mit D13 verbunden ist

Dann mal los ...

Als erstes stellt sich die Frage, wie man nun mit dem eImp kommunizieren soll. Dazu muss man ihn erst einmal “Commissionieren”, also bei electric Imp anmelden. Dazu bedarf es eines Accounts bei electric Imp, was aber nach Eingabe eines Usernamens, der e-mail adresses und eines Passworts problemlos funktioniert.

Dann wird es interessant. Denn jetzt braucht man ein iOS oder Android Mobiltelefon, denn der eImp wird über eine Folge von Lichtblitzen konfiguriert! Dazu läd man die entsprechende App, meldet sich mti dem neu angelegten Account an und gibt die WLAN Informationen in der Maske ein. Bei normalen privaten WLANs ist das kein Problem, WLAN, welche mit userid/password arbeiten werden noch nicht unterstützt. In meinem Fall war es ein einfacher Router mit WPA2, so dass nur die SSID und das Passwort eingegeben werden musste.

Der unkonfigurierte eImp blinkt orange und man kann an der Vorderseite ein kleine Öffnung erkennen, wo der EMpfänger für die Daten sitzt. Man muss beim Empfangen die Oberseite des eImp mit dem Finger abdecken, da das orangene Licht den Empfang stört. Man sollte das Mobile so nah wie möglich an den eImp halten. Tippt man den Send Button an, startet das Mobile kurz danach das Senden der Konfiguration indem es zu flackern beginnt. Werden die Daten verstanden, so blinkt das eImp kurz grün und versucht dann eine Verbindung mit dem WLAN herzustellen.

Leider hat das auf Anhieb nicht funktioniert. Erst nach vielen Versuchen kam ich auf die Idee, das Mobiltelefon um 90 Grad zu drehen, was auf Anhieb die Konfiguration transferierte. Hier scheint es sich um einen Polarisationseffekt zu handeln, der natürlich vom verwendeten Telefon abhängt (Galaxy Nexus).

Danach erscheint das angemeldete eImp sofort im Planner. Die Antwortzeit war erstaunlich kurz, was aufgrund der Netzverbindung (4 Mbps) nicht zu erwarten war.

Das erste Programm

Die erste Hürde, die für das Erstellen des ersten Programmes überwunden werden muss, ist die neue Programmiersprache: Squirrel

Als IDE wird der Browser verwendet, denn die gesamte Programmierung erfolgt in der Cloud auf der Entwicklerplatform Planner, welche von der Registrierung her schon bekannt ist. Das bedeuet aber auch, dass man den eImp nicht offline editieren kann sondern dazu immer mit dem Internet verbunden sein muss.

Die Sprache ist an C bzw. Javascript angelehnt und sieht auf den ersten Blick vertraut aus, wenngleich es keine explizite Typdeklationen zu geben scheint. Am einfachsten ist es, mit einem Beispielprogramm zu beginnen: die Implementiereung des blink Sketches wie vom Arduino her bekannt.

// Pin 8/9 blink
// using the shield LED on pin 8 and pin 9 to blink alternatively
// Variable to represent LED state
ledState1 <- 0;
ledState2 <- 1;
// blink function called every 100ms
function blink()
{
    // Change state
    ledState1 = ledState1?0:1;
    ledState2 = ledState2?0:1;
 
    // Reflect state to the pin
    hardware.pin9.write(ledState1);
    hardware.pin8.write(ledState2);
 
    // Schedule the next state change
    imp.wakeup(0.1, blink);
}
// Configure pin 9 as an open drain output with internal pull up
hardware.pin9.configure(DIGITAL_OUT_OD_PULLUP);
// Configure pin 8 as an open drain output with internal pull up
hardware.pin8.configure(DIGITAL_OUT_OD_PULLUP);
 
// Register with the server
imp.configure("Blinking Shield", [], []);
 
// Start blinking
blink();
 
// End of code.

Als erstes werden zwei variablen initialisiert, welche die LED-Zustände speichern. Zwei LED desshalb, weil sich auf dem Shield zwei LED befinden, welche mit den Pins 8 und 9 verbunden sind.

Die Funktion blink() schaltet die Zustände um, wobei man hier schön die Unterschiede zu Arduino C erkennen kann: Beim Arduino würde man schreiben

ledState1 = !ledState1;

und hier findet man eine implizite Bedingung

ledState1 = ledState1?0:1;

bei der im Falle, dass ledState1 1 ist eine 0 zurückgegeben wird, ansonsten eine 1. Das kann unter Umständen verwirrend sein, sollte einen aber nicht mehr befremden als wenn man ständig zwischen Basic und C wechselt.

Die hardware Befehle sind selbsterklärend und der Aufruf imp.wakeup entsprichet dem delay(), nur dass die Zeit in Sekunden angegeben wird.

Sobald man den Code ausführt (run code), wird dieser auf den eImp via dem Internet übertragen. Dies geschah auch wieder regelrecht instantan und mein eImp begann zu blinken.

Vorläufiges Fazit

Die ersten Schritte gestalteten sich sehr einfach, wenn man von den Problemen mit der Konfiguration absieht. Über das Forum wurde mit dem Zeitverzug zur USA recht schnell geantwortet wobei dieser Polarisationseffekt noch unklar ist. Die Handhabung des eImp und die Entwicklung von Code im Browser sowie die neue Sprache sind ungewöhnlich aber man kommt schnell damit zurecht. Der eImp hat ein gewaltiges Potential, das es nun zu erkunden gilt.

Den Kauf bereue ich bisher in keiner Weise, ganz im Gegenteil, ich empfehle eher, sich gleich zwei eImps zu besorgen und dann zwei Arduinos zu verbinden.

Das wird auch der Inhalt des zweiten Programs: Der eImp soll mit dem Arduino, der den Shield trägt, kommunizieren.

Arduino an eImp...

Der nächste Schritt ist nun, den eImp vom Arduino direkt anzusprechen. Dazu verwende ich ein einfaches Sketch, welches via SoftwareSerial einen periodischen String an den eImp schickt:

#include <SoftwareSerial.h>
 
SoftwareSerial impSerial(8,9);
 
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  impSerial.begin(9600);
}
 
int loopc = 0;
void loop() {
  // put your main code here, to run repeatedly: 
  Serial.print("loop: ");
  Serial.println(loopc);
  impSerial.print("loop: ");
  impSerial.println(loopc);
  delay(2000);
  loopc++;
}

Auf dem eImp wartet ein Code auf Input vom UART port (der Code wurde dem Tutorial von Sparkfun entnommen und ein wenig angepasst):

// Transmit data between UART and Input/OutputPorts on the impee
// by: Jim Lindblom
//     SparkFun Electronics
// date: September 26, 2012
// license: BeerWare
//          Please use, reuse, and modify this code as you need.
//          We hope it saves you some time, or helps you learn something!
//          If you find it handy, and we meet some day, you can buy me a beer or iced tea in return.
 
local rxLEDToggle = 1;  // These variables keep track of rx/tx LED toggling status
local txLEDToggle = 1;
 
// impeeIn will override the InputPort class. 
// Whenever data is received to the impee, we'll jump into the set(c) function defined within
class impeeIn extends InputPort
{
    name = "UART Out";
    type = "string";
 
    // This function takes whatever character was sent to the impee
    // and sends it out over the UART5/7. We'll also toggle the txLed
    function set(c)
    {
        hardware.uart57.write(c);
        toggleRxLED();
    }
}
 
local impeeInput = impeeIn();  // assign impeeIn class to the impeeInput
local impeeOutput = OutputPort("UART In", "string");  // set impeeOutput as a string
 
function initUart()
{
    hardware.configure(UART_57);    // Using UART on pins 5 and 7
    hardware.uart57.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS); // 19200 baud worked well, no parity, 1 stop bit, 8 data bits
}
 
function initLEDs()
{
    // LEDs are on pins 8 and 9 on the imp Shield
    // They're both active low, so writing the pin a 1 will turn the LED off
    hardware.pin8.configure(DIGITAL_OUT_OD_PULLUP);
    hardware.pin9.configure(DIGITAL_OUT_OD_PULLUP);
    hardware.pin8.write(1);
    hardware.pin9.write(1);
}
 
// This function turns an LED on/off quickly on pin 9.
// It first turns the LED on, then calls itself again in 50ms to turn the LED off
function toggleTxLED()
{
    txLEDToggle = txLEDToggle?0:1;    // toggle the txLEDtoggle variable
    if (!txLEDToggle)
    {
        imp.wakeup(0.05, toggleTxLED.bindenv(this)); // if we're turning the LED on, set a timer to call this function again (to turn the LED off)
    }
    hardware.pin9.write(txLEDToggle);  // TX LED is on pin 8 (active-low)
}
 
// This function turns an LED on/off quickly on pin 8.
// It first turns the LED on, then calls itself again in 50ms to turn the LED off
function toggleRxLED()
{
    rxLEDToggle = rxLEDToggle?0:1;    // toggle the rxLEDtoggle variable
    if (!rxLEDToggle)
    {
        imp.wakeup(0.05, toggleRxLED.bindenv(this)); // if we're turning the LED on, set a timer to call this function again (to turn the LED off)
    }
    hardware.pin8.write(rxLEDToggle);   // RX LED is on pin 8 (active-low)
}
 
// This is our UART polling function. We'll call it once at the beginning of the program,
// then it calls itself every 10us. If there is data in the UART57 buffer, this will read
// as much of it as it can, and send it out of the impee's outputPort.
function pollUart()
{
    imp.wakeup(0.1, pollUart.bindenv(this));    // schedule the next poll in 10us
    local bcnt = 0;
    local s = "";
    local byte = hardware.uart57.read();    // read the UART buffer
    // This will return -1 if there is no data to be read.
    while (byte != -1)  // otherwise, we keep reading until there is no data to be read.
    {
        s+=byte.tochar();
//        s+=byte;
        bcnt++;
        //  server.log(format("%c", byte)); // send the character out to the server log. Optional, great for debugging
        // impeeOutput.set(byte);  // send the valid character out the impee's outputPort
        byte = hardware.uart57.read();  // read from the UART buffer again (not sure if it's a valid character yet)
        toggleTxLED();  // Toggle the TX LED
        // server.show(byte);
    }
    if (bcnt > 0){
//        server.show("String received");
        server.show(s);
        impeeOutput.set(s);
    } 
}
 
// This is where our program actually starts! Previous stuff was all function and variable declaration.
// This'll configure our impee. It's name is "UartCrossAir", and it has both an input and output to be connected:
imp.configure("UartCrossAir", [impeeInput], [impeeOutput]);
initUart(); // Initialize the UART, called just once
initLEDs(); // Initialize the LEDs, called just once
pollUart(); // start the UART polling, this function continues to call itself
// From here, two main functions are at play:
//      1. We'll be calling pollUart every 10us. If data is sent from the UART, we'll send out out of the impee.
//      2. If data is sent into the impee, we'll jump into the set function in the InputPort.
//
// The end