Mobile Technology Digital 32
Author: Christopher Dzierzon; Alexander Frommelt; Tam Hanna; Jonas Hungershausen; Martin Mohr; Daniel Sorna; Lars Vogel
Date: 2018-07-11T23:00:00+00:00
Keywords: Mobile Technology; Android Things; IoT; Google Fuchsia; Flutter SDK; Sprachassistenten; ESP8266; Dart
Description: Mobile Technology ist der Wegbegleiter für alle, die sich professionell mit der Entwicklung für mobile Devices und den Möglichkeiten, die der Markt des Mobile Business und Marketing bereithält, beschäftigen. Das Magazin deckt dabei die gesamte Bandbreite an Plattformen und Technologien ab und bringt dem Leser nicht nur Development-Themen für die verschiedenen Mobile OS wie Android und iOS näher, sondern beleuchtet auch deren Einsatz im Enterprise-Umfeld. Es bietet darüber hinaus einen tiefen Einblick in die Chancen, die der Markt des Mobile Business und Marketing bereithält.
Publisher: entwickler.press
Rights: © 2018 entwickler.press. Alle Rechte, auch für Übersetzungen, sind vorbehalten. Reproduktion jeglicher Art (Fotokopie, Nachdruck, Mikrofilm, Erfassung auf elektronischen Datenträgern oder andere Verfahren) nur mit schriftlicher Genehmigung des Verlags. Jegliche Haftung für die Richtigkeit des gesamten Werks, kann, trotz sorgfältiger Prüfung durch Autor und Verlag, nicht übernommen werden. Die im Buch genannten Produkte, Warenzeichen und Firmennamen sind in der Regel durch deren Inhaber geschützt.

Mobile Technology Digital
Volume 32
ISBN: 978-3-86802-794-5
© 2018 Software & Support Media GmbH

Eine Publikation des Mobile Technology
in Kooperation mit entwickler.press

Ihr Kontakt zu Verlag und Redaktion:
Software & Support Media GmbH
entwickler.press
Schwedlerstraße 8
60314 Frankfurt
Tel: +49 (0)69 630089-0
Fax: +49 (0)69 630089-69
lektorat@entwickler-press.de
http://www.entwickler-press.de

Redaktion: Hartmut Schlosser
Korrektorat/Schlussredaktion: Jonas Bergmeister, Jasmin Höhl, Frauke Pesch
Satz: meat* – concept and design
Autoren: Christopher Dzierzon, Alexander Frommelt, Tam Hanna, Jonas Hungershausen, Martin Mohr, Daniel Sorna, Lars Vogel

Alle Rechte, auch für Übersetzungen, sind vorbehalten. Reproduktion jeglicher Art (Fotokopie, Nachdruck, Mikrofilm, Erfassung auf elektronischen Datenträgern oder andere Verfahren) nur mit schriftlicher Genehmigung des Verlags. Jegliche Haftung für die Richtigkeit des gesamten Werks, kann, trotz sorgfältiger Prüfung durch Autor und Verlag, nicht übernommen werden. Die im Kompendium genannten Produkte, Warenzeichen und Firmennamen sind in der Regel durch deren Inhaber geschützt.

Ist Flutter SDK der designierte Android-Nachfolger?

Neue Android- und iOS-Welt mit dem Flutter SDK
von Lars Vogel und Jonas Hungershausen

Google schickt ein neues Betriebssystem, Google Fuchsia, um die Gunst der User ins Rennen, und verunsichert damit ein wenig die Gemeinschaft der Android-Entwickler. Passend zum neuen Betriebssystem hat Google das Flutter SDK [1] entwickelt, mit dem man für Fuchsia Applikationen erstellen kann. Flutter eignet sich allerdings nicht nur für die Entwicklung von Fuchsia-Anwendungen, sondern auch für solche, die auf Android sowie iOS laufen – und das mit (fast) der gleichen Codebasis.

Google Fuchsia ist ein Echtzeitsystem, das auf einem neuen Mikrokernel, genannt Zircon (ehem. Magenta), basiert. Das neue OS unterscheidet sich von Googles bislang entwickelten Betriebssystemen (Android und Chrome OS), die auf dem Linux-Kernel basieren. Magenta wurde seinerzeit vom Projekt „Little Kernel“ abgeleitet, das ursprünglich als Android Bootloader diente und in C geschrieben ist. Laut Google soll Fuchsia das Android-Betriebssystem irgendwann ersetzen. Interessant ist außerdem, dass Googles neues OS unter sehr freizügigen Lizenzen (eine Kombination aus BSD- , MIT- und Apache-Lizenz) stehen wird und man sich damit von der GPL, die für Linux verwendet wird, verabschiedet. Das macht sicherlich die kommerzielle Adaption für andere Unternehmen attraktiver, da durch die Nutzung dieser Lizenzen keine Verpflichtung besteht, eigene Änderungen am Betriebssystem erneut zu veröffentlichen.

Das speziell für Fuchsia-, aber auch für die Entwicklung von Android- und iOS-Anwendungen vorgesehene Flutter SDK nutzt die Programmiersprache Dart, also nicht mehr Java oder Kotlin für die gewohnte Entwicklung von Apps mit dem Android SDK. Man fragt sich nun, was das Ganze soll. Ist Google nicht mehr mit Android und den entsprechenden Enwicklungstools zufrieden? Und sind Java bzw. Kotlin doch nicht mehr die Sprachen der Wahl für mobile Applikationen? Genaues weiß man natürlich nicht. Aber allein die Tatsache, dass Google offensichtlich ordentlich in ein neues System investiert, lässt einen entweder auf etwas Neues hoffen oder es wird einem angst und bange, je nach Einstellung.

Die Programmiersprache Dart

Flutter-Applikationen erstellt man also mit Dart. Warum aber gerade Dart und nicht Java oder Kotlin? Aus dem Hause Google heißt es dazu, dass man sich Dutzende Programmiersprachen angeschaut und sich dann für Dart entschieden hat, weil es besser als vergleichbare Sprachen sein soll. Ob das stimmt, sei einmal dahingestellt. Google gab jedenfalls vor einiger Zeit schon bekannt, dass man AdSense auf die hauseigene JavaScript-Alternative umgestellt habe, was das Bekenntnis des Suchmaschinenriesen zu Dart jedenfalls bestätigt. Denn mit AdSense (Googles Lösung für Werbung im Internet) verdient man in Mountain View immer noch einen Löwenanteil des Gewinns. Somit basiert der kritischste Teil von Googles Infrastruktur auf Dart. Von daher macht es sicherlich Sinn, wenn Google andere versucht zu motivieren, diese Programmiersprache ebenfalls zu nutzen. Außerdem ist das Unternehmen ja immer noch in einem Rechtsstreit mit Oracle wegen der Nutzung der Java-APIs in Android, was aus Sicht von Google zusätzlich für eine Alternative sprechen dürfte. Und zu guter Letzt wird Dart, wie oben bereits erwähnt, ausschließlich von Google entwickelt – was sicherlich auch im Sinne des Unternehmens ist, das sich nicht gerne an Open-Source-Projekten anderer beteiligt.

Einer der gerne hervorgehobenen Punkte ist, dass Dart sowohl Ahead of Time (AoT) als auch Just in Time (JiT) kompiliert. Dart wird also in nativen Code übersetzt, kann aber wie Java zur Laufzeit noch nachoptimiert werden. Damit vereint es die Vorteile von Programmiersprachen wie C (AoT) und Java (JiT). Dabei kommen die Objekterzeugung und der Garbage Collector ohne Locks aus, d. h. Aussetzer wie in früheren Java-Zeiten sollen nicht mehr vorkommen.

Eine Sache, die den Autoren an dem Flutter SDK sehr gut gefällt ist, dass man User Interfaces direkt in der Programmiersprache über Properties definieren kann. Ganz ehrlich, mag irgendjemand die Android-XML-Layoutfiles wirklich? Wahrscheinlich keiner. Wenn man dann noch versucht, in diesen XML-Dateien das Android Data Binding zu verwenden, findet man sich sehr schnell in der XML-Hölle wieder. In Dart und Flutter geht die Definition von UIs hingegen direkt im Code und sieht auch noch elegant aus, wie das Beispiel in Listing 1 zeigt, das in Dart 1 geschrieben wurde. Der new-Operator ist außerdem zusammen mit dem const Keyword in Dart 2 obsolet, d. h. man kann dann Dart-Widgets noch eleganter schreiben.

class FlutterTestingApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "Flutter rocks",
home: new MyScreen(),
);
}
}

Listing 1

Dart lässt sich sowohl in JavaScript als auch in nativen Code für Android und iOS kompilieren, sodass man seinen Code (teilweise) dann fürs Web und auch für mobile Anwendungen wiederverwenden kann. Google spricht hier gerne von bis zu 70 Prozent Wiederverwendbarkeit.

Die Programmiersprache nutzt außerdem ein spezielles Konstrukt für Threads: die sogenannten Isolates. Diese teilen sich keinen Arbeitsspeicher wie etwa Java-Threads, sondern kommunizieren über Nachrichten miteinander. JavaScript-Entwickler fühlen sich hier schnell an die Web Workers erinnert. Da der Arbeitsspeicher nicht geteilt wird, entfällt oft die Notwendigkeit für Locks und damit eine häufige Fehlerquelle.

Per Definition ist Dart single-threaded, Methoden können aber mit dem async Keyword markiert werden. In dem Fall wird ihr Rumpf asynchron aufgerufen, und man kann sie über await wieder mit dem Hauptthread synchronisieren (Listing 2).

foo() async {
// expensiveA() is in this case some function that fetches
// something or does some asynchronous operation
await data = expensiveA();
// Will wait until expensiveA() is completed and then continue the // execution
print(data);
}

Listing 2

Dart ist außerdem ein ECMA-Standard, auch wenn es aktuell ein „vom Hersteller kontrollierter Standard“ zu sein scheint, da Google alle Fäden in der Hand hält. Aber es gibt auch immer mehr Libraries für Dart, z. B. für reaktive Programmierung (RxJava), Firebase-Verbindungen und Datenbanken [2].

Wie entwickelt man Flutter-Apps?

Möchte man eine App mit Flutter schreiben, die sowohl auf Android als auch auf iOS läuft, so braucht man Zugang zu einem macOS-basierten Betriebssystem und Xcode, der IDE von Apple für iOS- und Mac-Apps. Das ist allerdings nur notwendig, wenn man eine kompilierte Version seiner App benötigt. Will man iOS ignorieren, kann man auf diese Voraussetzung verzichten, und es genügt lediglich ein Computer mit einem Android SDK und Flutter SDK. Hierbei gelten die gleichen Mindestvoraussetzungen in Sachen API-Level wie bei der klassischen Android-Entwicklung. Da sich Fuchsia zurzeit noch in einer frühen Entwicklungsphase befindet, ist es zurzeit nur bedingt möglich, Flutter auf dieser Plattform zu testen.

Bei der IDE-Wahl hat man aktuell die Auswahl zwischen dem leichtgewichtigen Texteditor Visual Studio Code oder der etwas umfangreicheren, dafür aber auch schwerfälligeren IntelliJ IDEA. Bei beiden ist jedoch die Installation eines separaten Plug-ins notwendig, um das volle Potenzial nutzen zu können. So bieten beide Plug-ins ein gutes Syntax-Highlighting für Dart sowie ein ausreichendes Tooling fürs Debuggen, das man von der klassischen Android-Entwicklung gewohnt ist.

Es spielt hierbei übrigens keine Rolle, ob man für iOS, Android oder beides gleichzeitig entwickelt; bald wird dann wohl auch Fuchsia hinzukommen. Da die Codebasis für alle drei Varianten überwiegend die gleiche ist, kann auch die gleiche Entwicklungsumgebung genutzt werden.

Plug-ins für Visual Studio Code

VS Code eignet sich sehr gut, um eine App mit Flutter zu schreiben. Da die grundlegenden Funktionen des Flutter SDKs auch per Konsole zu erreichen sind, ist es sogar möglich, jeden beliebigen Texteditor zur Entwicklung von Flutter-Apps zu nutzen. In diesem Fall wird der Editor VS Code allerdings noch durch das Plug-in Dart Code unterstützt, das Debuggen sowie Syntax-Highlighting wesentlich erleichtert.

Beim Entwickeln mit VS Code fällt gleich auf, dass das Flutter SDK sehr schnell einen Reload durchführt. Lange Wartezeiten, wie man sie von Android Studio kennt, treten zumindest in dem von uns verwendeten Visual Studio Code nicht auf.

Plug-ins für IntelliJ IDEA

Auch für die von Haus aus sehr umfangreiche Entwicklungsumgebung IntelliJ IDEA werden zwei Plug-ins benötigt, um das volle Potenzial der Flutter-Entwicklung zu nutzen. Sie heißen Dart und Flutter. Ersteres fügt die Unterstützung für Dart hinzu, Letzteres weitere Funktionen, die für das Entwickeln einer App mit Flutter benötigt werden.

Ein Fallbeispiel

Klingt doch alles ganz gut, oder? Wer jetzt also Blut geleckt hat, sollte gleich seine erste Flutter-App schreiben. Zunächst muss man sich allerdings noch das Flutter SDK installieren. Das geht erstaunlich einfach, und auf der Homepage von Flutter [3] ist genau beschrieben, welche Schritte durchzuführen sind. Ist dies erledigt, kann man schon durchstarten und die erste Anwendung auf einem angeschlossenen Android-Emulator laufen lassen. Dazu gibt man auf der Kommandozeile das Folgende ein:

flutter create beispielapp
cd beispielapp
flutter run

In Listing 3 ist der Quellcode für die voll funktionsfähige Flutter-App dargestellt, die für Android und iOS mit minimaler Funktionalität ausgestattet ist.

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;

@override
_MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;

void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
),
);
}
}

Listing 3

Sieht elegant aus, nicht wahr? Mit Visual Studio Code öffnet man jetzt einfach das Verzeichnis und kann sich das generierte main.dart anschauen. Parallel dazu sollte man schnell noch Dart installieren, das entsprechende Tooling findet sich bei Bedarf im Marketplace von Visual Studio [4]. Damit lässt sich der Code selbst relativ leicht bearbeiten, da mit dem Plug-in Codevervollständigung, Information Hovers und Syntax-Highlighting zur Verfügung stehen.

Das wichtigste Merkmal ist, dass das Fluent-API verwendet wird, um alles zu konfigurieren, etwa die Actionbar bzw. Toolbar. Auf der Homepage von Flutter gibt es dazu ein Beispiel [5]. Die AppBar Closure definiert hier die Toolbar-Einträge und legt fest, dass die _select-Methode aufgerufen wird (Listing 4). Was für eine Erleichterung gegenüber der aufwendigen XML-Menüdefinition und dem Registrieren dieser in der onCreateOptionsMenu- und der Auswertung in der onOptionsItemSelected-Methode im Android SDK.

@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: const Text('Basic AppBar'),
actions: <Widget>[
// action button
new IconButton(
icon: new Icon(choices[0].icon),
onPressed: () {
_select(choices[0]);
},
),
// action button
new IconButton(
icon: new Icon(choices[1].icon),
onPressed: () {
_select(choices[1]);
},
),
// overflow menu
new PopupMenuButton<Choice>(
onSelected: _select,
itemBuilder: (BuildContext context) {
return choices.skip(2).map((Choice choice) {
return new PopupMenuItem<Choice>(
value: choice,
child: new Text(choice.title),
);
}).toList();
},
),
],
),
body: new Padding(
padding: const EdgeInsets.all(16.0),
child: new ChoiceCard(choice: _selectedChoice),
),
),
);
}
}

Listing 4

Zusammenfassung

Die Kombination aus Dart und Flutter weiß zu gefallen. Die vogella Gmbh arbeitet ja schon seit Jahren mit verschiedenen Kunden an unterschiedlichsten Android-Apps, und wir sind erleichtert, mit Visual Studio Code endlich einmal ein elegantes Tooling an die Hand und eine Pause vom langsamen Android Studio zu bekommen. Die Ansätze von Dart empfinden wir als erfrischend neu nach vielen Jahren der mobilen Entwicklung mit Java und den unhandlichen Android-XML-Layoutfiles.

Was Google nun wirklich mit Flutter plant, wird sich sicherlich in der Zukunft zeigen. Zumindest wurde das Flutter SDK vor ein paar Wochen von der Alpha- in die zweite Betaphase geschickt. Wir empfehlen, das Ganze auf jeden Fall einmal auszuprobieren. Mit Visual Studio Code und ein paar Zeilen Dart Code kommt man ja schon relativ schnell zu einem ansehnlichen Ergebnis.

Als weiteres Beispiel haben wir auf GitHub [6] eine App abgelegt, die die aktuellen Kryptowährungen vom Portal CryptoCompare [7] ausliest und in einer Liste anzeigt. Das Ganze mit dem Android SDK zu erstellen, hätte sicherlich mehr Zeilen Code benötigt.

Lars Vogel ist Geschäftsführer der vogella GmbH, die Kunden im Bereich Eclipse, Android und anderen Themen unterstützt. Als Project-Management-Committee-Mitglied, Eclipse-Projektleiter und Committer hilft er dem Eclipse-Projekt.
Mail: lars.vogel@vogella.com

Jonas Hungershausen studiert zurzeit in Flensburg, nutzt aber (fast) jede Minute, um mit JavaScript und Spring Boot das Learn-Portal der vogella GmbH weiterzuentwickeln, und verbessert parallel dazu noch die Eclipse IDE. Zudem evaluiert er gerne neue Technologien.
Web: http://learn.vogella.com

Links & Literatur

[1] Flutter-Homepage: https://flutter.io/

[2] Dart-Bibliotheken: https://pub.dartlang.org/

[3] Installationsanleitung für das Flutter SDK: https://flutter.io/get-started/install/

[4] Marketplace für Visual Studio: https://marketplace.visualstudio.com/items?itemName=Dart-Code.dart-code

[5] Beispiel einer Toolbar mit Flutter: https://flutter.io/catalog/samples/basic-app-bar/

[6] Beispiel-App zum Auslesen der Kryptowährungen: https://github.com/vogellacompany/codeexamples-dart/

[7] CryptoCompare: https://www.cryptocompare.com/

©armando costantino/Shutterstock.com

Teil 2: Sensorik mit Android Things steuern

Noch mehr Dinge
von Tam Hanna

Am Ende des letzten Teils hingen wir in der Luft. Die für die Anzeige des Highlights eingefügten Tags waren zwar schon am Platz, die eigentliche Hervorhebung erschien allerdings noch nicht am Bildschirm. Jetzt wollen wir Android Things Beine machen. Neben der Fertigimplementierung des Fünf-Wege-Navigators inklusive der Weitergabe von Ereignissen wollen wir in diesem Teil auch erste Schritte in die faszinierende Welt der Sensoren unternehmen.

Artikelserie

Teil 1: Einstieg in das Entwicklerkit für Android Things

Teil 2: Sensorik mit Android Things steuern

Teil 3: Hardware steuern mit Android Things

Wir arbeiten wieder mit einem Raspberry Pi 3. Als Android-Things-Version dient nach wie vor 0.5.0, das Projektskelett aus dem vorigen Heft wird ebenfalls weiterverwendet.

Klassische Prozessrechnersysteme leiden unter anderem darunter, dass die einzelnen Komponenten nur wenig interaktiv sind: Wer mit einem primitiven Echtzeitbetriebssystem hantiert, ist nur wenig zur Realisierung von komplexen Infrastrukturen motiviert. Die am Ende des letzten Teils realisierten fünf Knöpfe generieren Ereignisse, die auch für den Rest des Android-Betriebssystems interessant sind. Die Stärke von Android Things ist, dass das Betriebssystem eine Unmenge von Schnittstellen anbietet, über die Entwickler eigene Ereignisse einspeisen und somit für andere Applikationen zugänglich machen können. Wir wollen dies in den folgenden Schritten mit den Fünf-Wege-Navigator-Ereignissen durchführen, müssen vorher aber einen Blick auf Abbildung 1 werfen.

Abb. 1: Mit ausreichend Nachbearbeitung: Der Knopf Nummer fünf ist markiert

Das von Google als Standard festgelegte Farbschema ist für die Fünf-Wege-Bedienung insofern ungeeignet, als die farblichen Unterschiede zwischen aktiven und nicht aktiven Steuerelementen minimal ausfallen. Zur Behebung dieses Problems reicht es aus, ein anderes Farbschema zu laden (Kasten: „Schwarz ist böse“). Da dieser Artikel nicht zu einem Tutorium in Sachen Android-Theme-Design ausarten soll, genügt es, das XML-Mark-up des Formulars folgendermaßen anzupassen:

<android.support.constraint.ConstraintLayout
android:theme="@android:style/Theme.Dialog"
xmlns:android="http://schemas.android.com/apk/res/android"

Ab der nächsten Programmausführung erscheint das gerade hervorgehobene Element in orange (Abbildung 2).

Schwarz ist böse

Dunkle Hintergründe sind im Labor extrem attraktiv. Wer einmal einen NuColor-Bildschirm von Danaher benutzt hat, weiß, was der Autor meint. Denken Sie beim Design von IoT-Hardware allerdings immer daran, dass ihr Gerät auch in der Sonne eingesetzt werden könnte. In diesem Fall neigen schwarze Displayteile zur Reflexion, was die Usability wesentlich verschlechtert.

Abb. 2: Dieses seit Android 1.0 vorhandene Theme funktioniert für unsere Bedürfnisse perfekt

Wer seinem Prozessrechner eine USB-Tastatur spendiert, kann das Highlight mit den Cursortasten verschieben. Wir wollen die Steuerung allerdings mit den Tastern bewerkstelligen. Eine Aufgabe, die die Implementierung eines User Drivers voraussetzt.

Brücke zum Betriebssystem

Google zeigt in der Dokumentation die Implementierung von User Drivers stets in Form eines Services: aus akademischer Sicht nett, in der Praxis aber nicht erforderlich. Wir wollen unseren Treiber stattdessen direkt im SniffThread einnisten, um beim Weiterleiten der Ereignisse keine zusätzliche Kopplung zu erzeugen:

public class SniffThread extends Thread{
private InputDriver myDriver;

Im ersten Akt deklarieren wir eine Member-Variable: Eine Instanz der Klasse InputDriver ist erforderlich, die für die eigentliche Interaktion zwischen Betriebssystem und Applikation verantwortlich ist.

Damit können wir uns der Erzeugung des Treibers zuwenden, die im Konstruktor von SniffThread erfolgt:

public SniffThread(Gpio _l, Gpio _r, Gpio _u, Gpio _d, Gpio _c){
InputDriver.Builder aBuilder=new InputDriver.Builder(InputDevice.SOURCE_CLASS_BUTTON);

Googles Dokumentation ist an dieser Stelle veraltet: In Version 8.0 von Android Things wurde der InputDriver-Builder in eine separate Klasse ausgelagert, die im Rahmen der Erzeugung eine Konstante entgegennimmt. Diese beschreibt, welche Art von Ereignissen prinzipiell in diesem Treiber anfällt. Wir übergeben hier SOURCE_CLASS_BUTTON, was die Events als von Knöpfen verursachte Ärgernisse qualifiziert.

Im nächsten Schritt wird der Builder mit Informationen ausgestattet, die schlussendlich zur Erzeugung des eigentlichen Treibers befähigen. Besonders interessant ist, dass sie hier alle vom Treiber potentiell ausgebbaren Tastaturscancodes anmelden müssen:

myDriver=aBuilder.setName("SUSDriver")
.setVersion(1)
.setKeys(new int[] {KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_DPAD_CENTER})
.build();

Zu guter Letzt wird der UserDriverManager instanziiert: Es handelt sich dabei um eine Managementklasse, die für das Anmelden von Usertreibern verantwortlich ist. Die Methode registerInputDriver registriert unseren Treiber sodann beim Kernel:

UserDriverManager manager = UserDriverManager.getManager();
manager.registerInputDriver(myDriver);

Für das eigentliche Absetzen der Ereignisse sind Sendemethoden verantwortlich. Wir benötigen in unserem Programmbeispiel fünf davon. Aus Platzgründen drucken wir hier allerdings nur die Methode für den Nach-Oben-Knopf ab:

private void triggerUpEvent(boolean pressed) {
int action = pressed ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
KeyEvent[] events = new KeyEvent[] {new KeyEvent(action, KeyEvent.KEYCODE_DPAD_UP)};
if (!myDriver.emit(events)) {
Log.w("SUS", "Unable to emit key event");
}
}

Google betrachtet Knopfereignisse als zustandshaltig: Das Event wird sowohl in einer Nach-Unten-Variante als auch in einer Nach-Oben-Variante angeboten, um sowohl das Drücken als auch das Loslassen des Tasters zu erfassen. Dies ist für uns allerdings nur insofern interessant, als wir es bei der Einbindung berücksichtigen müssen.

Ein weiteres neues Feature von Android 8.0 ist, dass User Drivers über eine Permission in der Manifest-Datei angemeldet werden müssen:

<uses-permission android:name="com.google.android.things.permission.MANAGE_INPUT_DRIVERS" />

Keine Volksbefragung

Das im letzten Teil realisierte Ausgeben der Zustandsinformationen erfährt durch die Zweiwertigkeit eine Komplikation: Wir müssen Android nun informieren, wenn der Nutzer die Taste drückt oder loslässt. Informatiker greifen an dieser Stelle reflexartig zum Zustandsautomaten: In unserem Fall ist dies insofern suboptimal, als Polling erstens ineffizient ist und zweitens den Code unserer Solution verlängert. Stattdessen wollen wir hier auf „Interrupts“ setzen: Android Things beobachtet die Pins in diesem Betriebsmodus für uns und feuert beim Auftreten von Änderungsereignissen selbsttätig ein Event ab.

Google erschwert uns die Arbeit mit dem Werfen von unnötigen Exceptions: Android Things kann auch beim Anmelden eines Handlers eine Exception werfen, was zu einer vergleichsweise umfangreichen Deklaration führt. Zudem wird der Interrupt durch das Einschreiben eines Handlers nicht aktiviert – das Betriebssystem liefert nur dann Ereignisinformationen, wenn man diese explizit anfordert (Listing 1).

myL=_l;
try {
myL.setEdgeTriggerType(Gpio.EDGE_BOTH);
myL.registerGpioCallback(new GpioCallback() {
@Override
public boolean onGpioEdge(Gpio gpio) {
try{
triggerLeftEvent(gpio.getValue());
}catch (Exception e){}
return true;
}
});
} catch (IOException e) {
e.printStackTrace();
}

Listing 1

Wir fügen den in Listing 1 abgedruckten Code – natürlich angepasst – auch in die vier anderen GPIO-Pins ein, um die Arbeit am ersten Projekt abzuschließen. Anschließend jagen wir es auf den Prozessrechner, wo das Kompilat mit dem Fehler java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.androidthings.myproject/com.example.androidthings.myproject.MainActivity}: java.lang.SecurityException: Caller lacks required permission com.google.android.things.permission.MANAGE_INPUT_DRIVERS verendet. Dieses lustige Verhalten liegt in einem Fehler von Android Studio begründet: Die IDE ist aus irgendeinem Grund nicht in der Lage, Android-Things-Endgeräte über die Aktualisierung der Permissionsliste des Kompilats zu informieren. Die Lösung des Problems besteht darin, den Prozessrechner neu zu starten, danach funktioniert alles wie geplant.

Analog und Digital

Der erste Raspberry Pi entstand als „Müllschlucker“ für Nokias aufgegebenes Meltemi-Projekt und die dabei übrig gebliebenen Prozessoren. Für Entwickler war dies insofern ungut, als dass für den Smartphoneeinsatz vorgesehene Prozessoren im Bereich ihrer Ein- und Ausgabefähigkeiten im Allgemeinen eher schwach ausgestattet sind. Das trifft auch auf den Raspberry Pi zu, der weder einen analogen Eingang noch einen analogen Ausgang besitzt. Zudem ist die Anzahl der Pulsbreitenmodulationsausgänge auf zwei beschränkt, weil der Prozessor schlichtweg nicht mehr Module mitbringt.

Wir wollen in den folgenden Artikeln mit verschiedenen Sensoren arbeiten. Die meisten von ihnen haben die unangenehme Eigenschaft, analoge, also wertkontinuierliche Signale auszugeben. Um diese für den Prozessrechner verwertbar zu machen, müssen wir sie im ersten Schritt „diskretisieren“. Dies ist die Aufgabe von Bauteilen, die als Analog-/Digitalwandler (A-/D-Wandler) bezeichnet werden (Kasten: „Wandlertanz“).

Wandlertanz

Das wichtigste Kriterium bei der Auswahl von A-/D-Wandlern ist die Auflösung: Je höher, desto genauer der Wandler (unter Vernachlässigung von Rauschen und sonstigen fortgeschrittenen Phänomenen). Problem Nummer zwei ist der Busstandard – während unser IS über acht Leitungen mit dem Prozessrechner kommuniziert, nutzen andere Wandler I2C oder SPI.

Wer einen Distributor nach A-/D-Wandlern fragt, findet tausende verschiedene Optionen. Wir wollen in den folgenden Schritten einen IS von National Instruments verwenden: Der ADC0804 ist im Allgemeinen preiswert erhältlich und steht im DIP-Gehäuse zur Verfügung, das zum Prototyping ideal geeignet ist. Abbildung 3 zeigt, wie wir ihn mit Prozessrechner und Rheostat verbinden.

Abb. 3: Der Rheostat erlaubt uns die Simulation eines Sensors

Beginnen wir mit der Betrachtung der beiden passiven Bauelemente, also des Widerstands und des Kondensators. Unser A-/D-Wandler muss eine Taktfrequenz generieren, mit der er seine diversen internen Funktionseinheiten versorgt. Der Hersteller löst dies durch Einbau eines Schottky-Inverters, der über Widerstand und Kondensator zum Oszillieren angelegt werden kann.

Das nächste Problem bei einem A-/D-Wandler ist, dass die analoge Größe in ihrer Eigenschaft als zeitkontinuierliches Signal ihren Wert mehr oder weniger beliebig verändern kann. Wir wollen hier ein zeitdiskretes Signal erzeugen, weshalb wir in einem als Sampling bezeichneten Prozess regelmäßig „schnüffeln“ und diese Werte zur Digitalisierung zwischenspeichern. Der ADC0804 löst dies normalerweise über eine Gruppe von Pins, über die der Mikrocontroller den Wandler zum Scharfschalten des Schnüfflers animieren kann. Da wir uns an dieser Stelle damit nicht aufhalten wollen, verbinden wir das Fertigsignal mit dem Startsignal: Hat der Wandler den ersten Konversionsdurchlauf beendet, startet er sogleich mit dem nächsten. Dadurch kann es zu Problemen kommen: Stellen Sie sich vor, dass unser Prozessrechner die angelieferten Daten von LSB zu MSB einliest. Während dieses Einlesens ändert sich das Signal allerdings rapide – ein Teil der Bits wäre nun neu, der andere alt. Zur Umgehung böte sich an, den Sampling-Start von Hand durchzuführen. Dies würde die Latenz allerdings erhöhen – auch in der Welt der Elektronik gibt es nun mal kein kostenloses Mittagessen.

Beim Design von Analogschaltungen ist es im Allgemeinen wichtig, auf die Massepotenziale zu achten. Unser Bauteil hat zwei Masseeingänge, der eine ist für das analoge, der andere für das digitale Subsystem verantwortlich. Masseeingang Nummer drei entsteht, weil wir die Möglichkeit hätten, Differenzialsignale anzunehmen. Themen, die im unter http://www.ti.com/lit/ds/symlink/adc0802-n.pdf bereitstehenden Datenblatt im Detail beschrieben werden.

Lasset uns codieren

Jetzt sind wir zum Programmieren des Wandlers bereit. Android Things ist in seiner Eigenschaft als Einwegbetriebssystem nicht wirklich für Situationen ausgestattet, in der mehrere Applikationen um ein- und dieselbe Hardwarekomponente wetteifern. Aus diesem Grund ist es empfehlenswert, für jedes Android-Things-Projekt eine eigene SD-Karte anzulegen. Wer die Karten im Internet oder im Einzelhandel erwirbt, kommt sehr preiswert an acht oder 16 GB große Karten.

Ob der immensen Weiterentwicklung von Android Studio ist es spätestens an dieser Stelle empfehlenswert, auf die aktuelle Version 3.0 umzustellen. Sie ist im Großen und Ganzen stabil. Wer mit einer deutschsprachigen Locale arbeitet, bekommt zeitweise einen Fehler der Bauart „invalid dimen“. Dieser lässt sich allerdings beim Start durch folgende Eingabe beheben:

~/Downloads/android-studio/bin$ export LC_NUMERIC="en_US.UTF-8"
~/Downloads/android-studio/bin$ ./studio.sh

Unter Windows arbeitende Entwickler finden bei der Google-Suche nach „android studio invalid dimen“ ebenfalls Hinweise. Die wichtigste Neuerung von Android Studio 3.0 ist, dass der Projekterstellungsassistent in der Lage ist, die Android-Things-Bibliotheken automatisch einzubinden. Wer eine neue Android Things Empty Activity anfordert, wird von Android Studio mit einem Projektskelett versorgt, das den XML-GUI-Parser direkt einbindet. Wir wollen das in den folgenden Schritten zur Realisierung des Projekts SUSMesssystem nutzen.

Während bei kleineren Steuerungen das direkte Interagieren mit GPIO-Pins effizient ist, macht uns unser ADC mit seinen acht Datenleitungen einen Strich durch die Rechnung. Aus diesem Grund legen wir ein Array an und bevölkern es unter Nutzung einer Hilfsfunktion (Listing 2).

public class MainActivity extends Activity {
Gpio myADCInputs[]=new Gpio[8];
@Override
protected void onCreate(Bundle savedInstanceState) {
. . .
PeripheralManagerService myPSM = new PeripheralManagerService();
myADCInputs[0]=getPin("BCM10", myPSM); //LSB
. . .
myADCInputs[7]=getPin("BCM26", myPSM); //MSB

Listing 2

Von besonderem Interesse ist hier die Nutzung der Abkürzungen LSB und MSB. Es handelt sich dabei um zwei Begriffe, die in der Welt der A-/D-Konversion geläufig sind. MSB steht hierbei für Most Significant Bit und beschreibt das Bit, das am meisten Gewicht mitbringt. Das LSB steht für Least Significant Bit und ist am wenigsten relevant.

getPin ist im Großen und Ganzen Code, den Sie aus dem letzten Teil der Serie kennen. Der einzige Unterschied zu vorher ist, dass wir die Initialisierung nun in eine dedizierte Methode auslagern.

Da Android nun mal Android ist, ist auch unter Android Things der ANR-Dialog nicht fern. Das erledigen einer sich permanent wiederholenden Messaufgabe lässt sich am einfachsten in Form eines Threads realisieren, dessen Deklaration nun mit einem Konstruktor beginnt:

public class ReaderThread extends Thread{
Gpio[] myField;
public ReaderThread(Gpio[] _field){
super();
myField=_field;
}

Diese auf den ersten Blick seltsam erscheinende Vorgehensweise ist erforderlich, weil wir das Feld mit den GPIO-Pin-Strukturen ja aus der Activity in den Thread befördern müssen. Im nächsten Schritt wenden wir uns der eigentlichen Frage zu, wie wir die vom ADC angelieferten Werte in ein für Menschen oder Prozessrechner verwertbares Format bringen können.

Die als Referenz bezeichnete Spannung – sie liegt, durch zwei geteilt, am Pin VREF/2 an und kann dort beeinflusst werden – wird von unserem achtbittigen Wandler in 256 Stufen unterteilt. Da wir hier keine externe Referenzspannung zuführen, haben wir also die vom Raspberry Pi gelieferten 3V3 geteilt durch 256, was eine Abstufung von 0,0128 Volt ergibt. Daraus folgt, dass wir zur Ermittlung eines realen Werts im ersten Schritt feststellen müssen, wie viele ADC-Einheiten erforderlich sind. Im Interesse der Übersichtlichkeit wollen wir uns anfangs darauf beschränken, einmal pro 250 ms zu samplen. Hierzu müssen wir in run() folgende Struktur anlegen:

@Override
public void run() {
while(1==1){
try {
Thread.sleep(250);
}
catch(Exception x){/*STFU*/}
}
}

A-/D-Wandler haben die angenehme Eigenschaft, stets mit Zweierpotenzen zu arbeiten. Aus diesem Grund können wir uns mit einer weiteren While-Schleife behelfen, die von 1-128 läuft und die jeweiligen Werte in ein Akkumulatorregister schreibt. Nach dem erfolgreichen Durchlaufen der gesamten Schleife können wir dieses Ergebnis mit dem Wert eines einzelnen Spannungsschritts multiplizieren, um uns am fertigen Ergebnis zu erfreuen. Hierzu können wir beispielsweise auf folgenden Code zurückgreifen:

try {
int wertFaktor=1;
int accu=0;
for(int i=0;i<8;i++) {
if(myField[i].getValue()) {
accu+=wertFaktor;
}
wertFaktor*=2;
}
Float aVal=accu*(float)3.3/256;
Log.e("Wert", aVal.toString() + "V");
Thread.sleep(250);
}

An dieser Stelle sind wir für einen Testlauf bereit. Wir schicken das Programm auf den Android-Things-Prozessrechner und ändern den Wert des Rheostaten. Dabei beobachten wir die Ausgabe in Logcat: In der Konsole werden regelmäßig Spannungswerte erscheinen. Zusätzlich besteht die Möglichkeit, ein Voltmeter über den Ausgang zu schalten und so die am ADC anliegende Spannung mit der gemessenen Spannung zu vergleichen. Im Interesse der Vermeidung von Volt-Nuts-Reaktionen: Ein 8-Bit-A-/D-Wandler hat mit einem Multimeter ungefähr so viel zu tun wie ein Apfel mit einer Apfelsine. Diese Klasse von Wandler ist für die Analyse von Prozessvariablen vorgesehen. Wer ein Messgerät auf Basis eines nach dem Flash-Prinzip arbeitenden Wandlers zu realisieren versucht, begibt sich auf den Holzweg.

Vom glücklichen Grünen

So ein, im Idealfall rund wachsendes, Zitrusbäumchen ist eine Dekoration, die im Labor durchaus attraktiv aussieht: Hilfspersonal dürfte zudem am Verzehr von Kumquats und ähnlichen Früchten Freude entwickeln. Problematisch ist, dass derartige Bäumchen sowohl in Sachen Beleuchtung als auch in Sachen Wasserversorgung sehr anspruchsvoll sind: Macht man einen Fehler, so darf man einen neuen Baum kaufen. Wer in einen Maker-Shop geht und nach einem Feuchtigkeitssensor fragt, wird normalerweise mit dem in Abbildung 4 gezeigten Element konfrontiert.

Abb. 4: Wechselt für etwa zehn Euro den Besitzer: ein Feuchtigkeitssensor für Pflanzen

Die eigentliche Messschaltung zum Anschluss an den A-/D-Wandler präsentiert sich dann wie in Abbildung 5. Die Hersteller trennen die Antenne vom Rest der Messschaltung, um das Recyceln Ersterer zu erlauben. In der Praxis korrodiert die Platine nämlich nach einigen Wochen, was ein Ersetzen erforderlich macht.

Abb. 5: Statt des Rheostaten wird nun ein Feuchtigkeitssensor mit dem A-/D-Wandler verbunden

Fazit

Auch wenn das Einlesen eines zur Erdfeuchtigkeit proportionalen Spannungswerts mit Sicherheit keiner nobelpreisverdächtigen Aufgabe entspricht: Wir haben in diesem Teil eine sehr ärgerliche Beschränkung des Raspberry Pi 3 überwunden. Bedenken Sie, dass es nicht nur Feuchtigkeitssensoren gibt: Der Importeur Ihres Vertrauens wartet nur darauf, eine Vielzahl von Sensorschaltungen aus China anzubieten, die diverse physikalische Werte in analoge Spannungen umsetzen. Leider ist das nur die halbe Miete: Es bringt nichts, wenn man die Feuchtigkeit der Pflanze misst, ohne auf diese Information angemessen reagieren zu können. Im nächsten Teil wenden wir uns deshalb dem zweiten Teil des klassischen MSR-Dreikampfs zu: dem Steuern. Freuen Sie sich darauf, mit dem Raspberry Pi Kontakt zu Pumpen und anderem Werkzeug aufzunehmen. Bis dahin wünscht Ihnen der Autor viel Vergnügen.

Tam Hanna befasst sich seit der Zeit des Palm IIIc mit der Programmierung und Anwendung von Handcomputern. Er entwickelt Programme für diverse Plattformen, betreibt Onlinenewsdienste zum Thema und steht für Fragen, Trainings und Vorträge gern zur Verfügung.
Mail: tamhan@tamoggemon.com

©Jozsef Bagota/Shutterstock.com

Sprachassistenten: Hype oder echte Alternative?

An technische Grenzen stoßen
von Christopher Dzierzon, Daniel Sorna und Alexander Frommelt

Sprachassistenten erfreuen sich einer immer größeren Beliebtheit. Fast jeder hat schon davon gehört oder sogar bereits einen Sprachassistenten benutzt. Doch was können die neuen Alltagshelfer, wo gibt es noch Probleme und wie kann man selbst Sprachassistenten programmieren?

Alexa von Amazon, Siri von Apple, Cortana von Microsoft oder Google Assistant sind in aller Munde. Diese Assistenten sind künstliche Intelligenzen, die versuchen, die menschliche Sprache zu erkennen, zu deuten und zu verarbeiten, um eine sinnvolle Antwort zu geben. Wie gut das funktioniert, ist noch sehr unterschiedlich. Teilweise sind diese Assistenten schon so intelligent, dass man das Gefühl hat, man kommuniziert wie mit einem Menschen. In vielen Fällen verstehen die künstlichen Assistenten die gesprochenen Sätze jedoch noch nicht richtig oder verarbeiten sie falsch, weil Informationen noch nicht implementiert wurden.

Vergleich bekannter Sprachassistenten

Sprachassistenten können ganz unterschiedlich aussehen und abrufbar sein. Das hängt von der gewählten Hard- und Software ab. So ist weder der Funktionsumfang bei jedem Assistenten gleich noch reagieren alle gleichermaßen zuverlässig.

Vom Aussehen erinnern alle Sprachassistenten (Abb. 1) an eine Bluetoothbox. Aufgrund der darin verbauten Technik sind sie jedoch etwas schwerer und benötigen eine externe Stromversorgung. Angeführt wird das Feld von Amazons Sprachassistent Alexa, der über einen Amazon Echo Dot, ein Amazon Echo oder einen Sonos Speaker angesprochen wird. Dieser wird zum Beispiel im eigenen Wohnzimmer platziert und kommuniziert über eine WLAN-Verbindung mit dem Internet und den Amazon-Servern.

Abb. 1: Smartlautsprecher, v. l. n. r.: Google Home, Harman Kardon Invoke, Amazon Echo, Harman Kardon Invoke, Amazon Echo Dot, Apple HomePod [1]

Die Bedienung erfolgt, wie erwartet, mit der eigenen Stimme, die sagt, was gewünscht ist und welcher Skill geöffnet werden soll. Ein Skill ist eine Funktion von Alexa, die ähnlich einer App bei einem Smartphone aktiviert werden kann und dann zur Nutzung bereitsteht. Alexa ist fähig, Smarthomegeräte wie Lampen, Thermostate und Ähnliches zu steuern. Amazon belohnt Entwickler von Skills mit verschiedenen Geschenken. Im Moment gibt es für jeden erfolgreich veröffentlichten Skill einen Pullover im Alexa-Design. Wenn viele „unique Users“ einen Skill nutzen, gibt es noch weitere Goodies dazu, wie beispielsweise Amazon Echo. Für richtig erfolgreiche Skills mit einer hohen Nutzeranzahl zahlt Amazon sogar Geld aus. Deshalb ist der Skill-Markt im Moment regelrecht überrannt mit neuen Skills, die mal mehr und mal weniger nützlich sind.

Apples Sprachassistent Siri ist auf diversen Geräten wie iPhone, iPod Touch, iPad und Apple TV verfügbar. Ursprünglich wurde Siri als eigenes Unternehmen gegründet und ging aus dem Projekt „CALO“ des amerikanischen Militärs hervor, das die „Defense Advanced Research Projects Agency“ (DARPA) ausgeschrieben hatte [2]. 2010 hat Apple Siri gekauft, und mit dem iPhone 4S wurde Siri das Gesprächsthema. Mittlerweile ist Siri mit dem Betriebssystem macOS Sierra sogar auf dem persönlichen Computer bereit, Sprachbefehle von technikbegeisterten Nutzern entgegenzunehmen und zu beantworten. So können Informationen ausgegeben, Nachrichten verschickt oder das Smarthome gesteuert werden. Dazu brachte Apple Ende 2017 den Apple HomePod auf den Markt. Einen besonderen Nutzen bietet Siri sehbehinderten Menschen, die durch die Barrierefreiheiteinstellung „VoiceOver“ eine Möglichkeit zur erleichterten Bedienung erhalten.

Googles Antwort auf Siri ist Google Assistant. Dieser lässt sich auf neueren Android-Smartphones sowie auf Lautsprechern und Smartwatches aufrufen und steht seit letztem Jahr auch in deutscher Sprache zur Verfügung. Google Assistant lässt sich zudem über die Plattform Dialogflow (vorher API.ai) in andere Produkte oder Dienste integrieren. Seit Mitte 2017 ist in Deutschland Google Home erhältlich, ein Smartlautsprecher, mit dem sich ein Smarthome steuern lässt.

Microsoft antwortete 2014 mit seinem Sprachassistenten Cortana. Angelehnt an die Videospielserie Halo, in der Cortana als künstliche Intelligenz den Spieler unterstützt, soll sie auch Windows-Nutzern auf dem Computer, dem Smartphone oder zu Hause auf Harman Kardon Invoke helfen. Auf iOS und Android kann Cortana mit Microsoft-Apps gestartet werden. Cortanas Leistungsumfang ist jedoch nicht mit der Konkurrenz vergleichbar. Auch Smarthomegeräte sollen bald ansteuerbar sein [3]. Zudem hat Microsoft eine Kooperation mit Amazon bekanntgegeben, wodurch Cortana Alexa Skills aufrufen kann und umgekehrt. Samsung möchte ebenfalls in den Markt einsteigen und hat mit „Bixby“ einen Sprachassistenten für das Samsung S8 und S8+ kreiert [4]. Seit 2017 kann der Nachfolger von S Voice genutzt werden, jedoch sind ihm seine Konkurrenten noch weit voraus.

Wo kann man Sprachassistenten einsetzen?

Leider können Sprachassistenten noch keine Emotionen verstehen, doch die Technik hierfür schreitet immer weiter voran. Im Moment ist es jedoch möglich, Informationen abzufragen und auszugeben. So sind naheliegende Einsatzgebiete Call- und Supportcenter, aber auch Services wie Essensbestellungen oder Geschäftsabwicklungen. Was alles bereits möglich ist, soll eine kleine Auswahl aus dem Amazon Alexa Skills Store zeigen. Einer der am besten und am meisten bewerteten Skills ist „Abfallkalender“. Dieser gibt dem Benutzer einen Überblick, wann welche Tonne auf die Straße zu stellen ist. Dafür muss der Nutzer den Abfallkalender zuvor online konfigurieren. Danach kann er zum Beispiel fragen, wann der Biomüll abgeholt wird, und Alexa benachrichtigt ihn einfach über die Alexa-App. Der Skill ist technisch sehr einfach, doch trotzdem sehr nützlich. Ebenfalls beliebt sind Skills, die verschiedene Musik oder Geräusche je nach Wunsch des Nutzers spielen. So kann der Skill „Einschlafgeräusche“ helfen, abzuschalten. Ebenso können Skills Radiosender spielen oder mit lustigen Sprüchen von Prominenten die Stimmung heben. In diese Kategorie fallen auch Skills wie die neuesten Nachrichten, z. B. die der Tagesschau oder die neueste Musik, die sich dank des Spotify Skills abspielen lässt.

Im Bereich Smarthome gibt es viele Angebote verschiedener Hersteller. Am bekanntesten sind die Philips-Hue-Leuchtmittel, die sich nicht nur an- und ausschalten lassen, sondern auch in unterschiedlichen Farben Licht geben können. Hierfür gibt es verschiedene Skills, die meist auch das tun, was der Nutzer möchte. Allerdings muss er dafür vorab alles richtig einrichten, das heißt, die Lampen mit einer Bridge koppeln und mit dem gleichen WLAN wie das Amazon-Echo-Gerät verbinden. Interessant ist der Einsatz von Sprachassistenten für sehbehinderte Menschen. Diese können Alltagsaufgaben leichter bewältigen, beispielsweise Essen bestellen oder Einkäufe erledigen. Im Gegensatz zu Bildschirmanwendungen können sie die Funktionen genauso nutzen wie nicht beeinträchtigte Personen. Rollstuhlfahrer können so zum Beispiel mittels Spracheingabe Türen öffnen oder sich den Weg zum Lichtschalter sparen. Schade ist, dass der finanzielle Anreiz fehlt, um für beeinträchtigte Personen passende Sprachassistenten gezielt zu entwickeln [5].

Grenzen und Probleme

Wie zuvor beschrieben, bieten Sprachassistenten bereits viele Möglichkeiten, die den Alltag erleichtern, haben aber auch nach wie vor teilweise Schwierigkeiten, Anfragen zu verstehen. Alle Sprachassistenten funktionieren noch nicht fehlerfrei und können nicht jedes Wort so verstehen, wie der Nutzer es erwartet. So kann es passieren, dass der Nutzer statt eines normalen deutschen Satzes einzelne Wörter staccato sprechen muss, damit der Sprachassistent erkennt, was gewünscht wird. Im Ernstfall könnte das zu Problemen führen. Man stelle sich nur vor, ein Fahrer versucht im Auto bei 160 km/h dem Sprachassistenten zu vermitteln, dass er den Scheibenwischer anschalten soll, was der Assistent bei dieser Geschwindigkeit, starkem Regen und Umgebungslärm jedoch nicht versteht. Ein weiteres Problem liegt darin, dass sich Nutzer unterschiedlich ausdrücken. Dorothea Kolossa vom Institut für Kommunikationsakustik der Ruhr-Universität Bochum erklärt dazu: „Zum einen wird dasselbe Wort nie zweimal gleich ausgesprochen und zum anderen ändert sich dabei auch die Geschwindigkeit. Die Muster, die der Computer interpretieren muss, sehen deshalb nie genau gleich aus“ [6]. Das kann besonders bei starken Dialekten oder Akzenten zum Problem werden, was Nutzer frustriert, wenn das System sie missversteht oder komplett den Dienst verweigert.

Inzwischen versuchen Forscher, durch Technologien wie maschinelles Lernen und künstliche neuronale Netze das menschliche Gehirn nachzuahmen. Das hat die Sprachanalyse bereits deutlich verbessert. Auch stehen mit der Zeit immer mehr Daten zur Verfügung, aus denen die künstlichen neuronalen Netze lernen können, wodurch sich die User Experience bei Nutzung der Sprachassistenten drastisch verbessert hat. Doch die Erkennungsleistung ist immer noch nicht mit der eines Menschen vergleichbar. Auch das Sprachmedium allein kann zum Problem werden. Da manche Eingaben korrekt geschrieben sein müssen, zum Beispiel der Nachname in Formularen, kommen Sprachassistenten hier schnell an ihre Grenzen. Bei Siri, Cortana und Google Assistant ist eine Eingabe mit Tastatur bzw. Touchscreen möglich. Bei Alexa findet die Eingabe über eine App/Web-App statt.

Der Datenschutz ist auch bei Sprachassistenten nicht zu vernachlässigen. Verbraucherschützer warnen beim Betrieb eines Sprachassistenten, insbesondere bei Alexa, vor großen Datenschutzrisiken. Da Alexa ständig auf ihr Aktivierungswort wartet, lauscht der Sprachassistent die ganze Zeit, und alle Sprachbefehle, die nach dem Aktivierungswort gesprochen werden, werden auf Amazon-Servern gespeichert und verarbeitet. Amazon speichert Einkaufslisten, Kalendereinträge und Musikwünsche, einige Fragen zur Weitergabe der Daten an Dritte sind unklar formuliert. Amazon rechtfertigt sich damit, dass die Datenerhebung nur zur Verbesserung von Alexa nötig sei. Entwarnung kommt durch die Serverstandorte. So werden die Daten von deutschen Benutzern auf Servern in EU-Ländern gespeichert, weshalb strengere europäische Gesetze gelten. In manchen Fällen kam es vor, dass Alexa aufgrund von Hintergrundgeräuschen, wie die eines Fernsehers, Waren bestellt hat. Das lässt sich unterbinden, indem man Einkäufe über den Sprachassistenten sperrt oder mit einem Zahlencode sichert. Das Mikrofon von Amazon Echo lässt sich manuell durch einen Knopf an der Oberseite des Geräts ausschalten, was ein rot leuchtender Ring anzeigt.

Weitere Risiken sind Hacker-Angriffe. Mögliche Angriffe auf die Privatsphäre, Datenspionage oder permanente Überwachung verringern die Begeisterung für Sprachsteuerungen. Technik- und Onlinesicherheitsexperten bewerten besonders jene Daten kritisch, die Amazon selbst auswertet und die in Alexa Skills verschiedener Hersteller benutzt werden. Empfehlenswert ist es deshalb, diese Skills zu prüfen und sicherzustellen, dass eine Datenschutzerklärung des Anbieters vorliegt. Ein kurzer Test zeigte, dass alle Daten nur verschlüsselt übertragen werden und selbst mit den dafür nötigen Kenntnissen und Zertifikaten keine Daten ausgelesen werden können. In einem weiteren Test wurde ein älteres Echo-Modell umgebaut und manipuliert. Das ermöglichte es zwar, den Sprachassistenten als Überwachungsapparat zu benutzen, doch sind alle neueren Geräte dagegen geschützt, und der Hacker müsste auch erst direkt vor Ort sein, um die Umbaumaßnahmen durchzuführen [7].

Entwicklung eines Skills

Doch wie kann man selbst einen Sprachassistenten entwickeln? Das ist gar nicht so schwer und soll anhand der Voraussetzungen für einen Amazon Alexa Skill gezeigt werden. Da es Amazon egal ist, in welcher Programmiersprache entwickelt wird, kann das Framework relativ frei gewählt werden. Die Amazon-Server empfangen und senden nur JSON Files in einem bestimmten Format (Abb. 2).

Abb. 2: Empfangene und gesendete JSON Files

Einige Frameworks werden von Amazon empfohlen, in diesem Beispiel wird das Framework Flask-Ask in der Sprache Python verwendet. Weiter benötigt man eine sichere HTTPS-Verbindung. Wer seinen Skill mithilfe von AWS (Amazon Web Services) hostet, hat dabei kein Problem, ansonsten wird ein SSL-Zertifikat benötigt. Während der Entwicklung kann dazu das Programm ngrok benutzt werden (Abb. 3), das Zugriff aus dem Internet auf den eigenen Rechner ermöglicht und dabei eine sichere Verbindung aufbaut.

Abb. 3: ngrok während der Laufzeit

Danach muss im Browser mit dem Alexa Skills Kit (ASK) von Amazon das Dialogmodell für den Skill definiert werden (Abb. 4 zeigt die Maske nach dem Einloggen).

Abb. 4: Alexa Skills Kit [8]

Nun kann ein einfacher Skill programmiert werden, der auf eine Anfrage (Intent) eine Antwort gibt. Um komplexere Anfragen zu bearbeiten, werden sogenannte Slots (Abb. 5) benutzt. Slots sind Platzhalter für Informationen in einem Intent. Ein Slot benötigt einen fest definierten Slot Type, der ihn einer Datenmenge zuordnet, wie z. B. Ort oder Datum. Amazon stellt dafür einige vordefinierte Slot Types zur Verfügung wie AMAZON.NUMBER oder AMAZON.DE_CITY. Der Nutzer kann diese Informationen bereits in seiner Anfrage füllen:

Nutzer: „Ich möchte eine Reise nach Berlin am 01.06.2018 buchen.“ Sollte der Nutzer die benötigten Slots nicht oder nur teilweise selbst füllen, werden sie anschließend abgefragt: Nutzer: „Ich möchte eine Reise nach Berlin buchen.“ Alexa: „Wann möchtest du deine Reise antreten?“ Nutzer: „Am 01.06.2018.“

Abb. 5: Alexa Skills Kit – Slot Types [9]

Bei Slots, die eine Ja/Nein-Eingabe fordern, z. B. erste Klasse, kann es zu Problemen kommen. Amazon hat einen vordefinierten YES_NO-Intent, dessen Priorität über der vom Entwickler definierten Slots liegt. Das führt dazu, dass der Skill nach einer Ja/Nein-Antwort des Nutzers aus dem Intent springt und in den YES_NO-Intent übergeht. Oder schlimmer: Alexa beendet den Skill und gibt die Antwort eines anderen Skills aus!

Um das zu vermeiden, empfiehlt es sich, einen eigenen JA_NEIN-Intent zu definieren. Dazu muss dieser anhand eines vorher festgelegten session.attribute erkennen, auf welche Frage der Nutzer geantwortet hat. So kann der JA_NEIN-Intent die Antwort zuordnen und den gefragten Wert im Backend füllen. Der Skill lässt sich bequem, auch ohne eigenes Amazon Echo, mit dem Testing-Tool per Text- oder Spracheingabe testen.

Voice Design

Um dem Nutzer eines Sprachassistenten ein möglichst angenehmes Erlebnis zu ermöglichen, sollten die Herangehensweisen des Voice Designs beachtet werden. Bei einer herkömmlichen Bildschirmanwendung kann der Entwickler durch Buttons und Eingabefelder bestimmen, welche Daten der Nutzer eingeben kann und welche Optionen die Anwendung bietet. Bei Skills ist das nicht ganz so einfach. Amazon gibt hierzu bewährte Methoden und Best Practices unter dem Namen Voice Design [10] heraus. Wir haben daraus einige wichtige Punkte entnommen und zusammen mit unseren eigenen Erfahrungen zusammengefasst:

1. Aufzählungen: Um den Anwender nicht zu überfordern, sollen Aufzählungen nicht mehr als fünf Elemente enthalten. Sobald mehr als fünf Punkte relevant sind, kann der Sprachassistent fragen, ob der Nutzer weitere Elemente hören möchte. Zusätzlich kann die gesamte Liste in der Alexa-Begleiter-App dargestellt werden.

2. Einheitliches Sprachbild: Dialoge sollen sich einheitlich anhören und natürlich klingen. Ausgaben müssen getestet werden, um zu erkennen, ob die Umwandlung von Text zu Sprache einwandfrei funktioniert. Außerdem ist Fachsprache tabu. Sollte juristische Sprache notwendig sein, ist eine Darstellung in der App am besten. Unübliche Abkürzungen sollten ausgeschrieben werden.

3. Kurze Antworten: Da die Inhalte nicht überflogen werden können, soll die Frage bzw. Eingabeaufforderung möglichst kurz und eindeutig sein. Gibt es mehrere Antwortmöglichkeiten, sollten nicht mehr als drei Optionen vorgegeben werden.

4. Nur notwendige Fragen: Um unnötige Fragen zu vermeiden, sollen möglichst Vermutungen und Schlussfolgerungen angestellt werden.

5. Bestätigungen: Dialoge mit vielen Bestätigungen sollen vermieden werden. Nur Aktionen mit wesentlichen Folgen sollten bestätigt werden, wie z. B. Aktionen, die andere Personen betreffen oder jene mit Geldbewegungen.

6. Wenig externe Medien benutzen: Alexa sollte ohne externe Medien benutzbar sein, sonst geht der Sinn eines Sprachassistenten verloren. Wenn die Alexa-App genutzt wird, darf das nicht für die Bedienung des Skills erforderlich sein.

7. Eindeutige Antwortmöglichkeiten: Wenn man eine Antwort möchte, muss man dies dem Nutzer auch in einer direkten Frage mitteilen. Der Nutzer muss nach der Frage genau wissen, welche Antworten möglich sind.

8. Der Nutzer muss geführt werden: Beim Öffnen eines Skills sollte der Nutzer einige Informationen bekommen: den Namen des Skills, eine Aufzählung der Funktionen und eine Anleitung, wie er nach Hilfe fragen kann. Man sollte dem Nutzer maximal drei Funktionen nennen und in der Hilfe genauer und mit Beispielen erklären, wie er sie nutzen kann. Der Nutzer muss den Skill an jedem Punkt beenden können.

Sprachausgaben können mithilfe von SSML (Speech Synthesis Markup Language) optimiert werden. Damit lassen sich Tonhöhe, Lautstärke und Geschwindigkeit anpassen, und Amazon bietet etliche sog. Speechcons: Begriffe und Redewendungen, die natürlicher und emotionaler ausgesprochen werden.

In Abbildung 6 sehen Sie noch ein kleines Codebeispiel aus unserem Skill: Wir fangen mit einem Decorator von Flask-Ask den Intent urlaubIntent auf und ordnen den Slot „Reiseziel“ dem String destination zu. In der Methode darunter prüfen wir, ob in diesem String etwas steht. Falls nicht, fragen wir den Nutzer nach seinem Reiseziel, da er das noch nicht im Intent genannt hat.

Abb. 6: Codebeispiel „urlaubIntent“

Seine Antwort wird mit derselben Methode aufgefangen und gibt ihm nun eine Empfehlung. Diese ist mit SSML versehen und nutzt eine Interjektion (interjection), um den vorgesprochenen Ausdruck „oh la la“ auszugeben. Nach den Ansätzen des Voice Designs fragen wir ihn daraufhin, ob er sich weiter informieren möchte, um den Dialog aufrechtzuerhalten.

Fazit: Hype oder echte Alternative?

Noch sind Sprachassistenten eher Spielerei, doch bieten sie viel Potenzial für die Zukunft. Zwar gibt es im Moment noch technische Schwächen, und ein intelligentes Gespräch ist noch nicht wirklich möglich, doch die Ansätze in Richtung künstliche Intelligenz sind gegeben und werden weiter erforscht. Eines haben alle Sprachassistenten gemeinsam: Sie sind noch weit davon entfernt, unersetzbar zu sein.

Christopher Dzierzon studiert Wirtschaftsinformatik an der Hochschule München und arbeitet als Werkstudent bei der adesso AG. Sein Tätigkeitsschwerpunkt umfasst die Entwicklung von Alexa Skills. Er beschäftigt sich zudem mit Sprachassistenten und ihren Anwendungsmöglichkeiten.
Mail: christopher.dzierzon@adesso.de

Daniel Sorna studiert Wirtschaftsinformatik an der Fachhochschule Rosenheim und arbeitet als Werkstudent im Bereich IT-Consulting Versicherungen bei der adesso AG. Mit seinem Team hat er bereits einen automatisierten, intelligenten Versicherungsberater in Form eines Sprachassistenten entwickelt.
Mail: daniel.sorna@adesso.de

Alexander Frommelt verantwortet als Competence-Center-Leiter den Bereich IT-Consulting Versicherungen bei der adesso AG. Er beschäftigt sich bereits seit mehr als fünfzehn Jahren mit Software- und Systemarchitekturen. Eines seiner aktuellen Interessensgebiete sind Sprachassistenten und ihre Einsatzmöglichkeiten.
Mail: frommelt@adesso.de

Links & Literatur

[1] https://c.mobilegeeks.de/wp-content/uploads/2017/06/HomePod-Home-Invoke-Echo-1280x720.jpg?x74386

[2] Bosker, Bianca: „SIRI RISING: The Inside Story Of Siri’s Origins – And Why She Could Overshadow The iPhone“: https://www.huffingtonpost.com/2013/01/22/siri-do-engine-apple-iphone_n_2499165.html

[3] Pakalski, Ingo: „Cortana steuert Smart-Home-Geräte“: https://www.golem.de/news/microsoft-cortana-steuert-smart-home-geraete-1710-130497.html

[4] Peuckert, Michael: „Samsung Bixby: Das bietet der digitale Assistent“: http://www.connect.de/ratgeber/samsung-bixby-assistent-sprache-galaxy-modelle-3197118.html

[5] Reker, Anika; Haubrich, Maik: „Kommerzielle Sprachassistenten als Hilfe im Alltag“: https://www1.wdr.de/unternehmen/der-wdr/karriere/bethel/sprachassistenten-smarthome-alltagshilfe-100.html

[6] Hornig, Nico: „Warum Spracherkennung so schwierig ist“: http://www.wiwo.de/unternehmen/it/spracherkennung/die-probleme-von-alexa-siri-und-google-assistant-warum-spracherkennung-so-schwierig-ist/20327384.html

[7] https://www.homeandsmart.de/alexa-datenschutz-oder-datenspion

[8] https://developer.amazon.com

[9] https://developer.amazon.com/alexa/console/ask/build

[10] https://developer.amazon.com/de/docs/custom-skills/voice-design-best-practices-legacy.html

Wir bauen eine Mausefalle im Internet der Dinge

Raus die Maus
von Martin Mohr

Es sind die kleinen Dinge, die uns das Leben leicht oder aber auch schwer machen können. In unserem Fall hat eine kleine Maus für Chaos gesorgt. Sie hat sich dazu entschieden, die günstige Gelegenheit einer offenen Tür zu nutzen, um so ins Haus zu kommen. Sie können sich nicht vorstellen, was eine kleine Maus an einem Sonntagnachmittag alles anstellen kann. Wir beschäftigen uns daher heute mit der modernen und humanen Art der Mäusejagd. Vorweg noch eine Anmerkung: Für diesen Artikel mussten keine Tiere sterben!

Wie kann man sich eine humane und moderne Mausefalle im Internet of Things (IoT) vorstellen? Die Frage ist leicht zu klären. Wir nehmen uns eine handelsübliche Lebendfalle aus dem Baumarkt. Daran schrauben wir einen Mikroschalter, der gedrückt wird, wenn die Falle schließt. Den Mikroschalter verbinden wir geschickt mit einer Batterie und einem ESP8266. Der ESP8266 schickt uns eine Mail, wenn eine Maus in der Falle ist – und fertig ist die IoT-Mausefalle. Damit die Maus auch in die Falle geht, braucht es natürlich noch den richtigen Köder. Man sagt zwar: „Mit Speck fängt man Mäuse“, aber mit Nussnougatcreme, Schokolade oder einer leckeren Erdnussbutter werden Sie mehr Erfolg haben. Klingt seltsam, aber die kleinen Nager stehen auf Nussnougatcreme (Kasten: „Wissenswertes über Mäuse“).

Wissenswertes über Mäuse

Mäuse sind kleine putzige Nagetiere, die immer auf der Suche nach etwas Fressbarem sind. Wenn es kalt wird, suchen die Hausmäuse gern Unterschlupf im warmen Haus oder in der Garage. Sie sind anpassungsfähig und richten sich schnell ihr neues Zuhause ein. Haben sie sich erst einmal niedergelassen und finden gute Bedingungen, können sie sich rasant vermehren. Mäuse können bis zu acht Mal im Jahr bis zu acht Nachkommen haben. Den scheuen Mäusen auf die Spur zu kommen, ist gar nicht so einfach. Mäusekot, angefressene Lebensmittel, aber auch abgeknabberte Kabel sind eindeutige Anzeichen dafür, dass Ihr Haus in Besitz genommen wurde. Und das ist auch schon die Wurzel der Probleme, die wir Menschen mit den Mäusen haben. Nicht nur, dass sie materielle Schäden verursachen können, sondern sie sind auch Überträger von gefährlichen Krankheiten, zum Beispiel Typhus, Hantavirus und Salmonellen. Auch Parasiten können eingeschleppt werden. Von daher gelten Mäuse als ernst zu nehmende Gesundheitsschädlinge. Umso wichtiger ist es, bei den ersten Anzeichen Gegenmaßnahmen zu ergreifen, um sie aus dem direktem Umfeld zu verbannen.

Noch ein wichtiger Punkt: Hausmäuse sind nicht mit den nützlichen Spitzmäusen zu verwechseln. Diese sind nicht mit den Mäusen verwandt. Sie gehören zu den Insektenfressern und stehen unter Naturschutz.

Alles in allem hört sich das nach einem einfachen Plan an. Doch wenn man genauer darüber nachdenkt, merkt man, dass viele Arbeitsschritte nötig sind, bis die Falle zuschnappt. Um eine bessere Vorstellung davon zu bekommen, was wir hier bauen wollen, werfen wir einen Blick auf die Abbildung 1. Unter [1] ist zudem ein kleines Video zu finden, das zeigt, wie die Falle funktioniert.

Abb. 1: Die Falle mit Elektronik

Wenn wir uns etwas intensiver mit der Thematik beschäftigen, stellen wir schnell fest, dass es gar nicht so leicht ist, mit einem Mikrocontroller wie dem ESP8266 E-Mails zu verschicken. Nicht zu vergessen, dass wir eine IDE einzurichten haben, um diesen Controller zu programmieren. Schauen wir uns die Schritte einen nach dem anderen an.

Schaltungsaufbau

Die Elektronik für unsere Mausefalle bauen wir auf einer kleinen Prototypplatine auf. Der Schaltplan zu unserer Mausefalle ist in Abbildung 2 zu sehen. Das zentrale Bauelement ist ein ESP8266. Dabei handelt es sich um einen Mikrocontroller, der eine WLAN-Schnittstelle mit eingebaut hat. Er ist kleiner als eine Briefmarke und kostet nur knapp vier Euro [2].

Abb. 2: Der Schaltplan zu unserer Mausefalle

Der ESP8266 hat zwei Betriebsmodi: Der „Flash Mode“ ist dazu gedacht, neuen Programmcode in den Controller zu laden. Das geschieht über die Anschlüsse RXD und TXD. Im „Run Mode“ führt der Controller das geladene Programm aus. Mit den Jumpern JP1 und JP2 wird gesteuert, in welchem Modus der ESP8266 nach einem Reset starten soll. Die Widerstände R1 bis R4 sind dazu da, den Betriebsmodus einzustellen. Falls Sie eine Adapterplatine für den ESP8266 verwenden, sehen Sie sich sie sehr genau an. Oft sind Adapterplatinen schon mit einigen Widerständen bestückt. Diese Widerstände können uns das Leben erleichtern oder auch Probleme erzeugen.

Die Programme werden mithilfe eines USB-zu-Seriell-Adapters [3] hochgeladen. Da wir ihn nur brauchen, wenn wir das Programm anpassen wollen, ist er nur auf die Platine gesteckt. Zu beachten ist, dass der Adapter auf 3,3 Volt stehen muss. Ist das nicht der Fall, wird der ESP8266 dauerhaft beschädigt.

Die LED und der Widerstand R5 sind zu Testzwecken mit auf der Platine verbaut. Es kann vorkommen, dass der ESP8266 im WLAN-Sendebetrieb große Energiemengen benötigt. Das kann die Betriebsspannung kurz einbrechen lassen. Im besten Fall würde der ESP8266 danach neu starten, im schlechtesten Fall ist er danach in einem undefiniertem Zustand. Um dieses Problem zu umgehen, ist C1 vorhanden. C1 stabilisiert die Betriebsspannung des ESP8266.

Der Kondensator C2 bildet mit dem Widerstand R6 und dem Mikroschalter eine Schaltung, die den Resetimpuls erzeugt. Würde man den Mikroschalter direkt an den ESP8266 anschließen, würde er bei gedrücktem Mikroschalter im Reset verharren, kein Programm würde starten. Man spricht bei einer solchen Schaltung von Flankentriggerung. Dabei wird auf Zustandswechsel reagiert, nicht auf die Zustände selbst.

Die Schaltung wird über zwei Batterien mit Spannung versorgt. Da sich der ESP8266 dauerhaft im Energiesparmodus befindet und nur aufwacht, wenn wir eine Maus gefangen haben, halten die Batterien sehr lange. Das genaue Zusammenwirken von Hardware und Programm beschreiben wir später.

Installation der IDE

Um Programme für den ESP8266 erstellen zu können, brauchen wir eine Entwicklungsumgebung und ein Tool, das den gebauten Code in den Mikrocontroller hochlädt. Die Arduino IDE vereint diese beiden Funktionen in einer Software. Sie ist zwar, wie der Name schon vermuten lässt, für die Entwicklung für die Arduino Boards gedacht, hat aber auch die Möglichkeit, Maschinencode für andere Prozessoren zu erzeugen. Dies geschieht über sogenannte Board-Manager. Es können Board-Manager für viele verschiedene Prozessoren nachinstalliert werden, unter anderen auch für den ESP8266.

Die Arduino IDE kann über die Homepage des Projekts heruntergeladen werden [4]. Man wählt dort einfach die für das jeweilige Betriebssystem passende Version aus und installiert sie. Unter Linux sind folgende Schritte zur Installation durchzuführen:

cd ~
cp Downloads/arduino-1.8.5-linux64.tar.xz ~
tar -xvf arduino-1.8.5-linux64.tar.xz
cd arduino-1.8.5

Sollte sich das Archiv nicht entpacken lassen, fehlt auf dem System vermutlich das Paket xz-utils. Unter Debian-Abkömmlingen wie Ubuntu lässt sich das Paket wie folgt installieren: sudo apt-get install xz-utils. Um die IDE zu starten, geben Sie ./arduino auf der Kommandozeile ein. Nachdem die IDE gestartet ist, tragen wir unter Datei | Voreinstellungen | Zusätzliche Boardverwalter-URLs folgenden URL ein: http://arduino.esp8266.com/stable/package_esp8266com_index.json. Damit veranlassen wir die Arduino IDE, die für den ESP8266 nötigen Board-Manager in die Liste der Manager aufzunehmen.

Als Nächstes starten wir die Installation des Board-Managers für den ESP8266. Das erledigen wir unter dem Menüpunkt Werkzeuge | Board | Bordverwalter … Suchen Sie dort einfach nach ESP8266. Nach erfolgreicher Installation kann jetzt das „Generic ESP8266 Modul“ unter Werkzeuge | Board ausgewählt werden. Unsere Entwicklungsumgebung ist jetzt in der Lage, Programme für den ESP8266 zu erstellen.

Jetzt müssen wir unseren aktuellen Benutzer noch dazu berechtigen, dass er auf die serielle Schnittstelle zugreifen darf. Dazu müssen wir ihn in die Gruppe dailout aufnehmen. Ein Reboot danach ist nicht unbedingt nötig, es würde auch ein erneuter Log-in des aktuellen Users reichen. Ein Reboot hat aber unbestritten den Vorteil, dass sich das System danach in einem zu 100 Prozent konsistenten Zustand befindet:

sudo usermod -a -G dialout $USER
sudo reboot

Damit Sie Ihre selbst geschriebenen Programme in den ESP8266 hochladen können, müssen Sie noch den USB-nach-Seriell-Adapter mit einem freien USB-Anschluss Ihres PCs verbinden.

Erstes kleines Testprogramm

Unser erstes Testprogramm (Listing 1) dient dazu, festzustellen, ob wir alles korrekt zusammengelötet haben. Es lässt die LED, die an der GPIO4 angeschlossen ist, blinken. Um es hochzuladen und zu starten, genügt es, den ESP8266 in den Flash-Modus zu bringen: DIP-Schalter auf ON und Mikrotaster drücken. Der Mikrotaster resettet den ESP8266 und startet in dem über die DIP-Schalter gewählten Modus. Jetzt können wir in der IDE den Button hochladen drücken. Nach einigen Sekunden ist das Programm in den ESP8266 geladen und wird automatisch gestartet. Sollte das Hochladen nicht auf Anhieb klappen, kann das viele Gründe haben. Überprüfen Sie bitte zuerst die Hardware: Ist wirklich alles korrekt verlötet? Haben Sie den richtigen Board-Manager ausgewählt (Generic ESP8266-Modul)? Ist die Übertragungsgeschwindigkeit auf 115 200 eingestellt? Oft ist auch einfach ein falscher Port gewählt, man muss auf jeden Fall einen ttyUSB-Port verwenden, auf keinen Fall einen COM-Port. Falls Sie den ESP8266 mit einer Adapterplatine betreiben, schauen Sie sich diese genau an. Oft sind Adapterplatinen bereits mit Widerständen und Brücken bestückt. Es kann sein, dass diese für uns nicht passen. Doch das waren auch schon alle üblichen Fehler, die auftreten können.

void setup() {
pinMode(4, OUTPUT);
}

void loop() {
digitalWrite(4, HIGH);
delay(1000);
digitalWrite(4, LOW);
delay(1000);
}

Listing 1: Blinkprogramm

Falls Sie das Beispielprogramm nicht abtippen möchten, schauen Sie in der IDE unter Datei | 01.Beispiele | Basics | Blink. Dort ist unser Quellcode zu finden. Generell sind die Beispielprogramme, die die IDE mitbringt, auf jeden Fall immer ein guter Einstieg für eigene Programme. Wenn alles soweit funktioniert, können wir uns dem E-Mail-Versand widmen.

Programm für den E-Mail-Versand

Damit wir eine E-Mail bekommen, sobald wir eine Maus gefangen haben, müssen wir jetzt noch einiges erledigen. Um Zeit zu sparen, verwenden wir eine schon fertige Bibliothek für den E-Mail-Versand. Sie kann frei unter [5] heruntergeladen werden. Nach dem Herunterladen entpacken wir das Zipfile in den libraries-Order der Arduino IDE. Wenn wir die IDE jetzt starten, würde sie eine fehlerhafte Bibliothek melden. Um das zu verhindern, kopieren wir die zwei Dateien sendemail.h und sendemail.cpp direkt in den Ordner esp8266-sendemail-master und löschen danach den Ordner src und die README.md-Datei. Die Arduino IDE kann jetzt die Bibliothek esp8266-sendemail-master verwenden.

Das Programm für den E-Mail-Versand ist etwas untypisch aufgebaut. Die Funktion loop(), in der sich normalerweise die Programme befinden, ist komplett leer. Das komplette Programm ist in der setup()-Funktion untergebracht. Am Ende der setup()-Funktion befindet sich das Kommando, um den ESP8266 schlafen zu legen. Aufgeweckt wird er, wenn die Resettaste (Maus in der Falle) gedrückt wird. Wenn der ESP8266 erwacht, startet er zuerst die setup()-Funktion, und so schließt sich der Kreis. Eigentlich ist der ESP8266 immer am Schlafen, außer es ist eine Maus in der Falle. Dann wird er kurz wach, schickt seine Mail und legt sich wieder zur Ruhe.

Die ersten Zeilen im Programm stellen eine Verbindung mit dem lokalem WLAN her. Wenn das funktioniert hat, wird direkt die E-Mail verschickt. Sie müssen natürlich Ihre WLAN-Parameter eintragen und auch die Parameter für den E-Mail-Versand anpassen. Die Parameter für den E-Mail-Versand finden sich mehr oder weniger gut versteckt auf der Homepage Ihres E-Mail-Providers.

Sehen wir uns nun die zwei Codezeilen für den E-Mail-Versand etwas genauer an. Die erste Zeile erzeugt ein Objekt von Typ SendEmail. Diesem werden alle Parameter übergeben, die benötigt werden, um sich mit einen SMTP-Server zu verbinden. In Tabelle 1 sind die Parameter der Reihe nach beschrieben.

Parameter

Beschreibung

SMTP-Host

Ist von E-Mail-Provider zu erfragen, z. B. smtp.gmail.com.

SMTP-Port

Oft 25, kann aber auch einen anderen Wert haben. Bei www.gmail.com: 465.

SMTP-Log-in

Ist von E-Mail-Provider zu erfragen, oft die komplette E-Mail.

SMTP-Pass

So gut wie immer start123. Bitte sichere Passwörter verwenden!

TIME-OUT

Maximale Wartezeit für Netzwerkoperationen. Ist sie zu knapp bemessen, gibt es einen Time-out, bevor die Mail versendet wurde.

SSL

Muss true sein, um SSL zu aktivieren.

Tabelle 1: Parameter des „SendEmail“-Objekts

Das SendEmail-Objekt hat eine Methode send(). Mit dieser Methode können E-Mails versendet werden. Die Parameter der send()-Methode sind in Tabelle 2 beschrieben.

Parameter

Beschreibung

send-from

Ihre E-Mail-Adresse

send-to

Die E-Mail-Adresse des Empfängers

subject

Der Betreff der E-Mail

Mail-Text

Der Inhalt der E-Mail

Tabelle 2: Parameter der „send()“-Methode

Jetzt kommt der knifflige Part. Jeder E-Mail-Provider verwendet eigene Parameter, die zuerst einmal bekannt sein müssen. Der ESP8266 kann nicht wie ein moderner E-Mail-Client die Parameter erraten. Sie können sich sicherlich vorstellen, dass hier der Teufel im Detail steckt. Es ist daher sehr wichtig, die Parameter gewissenhaft einzutragen. Ein anderes Problem ist die allgegenwärtige Spamflut. Die E-Mail-Provider müssen sich immer wieder neue Verfahren einfallen lassen, um ihre Systeme zu sichern. Aus diesem Grund kann es sich auch teilweise sehr schwierig gestalten, alle Parameter richtig zu setzen, um eine E-Mail versenden zu können. Daher verwenden wir hier exemplarisch die Parameter für einen der bekannteren Provider: Gmail.

SendEmail e("smtp.gmail.com", 465, "<Your-Email>", "<Your-Pass>", 5000, true);
e.send("<<Your-Email>>", "<<send-to>>", "<Subject>", "<Mail-Text>");

Bei Gmail kommen noch einige weitere Hürden hinzu. Die E-Mail-Adressen innerhalb der send-Anweisung müssen in spitzen Klammern stehen <>, daher die etwas sonderbare Darstellung in der Codezeile oben. Zusätzlich muss noch der Log-in für „weniger sichere Apps“ aktiviert werden. Um das zu erreichen, folgen Sie den Anweisungen in der Warnmail, die Sie von Gmail bekommen. Vermutlich verwenden auch andere Provider ähnliche Mechanismen, daher sollten Sie nicht so schnell aufgeben, wenn es auf Anhieb nicht klappt.

Da hier leider ziemlich viel schiefgehen kann, möchte ich noch ein paar Tipps zum Debuggen von Mikrocontrollerprogrammen mit auf den Weg geben. Sie haben sich sicherlich schon gewundert, was die Serial-Befehle in unserem Programm machen. Diese Befehle schreiben Ausgaben auf den seriellen Port des ESP8266. Um sie lesen zu können, klicken Sie in der Arduino IDE auf das Icon Serieller Monitor (Lupe oben rechts). Machen Sie das aber nicht, während Sie gerade dabei sind, Programme hochzuladen, das wird schiefgehen. Alle Ausgaben des Programms sind nun im seriellen Monitor zu sehen, sie sind bei der Fehlersuche oft essenziell.

Leider sehen wir hier nur, ob die Verbindung zu unserem WLAN geklappt hat. Wenn Sie den Verdacht haben, es könnte etwas mit dem Mailversand nicht stimmen, müssen Sie die SendEmail-Bibliothek in den Debug-Modus bringen. Das erreichen Sie, indem Sie im Ordner ~/arduino-1.8.5/libraries/esp8266-sendemail-master die Datei sendmail.cpp um die Codezeile #define DEBUG_EMAIL_PORT Serial erweitern. Die Codezeile muss am Anfang der Datei eingefügt werden. Wenn Sie jetzt das Programm neu bauen und wieder hochladen, bekommen Sie den kompletten Debug-Output der Bibliothek zu sehen. Damit kommt man den Fehlern, die beim E-Mail-Versand auftreten können, schnell auf die Schliche. Den Quellcode für unseren E-Mail-Versand können Sie in Listing 2 nachvollziehen.

#include <ESP8266WiFi.h>
#include <sendemail.h>
const char* ssid = "<your-ssid>";
const char* pass = "<your-pass>";

void setup() {
Serial.begin(115200);
Serial.println("\r\n") ;
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Verbunden mit ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

SendEmail e("<your-smtp-server>",<your-sntp-port>, "<your-smtp-login>","<your-smtp-pass>", 5000, true);
e.send("<send-from>", "<send-to>", "<Subject>", "<Mail-Text>");

delay(1500);
ESP.deepSleep(0);
}
void loop() {
}

Listing 2 : E-Mail-Versand

Fazit

Das Bauen der hier gezeigten Mausefalle ist zugegebenermaßen zeitaufwändiger als das Aufstellen einer normalen Falle. Sie kann aber den Stress für die gefangenen Tiere erheblich mindern, weil man die kleinen Quälgeister schnell wieder in Feld oder Wald aussetzen kann. Außerdem ist die Mausefalle für Kinder und Haustiere ungefährlich, kommt ohne Gift aus und fängt die Maus auf eine hygienische Art und Weise. Nebenbei lernen wir noch, wie die Energiesparfunktion des ESP8266 funktioniert und wie man mit einem Mikrocontroller E-Mails versenden kann. Von hier ist es nur noch ein kleiner Schritt zum eigenen Amazon-Dash-Button. Ihnen fallen sicher noch unendlich viele Anwendungen für dieses Basisprogramm ein. Daher wünsche ich viel Spaß bei eigenen Experimenten mit dem ESP8266!

Martin Mohr erblickte im Zeitalter der Magnetringkernspeicher und Hebdrehwähler das Licht der Welt und hat somit die komplette Entwicklung der modernen Computertechnik live miterleben dürfen. Die Vorliebe für alles, was blinkt, hat sich schon in seiner frühen Jugend entwickelt und wurde durch eine Ausbildung zum Elektroniker noch verstärkt. Nach dem Informatikstudium lag sein Beschäftigungsfeld überwiegend in der Entwicklung von Java-Applikationen. Mit dem Raspberry Pi ist die alte Liebe zur Elektronik wiedererwacht.

Links & Literatur

[1] Video: So funktioniert unsere Mausefalle: https://youtu.be/2H_RTiwckms

[2] ESP8266: https://ex-store.de/ESP8266-ESP-012-Version-12-WIFI-Wlan2Serial

[3] USB-Konvertermodul: https://www.amazon.de/USB-Konverter-Modul-FT232RL-Schnellversand/dp/B073FXMH5V

[4] Arduino IDE: https://www.arduino.cc/en/Main/Software

[5] Bibliothek für den E-Mail-Versand: https://github.com/gpepe/esp8266-sendemail

Table of Contents

- Impressum

- Neue Android- und iOS-Welt mit dem Flutter SDK. Ist Flutter SDK der designierte Android-Nachfolger? (von Lars Vogel und Jonas Hungershausen)

- Noch mehr Dinge. Teil 2: Sensorik mit Android Things steuern (von Tam Hanna)

- An technische Grenzen stoßen. Sprachassistenten: Hype oder echte Alternative? (von Christopher Dzierzon, Daniel Sorna und Alexander Frommelt)

- Raus die Maus. Wir bauen eine Mausefalle im Internet der Dinge (von Martin Mohr)