80% fanden dieses Dokument nützlich (5 Abstimmungen)
996 Ansichten400 Seiten

Arduino Manual

Manual de arduino

Hochgeladen von

arami28
Copyright
© All Rights Reserved
Wir nehmen die Rechte an Inhalten ernst. Wenn Sie vermuten, dass dies Ihr Inhalt ist, beanspruchen Sie ihn hier.
Verfügbare Formate
Als PDF, TXT herunterladen oder online auf Scribd lesen
80% fanden dieses Dokument nützlich (5 Abstimmungen)
996 Ansichten400 Seiten

Arduino Manual

Manual de arduino

Hochgeladen von

arami28
Copyright
© All Rights Reserved
Wir nehmen die Rechte an Inhalten ernst. Wenn Sie vermuten, dass dies Ihr Inhalt ist, beanspruchen Sie ihn hier.
Verfügbare Formate
Als PDF, TXT herunterladen oder online auf Scribd lesen

2.

Arduino

Au
Julian Finn & Alex Wenger

fla
ge
Manuel Odendahl,

Physical Computing für


Bastler, Designer & Geeks
o’r e i l l y s
basics

Microcontroller-Programmierung für alle


Rapid Prototyping
Mit kompletter Programmiersprachenreferenz
2. Auflage

Arduino – Physical Computing


für Bastler, Designer und Geeks

Manuel Odendahl, Julian Finn & Alex Wenger

Beijing · Cambridge · Farnham · Köln · Sebastopol · Taipei · Tokyo


Die Informationen in diesem Buch wurden mit größter Sorgfalt erarbeitet. Dennoch können
Fehler nicht vollständig ausgeschlossen werden. Verlag, Autoren und Übersetzer übernehmen
keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene Fehler und
deren Folgen.
Alle Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt und sind
möglicherweise eingetragene Warenzeichen. Der Verlag richtet sich im Wesentlichen nach den
Schreibweisen der Hersteller. Das Werk einschließlich aller seiner Teile ist urheberrechtlich
geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung,
Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

Kommentare und Fragen können Sie gerne an uns richten:


O’Reilly Verlag
Balthasarstr. 81
50670 Köln
Tel.: 0221/9731600
Fax: 0221/9731608
E-Mail: kommentar@[Link]

Copyright der deutschen Ausgabe:


© 2010 by O’Reilly Verlag GmbH & Co. KG
1. Auflage 2009
2. Auflage 2010

Bibliografische Information Der Deutschen Nationalbibliothek


Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der
Deutschen Nationalbibliografie; detaillierte bibliografische Daten
sind im Internet über [Link] abrufbar.

Lektorat: Volker Bombien, Köln


Korrektorat: Kathrin Jurgenowski, Köln
Satz: III-satz, Husby
Umschlaggestaltung: Michael Oreal, Köln
Produktion: Karin Driesen, Köln
Belichtung, Druck und buchbinderische Verarbeitung:
Druckerei Kösel, Krugzell; [Link]

ISBN 978-3-89721-995-3

Dieses Buch ist auf 100% chlorfrei gebleichtem Papier gedruckt.


Inhalt

Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IX

1 Von Königen und Kondensatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1


Die Geschichte des Arduino-Projekts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Der Arduino, das unbekannte Gerät . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Arduino-Projekte: eine kleine Vorstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Die Arduino-Entwicklungsumgebung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

2 Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser . . . . . . . . . 31
Elektrische Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Schaltungen, Bauteile und Schaltbilder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Löten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Fehlersuche in elektronischen Schaltungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

3 Workshop LED-Licht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Erste Schritte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Eine blinkende LED – das »Hello World« des Physical Computing . . . . . . . . . . . . . 84

4 LEDs für Fortgeschrittene . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109


LED-Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Animationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Tamagotchi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Brainwave und Biofeedback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

V
5 Sprich mit mir, Arduino! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Nach Hause telefonieren mit der seriellen Konsole . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Automatisierung mit Gobetwino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142

6 Arduino im Netz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153


Hello World – ein Mini-Webserver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Sag´s der Welt mit Twitter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Fang die Bytes – Datalogger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

7 Sensoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Sensoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Aktoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Elektronischer Würfel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191

8 Automation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Alles hört auf mein Kommando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
DMX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Barlicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
RF-Steckdosen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Gespensterschreck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

9 Wearable Computing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209


Programmierbare Kleidung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Wearable Komponenten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Die iPod-Steuerung im Mantel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

10 Musik-Controller mit Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227


Musik steuern mit dem Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Das MIDI-Protokoll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Die MidiDuino-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Ein MIDI-Zauberstab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
MIDI-Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244

11 Musik mit Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247


Töne aus dem Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Erster Sketch: Töne mit langsamer PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Zweiter Sketch: Angenehme Klänge mit schneller PWM . . . . . . . . . . . . . . . . . . . . . . 252
Dritter Sketch: Steuerung von Klängen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Vierter Sketch: Berechnungen in einer Interrupt-Routine . . . . . . . . . . . . . . . . . . . . . 255
Fünfter Sketch: Musikalische Noten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258

VI Inhalt
A Arduino-Boards und -Shields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Arduino-Boards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Arduino-Shields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269

B Arduino-Bibliotheken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
EEPROM-Bibliothek: Werte langfristig speichern . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Ethernet-Bibliothek: mit dem Internet kommunizieren . . . . . . . . . . . . . . . . . . . . . . . 277
Firmata-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
LiquidCrystal-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
Servo-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
Debounce-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
Wire-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
capSense-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288

C Sprachreferenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Übersicht: Programmiersprachen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Struktur, Werte und Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Programmwerte (Variablen, Datentypen und Konstanten) . . . . . . . . . . . . . . . . . . . . 297
Ausdrücke und Anweisungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
Ausdrücke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
Kontrollstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Sketch-Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Funktionsreferenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350

D Händlerliste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369

Inhalt VII
In diesem Kapitel:
• Für wen ist dieses Buch
Einleitung gedacht?
• Aufbau dieses Buchs
• Typografische Konventionen
• Verwendung der Code-
beispiele
• Die Codebeispiele zu diesem
Buch
• Die Arduino-Welt
• Dedication from David
Cuartielles

Vielleicht stehen Sie gerade im Laden und überlegen sich, ob Sie


dieses Buch kaufen möchten. Vielleicht haben Sie es auch schon
erworben, wofür wir uns natürlich recht herzlich bedanken. In
jedem Fall aber halten Sie gerade das erste deutschsprachige Buch
zum Thema Arduino in den Händen. Arduino ist die Verbindung
aus einem Board, das einen Mikrocontroller beherbergt, mit einer
Programmiersprache, die es sehr leicht macht, diesem kleinen Pro-
zessor auch Befehle zu erteilen. Zusammen bilden die beiden die
Basis für sogenanntes Physical Computing, die Verbindung der rea-
len, physischen Welt mit der virtuellen Welt der Einsen und Nullen.
Der Arduino eignet sich hervorragend für alle möglichen Projekte,
denn er ist günstig zu erwerben und einfach und vor allem schnell
zu programmieren. So wird die Zeit von der fixen Idee bis zur
Umsetzung möglichst kurz gehalten. Das bewahrt viele gute Pro-
jekte vor dem Papierkorb, in dem sie unweigerlich landen, wenn
ihre Schöpfer vor allzu großen Problemen stehen.
Der Arduino wurde im italienischen Ivrea entwickelt, um Design-
studenten möglichst leicht zu bedienende Werkzeuge an die Hand
zu geben, und hat seit 2005 einen fast beispiellosen Siegeszug ange-
treten. Rund um den Globus finden sich nun an Kunsthochschulen
Seminare zur Programmierung, zum Löten und über physikalische
Grundlagen, begünstigt durch die einfache Verfügbarkeit dieser
Technologie. Mehr über die Geschichte des Arduino finden Sie in
Kapitel 1.
Aber vorweg – um was geht es hier eigentlich genau? Arduino ist
zum einen eine Plattform, die aus einem Mikrocontroller besteht,
der ähnlich wie ein PC eigenständig Berechnungen durchführen

IX
kann, aber auch leicht mit vielen Sensoren zur Interaktion mit der
Umwelt verbunden werden kann. Arduino ist aber auch die dazu-
gehörige Entwicklungsumgebung, und – nicht zu vergessen – das
Framework, das viele komplizierte Details der hardwaregestützten
Entwicklung einfacher macht. So kann mit einem einzelnen Knopf-
druck der Programmcode sowohl kompiliert als auch direkt über
USB in den Arduino geladen werden.
All das erlaubt die schnelle Entwicklung von Prototypen; aber
dadurch, dass alle Teile auf bestehenden Standards wie C++ und
verbreiteten Mikrocontrollern basieren, kann es später auch losge-
löst vom Arduino-Konzept weiterverwendet werden.

Für wen ist dieses Buch gedacht?


Sie haben die Einleitung gelesen und fragen sich nun, ob Sie zu den
»Bastlern, Designern und Geeks« gehören, die der Buchtitel
anspricht? Nun, wahrscheinlich schon. Dieses Buch versucht, sei-
nen Leserinnen und Lesern die Welt des Physical Computing und
damit auch der Programmierung anhand von praktischen Beispie-
len näherzubringen.
Sie alle haben gemeinsam, dass sie fortan Neues entwickeln wollen,
entweder in der realen Welt als Gegenstand oder virtuell auf dem
Rechner als Daten und Software. Hier fügen sich mit Arduino zwei
Welten zusammen, die eigentlich nie richtig voneinander getrennt
waren, und doch ist das Überqueren dieser Grenze für viele eine
hohe Hürde. Der Programmierer scheut den Lötkolben und löst
Probleme lieber auf seine Weise, wogegen der Bastler lieber noch
drei weitere Bausätze verwendet, als dass er sich mit der Program-
mierung eines Computers oder Mikrocontrollers auseinandersetzt.
Bastlern, die bisher vielleicht nur in der physischen Welt an ihren
Projekten gearbeitet haben, werden dadurch neue Möglichkeiten
eröffnet: Sie können die im Buch aufgezeigten Ideen verfolgen und
dabei lernen, wie der Arduino zu ihrem Hobby viele neue Aspekte
beisteuern kann.
Als Designer und Medienkünstler werden Sie bislang möglicher-
weise ähnliche Probleme gehabt haben: Die Inspiration war da,
bloß an der Umsetzung hat es gehapert. Mit dem Arduino können
einfache Prototypen schnell umgesetzt werden, sodass man sich
nicht mit allzu komplizierter Technik aufhalten muss. Man kommt
auch nicht mehr in die Situation, dass Informatiker einem gern hel-

X Einleitung
fen würden, aber einfach nicht so recht verstehen, was man ihnen
eigentlich sagen will.
Auch wenn Sie schon Erfahrung mit einer Programmiersprache
haben, sollten Sie nun das Buch nicht beiseite legen: Es ist so aufge-
baut, dass die Programmierung beiläufig erklärt wird, während die
einzelnen Projekte zusammengesetzt werden. Selbst als Geek, des-
sen natürliche Umgebung meist aus einem Codedschungel besteht,
wird Ihnen die Lektüre also kaum langweilig werden. Besonders
wenn Sie zwar im Schlaf Software schreiben können, dafür aber
noch unerfahren in Sachen Lötkolben, Sensoren und Widerstände
sind, wird Ihnen dieses Buch bieten, was Sie suchen. All das erlaubt
das schnelle Erstellen von Prototypen, sodass nicht die langwierige,
umständliche Umsetzung, sondern die Idee im Vordergrund steht.
All das heißt natürlich auch, dass dieses Buch sich vor allem an Ein-
steiger richtet. Trotzdem geht es z.B. in Kapitel 11, das sich mit der
Anbindung von Arduino an die Welt der Musik beschäftigt, auch
ein wenig mehr in die Tiefe. Weiterhin bietet der Anhang eine voll-
ständige Referenz der Programmiersprache, sodass Sie diese Seiten
auch im weiteren Verlauf Ihrer Physical-Computing-Karriere auf
dem Schreibtisch behalten sollten, um jederzeit nachschlagen zu
können.
Der Projektcharakter ist bewusst nach den Prinzipien des Rapid
Prototyping gestaltet, um die Fantasie der Leser nicht unnötiger-
weise einzuengen. Wir freuen uns natürlich über Projektbeschrei-
bungen und Bilder der daraus entstandenen Arbeiten, die Sie uns
gern über Twitter (@arduinobuch) zuschicken können.
Hilfreich ist es, wenn Sie zum Buch auch ein Arduino-Board erwer-
ben, falls Sie noch keines besitzen. In Kapitel 1 finden Sie Hinweise
dazu, wo Sie den hier verwendeten Arduino Duemilanove beziehen
können. Weiterhin wird für die im Buch beschriebenen Workshops
eine Reihe von Bauteilen benötigt. Wir empfehlen, dass Sie die
Liste der benötigten Teile zu Anfang durchlesen und entsprechend
einkaufen. Zudem wäre es hilfreich, wenn Sie einen Lötkolben,
ausreichend Lötzinn und Entlötlitze sowie ein Steckbrett besitzen.

Aufbau dieses Buchs


Die Kapitel dieses Buchs lassen sich einteilen in einzelne Work-
shops und Erläuterungen der physikalischen Aspekte der Entwick-
lung von Arduino-Projekten. Nach der Einleitung und Einführung

Aufbau dieses Buchs XI


in Arduino sowie der Installation der Programmierumgebung wer-
den zunächst die physikalischen Grundlagen erklärt, und wir versu-
chen, Ihnen die Angst vor dem Basteln zu nehmen. Dazu gehören
zum Beispiel richtiges Löten und die Verwendung von Steckbret-
tern sowie etwas Hilfe bei der Fehlersuche. Ab Kapitel 3 werden
dann einzelne Projekte beschrieben, wobei Kapitel 7 als Einschub
die gängigsten Sensoren und Aktoren beschreibt. Zu jedem The-
menkomplex beschreibt das Buch zudem weitere Projekte, zu
denen man im Internet Anleitungen finden kann, sowie Ideen dazu,
was man mit dem erlernten Wissen noch alles anstellen kann.
Komplette Neueinsteiger in die Programmierung werden schon in
Kapitel 3 in die Grundbegriffe der Programmierung eingeführt und
sollten dieses Kapitel gründlich durcharbeiten. Ab Kapitel 5 wer-
den auch weiterführende Aspekte der Programmierung eingesetzt,
die ebenfalls recht ausführlich erklärt ist. Sollten Sie zunächst an
einer Stelle kapitulieren, empfehlen wir dennoch, weiterzulesen. Sie
werden mit Sicherheit später noch einmal darauf zurückkommen
können.
In Kapitel 1 wird zunächst die Geschichte des Arduino-Projekts
erläutert. Anschließend wird der Frage nachgegangen, was der
Benutzer eigentlich vor sich hat, wenn er ein Arduino-Board
gekauft hat. Das Kapitel endet mit der Installation und Erläuterung
der Arduino-Software und dem Anschluss des Boards an einen PC.
Kapitel 2 unternimmt einen Ausflug in die Welt des Physical Com-
puting. Zunächst werden der Begriff geklärt und eine Reihe ver-
schiedener Projekte vorgestellt. Im Folgenden erläutern wir die
physikalischen Grundlagen wie etwa den Zusammenhang zwischen
Strom, Spannung und Widerstand. Weitere Grundlagen umfassen
etwa den Aufbau von Schaltkreisen und wichtigen Bauteilen wie
Schalter oder Netzteil. Den Abschluss machen ausführliche Anlei-
tungen zum Basteln selbst: Lötkolben und Lötzinn werden ebenso
beschrieben wie die Fehlersuche mit Multimeter oder Oszilloskop.
Kapitel 3 beinhaltet den ersten Workshop des Buches. Ziel des
Workshops ist es, eine Lampe mit LEDs zu bauen und sie mit dem
Arduino zu betreiben. Dazu gehören die ersten Schritte in der Pro-
grammiersprache sowie der Aufbau von einfachen Schaltungen mit
LED, Widerstand und später Schaltern oder Tastern. Am Ende
steht der Code für eine programmierbare RGB-Lampe, die fast alle
Farben des sichtbaren Spektrums darstellen kann, sowie ein Aus-
blick auf weitere Möglichkeiten mit Arduino und Licht.

XII Einleitung
Kapitel 4 führt den Workshop aus Kapitel 3 fort und erklärt, wie an
den Arduino mit dem sogenannten Multiplexing auch Matrix-Dis-
plays mit 7x5-LEDs angeschlossen werden können. Zudem wird
mit dem Interrupt eine etwas weiter fortgeschrittene Technologie
erklärt. Der Workshop schließt mit einer Gehirnwellenmaschine,
die durch pulsierende LEDs für Entspannung im Kopf sorgen soll.
Kapitel 5 erlöst den Arduino aus seiner Einsamkeit und zeigt ver-
schiedene Möglichkeiten der Kommunikation mit dem Rechner
und darüber hinaus. Zunächst wird auf die einfache Verbindung
über den USB-Port eingegangen und auf die Kommunikation mit
der seriellen Konsole der Arduino-Programmierumgebung, die man
auch für die Fehlersuche nutzen kann. Anschließend wird das Pro-
gramm Gobetwino erklärt, das ebenfalls unkompliziert die Kom-
munikation zwischen Arduino und PC ermöglicht. Das Kapitel
schließt mit der Anbindung an Processing, eine Programmierumge-
bung, die dem Arduino als Vorbild gedient hat. Sie ermöglicht es,
einfach und schnell grafische Anwendungen zu entwickeln, die mit
dem Arduino gesteuert werden.
Kapitel 6 führt das fünfte Kapitel fort und erläutert die Verwen-
dung eines Ethernet-Shields. Dieser Aufsatz für das Arduino-Board
erlaubt den Anschluss eines Netzwerkkabels, sodass der Arduino
auch mit dem Internet verbunden werden kann. Zunächst wird ein
einfacher Webserver implementiert, mit dem man den Status des
Arduino im Browser anzeigen lassen kann. Dann folgt ein kleines
Projekt, das über Twitter meldet, ob das Licht im Raum an oder
aus ist – Physical Computing in Reinform! Zum Abschluss erklärt
das Kapitel den Datenspeicher, auf den der Arduino zurückgreifen
kann und beschreibt, wie sich dort einzelne Daten ablegen und wie-
der auslesen lassen.
Kapitel 7 bildet einen Einschub zwischen die verschiedenen Work-
shops des Buches. Nun, da einige Grundlagen erläutert sind, wer-
den die gängigsten Sensoren und Aktoren beschrieben, die man mit
dem Arduino verwenden kann, und einige Projekte und Einsatz-
möglichkeiten geschildert. Zudem liefert das Kapitel ein Beispiel
dafür, wie man einen kapazitiven Näherungssensor recht einfach
selbst bauen kann. Das Kapitel schließt mit einem kleinen Würfel-
Projekt, das auf einen kleinen Schalter aufbaut, der zufällig öffnet
und schließt.
Kapitel 8 vernetzt den Arduino noch weiter mit seiner Umgebung.
In diesem Kapitel wird eine Lichtsteuerung per DMX-Bus erklärt.
Anschließend wird der Arduino verwendet, um herkömmliche

Aufbau dieses Buchs XIII


Funksteckdosen aus dem Baumarkt anzusteuern. So kann man das
gesamte Haus ohne Probleme automatisieren; ob Lichter einge-
schaltet oder der Fernseher aus, bleibt ganz dem Bastler überlassen!
In Kapitel 9 wird ein kleiner Ausflug in die Welt der Kleidung unter-
nommen. Das Prinzip des »Wearable Computing« wird erklärt und
anhand eines kleinen Beispiels eingeführt. Mit dem erläuterten Pro-
jekt sollte es problemlos möglich sein, eine beliebiges Kleidungs-
stück zu einer iPod-Steuerung umzufunktionieren. Nie mehr lästiges
Herumfummeln, nur um die Musik an- oder auszumachen!
Kapitel 10 handelt von der Steuerung von Musik mit dem Arduino.
Dazu gehören verschiedene Musikprogramme auf dem PC, die
etwa über Midi angesteuert werden. Zudem geht das Kapitel auf
Möglichkeiten ein, mit Aktoren direkt auf Musikinstrumente ein-
zuwirken und sie so zu bespielen.
In Kapitel 11 wird dann der Arduino selbst zur Erzeugung von
Klängen verwendet. Zunächst geht das Kapitel dabei auf die elek-
tronische Klangerzeugung im Allgemeinen ein, bevor anhand eini-
ger Beispiele erläutert wird, wie man dem Arduino diese Klänge
entlocken kann. Den Abschluss des Kapitels macht ein Workshop,
in dem ein Theremin, ein elektronisches Musikinstrument, selbst
gebaut wird, dessen Töne sich ohne Berührung mit den Händen
steuern lassen.
Der Anhang ist in diesem Buch vergleichsweise lang. Er enthält
neben einer vollständigen Referenz zur Programmiersprache auch
eine Übersicht über die wichtigsten Arduino-Bibliotheken, Boards
und Shields. Damit dient das Buch auch als Nachschlagewerk beim
Entwickeln eigener Projekte.

Typografische Konventionen
Die folgenden typografischen Konventionen werden in diesem
Buch verwendet:
Kursiv
Wird für URLs, die Namen von Verzeichnissen und Dateien,
Optionen, Menüs und zur Hervorhebung verwendet.
Nichtproportionalschrift
Wird für Codebeispiele, den Inhalt von Dateien und sowie für
die Namen von Variablen, Befehlen und anderen Codeab-
schnitten verwendet.

XIV Einleitung
Verwendung der Codebeispiele
Dieses Buch soll Ihnen bei der Umsetzung Ihrer Projekte helfen. Es
ist allgemein erlaubt, den Code aus diesem Buch in Ihren Program-
men und Dokumentationen weiterzuverwenden. Dafür ist es nicht
notwendig, uns um Erlaubnis zu fragen, es sei denn, es handelt sich
um eine größere Menge Code. So ist es beim Schreiben eines Pro-
gramms, das einige Codeschnipsel dieses Buchs verwendet, nicht
nötig, sich mit uns in Verbindung zu setzen, beim Verkauf oder
Vertrieb einer CD-ROM mit Beispielen aus O’Reilly-Büchern dage-
gen schon. Das Beantworten einer Frage durch das Zitat von
Beispielcode erfordert keine Erlaubnis. Verwenden Sie einen erheb-
lichen Teil des Beispielcodes aus diesem Buch in Ihrer Dokumenta-
tion, ist unsere Erlaubnis dagegen nötig.
Eine Quellenangabe ist zwar erwünscht, aber nicht obligatorisch.
Dazu gehört in der Regel die Erwähnung von Titel, Autor, Verlag
und ISBN, zum Beispiel: »Arduino – Physical Computing für Bast-
ler, Designer und Geeks« von Manuel Odendahl, Julian Finn &
Alex Wenger. Copyright 2010 O’Reilly Verlag, ISBN 978-3-89721-
995-3.«
Falls Sie sich nicht sicher sind, ob die Nutzung der Codebeispiele
außerhalb der hier erteilten Erlaubnis liegt, nehmen Sie bitte unter
der Adresse kommentar@[Link] Kontakt mit uns auf.

Die Codebeispiele zu diesem Buch


Zu diesem Buch gibt es einen Twitter-Account namens
@arduinobuch unter [Link]
Dort werden interessante Links zu Arduino-Projekten genauso
angegeben wie Errata oder Hinweise zum Buch.
Die Codebeispiele zum Buch und weitere Informationen finden Sie
auch auf der Website des O’Reilly Verlags unter [Link]
de/catalog/micprogger.

Die Arduino-Welt
Arduino wird zwar von einer italienischen Firma vertrieben, die
Layoutdaten für das Board sind aber ebenso wie die Programmier-
umgebung unter einer Open-Source-Lizenz verfügbar. Die Weiter-
entwicklung wird also auch von einer Gemeinschaft unterstützt,

Die Arduino-Welt XV
die hilft, beides konstant zu verbessern. Zudem gibt es eine riesige
und stets wachsende Menge an Websites, die Arduino-Projekte
dokumentieren oder Anleitungen zum Basteln geben. Hier im Buch
sind viele dieser Projekte erwähnt, zusätzlich wollen wir einen klei-
nen Überblick darüber geben, welche Ressourcen und Websites im
Zusammenhang mit dem Arduino interessant sind.

Das Arduino-Projekt
Die Marke »Arduino« sowie die Rechte an den Schaltplänen liegen
bei der Firma [Link], die aus den ersten Arbeiten am Arduino her-
vorgegangen ist. Die Firma behält sich allerdings nur das Marken-
recht vor, alle anderen Daten können also frei verwendet werden,
sofern die Ergebnisse nicht unter dem Namen Arduino veröffent-
licht werden. Neben dem Arduino hat sich [Link] vor allem auf
Consulting und Training rund ums Physical Computing und den
Arduino spezialisiert.

Das Make Magazine


Das Make Magazine erscheint vierteljährlich beim O’Reilly Verlag
in den USA und ist auf Projekte zum Selbstbasteln spezialisiert.
Jede Ausgabe kommt mit einer ganzen Reihe an Anleitungen, die
Schritt für Schritt nachgebaut werden können. Unter [Link]
[Link]/ gibt es zudem eine umfangreiche Website, die unter
anderem auch ein Archiv für Arduino-Projekte beherbergt. Für wei-
tere Inspiration und Anleitungen sei Ihnen [Link]
com/archive/arduino/ empfohlen. Dort finden Sie eine lange Liste
von Ideen, mit denen man sich stundenlang beschäftigen kann.

Weiterführende Quellen
Neben den schon genannten Webseiten gibt es eine ganze Reihe
von Ressourcen rund um das Thema Arduino. Für den Erwerb von
Boards sei zusätzlich der entsprechende Absatz in Anhang A emp-
fohlen. Hier wollen wir einige interessante Websites vorstellen.
Diese Liste ist natürlich nicht einmal annähernd vollständig.
• [Link] ist eine Community-Seite, die Projekte und
Möglichkeiten rund um Arduino und seine Abwandlung Free-
duino sammelt. Die Seite verfügt über einen Index von Anlei-
tungen rund um Sensoren und Aktoren, die mit dem Arduino
verbunden werden können, und ist deshalb besonders nütz-

XVI Einleitung
lich, wenn man auf der Suche nach Informationen über ein
bestimmtes Bauteil ist.
• [Link] ist ein Portal im Netz, das Anleitungen für
allerlei Projekte zur Verfügung stellt. Auch zum Thema Ardu-
ino und Physical Computing wird man hier fündig, ebenso gibt
es einige Bastelanleitungen für selbstgebaute Sensoren oder
Aktoren.
• Ladyada ([Link] ist eine Website einer ehe-
maligen MIT-Studentin, die eine umfangreiche Ressourcen-
sammlung zum Thema Arduino zusammengetragen hat. Hier
finden sich viele Ideen, aber auch Angebote für verschiedene
Arduino-Shields.
• Die Webseite [Link] beschäftigt sich mit dem
künstlerischen und designerischen Aspekt von Physical Com-
puting. Insbesondere ist die Website empfehlenswert, weil sie
eine umfangreiche Ressourcensammlung zum Thema Wea-
rable Computing beherbergt, also Computer, die in Kleidung
eingearbeitet sind. Diese Unterseite ist unter [Link]
[Link]/page/12648/nl zu finden.
• Unter [Link] findet sich eine herausra-
gende Ressource rund um das Thema Wearable Computing.
Ein Blog beschreibt immer wieder neue und interessante Pro-
jekte, während eine Community zu fast allen Problemen eine
Lösung findet.

Danksagungen
Wir möchten hiermit noch einer Reihe von Menschen danken,
ohne die dieses Buch nicht möglich gewesen wäre. Zunächst möch-
ten wir unserem herausragenden Lektor Volker Bombien danken,
mit dem dieses Projekt weit mehr als eine normale Geschäftsbezie-
hung war. Weiterer Dank gilt Jens Ohlig für das großartige Einlei-
tungskapitel sowie allen unseren Freunden im Entropia e.V.,
besonders Cupe, Flowhase, Bugbabe, Neingeist, Syb, nanoc und
Hannes.
Zudem möchten wir in dieser zweiten Auflage besonders all jenen
danken, die uns wertvolles Feedback geschickt haben.
Julian Finn dankt desweiteren besonders Steffi sowie Silvan Hor-
bert, Roman Alexis Anastasini, Jayoung Bang und Martin Feld-
kamp für Inspiration und Instruktion.

Die Arduino-Welt XVII


Manuel Odendahl möchte seinen Dank aussprechen an Julia
Tziridis, Hans Hübner, Philip Baljeu, Martin Hirsch und Fabienne
Serriere.
Besonders bedanken möchte sich Alex Wenger bei seiner Frau und
seinen Kindern, die immer Verständnis für die viele Arbeit hatten.
Sicherlich ein ganzes Stück schlechter wäre dieses Buch ohne die
KorrekturleserInnen Prisca Fey, Benedikt Achatz, Frank Bierlein,
Greta Louise Hoffmann, Lukas Fütterer und David Loscher, die
uns mit hilfreicher Kritik aus Sicht unserer »Zielgruppe« unterstützt
haben.
Natürlich wäre das Buch auch nicht möglich ohne die fantastische
Arduino-Community und insbesondere die Hauptentwickler Mas-
simo Banzi, David Cuartielles, Tom Igoe, Gianluca Martino, David
Mellis und Nicholas Zambetti.
Ein ganz spezieller Dank geht an unseren Fotografen Jonas Zilius,
dem wir das Fotostudio mehrere Tage belagert haben, und an Yun-
jun Lee, der für uns all diese fantastischen Zeichnungen erstellt hat.

Dedication from David Cuartielles


Thinking, burning, redesigning
There is little things in life where it is actually allowed to fail. First
time I got to understand this, was at the end of my graduate studies
back in the 90's. A professor explained to me it didn't matter my
thesis could render somehow unsuccessful because I would at least
demonstrate the path of my choice was not the right one. It wasn't
a relief, but he claimed it should at least help others figuring out the
right way. In my defense I should say the project turned out right,
but it could also have failed and I would have gotten my degree.
Trial and error, in my opinion one of the most important aspects of
the scientific method, doesn't apply to its full extent when one
introduces the cost factor. One might consider not risking his pre-
cious smartphone to science when studying gravity by throwing it
from a certain height and measure the fall using the internal accele-
rometer. There could be a lot of beneficial outcomes from such an
experiment, but are you crazy enough to try?
The act of acquiring the right tool to do something is almost a reli-
gious one. Imagine you are about to learn astronomy, you will be

XVIII Einleitung
interested in getting a telescope to look at the stars. You might not
go for the »gold edition« one in the first place. People usually get
something that works, and if they like it and get hooked, then they
make a move for something better - and probably more expensive.
When it comes to learn about crafting electronic devices like you
want to feel the thrill of controlling a light bulb, starting up the
engine of your car remotely, or time up your fireworks next New
Year's Eve by means of digital logics ... Arduino offers a door to
easily access this world. Get yourself a board, download the soft-
ware, check out the examples and in a couple of sessions you will
be controlling motors, launching rockets, and reading data from a
GPS.
We made Arduino a tool for learning. It is made to be easy to use
for beginners, but also powerful for those that want to go deeper in
the topic. However, we wanted it to be affordable. We like people
to try things without the fear of breaking them. Your Arduino will
most likely not let you down, but if it did ... it wouldn't be a big
deal. It is cheap to get a new one, but even cheaper to fix it. Since it
is open source you can always consider the possibility of creating
your own version of it, our website will tell you how.
I hope this book will encourage you to try things out. Its authors
have put a lot of effort in transmitting one of the Arduino Philoso-
phy Fundamentals: make it work while having fun!

May 2010
David Cuartielles ist Mitentwickler des Arduino-Boards

Dedication from David Cuartielles XIX


KAPITEL 1 In diesem Kapitel:
• Die Geschichte des Arduino-
Von Königen und Projekts
• Der Arduino, das unbekannte

Kondensatoren Gerät
• Arduino-Projekte: eine kleine
Vorstellung
• Hardware
• Die Arduino-Entwicklungs-
umgebung

Die ersten Investitionen sind getätigt. Das Buch hier und ein Ardu-
ino-Board sind gekauft, und nun liegt dieses wundersame Gebilde
aus Schaltkreisen, Chips und Pins auf dem Tisch. Wo kommt es
her, wo wird es hingehen? Die folgenden Kapitel sollen darin Ein-
blick geben. Von der Geschichte des Arduino-Projektes geht es zur
Beschreibung des in diesem Buch verwendeten Boards, des Arduino
Duemilanove. Wenn Sie noch keines besitzen, können Sie in diesem
Kapitel auch Bezugsquellen nachschlagen. Anschließend werden
die Grundzüge des Physical Computing und der dafür notwendigen
Physik erklärt, um in den darauf folgenden Kapiteln schließlich mit
kleinen Workshops zu beginnen, die die Programmiersprache und
einfache Schaltungen erklären. Wer diese Workshops durcharbei-
tet, sollte anschließend in der Lage sein, größere Projekte mit Ardu-
ino durchzuführen. Ob dabei bunte Lampen gebastelt werden, eine
Pflanze über Twitter meldet, wenn sie Wasser benötigt, oder der
Arduino dazu verwendet wird, Musik zu machen – dieses Buch
sollte nicht nur Einsteigern genügend Möglichkeiten bieten, die
Welt des Physical Computing kennenzulernen.

Die Geschichte des Arduino-Projekts


Im Jahre 1002 ließ sich Arduino, Markgraf im oberitalienischen
Ivrea, nach dem Tod von Kaiser Otto III zum König von Italien
wählen. Er hatte sich damit eine Marktnische gesucht, die es vorher
nicht gegeben hatte: Italien war bis dahin von den römisch-deut-
schen Königen beherrscht worden. An die Macht gekommen war
Arduino durch unrechtmäßige Aneignung von Kirchengut, was
ihm nach der Ermordung des Bischofs Petrus von Vercelli 997 die
Exkommunikation einbrachte, seinen Weg zu mehr Einfluss aber

1
nicht aufhielt. Sein Geschäftsmodell erwies sich als letztendlich
nicht tragfähig: Nachdem er erheblichen militärischen Widerstand
von Adel und Klerus erfahren hatte, verzichtete er auf den Thron
und starb in einem Kloster. Italien bekam nach ihm erst in der Neu-
zeit wieder einen König.
Das Arduino-Projekt hat seinen Namen nicht direkt von dem
machthungrigen, aber letztendlich erfolglosen italienischen König
geerbt. Ein freundlicherer Namenspatron wäre sicher der Geograph
Giovanni Arduino (1714–1795), der Vater der italienischen Geo-
wissenschaft, nach dem auch der Meeresrücken Dorsum Arduino
auf dem Mond benannt ist. Noch näherliegend ist aber eine ganz
andere Erklärung für den Namen: »Arduino« war der Name einer
Studentenkneipe (die wiederum nach König Arduino benannt ist)
in der Nähe des Interaction Design Institute Ivrea (IDII) in Italien,
einer ehemaligen Hochschule für Gestaltung.
Ganz wie der König aus dem 11. Jahrhundert hat das Elektronik-
projekt Arduino aber etwas ganz Neues versucht, was es in dieser
Form bisher nicht gab. Allerdings ist dem Projekt bis jetzt größerer
Erfolg beschieden, und statt Machtgier und Intrigen ist das Leit-
prinzip die Offenheit.
Die Gestaltung von Interaktion wurde am IDII von 2001 bis 2005
gelehrt. Unter Interaction Design versteht man diejenige Fachrich-
tung der Gestaltung, die sich mit Verhaltensweisen von Produkten
und Systemen beschäftigt, mit denen ein Benutzer interagieren
kann. Das IDII hatte nur genau einen Kurs und einen Magisterab-
schluss in Interaction Design im Angebot. Obwohl die Schule nach
vier Jahren mit einer anderen Akademie zusammenlegt wurde,
nachdem die ursprüngliche Förderung ausgelaufen war, und heute
nicht mehr als eigenständige Institution existiert, hatte sie einen
Einfluss, der noch heute spürbar ist. Neben dem Arduino entstan-
den hier wichtige Beiträge zu der Grafikprogrammierplattform
»Processing« vom MIT Media Lab und ein viel gelesenes Standard-
werk zum Interaction Design.
Im Winter 2005 hatte Massimo Banzi, Dozent für Gestaltung am
IDII, ein Gespräch mit David Cuartielles, einem Mikrochip-Inge-
nieur aus Spanien, der einen Forschungsaufenthalt am Institut
absolvierte. Die beiden sprachen darüber, wie oft Banzi Klagen von
Studenten hörte, dass es keine preiswerten und einfach zu pro-
grammierenden Mikrocontroller-Plattformen für Kunstprojekte
gebe. Sie entwickelten ihr eigenes Design für ein Board. Ausgehend
von der Entwicklungsumgebung Processing schrieb David Mellis

2 Kapitel 1: Von Königen und Kondensatoren


eine Programmiersprache für das Projekt, und irgendwann muss
die Idee entstanden sein, das Ganze nach der örtlichen Kneipe zu
benennen.
Mit 3.000 Euro Startkapital wurden eine erste Serie von Arduinos
bei einem kleinen Hersteller produziert und das komplette Design
unter einer Creative-Commons-Lizenz im Internet veröffentlicht.
Creative Commons ist ein Satz von vorgefertigten Lizenzverträgen
für die Veröffentlichung und Verbreitung digitaler Medieninhalte.
Der einfachste CC-Lizenzvertrag verlangt vom Nutzer lediglich die
Namensnennung des Rechteinhabers. Unter diesen Bedingungen
ist auch das Hardwaredesign für Arduino verfügbar, solange es
unter den gleichen Bedingungen weitergegeben wird. Lediglich den
Namen »Arduino« möchten die Entwickler als Marke behalten und
bitten darum, eigene Entwicklungen unter einem anderen Namen
zu veröffentlichen.
Mittlerweile ist aus dem Projekt eine kleine internationale Firma
geworden, unterstützt vom Professor Tom Igoe vom Interactive
Telecommunications Program der New York University. Die Tatsa-
che, dass jeder sich das Design von Arduino schnappen kann und
in einer Fabrik in Fernost Kopien in Massenproduktion anfertigen
kann, hat nicht geschadet. Die Offenheit ist nicht nur ein Grund für
die Beliebtheit der Plattform, sondern hat auch dazu beigetragen,
dass sich Schaltungen und Code für Arduino an vielen Stellen im
Internet finden lassen. Eine Firma, die sich nicht der offenen
Gemeinschaft von Enthusiasten bedienen könnte, weil sie die Ver-
wertungsrechte mit Zähnen und Klauen verteidigt, hätte diesen
unschlagbaren Vorteil nicht.
Arduino als Gemeinschaft ist vergleichbar mit dem Phänomen der
Emergenz in der Natur. Dieser Begriff bezeichnet das spontane
Herausbilden von Strukturen in Systemen durch das Zusammen-
spiel ihrer Elemente, ohne dass das Endergebnis auf die einzelnen
Elemente direkt zurückführbar ist. Ob beim Ameisenbau oder bei
der freien Mikrocontroller-Plattform: Das Ganze ist größer als die
Summe seiner Teile.

Der Arduino, das unbekannte Gerät


Arduino besteht aus einer Entwicklungsumgebung und einem
Entwicklungsboard. Die Entwicklungsumgebung läuft auf einem
normalen Computer und bildet den Softwareteil. In ihr werden
Programme geschrieben, die dann auf dem Board, der Hardware,

Der Arduino, das unbekannte Gerät 3


ausgeführt werden. Das Board funktioniert dabei als Schnittstelle
von der Welt der Bytes zur der Welt der Dinge: Es kann Eingaben,
etwa von Sensoren, verarbeiten und elektrische Signale ausgeben.
Zum Beispiel an Aktoren, also Bauteile, die eine Auswirkung auf
die physikalische Welt haben. Das können Motoren sein, Relais
oder aber Ausgabeschnittstellen wie Lichter, Lautsprecher oder
Displays. Oder man steuert damit wiederum Sensoren, also Bau-
teile, die von der realen Welt beeinflusst werden und diese Verän-
derungen elektronisch weiterleiten, wie etwa einfache Schalter,
Temperatur- oder Lichtsensoren. Seine Anweisungen erhält das
Board von Programmen, die in der Arduino-Software geschrieben
und anschließend in den Speicher geladen werden.
Dabei kann der Entwickler frei entscheiden, ob er das Board vom
Computer abkoppeln und als eigenständiges Gerät einsetzen oder
als Schnittstelle zwischen Computer und Außenwelt verwenden
möchte. Indem es ständig mit dem Computer kommuniziert, kann
es benutzt werden, um Programme wie PureData, Processing,
Flash, VVVV oder Max/MSP zu steuern. Das Arduino-Board kann
hier durchaus mehr Arbeit leisten, als nur Daten zu übermitteln. Es
kann sie vorher verarbeiten, oder es kann für Benutzerschnittstellen
mit Tastern, Drehreglern, Lichtern und vielen anderen Möglichkei-
ten eingesetzt werden.

Abbildung 1-1
Das Arduino-Board

Beim Arduino-Projekt wird viel Wert auf eine Entwicklungsme-


thode gesetzt, die iterativ und interaktiv ist: Man geht davon aus,

4 Kapitel 1: Von Königen und Kondensatoren


dass Elektronik und Programmieren am besten durch Basteln, Aus-
probieren und Modifizieren erlernt werden können. Eine Schaltung
versteht man am besten, indem man sie zunächst aufbaut und zum
Laufen bringt. Anschließend kann man sie erweitern und modifi-
zieren. Auf die gleiche Weise lernt man auch den Umgang mit einer
Programmiersprache besonders gut. Des Weiteren gibt es im Inter-
net eine riesige Menge an verschiedenen Beispielen und Schaltun-
gen mit Arduino, die jeder bei sich zu Hause ausprobieren und
weiter modifizieren kann. Dadurch können viele Schaltungen sehr
einfach selbst gebastelt, analysiert und auch verstanden werden.
Die ursprüngliche Zielgruppe von Arduino waren Designer und
Künstler. Deswegen sind viele Funktionen sehr einfach gestaltet,
damit Benutzer, die noch nie zuvor programmiert und elektroni-
sche Schaltungen gebaut haben, sich schnell mit der Umgebung
vertraut machen können. Schon nach einigen Stunden können
eigene Prototypen und Projekte zum Laufen gebracht werden. Fort-
geschrittenen Nutzern mag vieles ein bisschen umständlich oder
ineffizient vorkommen, es steht ihnen aber auch nichts dabei im
Wege, fortgeschrittene Programme zu schreiben, die vollen Zugriff
auf die tieferen Funktionen haben. Das Ziel von Arduino ist, Kom-
plexität und Aufwand von normalen elektronischen Projekten zu
verringern, damit auch Anfänger sich schnell zurechtfinden und
nicht abgeschreckt werden.
Die Arduino-Software ist frei unter [Link] erhältlich
und wird als Open Source zur Verfügung gestellt. Das heißt, sie
darf verändert und wieder zum Download angeboten werden.
Auch die Schaltpläne für das Board sind frei, sodass es eine Vielzahl
von Abwandlungen zu kaufen gibt. Das derzeit (April 2010) aktu-
ellste Board ist der »Arduino Duemilanove«, der auch in diesem
Buch verwendet wird. Die Sprache basiert auf den Grundideen von
Processing, wobei sie keine Variante von Java ist, sondern vielmehr
auf C++ basiert. Man braucht diese Sprachen, wenn man denn
schon von ihnen gehört hat, nicht zu fürchten, denn ihre Komplexi-
tät wird bei Arduino durch viele hilfreiche Konstrukte vor dem
Benutzer versteckt (sie ist aber für fortgeschrittene Benutzer immer
noch zugänglich).
Natürlich gibt es noch eine Reihe von anderen Hardware-Entwick-
lungsumgebungen. Arduino bietet aber einige Vorteile:
• Arduino ist günstig. Die Software ist kann frei heruntergeladen
werden, das günstigste Arduino-Board schon für ca. 25 Euro

Der Arduino, das unbekannte Gerät 5


zu haben. Der Hauptchip kostet nur ca. vier Euro, lässt sich
also im schlimmsten Fall leicht austauschen.
• Arduino ist frei. Die Open-Source-Philosophie hat beim Ardu-
ino-Projekt viele Früchte getragen: Die Software wird ständig
von vielen Menschen in der Welt weiterentwickelt und verbes-
sert; dazu kommt eine Vielzahl an Bastelprojekten, die zum
Nachbauen und Erweitern im Netz veröffentlicht werden.
Auch die Schaltpläne für die Hardware stehen unter einer
Open-Source-Lizenz. Das Ergebnis ist eine Vielzahl von eige-
nen Arduino-Versionen, die jeweils speziell an die Bedürfnisse
eines Projektes angepasst wurden. Und zu guter Letzt ermög-
licht es diese Freiheit, dass im Internet eine Vielzahl von Erwei-
terungen verkauft werden kann; sogenannte Shields, die auf
das Board aufgesteckt werden. Mehr Informationen über
Shields finden sich im entsprechenden Anhang.
• Arduino funktioniert überall. Die Arduino-Software ist für
Windows, Mac OS X und Linux verfügbar und basiert auf Pro-
cessing, das schon seit Langem von vielen Künstlern und Pro-
grammierern eingesetzt wird. Das Board kann mit einem USB-
Kabel angeschlossen werden. Damit werden viele Probleme
vermieden, die in anderen Projekten auftreten. Andere Schwie-
rigkeiten lassen sich leicht lösen, weil Hard- und Software ent-
sprechend weit verbreitet sind.
• Arduino hat viele Fans und deren Gemeinde wächst stetig. So
ist es sehr einfach, sich mit anderen Nutzern auszutauschen
oder Hilfe zu bekommen, wenn es Probleme gibt. Auch die
Anzahl gut dokumentierter Beispielprojekte wächst ständig,
sodass gute Ideen leicht nachzubauen und an die eigenen
Bedürfnisse anzupassen sind.
• Arduino ist einfach. Die Programmiersprache basiert auf Pro-
cessing, das für ein einfaches Lernen entwickelt wurde. Es ist
besonders freundlich für Anfänger und macht es besonders
einfach, »schnell mal was auszuprobieren«. Das hilft aller-
dings nicht nur Einsteigern, sondern auch hartgesottenen Pro-
fis: Es genügt, ein paar Zeilen zu schreiben und auf den
»Upload and Run«-Knopf (siehe Kapitel 1) zu drücken, um ein
neues Programm auf die Hardware zu laden und auszuprobie-
ren. In vielen anderen Projekten muss man zuerst eine kom-
plexe Softwareumgebung einrichten, bevor die erste Zeile
Code geschrieben werden kann. Die Herangehensweise bei
Arduino gibt viel mehr Raum für kreative Entfaltung. Viele

6 Kapitel 1: Von Königen und Kondensatoren


Ideen können einfach ausprobiert werden, ohne dass einem
starren Vorgang gefolgt werden müsste, der eher Ingenieuren
entgegenkommt als Künstlern oder Designern.

Die Arduino-Philosophie
Im Gegensatz zu einer traditionellen Entwicklung von elektroni-
schen Projekten, bei denen der Prozess im Vordergrund steht, wie
sie z.B. in Ingenieurschulen gelehrt wird, wird bei Arduino-Projek-
ten Wert auf das Implementieren und Bauen gesetzt, weniger auf
das lange und anstrengende Planen. Alles ist dazu gedacht, mög-
lichst schnell und elegant einen funktionierenden Prototypen zum
Laufen zu bringen. Diese Herangehensweise mag zuerst ein biss-
chen verwirrend klingen: Ist sorgfältige Planung, gerade bei Elek-
tronik, nicht notwendig, um Fehler und Nebenwirkungen zu
vermeiden? Bei Arduino ist der Weg ein großer Teil des Ziels: Erst
beim Ausprobieren (und oft auch, wenn unvorhergesehene Fehler
oder nicht geplantes Verhalten zutage treten) setzt man sich mit der
Materie richtig auseinander. Und wenn ein schneller Erfolg eintritt,
motiviert das zusätzlich die Entwicklung: Die Energie bleibt erhal-
ten, auch wenn man sich durch größere Projekte hindurcharbeitet.
Das Basteln und Ausprobieren ist bei Arduino ein Spiel, das Spaß
machen soll. Anstatt zielstrebig von A nach B zu gehen, wie es sonst
bei Projekten der Fall ist, kommt es hier oft vor, dass man sich auf
dem Weg ein bisschen verirrt und dann auf einmal bei C landet.
Auch für fortgeschrittene Nutzer ist diese Eigenschaft von Arduino
sehr erfrischend: Man muss nicht mühsam, sauber und korrekt
Projekte bauen und Programme schreiben, sondern überrascht sich
schnell dabei, wie man wilde Ideen »einfach nur so« ausprobiert,
weil es eben sehr schnell möglich ist. Am besten lässt sich Arduino
mit älteren Homecomputern vergleichen, die einen beim Anschal-
ten gleich mit einem BASIC-Prompt einluden, verrückte Pro-
gramme zu schreiben.
Im Sinne des schnellen Erzeugens von funktionierenden Proto-
typen wird bei Arduino viel Wert auf die kreative Nutzung von
Technik gesetzt. Anstatt alles von Grund auf aufzubauen, werden
oft fertige Komponenten (sogenannte Shields, siehe auch
Anhang A) zusammengesteckt und mit fertigen Programmteilen
angesprochen (sogenannten Libraries, siehe auch Anhang B).
Ähnlich wie bei den schon kurz erwähnten grafischen Program-
mierumgebungen Max/MSP, Reaktor oder VVVV werden bei

Der Arduino, das unbekannte Gerät 7


Arduino oft einzelne Blöcke zusammengesteckt und mithilfe eines
angepassten Programms kombiniert. Dadurch lassen sich auch
viele aufwendige Schaltungen, die von anderen Entwicklern schon
entworfen wurden, leicht wiederverwenden. Oft werden bei Ardu-
ino-Projekten auch herkömmliche Haushaltsgeräte oder elektroni-
sche Spielzeuge modifiziert und »missbraucht«, um bestimmte
Schaltungen zu bauen.

Arduino-Projekte: eine kleine Vorstellung


Die Bandbreite an Arduino-Projekten reicht von Lichtinstallationen
über Gebrauchsgegenstände bis hin zur Robotik. Hier sollen einige
Projekte vorgestellt werden, die besonders interessant sind und
auch als Motivation gedacht sind, sich durch das Buch zu arbeiten,
die Programmiersprache zu erlernen und mit elektronischen Bau-
teilen zu experimentieren.

LilyPad und Wearable Computing


Das Arduino LilyPad, eine Abwandlung des in diesem Buch
benutzten Arduino-Boards, lässt sich auch in Kleidung einnähen.
Diese kann so mit LEDs ausgestattet werden, um etwa auf ihr
Umfeld zu reagieren oder mit ihm zu kommunizieren. Am wichtigs-
ten sind dabei leitende Stoffe oder solche, die ihre Form verändern
können sowie elektronische Bauteile, die in Kleidung eingearbeitet
sind. Das kann von Displays auf dem Rücken bis hin zu intelligen-
ter Bekleidung reichen, die ihre Umwelt wahrnehmen oder mit
anderen kommunizieren kann. In Kapitel 9 werden diese leitenden
Fäden näher beschrieben und ein Projekt erläutert, das diesem
sogenannten Weareable Computing zuzuordnen ist.

Interaktive Kunstinstallationen
Neben Designern und Modeschöpfern sind vor allem Künstler die
großen Nutznießer von Arduino. Da Künstler sich meistens nicht
mehr als nötig mit Technik und Programmierung beschäftigen,
sondern sich lieber auf ihre kreative Arbeit konzentrieren wollen,
ist ein einfach zu programmierender Mikrocontroller geradezu ein
Segen und eröffnet ganz neue Möglichkeiten, den eigenen Ideen
freien Lauf zu lassen.

8 Kapitel 1: Von Königen und Kondensatoren


Wundersame VGA-Bilder
Der koreanische Pionier der Videokunst Nam June Paik dürfte mit
Sicherheit einen Einfluss auf das Projekt von Sebastian Tomczak
gehabt haben, der ein VGA-Signal nutzt, um mit Signalstörungen
Bilder auf einem Computermonitor hervorzurufen. Die dafür not-
wendigen Signale werden von einem Arduino gespeist, an dem
einige Pins eines VGA-Kabels angeschlossen sind. Die anderen
Kabel hängen an einem Laptop, der für die horizontalen und verti-
kalen Frequenzsignale sorgt. Damit können zum Beispiel visuelle
Effekte passend zu laufender Musik erzeugt werden, und indem die
Farbkanäle bei einem anderen Monitor umgedreht werden, sind
sogar verschiedene Bilder auf einmal möglich. Weitere Informatio-
nen zu diesem Projekt finden Sie unter [Link]
com/2009/04/[Link], wo nicht
nur das Grundsetup erläutert wird, sondern auch einige Videobei-
spiele gezeigt werden.

Gute Luft
Das AIR-Projekt ist in erster Linie als soziales Experiment gedacht:
Jeder Teilnehmer erhält ein Gerät, basierend auf einem Arduino,
das Umweltdaten wie den Grad der Luftverschmutzung misst.
Diese Daten werden über ein Netzwerk zu einem zentralen Server
übertragen und an die anderen Teilnehmer weiterverbreitet. Die
Nutzer können also selbstständig herausfinden, wo in ihrer Umge-
bung besondere Verunreinigungen existieren. Das Projekt will zum
Beispiel die Reaktionen darauf herausfinden und sehen, ob die
Menschen sich selbstständig darum kümmern, ihre direkte Umwelt
lebenswerter zu machen. Zudem soll es Diskussionen rund um
Umweltpolitik, Gesundheit und soziale Zusammenhänge innerhalb
einer Gemeinschaft anregen. Die Website für das Projekt findet
sich unter [Link]

Buchstabenklettern
Eine spielerische Kunstinstallation hat Olaf Val mit dem Digiripper
geschaffen, eine Matrix von 7 mal 5 Elementen aus Plastik, die in
eine Wand eingelassen sind. Dahinter befinden sich Leuchtdioden.
Wenn diese aufleuchten, fahren die Plastikelemente aus und bieten
dem Nutzer Halt, um darauf zu klettern. Wird das Licht ausge-
schaltet, fährt das Element wieder ein, der Kletterer verliert seinen

Arduino-Projekte: eine kleine Vorstellung 9


Halt. Nun gilt es, sich eine Reihe von Buchstaben zu merken, die
nacheinander angezeigt werden. Wechselt der Buchstabe, muss
man schnell umgreifen, um nicht von der Wand herunterzufallen.
Gewonnen hat, wer am längsten durchhält. Die Website des Pro-
jekts finden Sie unter [Link] Es findet
regelmäßig seinen Platz in Ausstellungen im deutschsprachigen
Raum.

Abbildung 1-2
Digigripper, © Olaf Val

Klangstufen
Um dem Betrachter ein Gefühl für die Klänge seiner Stadt zu geben,
wurde die Installation »Klangstufen« geschaffen. Unter einer kleinen
Holztreppe sind Entfernungssensoren angebracht, die erkennen,
wenn ein Mensch auf einer Stufe steht. Der Betrachter kann nun
einen Punkt in der Stadt auswählen und einen Kopfhörer aufziehen.
Je nach Ort und Stufe hört er nun Klänge, die an diesem räumlichen
Punkt aufgenommen wurden. Jede Stufe repräsentiert dabei einen
Schritt in die Höhe, beginnend bei 0 Metern, auf denen man die
U-Bahn, Wasser oder das Rauschen in der Erde hört. Von dort aus
geht es weiter über den Klang der Stadt (200 m), des Umlands (1.
500 m), des Wetters (8.000 m) und der Flugzeuge (12.500 m). Das
Projekt befindet sich immer noch in der Weiterentwicklung wird
unter [Link] doku-
mentiert, wo man sich auch ein Video ansehen kann.

10 Kapitel 1: Von Königen und Kondensatoren


Klang-Körper
Die Installation Sonic Body bringt dem Betrachter die Geräusche
und Töne des menschlichen Körpers näher. In einem kleinen Raum
sind die inneren Organe eines Menschen aus Stoff nachgebildet,
sodass der Besucher das Gefühl hat, sich inmitten des Körpers zu
befinden. Die einzelnen Organe sind dabei mit Berührungssensoren
ausgestattet, die über einen Arduino zusammengeführt und mit
MAX/MSP verbunden sind. Werden die Organe berührt, gedrückt
oder gestreichelt, sorgt der angeschlossene PC für eine Kulisse von
Geräuschen, die aus dem Inneren des Körpers aufgenommen wur-
den. Ziel des Ganzen ist, Besuchern ein Gefühl für sich selbst und
für die wundersame Schönheit der Natur zu geben. Wer mehr
erfahren möchte, kann unter [Link] eine volle
Dokumentation finden.

Die binäre Brücke


Auch wenn der Arduino nur ein kleines Gerät ist, kann er auch für
Kunstinstallationen von großem Ausmaß verwendet werden. Im
Hafen von Malmö etwa haben vier Studenten eine Brücke mit zwölf
Bewegungssensoren ausgestattet. Diese sind in der Lage, zu mes-
sen, wie viele Menschen sich gerade auf der Brücke befinden. Die
Anzahl der Fußgänger wird dann in eine Binärzahl umgewandelt,
die wiederum die Farbgebung von Lampen steuert, die unter der
Brücke angebracht sind. Ist die Binary Bridge ([Link]
[Link]/) leer, ist sie auch nicht erleuchtet, ist sie voller Men-
schen, erstrahlt sie in vollem Glanz. Dazwischen leuchtet sie in
allen möglichen Farben von Grün bis Purpur, je nachdem, welche
Werte die Fußgänger gerade erzeugen.

Kreative Aggressionen
Boxsäcke eignen sich seit jeher recht gut, um angestauten Aggressi-
onen freien Lauf zu lassen, ohne dass dabei Menschen zu Schaden
kommen. Die Designer von Fluidforms ([Link]
[Link]) nutzen die Fäuste ihrer Kunden, um individuelle
Lampen zu erschaffen. Die Energie, die bei jedem Schlag in einen
speziell präparierten Boxsack freigesetzt wird, wird mit Sensoren
und einem Mikrocontroller an einen PC übermittelt. Dort läuft ein
3D-Programm, das einen weißen Zylinder anzeigt, der Schlag um
Schlag verformt wird. Das Ergebnis kann anschließend gespeichert
und mit einen 3D-Drucker gedruckt werden, welcher als Lampen-
schirm verwendet wird.

Arduino-Projekte: eine kleine Vorstellung 11


Roboter
Auch wenn Roboter noch weit davon entfernt sind, für uns zu den-
ken oder die Weltherrschaft zu übernehmen, findet man sie immer
mehr auch außerhalb von Produktionsstraßen in riesigen Fabrik-
hallen. Neben einer großen Anzahl an Spielzeugrobotern bevölkern
heute auch automatische Staubsauger und Wischmops unsere
Wohnzimmer, und die Anzahl der Projekte, die eigene Roboter
bauen oder im Handel erhältliche Geräte für sich nutzbar machen,
wird ständig größer.

Musikinstrumente
Einen ganz eigenen Bereich in der Kunst nehmen Projekte ein, die
Arduino nutzen, um Musik zu machen oder zu steuern. In diesem
Buch widmet sich Kapitel 10 der direkten Sounderzeugung und
Ausgabe auf dem Arduino. Zudem gibt das Kapitel eine Übersicht
über weitere Projekte in diesem Feld und beschreibt, wie man mit
dem Arduino eigene Musikinstrumente bauen kann.

Spiele
Ein Mikrocontroller, wie er auf dem Arduino-Board aufgebracht
ist, ist längst viel leistungsfähiger als die ersten Spielekonsolen, die
Anfang der 1980er in die Wohnzimmer der Welt drängten. Das
bedeutet natürlich, dass es möglich ist, einfache Computerspiele
auf dem Arduino selbst zu entwickeln oder bekannte Klassiker
nachzubauen. In diesem Buch finden sich zwei Spiele: In Kapitel 7
wird ein Würfel mit einem Kontaktsensor gebaut, in Kapitel 5 wird
Processing und ein Lichtsensor für ein kleines Geschicklichkeits-
spiel verwendet.

Pong auf dem Arduino


Das erste erfolgreiche Computerspiel aller Zeiten war Pong von
Atari, das seit 1972 die Welt revolutionierte. Dabei basierte das
Spiel nicht auf einem Mikroprozessor, sondern vielmehr auf einem
fest verdrahteten Schaltkreis. Das ändert natürlich nichts daran,
dass dieses berühmteste Tennis-Computerspiel der Welt auch auf
dem Arduino programmiert werden kann. Dabei muss es nicht
unbedingt auf dem Fernseher angezeigt werden. Auch Versionen
zum Beispiel mit LED-Anzeigen sind möglich. Das Projekt Blinken-
lights ([Link] nutzt gar die Fassade eines

12 Kapitel 1: Von Königen und Kondensatoren


ganzen Hauses: In den Fenstern sind Lampen angebracht, die von
einem zentralen Schaltkreis gesteuert werden. Auch wenn Blinken-
lights nicht auf Arduino basiert, zeigt das Beispiel, was alles mit ein
bisschen Kreativität und genügend Einsatz möglich ist. Wer seine
eigene Pong-Variante mit dem Arduino nachbauen möchte, findet
unter anderem bei Alastair Parker ([Link]
[Link]/arduinopong) eine Anleitung mit Schaltplan und passen-
dem Quellcode.

Spielend die Hand trainieren


Vor einigen Jahren waren Powerballs kurzzeitig in Mode: Plastik-
kugeln, in deren Innerem ein schwerer Rotor verankert ist, der
durch Kreisbewegungen auf Touren gebracht wird. Dabei baut sich
ein Drehmoment auf, das der Hand entgegenwirkt, wenn diese den
Ball seitlich kippt. Diese Bälle können dazu verwendet werden, das
Handgelenk zu stabilisieren und bei langen Computerarbeiten für
den Ausgleich in den Muskeln zu sorgen. Man kann sie aber auch
an einen Arduino anschließen und damit Geschwindigkeiten mes-
sen. Damit hat der Niederländer Eric Holm ein Spiel namens Gyro
als Abschlussarbeit gebaut: Die Messdaten steuern ein kleines
Raumschiff, das in die Höhe fliegt und dabei Objekten ausweichen
muss. Es ist unter [Link] beschrieben, wenn auch
leider nur spärlich, was dem geneigten Bastler natürlich nur als
Ansporn dienen sollte, die Funktionsweise selbst herauszufinden
und nachzubauen.

Gotcha!
Es mag zwar nicht die feine Art sein, auf Menschen zu schießen,
aber es kann durchaus Spaß machen, wenn es sich bei den Geschos-
sen beispielsweise um Farbkugeln handelt. Beim »Lasertag« werden
Infrarotstrahlen verwendet, wobei jeder Mitspieler neben seiner
Waffe auch die passende Kleidung trägt, die mit Sensoren ausge-
stattet ist. Diese Sensoren können zum Beispiel mit einem Arduino
(hier empfiehlt sich ein LilyPad) verbunden sein, der die Treffer
registriert und sofort oder nach Ende des Spiels zur Auswertung an
einen Rechner überträgt. Die Beschreibung eines vollständigen
Projektes finden Sie unter [Link]
opensource/[Link]?search_by=Arduino+laser. Hiermit sei
jedoch darauf hingewiesen, dass Laserspiele in Deutschland mit
Verweis auf die Garantie der Menschenwürde im Grundgesetz
verboten sind, da es bei den kommerziellen Angeboten darum
geht, möglichst viele Treffer zu landen, und nicht, wie bei Paint-

Arduino-Projekte: eine kleine Vorstellung 13


ball oder Gotcha, eine Fahne oder ein Gebiet zu erobern. Nach-
bauen darf man das Projekt natürlich trotzdem, und wer es
spielen möchte, wird sich auch auf moralisch akzeptable Spielre-
geln einlassen können.

Nicht wackeln!
Labyrinthe aus Holz haben schon Generationen von Kindern frust-
riert. Sie wissen schon: diese Spiele, bei denen eine Kugel auf einem
mit einem Drehknopf in zwei Richtungen schwenkbaren Unter-
grund vom Start ins Ziel gebracht werden soll, vorbei an Löchern,
durch die sie fallen kann. Dank dem Arduino ist nun die Zeit
gekommen, diesen garstigen Maschinen ein Schnippchen zu schla-
gen, denn mithilfe zweier Servos kann das Labyrinth auch ohne
zittrige Hände gesteuert werden, wie Jestin Stoffel zeigt. Man kann
allerdings auch diesen Triumph über die Schwerkraft ruinieren,
indem man ein Wii-Balance-Board anschließt, wie es unter http://
[Link]/2009/01/12/arduino-powered-
robotic-labyrinth-game/ erklärt wird.

Arduinoboy
Um einen Arduino mit dem Thema Computerspiele in Verbindung
zu bringen, braucht es nicht unbedingt ein Spiel: Längst wird auch
die Hardware alter und neuerer Konsolen verwendet, um mit dem
Arduino zu kommunizieren. Der Arduinoboy hingegen arbeitet mit
einem Nintendo Gameboy zusammen, dem Urvater aller Hand-
held-Konsolen, der seit 1989 weltweit 118 Millionen mal verkauft
wurde. Die Verbindung läuft dabei in die andere Richtung: Der
Arduino wird an einen Gameboy angeschlossen, um diesem als
Midi-Controller zu dienen. Für den Gameboy gibt es mittlerweile
eine ganze Reihe von Programmen wie Nanoloop und Little-
SoundDJ, die dem Soundchip Klänge entlocken können. Mehr
Informationen zu diesem Projekt finden Sie unter [Link]
[Link]/p/arduinoboy/.

Das automatisierte Zuhause


Schon in den zukunftsfreudigen 1950er Jahren erträumte man
neben atomgetriebenen Rasenmähern ein vollautomatisches Zu-
hause. Dank Physical Computing und bezahlbaren Bauteilen gibt
es nun immer mehr Menschen, die sich diesen Traum zumindest
teilweise erfüllen. Ob es eine Alarmanlage ist, die mögliche Einbre-

14 Kapitel 1: Von Königen und Kondensatoren


cher über Twitter melden kann, oder ein selbst gebauter Anschluss
für das kommerzielle X10-System – die Möglichkeiten sind vielfäl-
tig. Kapitel 8 zeigt auf, wie mit begrenzten Mitteln eine eigene
Heimautomatisierung über das DMX-Protokoll gestaltet werden
kann. Hier geht es darum, Lampen und Steckdosen mit dem Ardu-
ino zu steuern und so zum Beispiel die Hausbar mit der nötigen Be-
leuchtung auszustatten.

Ein frisch Gezapftes, bitte!


Nutzer der Bierbrau-Community Brewboard verwenden Arduino,
um die Temperatur in ihren Zapfanlagen zu regeln ([Link]
[Link]/[Link]?showtopic=77935). Das Projekt »BrewTroller«
geht noch ein ganzes Stück weiter und versucht, den Bierbraupro-
zess mithilfe eines Sanguino, einer Arduino-Variante, zu optimie-
ren. Der BrewTroller misst konstant das Volumen und die Tem-
peratur der einzelnen Braukomponenten und kontrolliert die
Hitzequellen, Pumpen und Ventile. Ziel des Ganzen ist der Auto-
Brew-Modus, also das vollständig automatisch gebraute Bier. Na-
türlich zeigt auch dieses Projekt, dass Technik nicht alle Projekte
lösen kann: Ob ein Bier wohlschmeckend ist, hängt auch immer
von der Qualität der Zutaten ab, und das richtige Rezept kann kein
Sensor oder Mikocontroller der Welt ersetzen.

Der Duft frischen Gebäcks


Geht man in ein Café in voller Vorfreude auf einen frisch gebacke-
nen Muffin, kann die Enttäuschung groß sein: Das Gebackene
schmeckt wie vom Vortag, weil das frische Blech noch nicht aus
dem Ofen ist. Oder es gibt nur noch Schokolade, weil die Blaubee-
ren heute gar nicht auf dem Programm standen und der Inhaber zu
beschäftigt war, um die Kreidetafel am Eingang zu aktualisieren.
Der BakerTweet ([Link] soll da Abhilfe schaffen,
eine kleine Box, die mit einem Arduino, einem kleinen Drehknopf
und Display ausgestattet ist. Dort können vorprogrammierte Back-
waren einfach ausgewählt werden, und der Arduino meldet die
Nachricht anschließend über eine Netzwerkverbindung an Twitter.
Der Vorteil: Cafés können einfach und direkt für sich Werbung
machen, und die Gäste wissen sofort Bescheid, wenn es sich lohnt,
eine kleine Auszeit zu nehmen. Das erste Café, das den BakerTweet
eingesetzt hat, war das Albion Café im Londoner Stadtteil Shore-
ditch; auf der Webseite des Projektes finden sich aber alle Details,
um selbst in das twitternde Bäckerbusiness einzusteigen.

Arduino-Projekte: eine kleine Vorstellung 15


Gadgets
Nicht alle Physical-Computing-Projekte müssen direkt einleuchten
oder einen Anwendungszweck verfolgen. Oft sind es auch die klei-
nen Ideen, die man schnell mithilfe eines Arduino umsetzen kann.
Das können kleine Experimente sein oder nutzlose, aber schöne
Ausstellungsobjekte. In Kapitel 4 erhält auch dieses Buch sein klei-
nes Gadget: eine Gehirnwellenmaschine, mit der man sich selbst in
einen Modus der Entspannung versetzen kann.

Schlaf beobachten mit dem Arduino


Weil die ehemalige MIT-Studentin Anita Lilie mehr über ihren
Schlafrhythmus erfahren wollte, erfand sie den Sleeptracker. In ers-
ter Linie wollte sie damit herausfinden, warum sie so ein Morgen-
muffel war. Sie hatte bemerkt, dass sie immer nur dann unausge-
schlafen war, wenn sie von einem Wecker geweckt wurde. Wenn sie
ohne aufwachte, ging es ihr gut. Sie ging von der Annahme aus, dass
es nicht die Menge an Schlaf war, die das Problem verursachte, son-
dern vielmehr der Zeitpunkt innerhalb eines 90-minütigen Rah-
mens, in dem der Schlaf tiefer und leichter wird. Das Ziel war also,
nicht etwa 6 oder 10 Stunden zu schlafen, sondern den genauen
Zyklus herauszufinden, um sich während besonders leichten Schlafs
wecken lassen zu können. Also schloss sie mehrere Beschleuni-
gungssensoren an einen Arduino an und zeichnete die Daten auf. So
konnte sie feststellen, wie lang ihr Schlafzyklus dauerte, und den
Wecker entsprechend programmieren. Ob sie damit Erfolg hatte, ist
leider nicht dokumentiert, was wohl auch daran liegt, dass die Daten
sich als deutlich komplexer als erwartet darstellten. Leider ist das
Projekt auch nicht als perfekter Wecker geeignet, da niemand gern
jede Nacht mit drei langen Kabeln und Sensoren am Körper verbrin-
gen möchte. Dennoch ist es sicher interessant und empfiehlt sich für
jeden, der neugierig ist und zufällig gerade drei Beschleunigungssen-
soren zu Hause hat. Eine genaue Dokumentation finden Sie unter
[Link]

Schöne Bilder
Digitale Bilderrahmen sind immer noch recht teuer und natürlich
viel langweiliger als ein selbst gebasteltes Projekt. Das March
Frame Project ([Link]
kann zwar keine digitalen Bilder anzeigen, aber immerhin mit ein-

16 Kapitel 1: Von Königen und Kondensatoren


fachen Methoden zwischen drei unterschiedlichen Motiven wech-
seln. Zwei dieser Bilder werden dabei in den Farben Rot und Blau
übereinandergelegt und auf ein Papier gedruckt. Das dritte ist
eine Schablone, die dahinter angebracht wird. Der Arduino steu-
ert nun drei unterschiedliche LEDs (eine rote, eine blaue und eine
weiße), die diese Motive zum Leuchten bringen. Wenn eines der
beiden farbigen Lichter leuchtet, löscht es das entsprechende
Motiv auf dem Bild aus, das andere wird klar dargestellt. Sind
beide aus, kann die weiße LED im Hintergrund die Schablone auf
das Papier projizieren. Das Ergebnis ist ein schöner Bilderrahmen
(sofern die Elektronik stilvoll verkleidet wurde), der mit Sicher-
heit für Aufsehen unter Besuchern sorgt.

Die glückliche Katze


Wer eine Katze besitzt, weiß, dass sie recht unruhig werden kann,
wenn der Futter- oder Trinknapf wieder einmal leer ist. Ein für-
sorglicher Besitzer, der über einen Arduino verfügt, kann diesen
dafür nutzen, rechtzeitig Meldung zu erstatten oder zumindest
beim Wasser sogar automatisch für Nachschub sorgen. Unter
[Link] fin-
det sich ein Projekt, das mit einem Ultraschallsensor den Wasser-
stand im Napf messen und sich bemerkbar machen kann. Der
Erschaffer des Projektes arbeitet derzeit auch daran, das Nachfül-
len zu automatisieren, was nicht allzu schwer sein dürfte – Nach-
ahmer und Bastler, die weitere Ideen umsetzen, sind dort
sicherlich willkommen!

Hardware
Hält man zum ersten Mal ein Arduino-Board in der Hand, erkennt
man nur einzelne Teile wieder, zum Beispiel den Anschluss für das
USB-Kabel. Anders als beim PC sollte aber ein Arduino-Nutzer alle
Bauteile seines Gerätes genau kennen.

Beschreibung
Alle Erklärungen in diesem Buch beziehen sich auf den Arduino
Duemilanove, die 2009er-Ausgabe des Arduino-Boards. Dieses
Board besteht im Wesentlichen aus den folgenden Bestandteilen.

Hardware 17
Abbildung 1-3
Das Arduino-Board mit seinen
einzelnen Bestandteilen

Mikrocontroller
Auf dem Arduino Duemilanove ist ein Atmega168- oder Atmega328-
Mikrocontroller angebracht, ein kleiner Computer, der mit 16 MHz
Taktfrequenz arbeitet. Er besitzt zwar wenig Speicher (16 bzw. 32
KByte Speicher und 2 bzw. 4 KByte Arbeitsspeicher) und kann nur
8-Bit-Befehle verarbeiten, dafür aber direkt mit anderer Hardware
verbunden werden. Natürlich besitzt dieser »Computer« weder
Festplatte noch Tastatur oder Display, aber er ist in der Lage, kleine
Programme auszuführen, die meist jeweils eine einzelne Aufgabe
erledigen.
Im Gegensatz zu anderen Entwicklungsboards muss der Mikrocon-
troller beim Arduino nicht direkt programmiert werden, der Code
wird vor dem Upload automatisch umgewandelt, erweitert und in
Maschinensprache übersetzt (kompiliert). Diese Maschinensprache
ist zwar durchaus für Menschen lesbar, aber sehr abstrakt und auf-
wendig zu programmieren.

USB-Port und USB-Chip


Der USB-Port verbindet das Board mit dem Computer. Dabei dient
er als Daten- und Stromquelle zugleich: Über das Kabel können
neue Programme hochgeladen werden, denn die 5 Volt und 0,5
Ampere, die über USB fließen, bieten genügend Strom. Der Ardu-
ino kann aber auch konstant über USB Daten austauschen, etwa
um als Steuerungselement für Computersoftware zu dienen. Da
USB ein verhältnismäßig komplexes Protokoll ist, wird die Kom-
munikation im USB-Chip umgewandelt.

18 Kapitel 1: Von Königen und Kondensatoren


Stromanschluss
Um Arduino-Programme auch unabhängig von einem Computer
laufen zu lassen, kann man auch ein Netzteil anschließen. So kann
das Board in ein größeres Projekt eingebaut werden und auch dann
laufen, wenn der Computer nicht angeschaltet ist. Optimal läuft
das Board bei 7 bis 12 Volt, wobei es dabei selbst etwa 40 mA benö-
tigt. Das kann sich aber deutlich erhöhen, wenn man zum Beispiel
LEDs an den Arduino anschließt.

Reset-Schalter
Das aktuell laufende Programm lässt sich natürlich auch neu star-
ten, wenn das Board nicht mit dem Computer verbunden ist. Dafür
dient der Reset-Schalter: Wird der rote Knopf betätigt, beendet der
Arduino alle derzeitigen Aktionen und begibt sich in den Anfangs-
zustand, den er auch beim Einschalten des Netzteils oder der USB-
Stromquelle hatte. Anschließend wird das aktuell auf dem Arduino
geladene Programm von Neuem ausgeführt.

Betriebsleuchte und Übertragungsleuchten


Ist der Arduino angeschaltet und es läuft ein Programm, so leuchtet
die mit PWR (für Power) markierte LED. Werden zwischen Ardu-
ino und Computer Daten übertragen, blinken die mit TX und RX
markierten Leuchtdioden. TX steht für Transmitter, RX für Recei-
ver, es wird also angezeigt, ob das Board gerade Daten sendet oder
empfängt.

Bootloader/ICSP-Header
Schließt man den Arduino über ein USB-Kabel an, kommuniziert
man nur mit dem sogenannten Bootloader – einem sehr kleinen
Programm, das immer auf dem Chip vorhanden ist. Sobald der
Prozessor mit Strom versorgt wird, wird es ausgeführt. Der Ardu-
ino-Bootloader ermöglicht es, über die USB-Schnittstelle ein
neues Programm hochzuladen. Dadurch, dass der Bootloader
immer zuerst ausgeführt wird, ist es möglich, auch bei einem
komplett defekten Programm wieder eine korrigierte Version
hochzuladen.
Über den ICSP-Header (In-Circuit Serial Programming) ist aber
auch die direkte Kommunikation mit dem Mikroprozessor mög-
lich. Dafür ist allerdings ein sogenannter Programmierer notwen-
dig, der an den Computer angeschlossen wird und über diese In-

Hardware 19
Circuit-Schnittstelle ein neues Programm auf den Arduino hochla-
den kann. Für die in diesem Buch erklärten Workshops ist die
Benutzung des ICSP-Header nicht nötig. Die Verwendung eines
externen Programmiergeräts wird allerdings dann gebraucht, wenn
ein neuer Bootloader auf den Arduino-Prozessor hochgeladen wer-
den soll (z.B. wenn man den Atmega168 auf einem älteren Arduino
Duemilanove durch einen Atmega328 austauschen möchte). Es ist
auch möglich, einen Arduino-Prozessor im Internet zu bestellen,
der schon mit einem Bootloader programmiert ist.

Digitale Pins
An der oberen Seite des Boards befinden sich 16 Steckplätze. 14
davon sind sogenannte digitale I/O-Pins (Input/Output). Sie sind
mit den Zahlen 0 bis 13 markiert und dienen als Anschlussmöglich-
keit für alle Sensoren und Aktoren, die zum Betrieb nur digitale Sig-
nale, also Einsen und Nullen benötigen, um etwas ein- und
auszuschalten. Dazu gehören zum Beispiel LEDs und Schalter, wie
sie in den Workshops ab Kapitel 3 verwendet werden. Sechs dieser
Pins haben zusätzlich die Beschriftung PWM. Mit dieser sogenann-
ten Pulsweitenmodulierung können beispielsweise LEDs gedimmt
werden (mehr dazu in Kapitel 3, Pulsweitenmodulierung). Beach-
ten sollte man zusätzlich, dass die Pins 0 und 1 auch für die serielle
Kommunikation mit dem Arduino (siehe Kapitel 5) verwendet wer-
den. Setzt man diese gleichzeitig als digitale Aus- oder Eingänge
ein, kann es zu merkwürdigen Nebenwirkungen kommen. Man
sollte also beachten, dass sich serielle Kommunikation und andere
Verwendung des Pins nicht in die Quere kommen. Außerdem kann
über die Pins 10 bis 13 mit dem SPI-Protokoll kommuniziert wer-
den, das allerdings nicht Bestandteil der Arduino-Sprache ist, wes-
halb es in diesem Buch nicht verwendet wird.

GND
Auf dem Board gibt es zwei Massepunkte, die als Minuspol für den
Stromkreis dienen. Sie sind mit GND (Ground) beschriftet und
befinden sich in den beiden Pinreihen oben und unten.

Analoge Pins
Die rechte Pinreihe auf der unteren Seite des Boards besteht aus
sechs Analogen Input-Ports, die in der Lage sind, analoge Signale
in digitale 10-Bit-Signale umzuwandeln. Das heißt, diese Signale
können 1.024 Werte annehmen. Dabei wird von einer maximalen

20 Kapitel 1: Von Königen und Kondensatoren


Eingangsspannung ausgehend ein Wertebereich festgelegt. Liegt
nun am Pin eine Spannung an, besteht diese aus einem Bruchteil
des Maximums. Dieser Bruchteil kann nun als Wert zwischen 0
und 1.023 weiterverarbeitet werden.

Bezugsquellen
Und woher bekommt man solch ein Arduino-Board? Natürlich aus
dem Internet.
Tatsächlich gibt es eine Handvoll Onlinehändler in Deutschland,
die sowohl den Arduino Duemilanove als auch seine Vorgänger, die
Bluetooth-Version und eine Vielzahl von Shields verkaufen. Die
Preise unterscheiden sich kaum, sodass andere Faktoren wie Ver-
sandkosten oder die zusätzliche Verfügbarkeit von Materialien eine
weitaus wichtigere Rolle spielen sollten. Eine aktuelle Liste von
deutschen Arduino-Händlern wird auf der Projektwebsite unter
[Link] geführt.
Besonders empfohlen sei das »Bausteln«-Projekt, auf dessen Web-
site [Link] nicht nur Arduino-Boards verkauft wer-
den, sondern die gesamte Philosophie behandelt wird. Die
Betreiber bieten weitergehenden Support an, veranstalten monat-
lich Baustel-Abende und arbeiten daran, eine deutsche Community
rund um Physical Computing und »Do-it-yourself«-Elektronik auf-
zubauen.

Abbildung 1-4
[Link]

Nun, da Sie vermutlich ein Arduino-Board besitzen und auch wis-


sen, wie es aufgebaut ist, kann mit der Installation der Entwick-

Hardware 21
lungsumgebung begonnen werden. Im folgenden Abschnitt wird
erklärt, wie das Arduino-Board an den PC angeschlossen und wie
das erste Programm auf dem Arduino ausgeführt wird.

Die Arduino-Entwicklungsumgebung
Installation der Arduino-Software
Die Arduino-Entwicklungsumgebung kann von der Arduino-Web-
site [Link] für alle drei gängigen Betriebssysteme
(Windows, Linux, Mac OS X) heruntergeladen werden (zum Zeit-
punkt des Schreibens dieses Buches ist die aktuelle Version ardu-
ino-018). Die Seite, die die aktuelle Version zur Verfügung stellt, ist
[Link] Dort kann das Archiv für
das jeweilige Betriebssystem heruntergeladen werden. Die Umge-
bung enthält den Arduino-Editor, die Arduino-Dokumentation
sowie eine Anzahl von Beispielprogrammen und Libraries. Im fol-
genden Abschnitt wird die Installation der Arduino-Umgebung
unter Windows und Mac OS X beschrieben. Die Installation unter
Linux ist ein bisschen komplizierter und hängt auch sehr von der
verwendeten Linux-Distribution ab. Deswegen verweisen wir auf
die Wiki-Seite zur Linux-Installation, [Link]
ground/Learning/Linux.
Nachdem die Archivdatei für die Arduino-Umgebung heruntergela-
den wurde, muss sie mit einem Doppelklick entpackt werden: Es
wird ein Ordner erzeugt, der arduino-[version] heißt. Dieser Ordner
kann jetzt an eine beliebige Stelle kopiert werden, zum Beispiel in
den Dokumentenordner oder nach C:\Program Files\ unter Win-
dows oder nach /Applications unter Mac OS X. Um Arduino zu
starten, genügt es dann, in diesem Ordner das Programm Arduino
zu öffnen. Vorher müssen allerdings noch ein paar Schritte ausge-
führt werden.
Mitgeliefert werden auch Treiber für den USB-Baustein, der auf
dem Arduino-Board installiert ist. Dieser Chip ist ein FTDI-seriell-
nach-USB-Konvertierer. Für Windows und Mac OS X sind Treiber
mitgeliefert, die installiert werden sollten, bevor das Board an den
Computer angeschlossen wird. Unter Linux sind diese Treiber
meistens schon im Distributions-Kernel enthalten. Je nachdem,
welches Arduino-Board benutzt wird (ältere Boards haben noch
keine eingebaute USB-Schnittstelle), muss ein externer USB-nach-
seriell-Adapter verwendet werden.

22 Kapitel 1: Von Königen und Kondensatoren


Installation der Treiber unter Windows
Unter Windows muss zuerst das Arduino-Board an den Computer
angeschlossen werden. Da das Betriebssystem noch keine Treiber
für die USB-Schnittstelle installiert hat, taucht der Installations-
assistent für unbekannte Hardware auf. Die automatische Installa-
tion von der Microsoft-Website und über Windows Update muss
übersprungen und die Installationsoption Von einer Liste oder
bestimmten Quelle installieren ausgewählt werden. Danach wird
die Weiter-Taste betätigt. Aktivieren Sie die Option Diese Position
auch durchsuchen und wählen Sie (über die Durchsuchen-Schalt-
fläche) den Ordner aus, in dem die lokale Arduino-Installation sich
befindet. In diesem Ordner muss der Unterordner Drivers\FTDI
USB Drivers ausgewählt werden. Anschließend kann über OK und
Weiter die Installation durchgeführt werden. Diese Schritte müs-
sen noch einmal wiederholt werden, weil die USB-nach-seriell-
Schnittstelle zwei Treiber benötigt: einen für die USB Schnittstelle
an sich und einen, um diese als seriellen Port im Betriebssystem
anzubieten.
Nach diesen Schritten können das Arduino-Board erneut an den
Computer angeschlossen und die Arduino-Entwicklungsumgebung
gestartet werden.

Installation der Treiber unter Mac OS X


Unter Mac OS X sind im Unterordner Drivers die Treiber für den
FTDI-USB-Chip zu finden. Diese heißen FTDIUSBSerialDriver_x_
x_x.dmg, wobei x_x_x für die aktuelle Versionsnummer steht.
Wird ein Macintosh-Rechner mit Intel-Prozessor verwendet (wie
bei den meisten neuen MacBooks, Mac Minis, Mac Pros und
iMacs), müssen die Treiber mit »Intel« im Namen installiert wer-
den. Wenn ein älterer Macintosh-Rechner mit G4- oder G5-Prozes-
sor verwendet wird, werden jene ohne »Intel« im Namen benötigt.
Nachdem das Disk-Image geöffnet wurde, führen Sie das Installati-
onsprogramm von FTDI aus. Die Installationsanleitung wird auf
dem Bildschirm angezeigt, und Sie werden aufgefordert, das Admi-
nistrator-Passwort einzugeben (was alles seine Richtigkeit hat,
denn es handelt sich um Systemtreiber, die mit Administratorrech-
ten installiert werden müssen). Nach der Installation ist es am sinn-
vollsten, den Rechner neu zu starten, um sicherzustellen, dass die
neuen Treiber auch geladen werden. Danach kann das Arduino-
Board an den Rechner angeschlossen werden. Funktioniert alles,

Die Arduino-Entwicklungsumgebung 23
müsste die PWR-LED grün leuchten und die LED, die mit L
gekennzeichnet ist, regelmäßig blinken. Ist das nicht der Fall, wird
in unter »Fehlersuche in Elektronischen Schaltungen« erklärt, wie
häufige Fehlerquellen zu erkennen und zu beheben sind.

Anschließen und Starten


Der Arduino Duemilanove wird mit einem USB-Kabel an den Rech-
ner und damit an die Entwicklungsumgebung angeschlossen. Als
nächster Schritt muss jetzt die Entwicklungsumgebung konfiguriert
werden, damit sie die korrekte serielle Schnittstelle benutzt und die
korrekte Boardbezeichnung verwendet. Im Tools-Menü der Ardu-
ino-Umgebung muss im Untermenü Serial Port die serielle Schnitt-
stelle ausgewählt werden, an die das Arduino-Board angeschlossen
ist. Unter Mac OS X heißt diese Schnittstelle meistens /dev/cu.
usbserial-x.

Abbildung 1-5
Der Windows Gerätemanager

Unter Windows ist dieser Schritt ein bisschen komplizierter, weil


Windows standardisierte Namen mit COMX: an alle seriellen
Schnittstellen vergibt. Um den genauen Namen der Arduino-USB-
Schnittstelle zu finden, muss der Gerätemanager gestartet werden
(über START → EINSTELLUNGEN → SYSTEMSTEUERUNG → COMPU-
TER). Unter dem Eintrag Ports (COM & LPT): werden die USB-
Schnittstelle des Arduino und der entsprechende COMX:-Name

24 Kapitel 1: Von Königen und Kondensatoren


angezeigt. Eine Eigenart von Windows ist, dass diese Bezeichnung
sich ändert, wenn das Arduino-Board an eine andere USB-Schnitt-
stelle des Computers angeschlossen wird.
Im nächsten Schritt muss noch das korrekte Arduino-Board einge-
richtet werden. Durch diese Einstellung weiß die Arduino-Entwick-
lungsumgebung, welcher Prozessor und welche Pin-Konfiguration
auf dem Arduino-Board verwendet werden. Unter dem Tools-Menü
müssen Sie im Untermenü Board das korrekte Board auswählen. Im
Fall des Arduino Duemilanove muss sichergestellt werden, dass
auch der korrekte Prozessor ausgewählt wird. Ältere Arduino Due-
milanove-Boards benutzten den Atmega168-Prozessor, während
neuere Boards den Atmega328-Prozessor verwenden.

Abbildung 1-6
Boardkonfiguration

Falls die entsprechende Board-Option nicht im Untermenü vorhan-


den ist, muss eine neuere Version der Arduino-Entwicklungsumge-
bung heruntergeladen werden.

Die Arduino-Entwicklungsumgebung
Das Fenster der Umgebung besteht aus drei Hauptbestandteilen,
nämlich der Symbolleiste und zwei Fenstern für den Programm-
code und die Kommunikation mit dem Arduino. Das schwarze
Kommunikationsfenster wird auch »Konsole« genannt.
Nachdem das Kabel verbunden wurde, müssen Sie in der Program-
mierumgebung das Board und den seriellen Port, also die Verbin-
dung, unter der die Kommunikation laufen soll, auswählen. Beide
Menüpunkte finden sich unter Tools.

Die Arduino-Entwicklungsumgebung 25
Die Symbolleiste
Die Symbolleiste besteht aus acht Symbolen, von denen mindestens
drei aus fast jedem anderen Programm bekannt sein sollten.

Abbildung 1-7
Die Symbolleiste

Abbildung 1-8 Das Symbol New öffnet einen neuen Sketch. Als »Sketches« werden
Das Symbol New Programme bezeichnet, wobei jedes Programm aus mehreren
Dateien bestehen kann. Dieser Sketch ist komplett leer. Wird
gerade ein anderer Sketch bearbeitet, sollte dieser gespeichert wer-
den, wobei das Programm dabei auch noch einmal nachfragt.

Abbildung 1-9 Das Symbol Open File öffnet einen gespeicherten Sketch. Damit
Das Symbol lassen sich auch Bibliotheken, die aus dem Netz heruntergeladen
Open File wurden, im Arduino-Programm ansehen und bearbeiten. Generell
werden alle Sketches als Dateien gespeichert, sodass sie auch mit
anderen Nutzern ausgetauscht werden können.

Abbildung 1-10 Das Symbol Save speichert den aktuellen Sketch. Gerade beim Pro-
Das Symbol Save grammieren ist es hier wichtig, daran zu denken, dass man alle Ver-
sionen, die man ausprobiert, getrennt abspeichert. Oft kommt man
erst nach langem Probieren darauf, dass ein Teil der ersten Version
eine gute Lösung war.
Die restlichen Symbole sind in zwei Gruppen aufgeteilt: die Steue-
rung des Arduino sowie die Kommunikation mit ihm. Die Pro-
grammsteuerung ist dabei recht einfach.

Abbildung 1-11 Mit diesem Knopf wird der aktuelle Sketch kompiliert, also in
Das Symbol Verify Maschinensprache übersetzt, und dabei auf seine Korrektheit über-
prüft. Das Ergebnis des Kompiliervorgangs sowie die Größe des
erzeugten Programms werden in der Konsole angezeigt. Damit
kann überprüft werden, ob das Programm auch in den Speicher des
Arduino passt (die Arduino-Variante mit Atmega168 hat 16 KByte
CodeSpeicher, von denen 2 KByte vom Arduino-Bootloader belegt
sind. Es sind also 14 KByte für den kompilierten Sketch übrig. Die
Arduino-Variante mit Atmega328 hat 32 KByte Codespeicher, von
denen 30 KByte für den kompilierten Sketch übrig sind). Ein Sketch
belegt allerdings nicht nur Codespeicher, sondern auch Arbeitsspei-
cher. Dieser wird nach der Kompilierung als »data« angezeigt. Die

26 Kapitel 1: Von Königen und Kondensatoren


Arduino-Variante mit Atmega168 hat 2 KByte Arbeitsspeicher, die
Arduino-Variante mit Atmega328 4 KByte. Es ist wichtig, sicherzu-
stellen, dass genügend Speicher vorhanden ist. Ansonsten kann sich
das Programm sehr merkwürdig verhalten. Nun kann man mit dem
Upload-Knopf das Programm auf das Board laden.

Das Stop-Symbol beendet das laufende Programm auf dem Ardu- Abbildung 1-12
ino. Der Arbeitsspeicher wird anschließend gelöscht, sodass bei Das Symbol Stop
einem erneuten Start der gesamte Programmablauf wieder von vorn
beginnt.

Das Upload-Symbol verarbeitet (»kompiliert«) den aktuellen Abbildung 1-13


Sketch in Maschinencode und lädt ihn auf den Arduino. Er funktio- Das Symbol Upload
niert also wie der Verify-Knopf, transportiert das Programm jedoch
danach auf den Arduino. Anschließend wird auf dem Board ein
Reset ausgeführt und damit begonnen, den Sketch abzuspielen.

Die Konsole dient als Kommunikationskanal zwischen dem Ardu- Abbildung 1-14
ino und der Programmierumgebung, sobald das Programm einmal Das Symbol Console
hochgeladen und gestartet ist. Dabei können Daten mit bis zu 9.
600 Bits pro Sekunde ausgetauscht werden, was genug ist, um
Kommandos an den Arduino zu senden und Informationen zu
empfangen. Eine genauere Erklärung der Kommunikation über die
serielle Konsole findet sich in Kapitel 6.

Das Codefenster
Bevor mit der eigentlichen Programmierung in der Arduino-Umge-
bung begonnen wird, wird ein Beispielprogramm auf das Arduino-
Board hochgeladen. Dazu wird eins der Beispiele, die mit der
Umgebung mitgeliefert werden, geöffnet. Über FILE → SKETCH-
BOOK → EXAMPLES können diese Beispiele ausgewählt werden. Wie
man sehen kann, wird schon eine große Menge von Beispielen mit-
geliefert, die man sich als Anregung und als Anleitung anschauen
kann. Zum Testen der Umgebung laden Sie über DIGITAL → BLINK
das Programm Blink, das die LED, die sich auf dem Arduino-Board
befindet, blinken lässt. Nachdem die Datei geöffnet ist, kann sie
übersetzt und auf das Arduino-Board hochgeladen werden. Dazu
muss der Upload-Knopf betätigt werden. Das Kompilieren kann
ein paar Sekunden dauern, danach beginnen die RX- und TX-LEDs
auf dem Arduino-Board zu flackern (was bedeutet, dass das über-
setzte Programm übertragen wird). Nach einen paar weiteren
Sekunden wird das Programm dann auch ausgeführt: Die LED

Die Arduino-Entwicklungsumgebung 27
beginnt zu blinken und die Arduino-Entwicklungsumgebung zeigt
Upload Completed an. Falls es Probleme beim Hochladen gibt, mel-
det die Umgebung in der braunen Zeile den Fehler. Als Erstes sollte
dann überprüft werden, ob das Arduino-Board korrekt an den
Computer angeschlossen ist und ob das richtige Board und die
richtige serielle Schnittstelle eingestellt wurden. Weitere mögliche
Probleme werden unter »Fehlersuche« in Kapitel 2 behandelt.
Code wird in der Arduino-Umgebung geschrieben wie in jedem
anderen Texteditor auch. Dabei wird das sogenannte Syntax High-
lighting unterstützt: Einzelne Programmelemente werden als sol-
che erkannt und so eingefärbt, dass sie sich leicht erkennbar von
den anderen unterscheiden. So lassen sich Fehler schon beim
Schreiben des Codes vermeiden. Beim Speichern einer Datei wird
diese in einem eigenen neuen Ordner unterhalb des sogenannten
Sketchbook (also Skizzenbuch) gespeichert. Das Verzeichnis für
das Skizzenbuch wird beim ersten Starten von der Arduino-Ent-
wicklungsumgebung erstellt (unter Mac OS X unter Dokumente/
Arduino, unter Windows in Eigene Dateien\Arduino. Der Pfad zu
diesem Verzeichnis kann leicht in den Einstellungen von Arduino
geändert werden (unter Mac OS X über ARDUINO → PREFERENCES,
unter Windows und Linux FILE → PREFERENCES). Dort lässt sich
auch einstellen, ob jede neue Datei zuerst benannt werden soll
(was sehr praktisch ist, weil das Skizzenbuch sich sonst schnell mit
vielen »sketch_XXX« benannten Dateien füllt) und ob leere
Dateien beim Verlassen der Umgebung gelöscht werden sollen.
Weitere Einstellungen für fortgeschrittene Benutzer können in der
Datei [Link], deren Pfad bei den Arduino-Einstellungen
angezeigt wird, von Hand mit einem normalen Texteditor einge-
tragen werden.

Mit dem Programmieren beginnen


Nun ist alles vorbereitet, um mit der Programmierung des Arduino
zu beginnen. In den folgenden Kapiteln sollen einzelne Workshops
nach und nach die Programmiersprache, aber auch die elektroni-
schen und physikalischen Grundlagen erklären. Dabei genügt
unser Platz natürlich nicht, um ausführlich große Basteleien zu
erläutern. Aber das, was erklärt wird, reicht aus, um anschließend
weitergehende Ideen zu verwirklichen. Zudem sind die einzelnen
Übungen so angelegt, dass sie in kurzer Zeit und mit wenig Mitteln
selbst ausprobiert werden können: Alle Bauteile sind günstig und
im normalen Elektronikfachhandel erhältlich, wenn sie nicht sogar,

28 Kapitel 1: Von Königen und Kondensatoren


etwa aus Drähten, selbst hergestellt werden können. Eine umfas-
sende Referenz zur Arduino-Programmiersprache finden Sie im
Anhang. Sie erklärt strukturiert und ausführlich alle Bestandteile
der Sprache und ist somit auch zum schnellen Nachschlagen geeig-
net, wenn Sie weitere Ideen ausprobieren wollen.
Um die Workshops sinnvoll auszuprobieren, empfiehlt es sich, eine
Arbeitsecke einzurichten. Hier sollte genügend Platz frei sein, um
Drähte zu schneiden und Bauteile zu verlöten. Nach jedem Basteln
ist es auch wichtig, diesen Platz wieder sauberzumachen, denn am
nächsten Tag hat man schon mal Probleme damit, eine halb fertig
liegengelassene Schaltung noch zu verstehen.
Zudem erklärt ein kleiner Exkurs die physikalischen Grundlagen
rund um Spannung, Stromstärke und Widerstand. Außerdem wird
der Begriff des Physical Computing ein wenig präzisiert, wozu
auch ein Ausblick auf bekannte und interessante Arduino-Projekte
gehört.

Die Arduino-Entwicklungsumgebung 29
KAPITEL 2 In diesem Kapitel:
• Elektrische Grundlagen
Physical Computing, • Schaltungen, Bauteile und
Schaltbilder

elektrische Grundlagen und • Löten


• Fehlersuche in elektronischen
Schaltungen
der Sprung ins kalte Wasser

Physical Computing ist die Verbindung von physikalischen Syste-


men mit Software und Hardware zu einem interaktiven Ganzen.
Oft wird ein Computer immer noch als Gerät betrachtet, das nur
über den Bildschirm und die Tastatur zu bedienen ist und Pro-
gramme ausführt. In diesem Buch wird aber nicht mit Computern
und Computerprogrammen gearbeitet, sondern mit dem allgemei-
neren Konzept des »informatischen Rechnens« (englisch »compu-
ting«). Mittlerweile sind in vielen alltäglichen Gegenständen kleine
eigenständige (eingebettete) Computer, oder Mikrocontroller, ein-
gebaut, die über physikalische Schnittstellen mit Umfeld und
Benutzer kommunizieren. Diese Schnittstellen unterscheiden sich
oft sehr von Tastatur, Maus und Display. So steckt zum Beispiel in
einer Kaffeemaschine ein kleiner Computer, der zwar über ein Dis-
play und Tasten mit dem Benutzer kommuniziert, aber gleichzeitig
auch über Temperatursensoren und Feuchtigkeitssensoren das
Kochen von Kaffee überwacht, über einen Motor Kaffeebohnen
mahlen und mit verschiedenen Pumpen und Druckventilen Wasser
erhitzen und Milchschaum erzeugen kann. Beim Physical Compu-
ting geht es also um die Verbindung von Rechnen und Rechnern
auf der einen Seite und der realen Welt auf der anderen. Mehr und
mehr Gegenstände werden so zu kleinen intelligenten Geräten: eine
elektrische Zahnbürste, die verschiedene Programme kennt, eine
Lampe, die sich nur anschaltet, wenn Menschen anwesend und
wach sind, ein Kühlschrank, der seinen eigenen Inhalt und Strom-
verbrauch überwacht und seinem Besitzer meldet, wenn bestimmte
Ware nachbestellt werden muss.

31
Der Vorteil dieser intelligenten Geräte ist, dass man den Umgang
mit ihnen deutlich flexibler gestalten kann. So werden viele kleine
Vorgänge auf den Benutzer direkt angepasst. Schließt man einen
Schalter an eine Lampe an, ohne einen Mikrocontroller einzuset-
zen, lässt sich kaum mehr erreichen, als dass man durch Betätigen
des Schalters das Licht an- oder ausschaltet. Mit einem Mikrocont-
roller kann man allerdings das Licht zum Beispiel für eine
bestimmte Zeit nach einem Schalterdruck anschalten (ähnlich wie
mit einer Zeitschaltuhr), oder nur dann, wenn andere Lichter schon
aus sind. Es ist auch möglich, über diesen einen Schalter deutlich
kompliziertere Vorgänge zu erkennen: Der Benutzer kann etwa
durch langes Drücken auf den Schalter den Zeitschaltmodus akti-
vieren oder die Lampe regelmäßig blinken lassen. Solche einfachen
Lichtsteuerungen findet man heutzutage in jeder Fahrradbeleuch-
tung: Die unterschiedlichen Blinkmuster lassen sich ohne »Rech-
nen« nicht einfach bauen.
Der Arduino-Prozessor ist ein gutes Beispiel für einen solchen
Mikrocontroller. Er verfügt über genügend Rechenleistung, um die
meisten Anwendungen locker zu erledigen, und hat mit seinen Aus-
und Eingängen Platz für Sensoren und Aktoren, mit denen viele
Projekte umgesetzt werden können.
Der Begriff »Physical Computing« beschreibt diese Kommunika-
tion zwischen Benutzer und einem physikalischen elektrischen
Gerät. Dieses kann eingehende Information (auf Englisch »Input« )
verarbeiten und anhand eines Programms in eine Reihe von Aus-
gangssignalen (auf Englisch »Output«) umwandeln. Ziemlich jedes
Programm kann als fortgehende Schleife dargestellt werden, die
Input zu Output verarbeitet. Dieser Ansatz wird auch in der Struk-
tur von Arduino-Programmen deutlich, wie Sie im entsprechenden
Abschnitt am Ende dieses Kapitels sehen werden.
Input erlaubt der realen Welt, mit dem Computer zu kommunizie-
ren. Sensoren können ihre Umwelt wahrnehmen und in Signale
verwandeln, die der Rechner verstehen kann. Dabei unterscheidet
man zwischen digitalem Input, der nur zwei Zustände (An und
Aus) kennt, und analogem mit einer Vielzahl von Zwischenwerten.
Neben Sensoren gehören zum Input auch all jene Bauteile, über die
ein Mensch Eingaben machen kann, wie etwa Schalter.
Die Ausgänge (oder auch der Output) ermöglichen es, die reale
Welt in der Umgebung des Computers zu verändern. Aktoren

32 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
manipulieren Licht und Ton oder setzen Dinge in Bewegung. Gene-
rell ist der Output dabei der schwierigere Teil des Physical Compu-
ting, weil er oft auch vom Erschaffer verlangt, dass dieser sich mit
den elektrischen und mechanischen Eigenschaften seiner Aktoren
auskennt und sie sinnvoll einsetzt. Es ist zum Beispiel viel einfa-
cher, die Umgebungshelligkeit zu messen, als sie mit richtig positi-
onierten und angesteuerten Lichtern zu verändern. Zum Output
zählt es aber auch, dass Bilder auf Monitoren angezeigt oder Töne
an Soundkarten ausgegeben werden, ein Mikrocontroller also wei-
tere angeschlossene Chips (und unter Umständen auch eigenstän-
dige Computer bzw. Mikrocontroller) steuert. Die gängigsten
Sensoren und Aktoren werden in Kapitel 7 vorgestellt.
Ein wichtiger Bereich des Physical Computing ist die Erweiterung
der Benutzerschnittstelle herkömmlicher Desktop-Computer.
Normale Software wird angepasst, damit sie mit physikalischen
Gegenständen interagieren kann. Dafür kann zum Beispiel die
Programmierumgebung Processing verwendet werden, die sich als
Schnittstelle zwischen Input und Output anbietet. Processing
besteht aus einer einfachen Programmiersprache, die vor allem die
Entwicklung von grafischen Programmen sehr leicht macht. In
diesem Buch taucht Processing deshalb an vielen Stellen auf, zum
Beispiel in Kapitel 5. Processing ist eng mit der Arduino-Program-
mierumgebung verwandt, in der Tat handelt es sich bei Arduino
um eine Weiterentwicklung davon, um Programme auf Mikrocon-
trollern schreiben zu können.
Ein Beispiel für eine solche Benutzerschnittstellenerweiterung sind
die Multitouch-Oberflächen, die es dem Benutzer erlauben, mit
mehreren Fingern oder Händen direkt mit einem Bildschirm zu
interagieren. Solche Oberflächen erinnern an den Film »Minority
Report«, und es gibt im Internet beeindruckende Videos auf den
Seiten der Forschungsgruppen, die sich mit diesem Konzept
beschäftigen. Sie lassen sich relativ einfach mit Kameras und Bea-
mern bauen und erobern zum Beispiel als Multitouch-Tische die
Museen und Bühnen dieser Welt. Es wird nicht mehr lange dauern,
bis wir diese auch in der freien Wildbahn beobachten können (das
iPhone und das iPad von Apple sind ein gutes Beispiel für diese
Technologie). Neue Eingabegeräte bedeuten auch einen neuen
Umgang mit Computern, die mit der Zeit immer weniger als solche
wahrgenommen werden.

Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser 33
Abbildung 2-1
Multitouch-Tisch: Reactable
(Foto: Xavier Sivecas Saiz)

Auch die großen Firmen haben die alternativen Eingabegeräte für


sich entdeckt, vom EyeToy von Sony, das Bewegungen des Spielers
über eine Kamera verfolgt, über Dance Dance Revolution, das den
Spieler zu mehr oder weniger echten Tanzschritten animiert und
diese als Grundlage für den Spielverlauf nimmt, bis hin zur Wii, die
Kamera und Bewegungssensoren kombiniert. Von Microsoft soll
Ende 2010 das Project Natal für die XBOX erscheinen, mit dem
über Kameras die Bewegungen der Nutzer in nie dagewesener Prä-
zision verarbeitet werden können. Allen gemeinsam ist der Trend,
sich von althergebrachten Konzepten zu lösen und neue Wege der
Benutzerinteraktion zu beschreiten.
Physical Computing harmoniert wunderbar mit Forschung und
Lehre: Studenten wird ein möglichst einfacher und vor allem inter-
essanter Einstieg in die Technik gegeben. Die Studenten wiederum
lassen sich von den schier unbegrenzten Möglichkeiten inspirieren
und entwickeln in Seminaren oder als Abschlussarbeiten die erstaun-
lichsten Projekte. Waren die Programmierung von Computern und
das Arbeiten mit elektrischen Bauteilen über Jahrzehnte eine
Domäne der Fakultäten für Informatik, Physik und Elektrotechnik,
ist es nun auch Kunst- und Designhochschulen möglich, ihre Kreati-
vität in eine weitere Dimension voranzutreiben. Interdisziplinäre
Gruppen rund um den Globus entwickeln dabei Technologien, die
schon bald auch in unseren Alltag übergehen werden, wobei sie die
Industrie oft vor sich hertreiben.

34 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Zunächst benötigt man für einen Einstieg in das Physical Compu-
ting jedoch einige Grundlagen, die im Folgenden erklärt werden.
Dabei geht es zunächst um die Physik von Schaltungen und
Stromkreisen, die Vorstellung häufig gebrauchter Bauteile und
Werkzeuge sowie die Einführung ins Basteln, Löten und in die
Fehlersuche. Im Anschluss folgt ein kurzer Überblick über die
Arduino-Programmiersprache und die dazugehörige Software.

Elektrische Grundlagen
Der Kern aller Physical-Computing-Projekte ist der elektrische
Schaltkreis. Alle Eingangs- und Ausgangsschnittstellen kommuni-
zieren über elektrische Signale. Diese Signale übermitteln sowohl
Information, indem diese in elektrische Werte codiert wird, als
auch Energie, um z.B. Licht oder mechanische Kraft zu erzeugen
(um Gegenstände zu bewegen oder Klänge zu generieren). Ein elek-
trischer Schaltkreis (auch Stromkreis genannt) besteht aus Bautei-
len, die eine gewisse Funktion erfüllen und mit diesen elektrischen
Signalen umgehen, sowie aus Verbindungen, die diese einzelnen
Bauteile miteinander verknüpfen.

Elektrische Größen: Strom, Spannung, Widerstand


In einem Stromkreis gibt es drei wichtige Größen, die im Folgenden
kurz näher beschrieben werden.
Die Spannung, gemessen in Volt, ist der relative Unterschied der
Energie zwischen zwei Punkten. Vergleicht man die Elektrizität mit
Wasser, dann entspricht die Spannung dem Wasserdruck in einer
Leitung. Nur wenn der Wasserdruck an einer Stelle höher ist als an
der anderen, fließt es auch durch eine Verbindung der beiden Stel-
len. Zum Beispiel fließt von einem Berg (hohe Spannung) das Was-
ser von oben nach unten. Das Gleiche passiert bei der Elektrizität:
Auch hier benötigen wir einen Spannungsunterschied, damit ein
Strom fließen kann. In einer Schaltung gibt es meistens einen Punkt
(GND oder ERDE genannt), der als Referenz für alle Spannungs-
messungen gilt. Bei einfachen Schaltungen verwendet man den
tiefstmöglichen, also null, für diesen Zweck, sodass alle Spannun-
gen in der Schaltung positiv sind. Wichtig ist, sich bei Spannungs-
angaben immer zu merken, dass damit eine Differenz zwischen
zwei Punkten gemeint ist.

Elektrische Grundlagen 35
Strom ist die Menge der elektrischen Energie, die durch eine Ver-
bindung in der Schaltung fließt, und wird in Ampere gemessen.
Elektrischer Strom ist eigentlich die Bewegung von Abermillionen
kleiner Partikel, die eine elektrische Ladung tragen: den Elektro-
nen. Diese fließen von einem Punkt mit hoher elektrischer Energie
(also hohem elektrischen Potenzial) zu einem Punkt mit niedriger.
Im Wasserbeispiel entspricht der Strom der Menge des Wassers,
die innerhalb einer konstanten Zeit durch eine Röhre fließt. Damit
Strom von einer Stelle in einer Schaltung zu einer anderen Stelle
fließen kann, müssen diese beiden Stellen verbunden werden, zum
Beispiel mit einem Draht oder auch einem Bauteil; eine Lampe
stellt auch eine Verbindung dar, durch die der Strom fließen kann.
Alle Teile einer Schaltung, durch die Strom fließt, stellen für den
Strom unterschiedlich große Hindernisse dar: den Widerstand,
gemessen in Ohm. Durch diese Strombegrenzung wird elektrische
Energie umgewandelt. Ein einfacher Widerstand z.B. wandelt die
Energie, die an ihm abfällt, einfach in Wärme um, während andere
Bauteile Energie etwa in Bewegung (wie ein Motor) oder in Licht
(LEDs und Lampen) umsetzen können. Digitale Bauteile benutzen
diese Energie, um Berechnungen auszuführen. Drähte und Verbin-
dungen auf einer Platine haben einen sehr geringen Widerstand, sie
begrenzen den Stromfluss fast nicht. Schließt man zwei Punkte mit
unterschiedlichen elektrischen Potenzialen über einen Draht zusam-
men, wird nur wenig Widerstand in den Weg gestellt, es fließt ziem-
lich viel Strom und es kommt zu einem Kurzschluss. Im besten Fall
greifen dann Schutzmechanismen: Beim Arduino-Board, das über
USB seinen Strom bekommt, wird der Strom dann vom angeschlos-
senen Rechner gekappt. In einer Wohnung springen dann meist die
Sicherungen heraus. Es ist allerdings auch möglich, mit Kurzschlüs-
sen Bauteile zu beschädigen oder sich selbst zu gefährden, weshalb
man beim Zusammenbauen von elektrischen Schaltungen immer
vorsichtig vorgehen sollte. Man sollte lieber ein zweites Mal über-
prüfen, ob auch keine Kurzschlüsse erzeugt werden.
Ein sehr einfacher Schaltkreis wäre z.B. eine Glühbirne, die an eine
Stromquelle angeschlossen ist. Um die Lampe ein- und ausschalten
zu können, wird noch ein Schalter in den Schaltkreis eingebaut.
Dieser ist ein Bauteil, das eine elektrische Verbindung erzeugen und
trennen kann: Ist er offen, besteht keine elektrische Verbindung,
und es kann auch kein Strom durch den Schalter fließen; ist er
geschlossen, verhält er sich wie ein Draht, und der Strom fließt hin-
durch. Die Lampe verhält sich wie ein Widerstand, der den Strom-

36 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
fluss begrenzt und die Energie des Stroms in Licht und Hitze
umwandelt.
Jedes Bauteil im Schaltkreis braucht eine gewisse Menge Strom, um
seine Aufgabe zu erledigen. Bekommt die Glühbirne nicht genug
davon, wird der Draht, der das Licht erzeugt, nicht heiß genug, und
die Birne leuchtet nicht. Bekommt sie aber zu viel Strom, brennt
der Draht durch und die Glühbirne ist danach defekt. Die Menge
Strom, die durch ein Bauteil fließt, und die Spannung, die an ihm
anliegt, müssen also genau eingestellt werden.

Abbildung 2-2
Anschließen einer Lampe

Ohmsches Gesetz
Um Strom und Spannung in einem Schaltkreis zu berechnen, lassen
sich folgende Formeln einsetzen, die die drei elektrische Größen
verbinden. Diese Formeln sind auch die am häufigsten gebrauchten,
um Schaltungen zu entwerfen, und nach einer gewissen Zeit entwi-
ckelt man auch ein Bauchgefühl, wie ein Schaltkreis zu entwerfen
ist. Sie werden auch Ohmsches Gesetz genannt und lauten wie folgt:
U (Spannung) = R (Widerstand) × I (Strom)
oder wenn man das Ganze umformt:
I (Strom) = U (Spannung) / R (Widerstand)
Anschaulich lassen sich diese Formeln wie folgt beschreiben: Je
höher die Spannung zwischen zwei Punkten, desto mehr Strom

Elektrische Grundlagen 37
wird zwischen ihnen fließen, wenn sie zusammengeschlossen wer-
den. Je größer der Widerstand zwischen diesen zwei Punkten,
desto weniger Strom wird fließen. Wird also eine Spannung an ein
Bauteil angeschlossen, fließt genau so viel, wie der Widerstand des
Bauteils zulässt.
Als Beispiel wird ein Bauteil (Glühbirne) mit einem Widerstand
von 15 Ohm verwendet (Im Zweifelsfall kann der genaue Wider-
stand mit einem Messgerät ermittelt werden) und es an eine Span-
nungsquelle von 5 Volt angeschlossen. Die URI-Formel ergibt:
I = 5 Volt / 15 Ohm → I = 0,33A
Bevor man das tatsächlich anschließt, sollte man auf der Glühbirne
nachsehen, ob sie einen Strom von 0,33A verträgt. Bei 5V ent-
spricht das P = 5 Volt × 0,33A → 1,65 Watt
Befinden sich in einer Schaltung mehrere Bauteile hintereinander,
so wird ihr Widerstand einfach addiert. Der Strom wird bei jedem
Bauteil ein bisschen stärker eingeschränkt. So lässt sich auch der
Strom einstellen, der durch eine Glühbirne fließt; man begrenzt
ihn, damit der Draht der Glühbirne nicht durchbrennt. Bei Bautei-
len, die hintereinander angeschlossen werden, sagt man, dass sie in
Serie geschaltet sind. Der Gesamtwiderstand der in der Abbildung
gezeigten Schaltung ist also
R (Gesamt) = R (Widerstand) + R (Glühbirne)

Abbildung 2-3
Widerstand und Glühbirne in Serie

Eine wichtige Anwendung von in Serie geschalteten Widerständen


ist eine Schaltung, die man Spannungsteiler nennt. Werden zwei
Widerstände mit den Werten R1 und R2 in Serie geschaltet und an
ihren Enden eine definierte Spannung U angelegt, so fließt durch
beide derselbe Strom, der durch I = U / (R1 + R2) gegeben ist.

38 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Dadurch fällt an jedem Widerstand also eine Spannung ab, die pro-
portional zu seinem Widerstandswert ist. Die Spannung an der
Stelle A im Bild ist also UA = U × (R2 / (R1 + R2)). Diese Schaltung
wird sehr oft benutzt, um zum Beispiel definierte Referenzspannun-
gen zu erzeugen, eine Spannung zu skalieren oder um resistive
Sensoren, also jene, die sich wie ein veränderbarer Widerstand ver-
halten, auszulesen.
Ein Spannungsteiler aus zwei gleich großen Widerständen teilt also
eine Spannung genau in der Mitte, aus 5 Volt werden 2,5V. Aller-
dings nur so lange, wie kein oder fast kein Strom von dieser Mitte
aus woanders hinfließt.

Abbildung 2-4
Spannungsteiler

Bauteile können auch parallel angeschlossen werden, man spricht


dann davon, dass sie parallel geschaltet sind. In diesem Fall teilt
sich der Strom in mehrere Wege auf und fließt abhängig vom ihren
einzelnen Widerständen.

Leistung
Eine weitere wichtige Größe ist die Leistung, die in Watt gemessen
wird. Die Leistung gibt an, wie viel Energie ein Bauteil verbraucht,
wenn es in einem Schaltkreis angeschlossen ist und Strom durch
ihn fließt. Die Leistung, die ein Bauteil benötigt, kann berechnet
werden, indem man die Spannung an seinen Anschlüssen mit dem
fließenden Strom multipliziert, der durch ihn fließt. Dadurch lässt
sich auch berechnen, wie viel Strom und Spannung notwendig
sind, damit ein Bauteil seine Aufgabe erledigen kann. So braucht
eine 60-Watt-Glühbirne bei einer Spannung von 12V also 5A
Strom, damit sie mit ihrer vollen Helligkeit leuchtet.
Die Leistung ist auch wichtig, um zu wissen, wie viel Strom und
Spannung ein Bauteil verträgt, bevor es durchbrennt. Ein handels-
üblicher Widerstand verträgt zum Beispiel 0.125 bis 0.25 Watt. Da
Energie niemals ohne Weiteres vernichtet werden kann (obwohl es
einem oft so vorkommt), muss der Widerstand diese Leistung als
Wärme wieder abgeben, er wird also heiß. Kann die Wärme nicht

Elektrische Grundlagen 39
schnell genug an die Umgebung (Luft oder Kühlkörper) abgegeben
werden, wird der Widerstand so heiß, dass er zerstört wird. Dabei
können sogar Gegenstände in seiner Umgebung in Brand geraten.

Sicherheitsregeln
Für Menschen sind Ströme von mehr als 5 bis 10 mA sehr gefähr-
lich. Für Spannungen kleiner als 48 Volt kann im Normalfall davon
ausgegangen werden, dass nichts passieren kann, da der Wider-
stand eines Menschen zu groß ist, um bei einer solchen Spannung
so viel Strom fließen zu lassen.
Die auf dem Arduino-Board verwendeten Spannungen von 5 und 3
Volt stellen keine Gefahr für den Menschen dar. Trotzdem sollten
direkte Verbindungen zum Menschen (Berührung, EEG usw.) min-
destens mit einem 100kOhm-Widerstand in Reihe abgesichert wer-
den, wenn das Arduino-Board nicht aus einer Batterie versorgt
wird. Niemand kann garantieren, dass das Netzteil (z.B. im ange-
schlossenen PC) bei einem Defekt sicher bleibt. So können im
Ernstfall plötzlich 230 Volt aus der Steckdose an der Schaltung
anliegen.
Für Experimente mit höheren Spannungen sollte unbedingt ein
Experte herangezogen werden. Mindestens aber sollte immer eine
Fehlerstromsicherung verwendet werden. Diese Sicherungen sind
als Zwischenstecker in Baumärkten erhältlich und trennen die Ver-
bindung, sobald ein Strom von mehr als 10 bis 30mA über die
Hand fließt.
Ist es unumgänglich, an einer unter Spannung stehenden Schaltung
zu arbeiten, sollte eine Hand immer hinter den Rücken gehalten
werden: So wird ein gleichzeitiges Berühren mit beiden Händen
verhindert und somit ein Stromfluss direkt durch das Herz ver-
mieden. Schlimme Unfälle passieren häufig dadurch, dass eine
Hand am geerdeten Metallgehäuse ist, während die andere ein
Strom führendes Teil berührt.

Analoge und digitale Schaltungen


Bei elektrischen Schaltungen wird oft zwischen rein elektrischen
Schaltungen und elektronischen Schaltungen unterschieden. Als
elektrische Schaltungen bezeichnet man im allgemeinen Schaltun-
gen, die ohne Halbleiter auskommen (Transistor, IC). Eine Lampe
mit einem Schalter ist zum Beispiel eine elektrische Schaltung.

40 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
In elektronischen Schaltungen werden oft Spannungen und Ströme
verwendet, um Informationen zu übermitteln, ohne dass man mit
dieser Energie direkt etwas antreiben möchte. Deshalb können
diese Ströme sehr viel kleiner sein. So kann zum Beispiel ein Audio-
signal als Spannung kodiert und in einer elektronischen Schaltung
verändert werden (z.B. um die Anteile an Höhen und Bässen einzu-
stellen, oder die Lautstärke). Erst im letzten Schritt wird dieses
Spannungssignal dann so verstärkt, dass damit große Lautsprecher
angesteuert werden können. Zur Verstärkung und Manipulation
dieser Signale werden Transistoren eingesetzt. Für viele Aufgaben
gibt es integrierte Schaltungen (ICs, integrated circuits), die diese
Leistungstransistoren ersetzen. Diese werden meistens Treiber
genannt. Diese integrierten Schaltungen können mehrere Millionen
einzelne diskrete Bauteile enthalten (wie z.B. Transistoren) und
werden in kleinen Plastikgehäusen mit Anschlusspins geliefert.
Diese Bauteile nennt man Chips, und es gibt sie von sehr einfachen
Varianten, die nur eine Handvoll Transistoren enthalten, über
komplizierte mikromechanische Sensoren (wie z.B. den Beschleu-
nigungssensor) bis hin zu großen Prozessoren wie z.B. einem Pen-
tium-Prozessor.
In elektronischen Schaltungen werden oft Spannungen eingesetzt,
die nur zwei Werte annehmen können: hohe Spannung (auch
HIGH-Spannung) und niedrige (auch LOW-Spannung). Diese zwei
unterschiedlichen Spannungen werden verwendet, um sogenannte
Bits zu codieren: 0 oder 1. Man spricht auch von diskreten Span-
nungswerten, weil es sich um zwei klar getrennte und definierte
Spannungen handelt, im Unterschied zu kontinuierlichen Span-
nungswerten, die über den gesamten Bereich von GND bis VCC
gehen. Diese Codierung, d.h. Darstellung von Information in Span-
nung, in diskrete Werte nennt man auch digitale Codierung (und
die verwendeten Spannungen werden digitale Spannungen
genannt), im Vergleich zur analogen Codierung (wie sie z.B. für
Audiosignale in einem Verstärker verwendet wird). Der größte Vor-
teil der digitalen Codierung ist, dass sich mit ihr Informationen
»exakt« übermitteln lassen. Eine analoge Spannung ist immer mit
Rauschen behaftet, das etwa durch die Umgebung erzeugt wird. Je
mehr eine analoge Spannung bearbeitet und übertragen wird, desto
stärker ist dieses Rauschen. Das lässt sich am besten mit analogen
Audioaufnahmen verdeutlichen: Eine Audiokassette oder eine
Schallplatte speichert analoge Informationen und wird mit der Zeit
und der Abnutzung immer schlechter. Je länger das benutzte Kabel
ist, das zum Anschluss des Abspielgeräts dient, desto schlechter

Elektrische Grundlagen 41
wird auch der Klang. Im Unterschied zu analogen Signalen lassen
sich digitale Signale wieder ohne Verlust verstärken. Wenn also
digitale Signale über lange Kabel gesendet werden, kann man sie
regelmäßig einlesen und wieder ausgeben. So ist es jetzt möglich,
über das Internet Leuten, die auf der anderen Seite des Globus
wohnen, ohne Verlust Fotos, Audioaufnahmen und Filme zu sen-
den. In einem deutlich kleinerem Maßstab wird diese Eigenschaft
in Chips benutzt, um Millionen von Transistoren zu verbinden,
ohne dass die ausgetauschten Spannungen am Ende vollends mit
Rauschen behaftet sind.
Die digitale Elektronik bildet die Grundlage für das »Rechnen« im
Physical Computing. Bei digitalen Signalen wird meistens kaum
Leistung übertragen (ein bisschen Strom wird immer noch in
Wärme umgewandelt, weswegen moderne Prozessoren auch sehr
schnell warm werden), sondern die Signale dienen rein der Kom-
munikation. Viele Sensoren und Aktoren bieten, obwohl sie intern
mit analogen Signalen und Werten arbeiten, eine digitale Schnitt-
stelle an, sodass sie sehr einfach anzuschließen sind. Der Königs-
baustein unter den digitalen Bauteilen ist der sogenannte Prozessor.
Er ist ein frei programmierbarer Computer, der sich in Schaltkreise
einbauen lässt. Hier wird zwischen Prozessor und Mikrocontroller
unterschieden. Erstere findet man etwa in Desktopcomputern und
Servern. Sie haben keine direkte Anbindung an die Umwelt, das ist
die Aufgabe weiterer Bausteine auf dem Mainboard. Bei einem
Mikrocontroller sind viele Schnittstellen (RS232, USB, Analog In,
PWM, IO-Ports) schon eingebaut, oft ist auch der Speicher direkt
integriert. Der Arduino-Prozessor hat eine interne Datenbreite von
8 Bit und ein paar Kilobyte Arbeitsspeicher. Er rechnet mit einem
Takt von 16 MHz.

Zusammenfassung der elektrischen Regeln


Diese ganzen Stromregeln lassen sich wie folgt zusammenfassen:
• Zwischen zwei Punkten in einem Schaltkreis liegt eine Span-
nung an.
• Zwischen zwei elektrisch verbundenen Punkten fließt ein
Strom.
• Der Fluss der Stroms hängt von der anliegenden Spannung
und dem Widerstand ab.

42 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
• Seriell geschaltete Bauteile addieren ihren Widerstand.
• Parallel geschaltete Bauteile teilen den Strom entsprechend
ihrem Widerstand auf.
Es reicht meistens aus, diese Regeln zu benutzen, um die Strom-
und Spannungswerte für ein neues Bauteil zu berechnen. Bei schon
einmal verwendeten Bauteilen lassen sich meistens ältere Schalt-
kreise und Einstellungen wiederverwenden, sodass sich nach eini-
ger Zeit eine Art Routine einstellt. Bei einem neuen Bauteil muss im
dazugehörigen Datenblatt, das die elektrischen Eigenschaften des
Bauteils beschreibt, nachgeprüft werden, wie hoch die minimalen
und maximalen Strom-, Spannungs- und Leistungswerte sind.
Diese sind oft in einer Tabelle zusammengefasst.

Tipp Es gibt im Internet viele hilfreiche Websites, die die Grundlagen


der Elektronik erklären. Besonders hilfreich sind z. B. die Websei-
ten [Link] und [Link]
[Link]/.

Schaltungen, Bauteile und Schaltbilder


Schaltungen bestehen aus einzelnen elektrischen bzw. elektroni-
schen Bauteilen, die miteinander über elektrische Leiter (Drähte)
verknüpft werden. Schon mit dem Anschließen einer Lampe an
eine Steckdose wird also eine, zugegebenermaßen recht einfache,
elektrische Schaltung hergestellt. Für komplexere Schaltungen ver-
wendet man heutzutage Platinen. Das sind Platten aus Glasfasern
und Epoxidharz, auf denen Kupferleiterbahnen dafür sorgen, dass
die Bauteile befestigt und verbunden werden. Das Mainboard eines
Computers ist ein gutes Beispiel für eine solche Platine, wenn auch
schon eine sehr große und komplexe.
Platinen sind nicht viel schwieriger zu entwerfen als Steckbrettauf-
bauten (siehe Kapitel 2, Abschnitt »Steckbretter«). Hierfür werden
spezielle CAD-Programme eingesetzt. Es kann sinnvoll sein, die
Schaltung vorher zu testen, da es schwierig ist, eine fertige Platine
zu modifizieren. Deswegen werden beim Entwurf und für den
Heimgebrauch oft spezielle Platinen eingesetzt, die Lochrasterplati-
nen und Steckbretter genannt werden. Auf diesen Platinen ist es
leicht möglich, schnell Schaltungen aufzubauen und auch nach-
träglich zu verändern.

Schaltungen, Bauteile und Schaltbilder 43


Bauteile
Bauteile sind die einzelnen physikalischen Komponenten in einer
elektronischen Schaltung. Sie können zum einen rein elektrische
Bauteile sein, die bestimmte Eigenschaften haben, aber kein eigenes
variables Verhalten an den Tag legen. Diese Bauteile nennt man
passive Komponenten, und zu ihnen gehören unter anderem Wider-
stände, Kondensatoren und Spulen. Zum anderen gibt es Bauteile,
die ihre Eigenschaften mechanisch ändern können. So kann zum
Beispiel ein elektrischer Kontakt mechanisch erstellt oder unterbro-
chen werden, wie es bei einem Schalter der Fall ist. Es ist auch mög-
lich, wie bei einem Potentiometer mechanisch den Widerstand des
Bauteils einzustellen. Andere Bauteile hingegen benutzen die elek-
trischen Eigenschaften von Halbleitermaterialen, um Signale elek-
tronisch zu verarbeiten. Diese Halbleiterbauteile reichen von der
einfachen Diode und dem LED über Transistoren bis hin zu Prozes-
soren in Desktopcomputern. Viele Halbleiterbauteile sind eigene
elektronische Schaltungen, die (meistens) in Silizium realisiert und
als ICs verpackt sind.
Jedes Bauteil kann es in einer Vielzahl von verschiedenen Versionen
und Bauformen zu kaufen geben. Es gibt bei Bauformen zwei
Hauptfamilien: bedrahtete Bauformen und SMD-Bauformen.
Bedrahtete Bauteile haben, wie ihr Name schon sagt, Drähte zum
Anschließen an weitere Komponenten. Dadurch sind sie recht ein-
fach von Hand zusammenzustecken oder zusammenzulöten, wes-
wegen sie für den Heimgebrauch besonders gut geeignet sind. In
diesem Buch werden nur bedrahtete Bauteile verwendet. Die
andere, mittlerweile extrem verbreitete Bauform ist die SMD-Bau-
form (surface mounted devices, was frei übersetzt so viel heißt wie
»Oberflächenbauteile«). Diese Bauteile haben sehr kurze Anschlus-
drähte, die direkt auf die Platine gelötet werden. Die SMD-Bauform
ist für die industrielle Fertigung bestimmt, und solche Bauteile las-
sen sich nicht angenehm von Hand zusammenschließen. Oft wer-
den Sensoren oder digitale Bausteine allerdings nur in SMD-
Bauform vertrieben. Um sie trotzdem einfach mit dem Arduino-
Board und anderen Schaltungen verbinden zu können, gibt es für
Bastler kleine Adapterplatinen, die SMD-Bausteine mit längeren
Drähten verbinden.
Nicht alle Bauteile des gleichen Typs verhalten sich auch gleich,
besonders wenn es sich um komplexere Sensoren oder Aktoren
handelt. In den sogenannten Datenblättern sind alle physikalischen

44 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Eigenschaften und sonstige Informationen zusammengefasst, die
für eine korrekte und vollständige Verwendung des entsprechenden
Bauteils nötig sind. Im Internet gibt es eine ganze Reihe von Daten-
blattsammlungen, die die meisten gängigen Bauteile umfassen. Die
Websites [Link] und [Link]
[Link]/de/ stellen tausende von PDFs zur Verfügung, die von
den Herstellern dort hochgeladen wurden.
Diese unterschiedlichen Bauteile kann man bei vielen Distributoren
und Elektronikläden erwerben. Das Suchen und Bestellen von elek-
tronischen Komponenten kann schnell zu einem eigenen Sport
werden: Meistens gibt es nicht nur eine Version von einem Bauteil,
sondern gleich 15, die ähnliche Eigenschaften haben, sich aber
leicht voneinander unterscheiden. Hier lohnt es sich oft, bei ver-
schiedenen Läden und Distributoren nachzugucken, ob bestimmte
Bauteile vielleicht billiger zu erhalten sind, oder in einer sinnvolle-
ren Bauform oder mit besseren Eigenschaften. Zum Glück gibt es
mittlerweile, gerade für Arduino-Anfänger, Läden, die sich auf den
Hobbybastelbereich konzentrieren, wie z.B. [Link]
[Link] und [Link] Dort lassen sich auch
viele verschiedene Arduino-Boards und -Shields (siehe Anhang A),
Adapterplatinen, interessante Sensoren und sogar fertige Projekte
zum Selbstbauen (sogenannte Kits, in denen alle Bauteile für ein
Projekt schon zusammengelegt sind) erwerben.

Schaltbilder
Schaltbilder sind eine Art »Sprache«, um Informationen über elek-
tronische Schaltungen auszutauschen. Sie werden verwendet, um
Schaltungen in abstrahierter und vereinfachter Form grafisch dar-
zustellen. So können Entwickler diese entwerfen und planen, ohne
eventuelle physikalische Notwendigkeiten wie die eigentliche
Kabelführung zu berücksichtigen.. Mit ihnen lassen sich vage
bestimmte Schaltungen definieren, es ist aber auch möglich, genau
jedes Bauteil zu spezifizieren. Viele elektronische Projekte im Inter-
net werden auf diese Weise erklärt. Im unteren Schaltbild wird zum
Beispiel beschrieben, wie zwei LEDs über ihren jeweiligen Vorwi-
derstand an eine Batterie anzuschließen sind. Die zweite LED ist
über einen Schalter getrennt aktivierbar (siehe Abbildung 2-5).
Schaltbilder sind Diagramme, die zeigen, wie einzelne Bauteile mit-
einander verknüpft werden. Jedes Bauteil wird durch ein Symbol
dargestellt. Ihre Darstellung variiert allerdings von Schaltbild zu

Schaltungen, Bauteile und Schaltbilder 45


Abbildung 2-5
LED-Schaltbild

Schaltbild (in den USA werden zum Beispiel Widerstände als Zick-
zack-Linien dargestellt, in Europa dagegen als kleine Kästchen).
Viele Bastler benutzen auch ihre eigenen Symbole um bestimmte
Bauteile zu zeichnen. Jedes dieser Symbole wird dann mit Strichen
mit anderen verbunden, und jeder dieser Striche steht für eine elek-
trische Verbindung. Die Bauteile werden meistens noch mit Namen
und Werten beschrieben (z.B. den Widerstandswerten einzelner
Widerstände, den Herstellernamen und den genauen Typbezeich-
nungen). Schaltbilder (oder Schaltpläne) können mit einer Reihe
von Programmen erstellt und bearbeitet werden (es ist natürlich
auch möglich, Schaltbilder auf eine Papierserviette zu zeichnen)
und greifen dabei auf einen Satz von meist genormten Symbolen für
die einzelnen Bestandteile zurück.

Tipp Für den Heimbereich bieten sich zum Zeichnen von Schaltbil-
dern Programme an wie gEDA (eine Open-Source-Lösung, die
aus vielen einzelnen kleinen Programmen besteht), KiCad (das
auch frei ist) oder EAGLE (das für den Heimbereich frei ist). Es
reicht meistens allerdings, die Schaltung auf einem einfachen
Blatt Papier zu entwerfen.
GEDA: [Link]
KiCad: [Link]
EAGLE: [Link]

Es kommt häufig vor, dass in einem Schaltbild Verbindungen


gezeichnet werden, die sich überkreuzen. Deswegen werden diese,
wenn sie auch wirklich zusammengeschaltet sind, mit einem klei-
nen Punkt gekennzeichnet, um zu verdeutlichen, dass es keine

46 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
getrennten Verbindungen sind. Weiterhin werden oft benutzte
Spannungen in der Schaltung (meistens jene, die von der Stromver-
sorgung zur Verfügung gestellt werden) mit einem einzelnen Sym-
bol gezeichnet, sodass es nicht notwendig ist, jeden Baustein
immer mit der Stromversorgung zu verbinden. Die Masse (also die
Spannung 0 Volt) wird meistens mit einem umgekehrten T-Symbol
dargestellt, während die Spannungsversorgung (bei Arduino-Schal-
tungen meistens 5 Volt) mit einem Pfeil nach oben dargestellt wird.
Wie so oft sind diese Symbole aber von Schaltbild zu Schaltbild
unterschiedlich, und es ist wichtig, hier nicht Spannungen zu ver-
wechseln. Bei ICs wird die Spannungsversorgung oft gar nicht erst
mit eingezeichnet, sondern es wird davon ausgegangen, dass dem
IC auch Strom zugeführt wird.
In der unteren Abbildung ist diese Schaltung mit zwei LEDs und
Vorwiderständen dieses Mal mit eigenen Symbolen für die Span-
nungsversorgung gezeichnet.

Abbildung 2-6
Schaltbild mit Spannungs-
versorgungssymbolen

Nachdem eine Schaltung entworfen wurde, ist es Zeit, sie mit rich-
tigen Bauteilen zu realisieren. Das Schaltbild ist also sozusagen ein
Bauplan. Oft ist es nicht möglich, die Bauteile so anzuordnen, wie
sie auf dem Schaltbild vorkommen. Bei Platinen werden dazu oft
mehrere Schichten Kupfer benutzt, bei Steckbrettschaltungen wer-
den für die Verbindungen sowohl die vertikalen und horizontalen
Lochreihen des Steckbretts als auch einzelne gesteckte Drähte ver-
wendet. Die Bauteile müssen nicht so angeordnet werden wie auf
dem Schaltbild. Es ist allerdings sinnvoll, auch auf dem Steckbrett
oder der Platine Bauteile, die in einem Zusammenhang miteinander
stehen, nah beieinander aufzubauen. Wichtig ist, dass jede elektri-
sche Verbindung, die auf dem Schaltbild steht, auch im physikali-
schen Aufbau hergestellt wird.

Schaltungen, Bauteile und Schaltbilder 47


Schalter
Schalter sind mechanische Bauteile, die eine elektrische Verbin-
dung herstellen oder trennen können. Meistens werden durch die
physische Betätigung des Schalters zwei elektrische Leiter miteinan-
der verbunden. Es gibt allerdings auch magnetische Schalter, bei
denen die elektrischen Leiter durch einen Magneten aneinanderge-
zogen und so verbunden werden. Interessant sind auch sogenannte
»Ball Switches«, die den Kontakt über einen kleinen metallischen
Ball herstellen, der auf die elektrischen Leiter rollt, wenn der Schal-
ter gekippt wird. In Kapitel 7 wird ein kleiner Erschütterungssensor
beschrieben, der auch als Schalter funktioniert: Ein kleiner Drah-
tring liegt lose auf zwei Kontakten und öffnet bei Erschütterungen
kurz den Stromkreis.
Schalter vertragen eine bestimmte anliegende Spannung und eine
bestimmte Menge Strom, der durch sie fließt. Bei den elektroni-
schen Schaltungen in diesem Buch werden sehr kleine Spannungen
und Ströme benutzt, sodass es hier bei den einsetzbaren Schaltern
keine Beschränkungen gibt. Deswegen ist es auch möglich, aus
allen möglichen elektrischen Leitern (z.B. Draht und Aluminiumfo-
lie) auch eigene interessante und innovative Schalter zu entwerfen.
Es gibt eine Unmenge verschiedener Schalter, die man käuflich
erwerben kann. Diese unterscheiden sich natürlich durch ihre
mechanische Bauform, also ihre Größe, ihr Aussehen, die Mate-
rialien, aus denen sie gebaut sind, und dadurch, wie sie an einem
Gehäuse angebracht werden. Für Entwicklungsschaltungen, die
z.B. auf einem Steckbrett zusammengebaut werden, ist es meistens
nicht so wichtig, welche Schalter eingesetzt werden. Soll eine Schal-
tung allerdings auf einer Platine gebaut (entweder auf einer richti-
gen Platine oder auf einer Lochrasterplatine) und später in ein
Gehäuse eingebaut werden, ist es wichtig, sich schon im Voraus
Gedanken über das fertige Gerät zu machen. Besonders muss dort
auf die Größe und Befestigung der Schalter geachtet werden, denn
nichts ist frustrierender, als im Nachhinein zu merken, dass alles
gar nicht in das vorgesehene Gehäuse passt. Es ist auch durchaus
möglich, die Komponenten zuerst rein mechanisch zusam-
menzusetzen, um zu sehen, ob auch alles seine Richtigkeit hat.
Bei Schaltern gibt es zwei unterschiedliche Funktionsweisen, näm-
lich Schalter und Taster. Bei einem Schalter wird meistens langfris-
tig eine elektrische Verbindung geschaltet, während bei einem
Taster nur ein Kontakt hergestellt wird, solange er betätigt wird.

48 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Wird er wieder losgelassen, wird der Kontakt wieder unterbrochen
(solche Taster nennt man »normally open« oder »n. o.«, also »im
Normalzustand offen«). Es gibt auch Taster, die ohne Betätigung
durch den Benutzer einen Kontakt herstellen und diesen erst beim
Betätigen unterbrechen. Diese nennt man »normally closed« oder
»n. c.«.
Weiterhin gibt es viele verschiedene Schalter, die sich durch die
Anzahl der durch sie einstellbaren Verbindungen unterscheiden. So
gibt es einfache, die nur eine elektrische Verbindung trennen oder
aufbauen können. Kompliziertere Schalter können aber z.B. paral-
lel zwei, drei oder mehr Verbindungen aufbauen und trennen.
Generell werden Schalter durch die Anzahl der verschiedenen her-
stellbaren Verbindungen (auf Englisch »poles«) und die Anzahl der
elektrischen Leitungen, die verbunden werden können (auf Eng-
lisch »throws«) beschrieben. In der folgenden Tabelle sehen Sie
eine Übersicht herkömmlicher Schaltertypen.

Schalterbezeichnung Beschreibung Tabelle 2-1


Schaltertypen
SPST Dieser einfacher Schalter stellt eine Verbindung her oder trennt sie.
(Single Pole, Single Throw)
SPDT Ein Eingang kann mit zwei unterschiedlichen Ausgängen verbunden
(Single Pole, Double Throw) werden.
DPST Zwei Verbindungen können parallel hergestellt oder getrennt wer-
(Double Pole, Single Throw) den.
DPDT Hier können zwei Eingänge parallel mit separaten Ausgängen ver-
(Double Pole, Double Throw) bunden werden.

Abbildung 2-7
Schalter

Schaltungen, Bauteile und Schaltbilder 49


Widerstand
Ein Widerstand ist ein Bauteil, das elektrische Energie in Hitze
umwandelt. Dadurch begrenzt sich der Stromfluss. Der Wert eines
Widerstands wird in Ohm angegeben; anhand der Regeln, die in
den vorigen Abschnitten vorgestellt wurden, lässt sich dadurch die
Strombegrenzung berechnen. Widerstände sind kleine Bauteile, die
zwei Anschlüsse besitzen. In welcher Richtung sie eingesetzt wer-
den, spielt keine Rolle, allerdings sehr wohl ihre Größe. Da ein
Widerstand Energie in Hitze umsetzt, muss gewährleistet werden,
dass er diese Energie auch aushalten kann. Für Schaltungen in die-
sem Buch, in denen mit kleinen Strömen und kleinen Spannungen
gearbeitet wird, reichen meistens herkömmliche Widerstände mit
1/4 oder 1/8 Watt.
Widerstände werden aus verschiedenen Materialien hergestellt. So
gibt es etwa Kohleschichtwiderstände und Metallschichtwiderstände.
Diese haben unterschiedliche Eigenschaften; Kohleschichtwider-
stände sind z.B. billiger, aber nicht so präzise wie Metallschichtwider-
stände. Diese inhärente Genauigkeit von Widerstandswerten hat
dazu geführt, dass sie in verschiedene Werteklassen eingeteilt wer-
den. Diese sind standardisiert und werden als »E-Reihen« bezeichnet:
E-3 ist eine Reihe mit drei Werteklassen von sehr grober Toleranz, E-
6 hat sechs, die ein bisschen genauer sind, und so geht es weiter bis zu
E-192 für Hochpräzisionswiderstände. Es kann deswegen z.B. unan-
genehm sein, einen genauen Spannungswert zu berechnen, nur um
am Ende herauszufinden, dass man dazu einen Widerstand mit 25,98
Ohm und einen mit 1034 Ohm braucht, den es in dieser Form nicht
gibt (oder der nicht bezahlbar ist). In unseren Schaltungen, die meis-
tens mit digitalen Spannungen arbeiten, sind viele Widerstände als
Pull-ups oder als Schutzwiderstände eingesetzt, weswegen ihr ge-
nauer Wert nicht so wichtig ist.
Die Werte auf Widerständen sind durch einen Farbcode angege-
ben: Verschiedene Streifen auf ihrem Körper geben an, welchen
Widerstandswert in Ohm dieses Bauteil hat und mit welcher
Genauigkeit zu rechnen ist. In der folgenden Tabelle werden die
Farbcodes für Widerstände erläutert. Es gibt zwei verschiedene
Farbcodes für Widerstände. Im ersten werden vier Farbbänder
benutzt. Die ersten zwei geben den Widerstandswert an, das dritte
die Größenordnung (also den Wert, mit dem die zwei ersten Bän-
der multipliziert werden), während das vierte Band (das meistens

50 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
ein bisschen abgesetzt von den anderen an einem Ende des Wider-
stands zu finden ist), die Toleranz angibt, also beschreibt, wie
genau der angegebene Wert zum tatsächlichen passt. Beim zweiten
Code werden fünf Farbbänder benutzt. Hier geben die ersten drei
den Widerstandswert an, das vierte ist der Multiplikator, und das
letzte Band gibt die Toleranz des Widerstands an.

Erstes Zweites Drittes Tabelle 2-2


Farbe Band Band Band Multiplikator Toleranz Widerstandsfarbcodes
Schwarz 0 0 0 1 Ohm -
Braun 1 1 1 10 Ohm 1,00%
Rot 2 2 2 100 Ohm 2,00%
Orange 3 3 3 1.000 Ohm
Gelb 4 4 4 10.000 Ohm
Grün 5 5 5 100.000 Ohm 0,50%
Blau 6 6 6 1.000.000 Ohm 0,25%
Violett 7 7 7 10.000.000 Ohm 0,10%
Grau 8 8 8 - 0,05%
Weiß 9 9 9 -
Gold 0,1 5,00%
Silber 0,01 10,00%

Es ist praktisch, Widerstände in kleine Kästchen oder Schubladen


zu sortieren und jeweils mit einem numerischen Wert zu versehen.
Dabei muss man aber sicherstellen, dass der angegebene Wert auch
tatsächlich dem realen entspricht. Eine andere Methode, um den
Widerstandswert eines Bauteils abzulesen, ist die Benutzung eines
Multimeters, was im entsprechenden Abschnitt erklärt wird.

Abbildung 2-8
Widerstand

Schaltungen, Bauteile und Schaltbilder 51


Variabler Widerstand
Abbildung 2-9
Potentiometer

Ein variabler Widerstand ist, wie sein Name schon sagt, einer, bei
dem der Wert eingestellt werden kann. Bekannte Beispiele für vari-
able Widerstände sind Potentiometer und Schieberegler. Ein Poten-
tiometer besteht aus einem speziellen Widerstand, an dem ein
sogenannter Schleifer angebracht ist, der sich durch die Drehung
entlang der leitenden Oberfläche bewegt. Dadurch vergrößert oder
verkleinert er auch den Widerstandswert und somit die Spannung,
die am Potentiometer anliegt. Ganz ähnlich wie Drehpotentiometer
funktionieren auch Schieberegler (oder »Fader«). Dort ist der
Schleifer nicht rund, sondern länglich, sodass der Regler bei einer
Bewegung den Widerstand verkürzt. Bekannte Anwendungen sind
Lautstärkeregler oder Crossfader auf Mischpulten. Im Arduino-
Bereich können Fader z.B. für die Steuerung von Licht oder Ton
verwendet werden.
Potentiometer und Schieberegler haben meistens drei Anschlüsse.
Die zwei äußeren sind an beiden Enden des zu manipulierenden
Materials angebracht, und der Widerstand zwischen ihnen verän-
dert sich nicht. Der dritte Anschluss liegt am Schleifer an und der
Widerstand von diesem Anschluss zu den beiden anderen variiert,
je nachdem, wie der Schleifer bewegt wird. Wenn an den beiden
äußeren Anschlüssen definierte Spannungen angebracht werden,
wird ein Spannungsteiler gebildet. Dadurch variiert die Spannung
am mittleren Anschluss zwischen den beiden äußeren Spannungen.
Dieser Wert lässt sich dann durch einen analogen Eingang am
Arduino auslesen.
Es gibt allerdings auch noch eine ganze Reihe anderer Bauteile, die
sich wie variable Widerstände verhalten (man nennt diese Bauteile

52 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
auch resistive Sensoren). So gibt es lichtempfindliche Widerstände,
die ihren Wert ändern, je nachdem, wie viel Licht aus sie einfällt.
So einen Widerstand nennt man LDR (light dependent resistor)
oder auch Fotowiderstand oder Fotozelle. Thermistoren sind
Widerstände, die ihren Wert je nach Temperatur ändern. Druck-
sensoren und Flexsensoren sind Widerstände, die ihren Wert
ändern, je nachdem, wie viel Druck auf sie ausgeübt wird oder wie
stark sie gebogen werden. Wie Widerstände habe diese Bauteile
auch zwei Anschlüsse, und ihre Richtung ist nicht relevant. Oft
werden resistive Sensoren mit einem weiteren Widerstand an defi-
nierte Spannungen angeschlossen, um so einen Spannungsteiler
aufzubauen. Dadurch lässt sich ein resistiver Sensor wie ein Poten-
tiometer auslesen. Mehr Informationen zu resistiven Sensoren fin-
den Sie in Kapitel 7.

Kondensator
Einen Kondensator kann man als ein Speicherbauteil für elektrische
Ladung betrachten. Fließt Strom hinein, speichert dieser intern eine
Ladung. Wird die Spannung entfernt, leert sich der Kondensator
und liefert Strom, bis er keine Ladung mehr enthält. Dieses Entlee-
ren geschieht allerdings nicht sofort, sondern spielt sich über einen
gewissen Zeitraum ab, der von der Kapazität des Kondensators
(wie viel elektrische Ladung er aufnehmen kann, gemessen in
Farad) und von der Menge des fließenden Stroms abhängt.
Dadurch können Kondensatoren z.B. eingesetzt werden, um sich
schnell verändernde Ströme zu begrenzen und »aufzuweichen«:
Fließen kurze Stromstöße, sammelt der Kondensator sie auf, wird
der Stromfluss kleiner, braucht er seine gespeicherte Ladung auf,
um den Strom aufrechtzuerhalten.
Farad ist eine sehr große Größe, weshalb die Kondensatoren in den
Arduino-Schaltungen meistens in Bereiche von Mikrofarads bis
Picofarads gehen. Kondensatoren gibt es sowohl in unpolarisierter
Bauform, bei der es keinen Einfluss hat, in welcher Richtung sie
angeschlossen werden, als auch in polarisierter Bauform. Bei die-
sen polarisierten Kondensatoren (meistens Elektrolytkondensato-
ren, kurz auch Elkos genannt) steht auf dem Gehäuse, welcher
Anschlusspin an die positive und welcher an die negative Seite
angeschlossen werden muss. Bei digitalen Schaltungen werden sie
oft eingesetzt, um die Spannungsversorgung für Bausteine zu glät-
ten. Sie können auch benutzt werden, um kurze Impulse, wie sie
z.B. aus Piezomikrofonen kommen, zeitlich zu verlängern, sodass

Schaltungen, Bauteile und Schaltbilder 53


ein Mikrocontroller Zeit hat, diese zu verarbeiten. Ein wichtiger
Einsatzbereich von Kondensatoren ist die Implementierung von
Filtern, die ein Signal in bestimmten Frequenzen abschwächen
oder verstärken. Wir verwenden einen Filter auf Basis eines Kon-
densators und eines Widerstands (ein sogenanntes RC-Netzwerk)
in Kapitel 10, in dem es um Musik mit dem Arduino geht.

Abbildung 2-10
Kondensatoren

Transistor und Relais


Abbildung 2-11
Transistoren

Transistoren und Relais (englisch Relays) sind Bauteile, die zum


Schalten von größeren Strömen verwendet werden. Im Gegensatz
zu ihren normalen, mechanischen Geschwistern werden Transisto-
ren und Relais allerdings elektronisch geschaltet. Wenn in ein
Relais ein kleiner Strom fließt, wird durch eine Spule ein Magnet-
feld erzeugt, das einen mechanischen Schalter schließt. Damit las-
sen sich elektrisch getrennte Netzwerke schalten. Sie werden oft
verwendet, um z.B. Bauteile mit Netzspannung zu betreiben. Relais
werden genauer im Abschnitt über Aktoren beschrieben.
Im Gegensatz zu Relais benutzen Transistoren die Eigenschaften
von Halbleitermaterialien (in den meisten Fälle Silizium), um
Ströme zu steuern. Sie werden oft für Bauteile verwendet, die grö-
ßere Ströme benötigen, etwa Motoren, Glühbirnen oder viele
LEDs.

54 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Abbildung 2-12
Relais

Dioden
Abbildung 2-13
Diode

Eine Diode funktioniert wie eine Einbahnstraße: Die Elektrizität


kann nur in eine Richtung fließen. Dioden haben zwei Anschlüsse,
Anode (+) und Kathode (–). Ein Strom kann nur von der Anode zur
Kathode fließen. Deswegen haben Dioden immer eine Richtung;
meistens ist die Kathode durch einen Strich auf dem Diodenge-
häuse gekennzeichnet. Dioden werden verwendet, um Signale zu
richten, wie im folgenden Bild gezeigt ist. Sie verhindern, dass z.B.
eine negative Spannung anliegt, indem sie diese kurzschließt. Im
Arduino-Prozessor sind an jedem Pin auch Schutzdioden ange-
schlossen, die sicherstellen, dass keine negative oder zu hohe Span-
nung angelegt werden kann.
Es gibt verschiedene spezielle Dioden, zum Beispiel Zener-Dioden,
die Strom ab einer bestimmten Spannung in der Sperrrichtung
durchlassen, sodass sie zur Spannungsbegrenzung und -regelung
verwendet werden können.

Abbildung 2-14
Invertierungsschutz mit einer
Diode

Schaltungen, Bauteile und Schaltbilder 55


Netzteil
Abbildung 2-15
Netzteile

Für die meisten Arduino-Projekte wird eine Gleichspannung (DC)


benötigt. Dazu können kleine Steckernetzteile oder die USB-Ports
verwendet werden. Für kleinere Projekte sind 200 bis 300 mA aus-
reichend. Werden viele LEDs, Lampen oder Relais eingesetzt, kann
der benötigte Strom natürlich viel höher sein, weswegen es ratsam
ist, gleich ein Netzteil zu beschaffen, dass 1.000 mA liefern kann.
Vorsichtig sollte man mit älteren Universalnetzteilen sein, deren
Regelung meist schlecht oder gar nicht vorhanden ist. Eine einge-
stellte Spannung kann ohne große Belastung durchaus 3 bis 5 Volt
größer als angegeben sein. Dem Arduino-Board macht das aller-
dings nichts aus, da hier noch ein Spannungsregler verbaut ist, der
diese Spannung anpasst.
Eine andere Variante sind die immer gebräuchlicher werdenden
Schaltnetzteile, die man an ihrem geringen Gewicht erkennen
kann. Sie bieten den Vorteil, ziemlich viel Strom liefern zu können,
ohne dabei nennenswert warm zu werden, können allerdings emp-
findliche Schaltungen stören.

Spannungsregler
Lineare Spannungsregler erzeugen aus der ursprünglichen eine
geregelte niedrigere Spannung. Dazu müssen am Eingang 2 bis 3
Volt mehr anliegen, als die Ausgangsspannung sein soll.
Häufig wird der Regler 7805 (5 Volt) verwendet. Er kann aus 7 bis
35 Volt eine geregelte Spannung von 5 Volt erzeugen. Je höher die
Eingangsspannung, desto besser muss die Kühlung sein; hier wird
empfohlen, ein kleines Stück Blech an den Regler zu schrauben.

56 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Auf dem Arduino-Board ist schon ein Spannungsregler montiert,
außerdem funktioniert der USB-Chip auch als Quelle für eine Span-
nung von 3,3 Volt. Die Spannung, die das Arduino-Board auf den
Spannungsversorgungspins liefert, ist also schon reguliert.

Steckbretter
Abbildung 2-16
Steckbrett

Steckbretter sind ein schneller Weg, um kleine Schaltungen auszu-


probieren. Sie bestehen aus einem oder mehreren Plastikbrettern,
die in regelmäßigen Abständen durchlöchert sind. In diese Löcher
lassen sich dann herkömmliche Bauteile (z.B. ICs in der DIP-Form,
bedrahtete Widerstände oder LEDs) und einzelne Drähte stecken.
Innerhalb des Bretts sind diese Löcher elektrisch verbunden. So las-
sen sich sehr leicht Schaltungen entwerfen: Zuerst werden die
benötigten Bauteile auf das Brett gesteckt und dann untereinander
mit Drähten verbunden.
Steckbretter sind allerdings nicht einheitlich aufgebaut, weshalb
man zuerst herausfinden sollte, wie die Stecklöcher intern verbun-
den sind. Im Normalfall gibt es oben und unten eine durchgehend
verbundene Reihe. Die obere wird mit 5 oder 3 Volt verbunden, die
untere mit Ground (GND). So kann man der Schaltung von jeder
Stelle aus die zwei Referenzspannungen zuführen.

Schaltungen, Bauteile und Schaltbilder 57


Wichtig ist, dass alle Drähte und Bauteile gut eingesteckt sind, weil
es sonst zu Kurzschlüssen und Unterbrechungen in der Schaltung
kommen kann. Besonders bei neuen Steckbrettern lassen sich
Drähte und andere verdrahtete Bauteile oft nur mit Schwierigkeit in
die Löcher hineindrü[Link] ist es immer nützlich, eine
kleine Zange zur Verfügung zu haben, um hartnäckige Schaltungen
sauber aufzubauen. Ansonsten verbringt man viel Zeit mit unnöti-
ger Fehlersuche. Wegen ihrer Bauweise sind Steckbretter auch sehr
anfällig für Rauschen und Störsignale, sodass sich manchmal
bestimmte Sensoren oder Bausteine (besonders solche, die mit klei-
nen Spannungen oder hoher Geschwindigkeit arbeiten) falsch ver-
halten. Auch hier gilt die Regel, alle Verbindungen möglichst kurz
zu halten.
Ein weiteres Problem mit Steckbrettern ist, dass die Schaltungen,
die auf ihnen aufgebaut sind, recht schnell kaputt gehen. Ein Steck-
brett ist auch relativ groß und unhandlich, sodass es sich nicht ein-
fach transportieren lässt. Auch ein Gehäuse ist aus diesen Gründen
meistens nicht sehr praktisch. Deswegen werden Steckbretter vor
allem für Entwicklung und Prototypentwurf eingesetzt. Wenn eine
Schaltung auf dem Steckbrett funktioniert und später weiterver-
wendet werden soll, lohnt es sich, sie auf eine Lochrasterplatine zu
transferieren oder gleich eine Platine zu entwerfen (siehe auch in
den Abschnitten über Löten auf Lochrasterplatinen und Platinen in
diesem Kapitel).
Auf den meisten Darstellungen in diesem Buch wird ein Steckbrett
verwendet. Dazu werden einzelne Drähte von den Anschlusspins
des Arduino-Boards damit verbunden. Es gibt auch spezielle Ardu-
ino-Boards und Arduino-Shields, die ihr eigenes kleines Steckbrett
mitbringen, sodass sich direkt auf dem Board selbst kleine Schal-
tungen entwerfen lassen.

Kabel, Stecker und Buchsen


Zu den wichtigsten Bauteilen in elektronischen Schaltungen, die
oft nicht erwähnt werden, gehören Kabel, Stecker und Buchsen.
Kabel werden verwendet, um verschiedene Bauteile miteinander zu
verbinden. Das kann in Form von Leiterbahnen auf der Platine
geschehen, aber auch mit Drähten, die auf einer Lochrasterplatine
angelötet werden, oder mit Kabeln. Hiervon gibt es zwei unter-
schiedliche Arten. Die eine hat als Leiter einen einfachen Draht
und ist einfacher zu verwenden, weil sie sich zum Beispiel sehr

58 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
leicht in Steckbretter stecken lässt und weil sie nach dem Biegen
ihre Form behält. Allerdings ist sie mechanisch nicht sehr belast-
bar, weil der einzige Draht in ihrem Kern sehr schnell brechen
kann, wenn man das Kabel bewegt.
Deshalb gibt es eine andere Sorte Kabel, die in ihrem Innern eine
Kupferlitze hat, die aus vielen kleinen einzelnen, biegsamen Dräh-
ten besteht. Diese Kabel sind deutlich robuster und werden oft
verwendet, um zum Beispiel Schalter und Taster mit einer Platine
zu verbinden oder Kabel über längere Distanzen zu verlegen. Es
gibt sie auch in mehradriger Ausführung, z.B. als Netzwerk-, Tele-
fon- und Druckerkabel. In einem mehradrigen Kabel sind mehrere
einzelne Litzenkabel zusammen verlegt, sodass sich z.B. mehrere
Datenleitungen mit einem einzigen Kabel verbinden lassen. Aller-
dings kann man Litze nicht einfach ins Steckbrett einstecken, son-
dern muss sie an eine Steckerleiste anlöten, die man dann in das
Steckbrett einbauen kann.
Eine praktische Alternative zu Steckbrettern sind Kabel mit Kroko-
dilklemmen, die sich gut dazu eignen, größere mechanische Bau-
teile miteinander zu verknüpfen, um Projekte, die viel Raum
brauchen, aufzubauen. Allerdings halten Krokodilklemmen nicht
besonders gut, sodass diese Art des Verkabelns wirklich nur kurz-
zeitig verwendet werden sollte, um dann z.B. durch robuste Stecker
ersetzt zu werden.
Zusätzlich zu Kabeln gibt es auch eine unendliche Anzahl verschie-
dener Stecker und Buchsen; viele Kabel sind auch schon mit pas-
senden Steckern versehen (alternativ kann man Stecker auch
anlöten oder mit einer sogenannten Crimpzange ancrimpen). Es
gibt sie in allen Formen und Größen, und sie werden verwendet,
um Platinen mit Strom zu versorgen und verschiedene Platinen
oder Bauteile miteinander zu verknüpfen, ohne dass jedes Mal eine
Verbindung gelötet werden muss.
Eine wichtige und beim Basteln häufig verwendete Steckerform
sind die sogenannten Pin- und Buchsenleisten, die meistens in
einem 2,54-mm-Raster verwendet werden. Pinleisten bestehen aus
einer oder zwei Reihen von Pins, die aus der Platine hervorstehen.
Sie werden verwendet, um Flachbandkabel aufzustecken oder
bestimmte Verbindungen mithilfe von Jumpern herzustellen. Auf
dem Arduino-Board gibt es eine doppelreihige Pinleiste (2x3), die
zum Programmieren des Arduino-Prozessors verwendet wird. Auf
älteren Arduino-Boards wie dem Arduino NG wird auch eine

Schaltungen, Bauteile und Schaltbilder 59


kleine Pinleiste in Verbindung mit einem Jumper benutzt, um die
Stromversorgungsquelle auszuwählen.
Das Pendant zu Pinleisten sind Buchsenleisten, wie sie auf dem
Arduino-Board verwendet werden, um die Eingangs- und Ausgangs-
pins des Prozessors mit der Außenwelt zu verbinden. Buchsenleis-
ten sind insbesondere für das Ausprobieren von Schaltungen auf
einem Steckbrett praktisch, weil sich die Drähte, die auf dem Steck-
brett verwendet werden, sehr leicht hineinstecken lassen. Allerdings
fallen diese Kabel dementsprechend auch schnell wieder aus den
Buchsen heraus, sodass hier ein bisschen Vorsicht geboten ist, wenn
der Aufbau bewegt wird.
Ein weiterer Vorteil der Buchsenleisten auf dem Arduino-Board ist,
dass es dadurch möglich ist, ein weiteres Board, das mit Pinleisten
versehen ist, aufzustecken. Dadurch sind sofort alle Pins des Ardu-
ino-Prozessors mit den Pins der Schaltung auf dem zweiten Board
verbunden, und der ganze Aufbau ist sehr solide. Es gibt eine ganze
Reihe von Erweiterungsboards für den Arduino, die »Shields«
(Schilde) genannt werden. Eine Auswahl dieser Shields wird in
Anhang A vorgestellt.

Abbildung 2-17
Kabel

Abbildung 2-18
Stecker

60 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
ICs
ICs (integrated circuits, integrierte Schaltkreise), auch Chips
genannt, sind komplette Schaltungen, die in einem eigenen kleinen
Plastikgehäuse platziert werden und sich für spezielle Aufgaben in
einer Schaltung einsetzen lassen. ICs sind also ein Ersatz für Schal-
tungen, die man meistens auch separat aufbauen könnte; aber
durch die seit den 1960er Jahren immer weiter verbesserten und
verfeinerten Herstellungsmethoden ist es möglich, solche Schaltun-
gen auf dem Bruchteil eines Quadratzentimeters zu realisieren.
Integrierte Schaltkreise können sehr einfache Schaltkreise sein
(zum Beispiel eine Reihe von Transistoren zur Stromverstärkung,
die man Treiberbausteine nennt), aber auch hoch komplizierte
CPUs und Signalprozessoren. Auch der Arduino-Prozessor ist ein
solcher Baustein.
ICs gibt es in verschiedenen Bauformen; die meisten haben mittler-
weile die SMD-Bauform, weshalb sie nicht so einfach beim Auf-
bauen von Schaltungen auf der Steckplatine zu verwenden sind.
Dazu eignet sich die DIP-Bauform deutlich besser, weil diese sich
direkt auf der Steckplatine einstecken lässt. Alle ICs haben Pins, die
zur Stromversorgung angeschlossen werden sollen. Hier ist beson-
dere Vorsicht geboten, damit man die Stromversorgung nicht inver-
tiert (als GND an die positive Spannung anschließen und VCC an
die Masse), weil dadurch oft die Chips kaputtgehen. Zu jedem IC
gibt es vom Hersteller ein Datenblatt, das die Pinbelegung zeigt
(hier heißt GND auch oft Vss) und die Funktionsweise des Chips
erklärt. Weiterhin gibt es in jedem Datenblatt eine Tabelle, die
Grenzwerte und Sollwerte für verschiedene Größen wie maximalen
Strom, maximale Spannung und niedrigste und höchste Geschwin-
digkeit angibt. Oft ist es praktisch, im Arduino-Wiki unter http://
[Link]/ zu suchen, ob es schon Beispielschaltungen zu einem
bestimmten Chip gibt (und vielleicht sogar schon eine Library, die
die Kommunikation mit dem Chip implementiert).
Wenn eine Schaltung auf einer Platine gebaut wird (oder auch auf
einer Lochrasterplatine), ist es bei DIP-Gehäusen sinnvoll, die
Chips auf einem Sockel einzubauen. Der Sockel wird auf die Platine
gelötet und der Chip dann nur in den Sockel eingesteckt. Mit einem
Schraubenzieher oder einer dünnen Zange (es gibt auch spezielle
Chipzangen) lässt er sich dann auch vorsichtig wieder herausneh-
men. Dadurch lassen sich defekte Chips auswechseln, ohne gleich

Schaltungen, Bauteile und Schaltbilder 61


eine neue Platine bauen zu müssen oder eine extensive Entlötaktion
durchzuführen.
In diesem Buch kommen nur wenige ICs zum Einsatz, und wenn
welche benutzt werden (z.B. der Ethernet-Controller in Kapitel 6),
sind sie auf einem externen Shield angebracht. Es gibt allerdings
eine Reihe wichtiger Chips, die häufig praktisch eingesetzt werden.
Erwähnenswert sind hier sogenannte Shift-Register. Diese Bauteile
können über eine synchrone serielle Schnittstelle (also zwei Pins,
von denen der eine als Taktgeber benutzt wird und der andere zur
Datenübertragung) Daten empfangen und senden. Es gibt zwei
Arten von Shift-Registern: Solche, die als Ausgabe benutzt werden,
indem sie über die serielle Schnittstelle Daten empfangen und beim
Aktivieren eines sogenannten Latch-Signals an ihre Ausgänge legen,
und solche, die als Eingabe benutzt werden. Sie übertragen die
Daten, die an ihren Eingängen liegen, seriell an den Empfänger.
Dadurch kann man mehrere digitale Ausgänge oder Eingänge über
eine serielle Schnittstelle einlesen und spart sich so eine große
Anzahl an belegten Pins. Ein weiterer Vorteil von Shift-Registern
ist, dass man sie verketten kann. Es ist also möglich, über eine seri-
elle Schnittstelle beliebig viele von ihnen auszulesen oder zu schrei-
ben. Weit verbreitete Shift-Register sind z.B. das Ausgabe-Shift-
Register 74HC595 und die Eingabe-Shift-Register 74HC165 oder
CD4021. Ihre Verwendung ist im Arduino-Wiki unter [Link]
[Link]/en/Tutorial/ShiftIn und [Link]
rial/ShiftOut erklärt, und es gibt in der Arduino-Programmierspra-
che passende Funktionen, um diese Chips anzusprechen.
Ein sehr wichtiger Chip auf dem Arduino-Board ist der Mikrocont-
roller der AVR-Familie von Atmel. Dieser Chip enthält einen kom-
pletten kleinen Mikroprozessor, auf dem alle Arduino-Programme
ausgeführt werden. Das Arduino Duemilanove gibt es mit zwei ver-
schiedenen Versionen des AVR-Chips: eine Version mit Atmega168
(so heißt die genaue Bezeichnung des Chips) und eine mit
Atmega328. Die neue Version mit Atmega328 verfügt über ein biss-
chen mehr Speicher. Bei einem Arduino-Board mit Atmega168
kann man einfach einen neuen Atmega328-Chip mit Arduino-
Bootloader (siehe Kapitel 1) bestellen und den Atmega168 austau-
schen. Dazu muss nur der alte Chip zunächst vorsichtig mit einem
Schraubenzieher ausgehebelt werden, damit man den Atmega328
einstecken kann. Dabei muss man auf die Richtung achten: Auf der
Platine ist eine Darstellung des Chips mit einer kleinen Kerbe einge-
zeichnet, die auch auf dem eigentlichen Chip vorhanden ist.

62 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Abbildung 2-19
ICs

Zangen und Pinzetten


Es gibt eine Reihe sehr praktischer Werkzeuge für die Arbeit mit
Drähten, Kabeln und elektronischen Komponenten. Diese Werk-
zeuge kommen immer wieder zum Einsatz, weswegen es auch nicht
verkehrt ist, auf Qualität zu setzen und ein bisschen mehr auszuge-
ben. Mit guten Werkzeugen macht das Basteln deutlich mehr Spaß,
und das Ergebnis ist meistens auch weniger fehleranfällig.
Eine Zange, die oft zum Durchtrennen von Kabeln, Drähten und
Bauteilbeinchen benutzt wird, ist der Seitenschneider. Es gibt spezi-
elle kleine Seitenschneider zum Arbeiten mit elektronischen Schal-
tungen. Sie haben isolierte Griffe und Schneidekanten, die auf der
einen Seite gerade sind. Dadurch lassen sich Komponentenbeine
sehr nah an der Platine abschneiden und Drähte präzise trennen.
Beim Durchtrennen von Drähten und Bauteilbeinchen sollte immer
ein Finger die abzuschneidende Seite festhalten, damit diese nicht
durch den Raum fliegt und unter Umständen Menschen verletzt. Es
gibt auch spezielle Seitenschneider, die über eine kleine Metallkon-
struktion gleich die abzuschneidenden Teile fixieren. Weiterhin ist
es mit einem kleinen Trick auch möglich, mit dem Seitenschneider
Kabel schnell abzuisolieren. Dazu drückt man den Seitenschneider
nicht komplett zu, sodass nur die Hülle geschnitten wird, und zieht
dann die Ummantelung vom Kabel ab. Das erfordert ein bisschen
Übung, damit nicht die Litze oder der innere Draht beschädigt
wird, spart aber später immer einen Werkzeugwechsel.
Für genau diesen Vorgang gibt es die Abisolierzange, eine spezielle
Zange, mit der das Abisolieren präzise und wiederholbar durchge-
führt werden kann (das ist insbesondere dann praktisch, wenn sehr
viele Kabel abisoliert werden müssen). Für Bastelzwecke lohnt sich
eine kleine solche Zange für die dünnen Drähte, die auf einem
Steckbrett eingesetzt werden. Alternativ kann man auch schon fer-
tig abisolierte Drähte für Steckbretter benutzen (die man in ver-
schiedenen Farben und Größen kaufen kann).

Schaltungen, Bauteile und Schaltbilder 63


Weitere wichtige Werkzeuge sind Spitzzange und Pinzette, mit
denen man kleinere Komponenten platzieren kann. Oft ist das
Steckbrett ein bisschen widerspenstig und es ist notwendig, Drähte
und Komponenten mit einer dünnen Zange einzustecken. Weiter-
hin kann man mit einer Pinzette auch eingesteckte Kabel einfacher
herausziehen, ohne andere Kabel in Mitleidenschaft zu ziehen (was
bei größere Steckbrettprojekten meist ein Problem ist).

Abbildung 2-20
Zangen

Löten
Die meisten der Schaltungen in diesem Buch lassen sich ohne
Löten auf einem Steckbrett anbringen. Allerdings ist diese Art, Pro-
jekte aufzubauen, weder sonderlich stabil noch elegant oder ästhe-
tisch. Immer besteht die Gefahr, dass einzelne Kabel aus den
Löchern herausfallen, wenn z.B. am Arduino gezogen wird. Auch
das Steckbrett selbst hat oft nicht die gewünschten Dimensionen,
sodass es nicht möglich ist, die komplette Schaltung in ein
Gehäuse einzubauen oder im Rahmen einer Kunstinstallation an
einem Gegenstand zu befestigen. In all diesen Fällen ist es sinnvol-
ler, die Schaltung, sobald sie fertig und getestet ist, in eine endgül-
tige Form zu bringen, indem man sie auf eine Platine lötet. Das ist

64 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
nur halb so wild, wie es klingt, und nach ein paar Versuchen stellt
sich schnell heraus, dass Löten sogar Spaß macht. Vor allem wer-
den dadurch die einzelne Projekte, die in diesem Buch vorgestellt
oder später eigens entwickelt werden, zu richtigen benutzbaren
und robusten Gegenständen, die immer wieder verwendet werden
können.
Im Internet gibt es eine große Gemeinde von Elektronikerinnen
und Elektronikern, die Schaltungen und Projekte entwickeln und in
Form von Schaltplänen und Bausätzen veröffentlichen. Mit Löt-
kenntnissen ist es dann sehr einfach, einen dieser Bausätze zu
bestellen, zu bestücken und zum Laufen zu bringen. Diese Bausätze
reichen von einfachen Blinkschaltungen (wie der Brainmachine von
Mitch Altman, unter [Link] zu finden
und auch in Kapitel 4 beschrieben, und dem Open Heart Kit von
Jimmie Rodgers, unter [Link]
zu finden) über Gadgets wie das T.V.-be-Gone (auch von Mitch
Altman, unter [Link] bis hin zu komplizierten
Projekten wie der x0xbox (einem Nachbau der legendären TR-303
Groovebox von Ladyada), irrsinnig vielen verschiedenen Synthesi-
zermodulen (siehe auch Kapitel 10), Robotern, selbstfahrenden
Autos und Ähnlichem. Das Löten eröffnet also eine riesige Welt an
Möglichkeiten.

Lochrasterplatinen
Die einfachste Art, eine Schaltung von einem Steckbrett auf eine
Platine zu bringen, ist die Benutzung einer Lochrasterplatine. Diese
gibt es in verschiedenen Formen. Sie bestehen aus einer Grund-
platte (meistens aus Epoxid, manchmal auch aus Karton), auf der
in regelmäßigen Abständen Löcher eingestanzt sind. Diese Löcher
sind von einer kleinen Kupferschicht umgeben und auf manchen
Platinen auch schon rudimentär verknüpft (in sogenannten Rails,
Verknüpfungen, die sich über das ganze Board ziehen). Dort lassen
sich Komponenten hindurchstecken, ähnlich wie bei einem Steck-
brett. Die Beinchen dieser Komponenten werden dann an die Kup-
ferschicht gelötet, siehe Abschnitt »Löten«.
Wie man sich leicht vorstellen kann, tauchen hier deutlich mehr
Probleme auf, als wenn eine Schaltung auf einem Steckbrett zusam-
mensetzt wird. Ist ein Bauteil schon angelötet, ist es nur schwer
wieder zu lösen. Weiterhin dürfen sich Drähte nicht kreuzen, weil

Löten 65
Abbildung 2-21
Gelötete Lochrasterplatine

es bei einer Berührung zu einem Kurzschluss zwischen zwei Leitun-


gen kommt. Benutzt man allerdings isolierte Kabel, die sich kreuz
und quer überschneiden, wird die Schaltung sehr schnell unüber-
sichtlich. Es ist auch möglich, dass man plötzlich feststellt, dass
eine bestimmte Leitung gar nicht ziehbar ist, weil es keinen Platz
mehr auf der Platine gibt.
Deswegen ist es sehr wichtig, sich im Voraus Gedanken zu machen,
wie die Bauteile angeordnet und miteinander verknüpft werden sol-
len. Es ist z.B. möglich, die Schaltung auf kariertem Papier zu
zeichnen und dort die Bauteile anzuordnen. Als Grundregel gilt,
dass alle Leitungen auf der Unterseite der Platine in vertikaler Rich-
tung und vereinzelte Verknüpfungen dann auf der Oberseite hori-
zontal mit einem weiteren Draht gezogen werden. Dadurch bleibt
die Schaltung übersichtlich, und es ist einfach, sie zu erweitern.
Dieses Vorgehen ähnelt dem eigentlichen Entwerfen von Platinen
und ist eine Kunst für sich. Übung macht den Meister, und nach
einigen Versuchen steht keiner Schaltung mehr die Platine im Weg!
Es ist auch möglich, ein richtiges Entwurfsprogramm für Platinen
zu verwenden (z.B. EAGLE, KiCad oder gEDA, siehe oben im
Abschnitt »Schaltbilder«).

Lötkolben und Lötzinn


Wenn der Entwurf für die Schaltung steht, ist es Zeit, ans Löten zu
gehen. Hierbei werden elektronische Bauteile mit geschmolzenem
Metall verbunden und auf eine Platine montiert (im Gegensatz zu
einem Steckbrett, wo die Bauteile nur eingesteckt und mit Drähten
verknüpft werden). Die Metallelemente der Platine (die Leitungen)

66 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
und der Bauteile (die Drahtbeinchen) werden mit der Spitze des
Lötkolbens erhitzt, und ein drittes Metall (das man Lötzinn oder
Lot nennt) wird zum Schmelzen gebracht. Das geschmolzene
Lötzinn haftet an beiden Metalloberflächen (auf Platinen wird
meistens Kupfer verwendet) und erhärtet sich beim Kühlen, sodass
es Bauteil und Platine zusammenhält.
In diesem Abschnitt werden die verschiedenen Werkzeuge und Ver-
brauchsmaterialien vorgestellt, die beim Löten verwendet werden.
Das wichtigste Werkzeug ist natürlich der Lötkolben. Er besteht
aus einer kleinen Lötstation (es gibt auch Lötkolben, die direkt an
die Stromversorgung angeschlossen werden), mit der der Lötkol-
ben an- und ausgeschaltet wird, dem Kolben an sich, der aus einem
Griff und einem Heizelement besteht und über ein Kabel an die
Lötstation angeschlossen ist, und einer Lötspitze aus Metall, mit
der die eigentliche Lötarbeit durchgeführt wird.
Es gibt sehr viele Lötkolben, die man käuflich erwerben kann, je
nachdem, welche Eigenschaften gewünscht sind. Auf zwei Dinge
sollte geachtet werden: Zunächst die Leistung, die der Lötkolben
erbringen kann. Diese wird in Watt gemessen und beeinflusst, wie
schnell ein Kolben seine Lötspitze erhitzen kann. Die andere wich-
tige Eigenschaft ist, dass der Lötkolben über eine Temperaturrege-
lung verfügen sollte. Dadurch lässt sich die Temperatur der Spitze
einstellen und je nach benutzten Bauteilen und zu lötenden Flächen
(für größere Bauteile und Flächen wird mehr Leistung benötigt)
verändern. Besonders interessant sind Lötkolben mit automati-
scher Temperaturregelung, die die Leistung immer so anpassen,
dass die Lötspitze die gewünschte Temperatur hat. Für elektroni-
sche Schaltungen braucht man ein Lötkolben, der ungefähr 25 bis
45 Watt Leistung hat. Bei größerer Leistung besteht die Gefahr,
dass Bauteile und Platine beschädigt werden, und bei kleinerer
Leistung heizt der Kolben das Lötzinn nicht genug, was die Gefahr
schlechter Lötverbindungen erhöht.
Die Spitze des Lötkolbens ist praktisch gesehen der wichtigste Teil
des Lötkolbens. Es ist wichtig, eine gute Lötspitze auszusuchen
(aus Eisen, nicht aus Kupfer). Je dicker die Spitze ist, desto mehr
Hitze kann an die zu lötenden Bauteile übertragen werden, aber
umso vorsichtiger muss dann vorgegangen werden, um nicht
angrenzende Bauteile und Lötpunkte mit zu erhitzen. Mit einer
kleineren Spitze ist es zwar einfacher, präzise zu arbeiten, durch die
geringere Hitzeübertragung ist es allerdings schwieriger, gute Löt-
punkte zu erzeugen. Besonders wichtig ist, dass die Spitze nicht

Löten 67
oxidiert. Sonst überträgt sie keine Hitze mehr, und es wird sehr
schwer, sauber zu löten. Deswegen muss sie regelmäßig gesäubert
und anschließend mit Lötzinn geschützt werden (es wird ein biss-
chen Lötzinn auf der Spitze geschmolzen und dort gelassen). Säu-
bern kann man die Spitze mit einem kleinen nassen Schwamm
(allerdings nicht, wenn bleifreies Lötzinn verwendet wird) oder z.B.
mit Stahlwolle. Es kann vorkommen, dass nach einiger Zeit die Löt-
spitze, besonders wenn sie schlecht gepflegt wird, komplett oxi-
diert und nicht mehr zum Löten verwendet werden kann. Bei den
meisten Lötkolben lässt sich die Lötspitze austauschen; vor dem
Austauschen sollte die Spitze natürlich abgekühlt sein.

Abbildung 2-22
Lötkolben

Das zweite wichtige Element beim Löten ist das Lötzinn. Auch hier
gibt es eine große Menge verschiedener Arten, insbesondere seit in
Europa die ROHS-Regelung in Kraft getreten ist, die für die indus-
trielle Fertigung bleifreies Lötzinn vorschreibt. Im Hobbybereich ist
es allerdings immer noch möglich, mit bleihaltigem Lötzinn zu
arbeiten, was auch deutlich einfacher ist, denn bleifreies Lötzinn
hat einen deutlich höheren Schmelzpunkt und benötigt starke
Flussmittel. Diese sind schädlich und man kommt gerade beim
Handlöten leicht mit ihnen in Kontakt. Als Lötzinn für die Projekte
in diesem Buch und für weitere Hobbyelektronikprojekte sei nor-
males bleihaltiges 60/40-Lötzinn mit Flussmittelkern empfohlen.
Das bedeutet, dass 60% aus Zinn bestehen und 40% aus Blei.
Wegen der enthaltenen Flussmittel (die dazu verwendet werden,
die Metalle vor dem Verbinden zu säubern, um das Anhaften des
Lötzinns zu erleichtern) lässt sich damit sehr gut arbeiten. Verfüg-

68 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
bar ist es in kleinen Drahtspulen mit verschiedenen Durchmessern.
Es ist empfehlenswert, eher dünnes Lötzinn zu nehmen, weil sich
dadurch die aufgetragene Menge einfacher kontrollieren lässt.
Praktisch sind zum Beispiel Spulen mit 0,5 mm Durchmesser.

Abbildung 2-23
Dritte Hand

Hilfreich beim Zusammenlöten von komplizierteren Schaltungen


ist eine kleine Tischzange, die man dritte Hand nennt. In ihren
Klemmen kann man zum Beispiel eine Platine einspannen, sodass
man Bauteile leichter einstecken, festhalten und anlöten kann. Es
ist auch möglich, damit einzelne mechanischen Komponenten fest-
zuhalten. Kleiner Tipp am Rande: Man kann auch Lötzinn so ver-
biegen, dass es von selbst auf der Tischoberfläche hält, sodass man
einfacher Komponenten anlöten oder Kabel verzinnen kann.

Löten
Der eigentliche Lötvorgang ist sehr einfach. Als Erstes muss ein
Bauteil durch die Löcher in der Platine (sei es auf einer Lochraster-
platine oder auf einer richtigen) gesteckt und dort festgehalten wer-
den. Das kann man entweder mit einer dritten Hand machen oder
einfach, indem man die Beinchen des Bauteils leicht verbiegt,
sodass es von selbst hängenbleibt. Im nächsten Schritt werden mit
dem Lötkolben in der einen Hand und mit dem Lötzinn in der
anderen das Beinchen und die Leitung auf der Platine erhitzt. Nach
ein oder zwei Sekunden ist die Stelle heiß genug, dass man das
Lötzinn anbringen und an die Lötspitze halten kann. Das Lötzinn

Löten 69
schmilzt sofort (wenn die Temperatur des Lötkolbens richtig einge-
stellt ist – ca. 300 Grad Celsius für bleihaltiges Lötzinn und 350 bis
400 Grad für bleifreies) und verteilt sich auf Platine und Beinchen.
Anschließend werden Lötkolben und Lötzinn entfernt, der Löt-
punkt kühlt ab, und das Bauteil ist mit der Platine verbunden. Der
erzeugte Lötpunkt sollte glatt und glänzend sein (bei bestimmten
bleifreien Lötzinnen sind die Lötpunkte allerdings immer grau und
matt) und das komplette Loch auf der Platine überdecken. Ist der
Lötpunkt matt und merkwürdig geformt, bildet er mit hoher Wahr-
scheinlichkeit eine kalte Lötstelle, die schlecht oder gar nicht leitet
und wahrscheinlich auch leicht durch mechanische Belastung
bricht.
Eine wichtige Regel für den Lötvorgang ist, dass weniger Lötzinn
besser ist. Es sollte immer nur so viel Lötzinn angebracht werden,
wie ausreicht, um eine stabile Verbindung herzustellen. Bei zu viel
Lötzinn besteht die Gefahr, dass sich ein kleines Lötkügelchen bil-
det, das unter Umständen nicht richtig leitet. Ein weiterer wichtiger
Punkt ist, dass der Vorgang schnell ausgeführt werden sollte. Die
verschiedenen Schritte sollten zusammen nicht mehr als fünf
Sekunden dauern. Je länger an einer Lötstelle geheizt wird, desto
mehr steigt die Wahrscheinlichkeit, dass sowohl Bauteil als auch
Platine beschädigt werden (gerade bei Lochrasterplatinen kommt
es vor, dass sich die Kupferschicht vom Platinenmaterial löst). Je
länger das Lötzinn erhitzt wird, desto weniger Flussmittel enthält es
(weil dieses sehr schnell verdampft). Wenn kein Flussmittel mehr
vorhanden ist, fließt das Lötzinn nicht mehr richtig und bleibt an
Lötkolben, Bauteil und Platine haften, sodass er sich nicht mehr
sauber verarbeiten lässt: Es kommt zu einer kalten Lötstelle. In die-
sen Fällen lässt sich das Problem durch Hinzufügen von Flussmittel
oder durch Entfernen des Lötzinns lösen (siehe nächster Abschnitt
»Entlöten«).
Nachdem ein oder mehrere Lötpunkte bearbeitet worden sind,
muss die Spitze des Lötkolbens gereinigt werden. Dazu kommt der
zuvor erwähnte Schwamm oder Stahlwolle zum Einsatz. Die Löt-
spitze sollte stets leicht von Zinn bedeckt und glänzend sein, um
Oxidation zu vermeiden.
Um Kabel und Drähte anzulöten, müssen die abisolierten Enden der
Kabel verzinnt werden. Bei Litze ist es praktisch, die einzelnen Kup-
ferdrähte zusammenzudrehen, sodass sie nicht abstehen. Anschlie-
ßend wird das Ende des Kabels leicht erhitzt und mit Lötzinn
bedeckt. Dadurch lässt sich ein Kabel leicht an einem Bauteil befes-

70 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
tigen, weil das zuvor verzinnte Ende beim Aufheizen gleich angelö-
tet wird.
Um Leiterbahnen auf einer Lochrasterplatine herzustellen, wird oft
verzinnter Draht verwendet (mit Kupferlack bedeckter Draht funk-
tioniert nicht so gut, weil diese Lackisolierung erst weggebrannt
werden muss). Es ist wichtig, bei Drähten, die geknickt werden,
alle möglichen Kanten auf der Lochrasterplatine zu befestigen,
damit sich die Drähte nicht lösen oder verbiegen und so Kurz-
schlüsse erzeugen.

Entlöten
Trotz aller Vorsicht und Übung kommt es immer wieder vor, dass
ein Bauteil entweder falsch angelötet wird oder beim Löten ein Feh-
ler passiert, wenn zum Beispiel zwei benachbarte Lötpunkte aus
Versehen verbunden werden. In diesen Fällen muss die fehlerhafte
Stelle entlötet werden. Dazu gibt es verschiedene Möglichkeiten:
Bei einem Bauteil müssen alle Beinchen auf einmal entlötet werden,
damit es auch ausgesteckt werden kann. Im einfachsten Fall (wenn
z.B. die Beinchen nahe beieinander liegen) können alle Beinchen
auf einmal erhitzt werden, indem man den Lötkolben schräg hält
(dabei auf mögliche Verbrennungsgefahr achten!) oder noch mehr
Lötzinn auf die zu entlötenden Stellen gibt, damit alle Stellen ver-
bunden sind. Während eine Stelle erhitzt wird, kann man dann das
Bauteil entfernen (hier muss auch darauf geachtet werden, dass es
nicht zu Verbrennungen kommt, weil das Bauteil und besonders
seine Beine heiß sind). Geschwindigkeit ist dabei auch von Vorteil,
weil dadurch die Bauteile nicht beschädigt werden. Beim Heraus-
ziehen muss darauf geachtet werden, dass die Lötstellen auch wirk-
lich geschmolzen sind, da man sonst leicht die Platine beschädigen
kann, wenn sich Leiterbahnen bzw. Kupferringe von ihr lösen.
Systematischer kann man vorgehen, indem man Entlötlitze verwen-
det. Entlötlitze ist eine eng geflochtene Kupferlitze, die Lötzinn
aufsaugen und so von der Platine abtragen kann. Die zu entlötende
Stelle wird durch die Litze hindurch erhitzt, und das geschmolzene
Lötzinn wird von der Litze aufgesaugt. Wenn anschließend die
Lötstelle frei von Zinn ist, können die Bauteile entfernt werden.
Hier muss darauf geachtet werden, dass die Stellen wirklich sauber
und frei sind, weil sonst die Platine beim Herausziehen beschädigt
werden kann. Da die Litze aus Kupfer ist, wird auch sie sehr
schnell heiß.

Löten 71
Alternativ kann man auch eine sogenannte Entlötpumpe verwen-
den, um Lötzinn von der Platine abzutragen. Die Entlötpumpe
muss zuerst geladen werden, indem die interne Feder gespannt
wird. Anschließend wird die zu entlötende Stelle mit dem Lötkol-
ben erhitzt, die Entlötpumpe sehr nah darübergehalten und das
geschmolzene Lötzinn aufgesaugt, indem der Pumpentaster, der die
Feder auslöst, gedrückt wird. Dadurch wird das Zinn in die Pumpe
aufgenommen und von der Platine abgetragen. Beim nächsten
Aufladen der Pumpe wird das aufgesaugte Lötzinn nach außen
gepresst und muss entsorgt werden. Bei der Verwendung ist Vor-
sicht geboten, weil man mit ihr sehr leicht Platinen beschädigen
kann, wenn die Lötstelle nicht richtig erhitzt wurde.
Schließlich kann man z.B. für Chips oder mechanische Bauteile
auch mit einer Heißluftpistole, die auf 300 bis 350 Grad kalibriert
wird, großflächig entlöten. Die entsprechende Stelle wird mit der
Heißluft erhitzt, bis das Zinn schmilzt. Anschließend kann man
durch Umdrehen der Platine und leichtes Rütteln die Chips herun-
terfallen lassen. Bei diesem Vorgang können Chips schnell beschä-
digt werden, und der zu entlötende Bereich ist auch nicht sehr
präzise einzustellen. Auch wird die Platine bei dem Vorgang extrem
heiß, weshalb große Vorsicht geboten ist.

Sicherheit
Auch wenn Löten keine sonderlich gefährliche Aktivität ist, sollten
ein paar Sicherheitsregeln beachtet werden. Die wichtigste ist
natürlich, dass man den Lötkolben nicht an der Spitze berühren
sollte. Das klingt zwar selbstverständlich, ist aber in der Realität
doch nicht so einfach. Wie man auch schnell merkt, sind Metalle
besonders gute Hitzeleiter, sodass Bauteilbeinchen oder Drähte,
wenn sie mit dem Lötkolben erhitzt werden, schnell sehr heiß wer-
den und auch nicht sonderlich schnell abkühlen. Deswegen ist es
besser, beim Löten keinen direkten Kontakt zu erhitzten Metalltei-
len zu haben. Das gilt auch für Lötzinntropfen, die beim Löten
abfallen. Diese können auch nach Minuten noch extrem heiß und
geschmolzen sein. Beim Löten kommt es auch schnell zu kleinen
Spritzern von Flussmittel und Lötzinn, weswegen es wichtig ist,
eine Brille zu tragen, damit diese Spritzer nicht in die Augen gelan-
gen. Es ist natürlich auch sinnvoll, den PC nicht in der unmittelba-
ren Nähe des Lötkolbens zu verwenden, besonders wenn es sich
dabei um einen Laptop handelt: Zu schnell kann es passieren, dass
die heiße Spitze an die Tastatur kommt und eine Taste zum

72 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Schmelzen bringt oder im schlimmsten Fall sogar ein Loch in den
Monitor brennt.
Beim Löten entstehen auch Dämpfe, die auf Dauer nicht gesund
sind (besonders die Flussmitteldämpfe können allergische Reaktio-
nen auslösen). Deswegen ist es wichtig, auf eine gute Lüftung am
Lötplatz zu achten. Für viele Projekte reicht es schon, das Fenster
aufzumachen. Es ist aber auch möglich, eine kleine Rauchabzugs-
einrichtung, die den Rauch mit einem Ventilator abzieht, in der
Nähe des Lötplatzes aufzubauen. Dadurch werden die Dämpfe
abgezogen und gelangen nicht in Ihre Lunge. Man kann sich auch
eine solche Abzugseinrichtung selber mit einem kleinen Ventilator
bauen. Wenn bleifreies Lötzinn verwendet wird, ist eine solche
Abzugseinrichtung quasi unabdingbar, weil die verwendeten Fluss-
mittel viel aggressiver sind. Wegen dieser Chemikalien und des
Bleis im Lötzinn ist es wichtig, nach dem Löten gründlich die
Hände zu waschen.

Fehlersuche in elektronischen Schaltungen


Wie man beim Basteln schnell feststellen kann, wird ein Großteil
der Zeit beim Arbeiten an elektronischen Schaltungen und Projek-
ten damit verbracht, Fehler zu identifizieren, zu isolieren und korri-
gieren. Das klingt natürlich nicht sehr erholsam und erfüllend, aber
das Beheben eines Fehlers oder eines Problems ist eine sehr befrie-
digende Tätigkeit. Auch hier muss man allerdings mit System vor-
gehen, weil sonst schnell noch mehr Fehler eingebaut werden, bis
am Ende vom schönen ursprünglichen Projekt nur noch ein großes
Chaos übrig bleibt.
Häufige Fehlerquellen in Arduino-Projekten sind natürlich fehler-
hafte Schaltungen (weil z.B. ein bestimmtes Bauteil falsch ange-
schlossen wurde oder falsch angesprochen wird). Auch mechanische
und elektrische Probleme (z.B. Wackelkontakte oder fehlerhafte
Bauteile) können zu interessanten Ergebnisse führen. Da in Ardu-
ino-Projekten auch Software eine große Rolle spielt, können viele
Probleme von einem Fehler in der Programmierung stammen. Elek-
tronische Schaltungen und Mikrocontroller-Programme (also Pro-
gramme, die auf sehr kleinen Prozessoren laufen, die keinen
Bildschirm oder keine Tastatur haben) sind eine ganz eigene Welt.
Hier können obskure Probleme sehr wohl durch Fehler in der Soft-
ware verursacht werden, es ist aber umgekehrt auch möglich, dass
das scheinbar komplett zufällige Verhalten der Schaltung daher

Fehlersuche in elektronischen Schaltungen 73


rührt, dass ein Chip nicht mit Strom versorgt wird. Umso wichtiger
ist es also, bei der Fehlersuche systematisch und Schritt für Schritt
vorzugehen. In diesem Abschnitt werden einige Fehlerquellen vorge-
stellt sowie verschiedene Werkzeuge, mit denen sich Probleme in
elektronischen Schaltungen identifizieren lassen. Nach einiger Zeit
wird die Fehlersuche zu einer Selbstverständlichkeit, und es entwi-
ckelt sich allmählich eine Art Bauchgefühl dafür, welche Bauteile
sich falsch verhalten könnten, welche Softwarekonstrukte anfälliger
sind und welche dunklen Kräfte mal wieder Unheil stiften. Jeder
Bastler hat seine eigenen Kriegsgeschichten über den unheilbaren
Bug vom Sommer 1999 oder die gefürchtete asiatische Temperatur-
sensortransistorverstärkungsschaltung.
Der wichtigste Schritt bei der Fehlersuche wird hier gleich zuerst
verraten: tief durchatmen und eine Pause machen. Manchmal
reicht eine erholsame Nacht oder ein kleiner Spaziergang, um
plötzlich einen Fehler zu entdecken. Für die Autoren dieses Buchs
gibt es den »Point of no return«. Ab einer gewissen Uhrzeit (meis-
tens gegen 3 Uhr morgens) ist ein Punkt erreicht, an dem jeder Auf-
wand den Fehler nur noch schlimmer macht. Dann wird
beschlossen, den Arbeitsplatz ein bisschen aufzuräumen und am
nächsten Tag mit frischen Kräften weiterzumachen.
Der zweitwichtigste Schritt bei der Fehlersuche ist, die Schaltung
einer Testperson zu erklären (z.B. der Lebensgefährtin oder der
nächstbesten Person, die vorbeiläuft). Dabei ist es meistens relativ
unwichtig, wie gut sich diese Person mit dem Thema auskennt,
denn meistens wird beim Vortragen und Erklären des Problems die
Fehlerquelle sofort klar. Unter Programmierern wird dieser Vor-
gang »Rubberducking« genannt (von englisch »Rubber Duck«,
Plastikente), weil manche Programmierer sich eine Plastikente auf
den Bildschirm stellen und ihr, die nun wirklich keine Program-
mierexpertin ist, bei Fehlern im Programm die möglichen Ursachen
vortragen.
Die Fehlersuche kann man in verschiedene Bereiche aufteilen. Der
erste Bereich ist das Verstehen der Schaltung und der Software:
Hierbei sollte klar sein, wie die Schaltung funktioniert, welche
Spannungen an welcher Stelle anliegen sollten, wie diese sich ver-
ändern, wie jedes Bauteil funktioniert und wie die Software sich zu
verhalten hat. Bei Programmen sollte klar sein, welche Funktion
welche Auswirkungen hat, von wo sie wie oft aufgerufen wird, wel-
che Libraries verwendet werden, welche Variablen an welcher
Stelle geschrieben und gelesen werden und wie der generelle Pro-

74 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
grammablauf gestaltet ist. Erst wenn die Schaltung richtig ver-
standen wurde, kann man beurteilen, ob Teilbereiche sich nicht so
verhalten, wie sie sollten, ob ein Bauteil seine Aufgabe nicht erfüllt,
oder ob es bei der Programmausführung zu Problemen kommt.
Deswegen ist es natürlich sinnvoll, Schritt für Schritt vorzugehen
und erst mit sehr einfachen Schaltungen und Projekten anzufangen,
bis man mit ihnen gut vertraut ist. Anschließend kann man darauf
aufbauend immer kompliziertere Projekte bauen.
Der zweite Bereich ist das Vereinfachen und Aufteilen des Projekts
in kleine Bereiche, die sich getrennt testen lassen. Besteht ein Pro-
jekt aus einem Temperatursensor, einer LED, einer Tastatur und
einer Servosteuerungsschaltung, ist es sinnvoll, jedes dieser Bauteile
und Schaltungen getrennt zu überprüfen. So ist gewährleistet, dass
keine Interaktion zwischen verschiedenen Bauteilen und Pro-
grammteilen Ursache des Problems ist. Durch diese Aufteilung
wird auch die Komplexität der Schaltung und der Software drama-
tisch reduziert. Ist etwa die LED falsch herum angeschlossen, lässt
sich das in einem separaten Test, bei dem man nur die LED an- und
ausschaltet, deutlich einfacher überprüfen, als wenn die LED theo-
retisch nur angeht, wenn die Temperatur über 50 Grad liegt. Bei
einer elektronischen Schaltung gibt es verschiedene Wege, die mög-
lichen Fehlerquellen in kleine Bereiche zu isolieren.
Der einfachste Schritt ist, die Software so zu verändern, dass nur
eine bestimmte Komponente angesprochen wird. Diese Testroutine
lässt sich am besten als neuer Sketch in der Arduino-Umgebung
schreiben. So kann für jede Teilschaltung (z.B. die LED, den
Temperatursensor, die Tastatur und die Servosteuerung in der obi-
gen Schaltung) getestet werden, ob sie funktioniert. Diese Test-
Sketches sollten so geschrieben werden, dass sie keine komplexe
Logik beinhalten (wie bei komplizierten Unterscheidungsfällen
oder einer Benutzerschnittstelle), sondern sie sollten der Reihe
nach verschiedene Funktionalitäten der untersuchten Schaltung
testen. Funktioniert die untersuchte Schaltung, kann man Schritt
für Schritt die weiteren Komponenten wieder mit in den Pro-
grammquellcode einbeziehen, bis die Schaltung nicht mehr funkti-
oniert. Ab dem Moment weiß man, wo das Problem zu suchen ist.
Wenn die mögliche Problemquelle identifiziert wurde, muss wieder
der erste Schritt »Verstehen« angewendet werden, um nachzuvoll-
ziehen, was fehlerhaft ist. Oft lohnt es sich auch, ein kleines Log-
buch zu führen, in das notiert wird, welche Fehlerquellen für
welche Probleme verantwortlich sind und wie sie zu beheben sind.

Fehlersuche in elektronischen Schaltungen 75


Oft passieren nämlich immer wieder dieselben Probleme, ohne dass
man sich im Eifer des Bastelns dran erinnern kann, was letztes Mal
verbessert wurde.
Um Komponenten in Software zu testen, kann man die Debugging-
methode »printf« anwenden. Dazu wird entweder die serielle
Schnittstelle oder eine andere Ausgabemöglichkeit wie ein Textdis-
play oder eine Reihe LEDs verwendet, um an bestimmten Stellen
im Programm Informationen auszugeben. So kann z.B. bei jedem
Durchlauf der Hauptschleife im Programm eine LED ein- und aus-
geschaltet werden. Leuchtet die LED konstant, lässt sich daraus
ableiten, dass das Programm irgendwo nach dem Anschalten hän-
gen geblieben ist. Durch Verschieben der Anschaltanweisung kann
man sich so Schritt für Schritt an die mögliche Fehlerquelle heran-
tasten. Es ist Vorsicht geboten bei komplizierten Ausgabemetho-
den, z.B. der seriellen Schnittstelle oder einem grafischen Display,
weil diese dann auch ein Teil des Problems werden können, wenn
sie z.B. zu lange bei der Ausführung brauchen oder andere Kompo-
nenten elektrisch beeinflussen.
Wenn die getesteten Komponenten immer noch nicht funktionie-
ren, ist es manchmal notwendig, die aufgebaute Schaltung auseinan-
derzunehmen, um sicherzustellen, dass nicht andere Komponenten
durch eine nicht erkannte Interaktion die Schaltung stören. Hier ist
es sinnvoll, vorsichtig, langsam und Schritt für Schritt vorzugehen.
Nach jeder Änderung der Schaltung sollte ein Testprogramm ausge-
führt werden, um nachzuprüfen, ob der Fehler verschwunden ist. Ist
das der Fall, dann war die letzte Veränderung wahrscheinlich die
Quelle des Fehlers. Deswegen ist es wichtig, immer nur eine Verän-
derung auf einmal zu machen, damit man anschließend feststellen
kann, was die Ursache war. Werden gleichzeitig fünf Funktionen
und drei Bauteile ausgetauscht, kann nicht mehr nachvollzogen
werden, was die Ursache des Problems war. Bei Software ist es oft
sinnvoll, Zwischenkopien des Programms bei Veränderungen zu
machen (und nicht große Blöcke auszukommentieren, weil das zu
einem schwer lesbaren und chaotischen Quelltext führt). Es gibt
besondere Programme, die genau diese Aufgabe übernehmen:
Source-Versioning-Systeme, die insbesondere für große Projekte
sinnvoll sind, im Rahmen von Arduino-Projekten oft jedoch ein bis-
schen zu umständlich sein können.
So kann man systematisch an die möglichen Fehlerquellen kom-
men. Allerdings bestätigt die Ausnahme die Regel, und manchmal
ist die Fehlerursache komplett woanders zu suchen. Solche Fälle

76 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
lassen sich nie voraussehen, und sie machen lustigerweise auch
einen großen Teil des Spaßes aus. Wenn man nach acht Stunden
endlich die Fehlerquelle identifiziert hat, die über fünf Umwege
und drei Winkel an einer komplett anderen Stelle einen Fehler aus-
gelöst hat, fühlt man sich so erfolgreich wie Superman.

Häufige Fehlerquellen
In diesem Abschnitt werden einige Arduino-spezifische Fehlerquel-
len und Testvorgänge beschrieben. Als Erstes sollte immer sicher-
gestellt werden, dass das Arduino-Board mit Strom versorgt ist. Das
Board wird über USB an den Rechner angeschlossen. Die Power-
LED sollte hellgrün leuchten. Leuchtet sie nur schwach oder flim-
mert, gibt es ein Problem mit der Stromversorgung: Entweder der
USB-Port am Computer ist defekt oder das Kabel funktioniert nicht
richtig. Ist die Power-LED komplett aus, gibt es ein Problem mit
dem Computer, mit dem Kabel oder mit dem Board an sich. In die-
sen Fällen sollten ein anderes Kabel und ein anderer Computer
ausprobiert werden. Wenn das Board immer noch nicht angeht,
sollte es gewechselt werden.
Wenn der Arduino zum ersten Mal angeschlossen wird, sollte das
Testprogramm, das mitgeliefert wird, ausgeführt werden und die
L-LED regelmäßig blinken. Wenn sie das nicht tut, ist vermutlich
schon ein anderes Programm hochgeladen worden. Das richtige
Funktionieren des Prozessors und der LED kann überprüft werden,
indem das LED-Testprogramm hochgeladen wird (siehe Kapitel 1).
Lässt es sich nicht hochladen, kann das an einem Softwareproblem
auf der Computerseite liegen (das ist auch die wahrscheinlichste
Erklärung, keine Panik). Es sollte überprüft werden, ob die richtige
serielle Schnittstelle und das richtige Boardmodell in der Arduino-
Entwicklungsumgebung ausgewählt ist (siehe ebenfalls Kapitel 1).
Weiterhin kann man unter Windows im Gerätemanager und unter
Mac OS X im Programm System Profiler, das unter /Programme/
Dienstanwendungen zu finden ist, nachprüfen, ob das Arduino-
Board tatsächlich als serielle Schnittstelle erkannt wird. Ist alles
korrekt eingestellt, sollte auch überprüft werden, ob die Arduino-
Entwicklungsumgebung die aktuellste Version ist.
Bei Schaltungen, die auf Steckbrettern aufgebaut werden, kann es
schnell zu kleinen elektrischen Fehlern kommen, weil die einge-
steckten Kabel leicht wieder herausrutschen können. Deswegen
sollte immer sichergestellt werden, dass alle Kabel richtig sitzen

Fehlersuche in elektronischen Schaltungen 77


und die abisolierten Enden sich nicht berühren. Weiterhin kommt
es manchmal auch vor, dass das Steckbrett an sich defekt ist, sodass
z.B. die horizontale Durchkontaktierung einzelner Stecklöcher
nicht mehr vorhanden ist oder im Gegenteil komplette Reihen
kurzgeschlossen sind. Wird ein elektrisches Problem vermutet,
sollte man ein bisschen an den Kabeln wackeln, um zu sehen, ob sie
vielleicht das Problem sind, und zur Not die Schaltung auf einem
anderem Bereich des Steckbretts aufbauen (oder auf einem kom-
plett anderem Steckbrett).
Die Erklärung für viele weitere Arduino-Fehler (insbesondere Soft-
ware- und Konfigurationsfehler) können Sie unter [Link]
[Link]/en/Main/FAQ nachlesen. Weiterhin sei auf die Arduino-
Foren unter [Link] hingewie-
sen, in denen viele hilfsbereite Arduino-Bastler und -Bastlerinnen
Projekte vorstellen und erklären und anderen Leute helfen. Die
Teilnehmer in den Arduino-Foren sind alle freiwillig dort und
möchten deshalb mit Respekt behandelt werden. Niemand ist ver-
pflichtet zu helfen und schon gar nicht, einfache Aufgaben wie etwa
das Googlen nach Informationen oder das Ausrechnen von Wider-
ständen für andere zu übernehmen. Als Regel guten Umgangs gilt
es, zunächst alle verfügbaren Anleitungen und Handbücher zu die-
sem Thema zu konsultieren und auch Suchmaschinen zu befragen.

Das Multimeter
Ein sehr wichtiges Werkzeug bei der Fehlersuche ist das Multime-
ter. Damit lassen sich verschiedenste elektrische Größen messen:
Strom, Spannung, Widerstand und Kontinuität. Bestimmte Multi-
meter erlauben auch das Messen von Kapazitäten und das Überprü-
fen und Verstärkungsmessen bei Transistoren (diese Funktionalität
ist allerdings oft nicht so wichtig). Es gibt analoge und digitale Mul-
timeter: Erstere stellen die gemessene Größe mit einer Nadelanzeige
dar und sind oft nicht sehr genau. Die meisten heutigen Multimeter
sind allerdings digital und zeigen die gemessenen Werte auf einem
LED-Display an.
Ein solches Gerät hat zwei Anschlüsse, an die sich Testspitzen
anschließen lassen. Eine (meistens schwarz) wird an den Masseste-
cker des Multimeters angeschlossen, während die andere (meistens
rot) an den V-Stecker angeschlossen wird. Oft besitzen Multimeter
zwei V-Stecker, von denen der eine für große Spannungen und
Ströme ausgelegt ist und bei normalen Arduino-Schaltungen nicht

78 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
zum Einsatz kommt. Mit diesen Testspitzen kann man beliebige
Punkte in der Schaltung berühren (natürlich müssen diese Punkte
metallisch sein, damit auch ein Kontakt entsteht) und so elektri-
sche Größen messen. Es ist wichtig, dass höchstens mit einer Hand
eine der Testspitzen direkt berührt wird. Kommen beide Testspit-
zen in Kontakt mit dem Körper des Benutzers, wird seine Haut
gleich mitgemessen, was insbesondere bei Widerständen zu fal-
schen Ergebnissen führen kann.
Die gewünschte Funktionalität des Multimeters lässt sich meistens
über ein Drehrad einstellen. Zu den verschiedenen Größen (A für
Strom, V für Spannung, R oder Ohm für Widerstand) lässt sich
auch die gewünschte Größenordnung einstellen.

Abbildung 2-24
Multimeter

Elektrische Verbindungen überprüfen


Eine sehr praktische Funktion des Multimeters, die meistens mit
einem kleinen Lautsprechersymbol gekennzeichnet ist, ist das
Überprüfen der elektrischen Kontinuität, also ob zwei Punkte in
einer Schaltung kurzgeschlossen sind. Bei der Überprüfung der
elektrischen Kontinuität ist egal, welche der Testspitzen man
benutzt. So kann man z.B. überprüfen, ob ein Bauteil tatsächlich an
das Arduino-Board angeschlossen ist, indem man eine Testspitze
auf das relevante Beinchen des Arduino legt und das andere an eins
der Beinchen des Bauteils. Piept das Multimeter (manchmal wird
auch eine Lampe eingeschaltet), besteht zwischen beiden Punkte

Fehlersuche in elektronischen Schaltungen 79


eine elektrische Verbindung. So lassen sich auch Kurzschlüsse zwi-
schen zwei Punkten feststellen, die eigentlich nicht verbunden sein
sollten. Wenn also vermutet wird, dass irgendwo eine Leitung
getrennt ist oder ein Kurzschluss besteht, kann man das schnell mit
dem Multimeter nachprüfen. Auch fehlerhafte Lötpunkte lassen
sich so erkennen. Es ist oft sinnvoll, vor dem Anschließen einer
neuen Schaltung zu überprüfen, ob vielleicht ein Kurzschluss zwi-
schen Masse und Versorgungsspannung besteht.

LED und Diodenrichtung messen


Eine weitere praktische Funktion des Multimeters ist das Überprü-
fen von LEDs und Dioden. Meistens ist diese Funktion mit dem
Symbol einer LED gekennzeichnet. Die rote Testspitze muss an die
positive Seite der LED gebracht werden (die Anode, siehe Kapitel 3)
und die schwarze Testspitze an die Kathode. Ist die LED richtig
angeschlossen und nicht defekt, wird sie leicht aufleuchten, weil
das Multimeter zum Testen der Dioden einen kleinen Strom fließen
lässt. Zusätzlich zeigt das Multimeter auf dem Display an, ob Strom
fließt (das kann von Multimeter zu Multimeter unterschiedlich
angezeigt werden). So kann man leicht überprüfen, in welche Rich-
tung eine LED angeschlossen werden muss. Ähnlich können auch
herkömmliche Dioden geprüft werden.

Widerstandswerte messen
Das Multimeter kann als Ohmmeter eingesetzt werden, um den
Widerstandswert von Widerständen zu messen. Beide Testspitzen
müssen an die Anschlüsse des Widerstandes gebracht werden.
Generell lassen sich Widerstände nur getrennt messen. Sind sie in
einer Schaltung eingebaut, wird der parallele Widerstand des Rests
der Schaltung auch mitgemessen, und der Ergebniswert ergibt nicht
viel Sinn. Die Ohmmeter-Funktionalität des Multimeters kann mit
dem Auswählen einer der Ohm-Größenordnungskategorien akti-
viert werden. Ist die Größenordnung des zu messenden Widerstan-
des unbekannt, kann man sich herantasten, indem man zunächst
die kleinste wählt.

Spannungen messen
Eine sehr wichtige Funktion zum Überprüfen von Schaltungen und
für die Suche nach Fehlern in einer Schaltung ist die Voltmeter-
Funktionalität des Multimeters. Ähnlich wie bei der Ohmmeter-

80 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
Funktionalität lassen sich hier verschiedene Spannungsgrößenord-
nungen auswählen. Da aber Spannungen in einer Arduino-Schal-
tung meistens unter 5 Volt liegen, kann man die entsprechende
Größenordnung gleich auswählen. Die schwarze Testspitze sollte
meistens an die Masse der Schaltung angeschlossen werden. Wird
der Multimeter oft eingesetzt, kann man zum Beispiel ein Kabel mit
Krokodilklemme verwenden, um die Masse fest zu verbinden. Mit
der roten Testspitze lassen sich dann Spannungen an verschiedenen
Stellen in der Schaltung untersuchen. Wichtig ist zum Beispiel zu
überprüfen, ob jedes Bauteil an den vorgesehenen Pins auch mit der
richtigen Spannung versorgt wird. Ist die Spannung an dem gemes-
sen Punkt variabel, hängt die Anzeige von der Geschwindigkeit des
Multimeters ab. Genaue Variationen lassen sich mit einem Multi-
meter nicht messen (dazu sollte ein Oszilloskop verwendet werden,
siehe unten), man kann aber grob überprüfen, ob zum Beispiel
Daten über eine serielle Leitung übertragen werden. Wichtig ist
beim Messen einer laufenden Schaltung, dass mit den Testspitzen
des Multimeters keine Kurzschlüsse erzeugt werden. Es ist dazu
praktisch, die Testspitze möglichst vertikal über die zu messenden
Punkte zu halten.

Ströme messen
Eine weitere Funktionalität zum Messen von laufenden Schaltun-
gen, die allerdings nicht so oft verwendet wird wie die Voltmeter-
Funktionalität, ist die Amperemeter-Funktionalität zum Messen
von Strömen. Dafür muss das Multimeter allerdings in Serie mit der
zu messenden Leitung eingebaut werden. Die Leitung muss also
getrennt und das Multimeter sozusagen als »Verbindungskabel«
eingesetzt werden. Dazu sind Krokodilklemmen sehr praktisch.
Wenn das Multimeter in Serie angeschlossen und die Ampereme-
ter-Funktionalität ausgewählt sind, werden die gemessenen Ströme
auf dem Display angezeigt. Damit kann man zum Beispiel den
Strom zu einer LED messen, um sicherzustellen, dass er den maxi-
malen Wert nicht überschreitet.

Das Oszilloskop
Ein nützliches und aufschlussreiches Werkzeug, das allerdings
nicht sehr erschwinglich ist, ist das Oszilloskop. Ein Oszilloskop ist
eine Art grafischer Voltmeter, mit dem Spannungen nach Zeit
gemessen werden. So ist es möglich, den zeitlichen Verlauf einzel-

Fehlersuche in elektronischen Schaltungen 81


ner Spannungen anzuzeigen. Damit kann zum Beispiel die Breite
von PWM-Pulsen gemessen werden (siehe Kapitel 3) oder die Aus-
gangsspannung verschiedener analoger Sensoren. Alle Funktionen
des Voltmeters können damit übernommen werden, um z.B. zu
überprüfen, ob Taster richtig schalten, Kommunikationsproto-
kolle richtig implementiert werden und Taktsignale für verschie-
dene Chips schnell genug sind. Ein Oszilloskop ist ein extrem
wertvolles Werkzeug, um kompliziertere Schaltungen zu untersu-
chen und generell einen grafischen Eindruck von der Elektronik zu
bekommen.

82 Kapitel 2: Physical Computing, elektrische Grundlagen und der Sprung ins kalte Wasser
KAPITEL 3 In diesem Kapitel:
• Erste Schritte
Workshop LED-Licht • Eine blinkende LED – das
»Hello World« des Physical
Computing

Nun soll also der erste Workshop beginnen, dessen Ziel es ist, eine
in allen Farben des Regenbogens leuchtende LED-Lampe zu
bauen. Natürlich geht es nicht darum festzulegen, welche Form
oder Farbe sie bekommen soll. Vielmehr wird dieses Kapitel hof-
fentlich genügend Anleitung geben, um im Anschluss ein eigenes
Licht programmieren zu können. Dieses kann aus einer oder meh-
reren Lichtquellen bestehen, die sich auch in ihrer Helligkeit ver-
ändern lassen, entweder durch Programmierung oder durch ein
Steuerungselement wie einen Schalter oder Drehknopf. Zudem
wird erklärt, wie man aus Rot, Grün und Blau Farben mischen
kann, um den Raum auch mehrfarbig zu erhellen. Am Ende des
Kapitels werden zusätzlich weitere Projekte beschrieben, die mit
Anleitungen aus dem Internet nachgebaut werden können. Auf
dem Weg durch das Kapitel werden die Grundlagen erläutert, die
zum Programmieren eines Arduino nötig sind. Dieser Workshop
richtet sich also auch an Leute, die soeben zum ersten Mal ein
Arduino-Board angeschlossen haben.

Erste Schritte
Um dieses Kapitel durchzuarbeiten, sind zum ersten Mal in diesem
Buch einige Bauteile nötig, nämlich
• vier LEDs (drei davon in Rot, Grün und Blau) und passende
100-Ohm-Widerstände,
• ein Taster,
• ein Schalter und
• ein Drehknopf.

83
Ein einfaches Arduino-Programm: Übersicht
Ein Arduino-Programm kann aus vielen miteinander verbundenen
Dateien bestehen, hat jedoch mindestens zwei Teile: das Setup und
die Hauptfunktion.

Setup
Der Setup-Teil des Programms ist gekennzeichnet durch die Funk-
tion setup():
void setup()
{
}

Zwischen die geschweiften Klammern werden nun alle Befehle


gesetzt, die vor dem Start des Hauptprogramms zum Einrichten des
Arduino benötigt werden, etwa die Festlegung einzelner Pins als
Ein- oder Ausgang.
Die Setup-Routine wird nur ein einziges Mal ausgeführt, wenn das
Board neu an eine Stromquelle (oder per USB an den Rechner)
angeschlossen oder neuer Code hochgeladen wird.

Loop
Die Funktion loop() wird auch als Hauptfunktion bezeichnet. Von
hier aus werden andere Bestandteile des Programms aufgerufen
oder Befehle abgearbeitet. Wie der Name schon verrät, läuft loop()
in einer Schleife, das heißt sie beginnt immer wieder von vorn,
sobald sie durchlaufen wurde. Ganz analog zur setup()-Funktion
sieht auch loop so aus:
void loop()
{
}

Eine blinkende LED – das »Hello World«


des Physical Computing
Beim Erlernen von Programmiersprachen ist es üblich, zuerst einen
einfachen Text auf dem Bildschirm auszugeben, um über die Spra-
che einen Gruß an die Welt hinaus zu senden. Auf dem Arduino
wird dieser Gruß mit Licht übermittelt, indem eine angeschlossene
LED zum Blinken gebracht wird. LEDs sind Licht aussendende
Dioden (light emitting diodes). Eine Diode ist ein Bauteil, das

84 Kapitel 3: Workshop LED-Licht


Strom nur in eine Richtung durchlässt, bei einer LED wird dabei
sichtbares oder unsichtbares Licht erzeugt.
Die Lichtfarbe einer LED hängt von ihrem Aufbau und den verwen-
deten Materialien ab. Lange Zeit war es nicht möglich, blaue und
weiße LEDs herzustellen. In vielen älteren Geräten gibt es daher
nur rote, grüne und gelbe LEDs. Durch neuere Technologien sind
mittlerweile fast alle Farben herstellbar. Trotzdem hat sich eine
Handvoll Farben etabliert. Mehr Informationen zu genauen Daten
verschiedener LEDs finden Sie im Anhang.

Hardware
LEDs besitzen ein langes und eines kurzes Beinchen, die Pins:
Anode und Kathode (kleine Merkhilfe: kurz = Kathode). Sind die
Pins bereits abgeschnitten worden, etwa um sie irgendwo zu verlö-
ten, findet man die Kathode an der Seite, an der die LED leicht
abgeflacht ist. Die LED wird mit der Anode, also der positiven
Seite, mit dem 100-Ohm-Widerstand verbunden, und dieser wird
am Arduino-Pin 13 angebracht, die negative Seite wird an der
Masse (GND, zu englisch »ground«) angeschlossen.

Abbildung 3-1
Arduino-Board

Eine blinkende LED – das »Hello World« des Physical Computing 85


Die LED beginnt zu leuchten, wenn durch sie ein Strom von ca. 2
bis 20 mA fließt. Zu viel Strom ist schädlich für die LED und kann
sie im schlimmsten Falle sofort zerstören. LEDs dürfen immer nur
mit einem Vorwiderstand oder einer speziellen Schaltung betrieben
werden, damit der Strom nicht zu groß wird.
• U = Spannung der Batterie/des Arduino-Boards (5 Volt)
• Uled = Flussspannung der LED (siehe Datenblatt, 3 Volt ist für
die meisten LEDs ein guter Richtwert)
• I = der gewünschte Strom durch die LED (ein sicherer Wert ist
10 mA)
• R = der zu berechnende Widerstand
• R = (U-Uled) / I
Bei 5 Volt und einer LED mit einer Flussspannung von 3 Volt ergibt
sich für 20 mA ein Vorwiderstand von 100 Ohm.

Programmierung
Zunächst wird Pin 13 mit einer Variablen verbunden. Das
geschieht, um im weiteren Verlauf des Programms auf ledPin1
zurückgreifen zu können. So kann schnell der Pin geändert werden,
ohne dass das ganze Programm durchgearbeitet werden muss.
Zudem steht so keine 13 im Programmverlauf, sondern eine ver-
ständliche Bezeichnung, die beim Lesen oder nachträglichen Bear-
beiten des Codes behilflich ist.
Variablen können verschiedene Datentypen besitzen, je nachdem,
welche Inhalte in ihnen gespeichert werden. In diesem Fall wird
eine ganze Zahl (»Integer«) gespeichert, dem Variablennamen wird
bei der Initialisierung also der Typ int vorangestellt.
Im Setup wird dieser Pin als Ausgang definiert. Im Hauptteil wird
schließlich ein digitales Signal auf diesen Ausgang geschrieben.
HIGH lässt dabei Strom durch den Ausgang fließen, während LOW
diesen Stromfluss unterbricht. So leuchtet die LED oder erlischt.
Dazwischen wird der Programmablauf mit dem Befehl delay für 1.
000 Millisekunden, also eine Sekunde, unterbrochen – es wird
gewartet.

Hinweis An jeder Stelle des Programms können Kommentare verfasst


werden. Sie werden mit // oder # markiert und beim Überset-
zen des Programms nicht berücksichtigt. Das erhöht die Ver-
ständlichkeit des Codes.

86 Kapitel 3: Workshop LED-Licht


int ledPin1 = 13; // LED an digitalen Pin 13 angeschlossen
void setup()
{
pinMode(ledPin1, OUTPUT); // setze digitalen Pin als Output
}
void loop()
{
digitalWrite(ledPin1, HIGH); // schalte LED ein
delay(1000); // warte eine Sekunde
digitalWrite(ledPin1, LOW); // schalte LED aus
delay(1000); // warte eine Sekunde
}

Aufgabe:
Eine zweite LED anschließen und beide wechselnd blinken lassen.

LEDs über Schalter/Taster steuern


Die digitalen Pins können auch als Eingabepins definiert werden. In
diesem Beispiel wird ein Schalter benutzt, um zwischen den beiden
LEDs hin- und herzuschalten. Dabei wird die if-else-Abfrage einge-
führt.
Taster und Schalter finden sich in jedem Haushalt: Entweder direkt
in der Wand, um das Licht ein-zuschalten, oder an Geräten, um
deren Funktionen einzustellen, zu starten oder zu stoppen.
Ein Schalter hat die zwei Stellungen Ein und Aus und verbleibt in
der zuletzt vom Benutzer gewählten Stellung.
Im Unterschied dazu springt ein Taster nach dem Loslassen sofort
wieder in den ungedrückten Zustand zurück. Er eignet sich also
nicht, um eine Lampe dauerhaft einzuschalten. Für die Verwen-
dung bei einer Klingel dagegen ist er ideal: Nach dem Betätigen soll
sie wieder aufhören zu schellen, der Taster springt zurück.
Schalter und Taster besitzen mindestens zwei Anschlüsse. Es gibt
sie aber in beliebig vielen Varianten:
• Mit drei Anschlüssen, als Umschalter (der mittlere Anschluss
wird wahlweise mit dem einen oder dem anderen Pin verbun-
den)
• Mit mehreren Schaltern
• Mit mehr als zwei Schaltstellungen (damit kann man verschie-
dene Aktionen mit einem einzigen Schalter auswählen)

Eine blinkende LED – das »Hello World« des Physical Computing 87


Abbildung 3-2
Das Schaltzeichen für einen Taster

Abbildung 3-3
Das Schaltzeichen für
einen Schalter

Abbildung 3-4
Verschiedene Schalter/Taster

Hardware
Um einen Schalter oder Taster mit dem Arduino abzufragen, wird
die eine Seite des Bauteils mit einem IO-Pin (in diesem Fall Pin 2)
und die andere mit GND verbunden.
Der Arduino erkennt an seinen IO-Pins hohe Spannungen (2–5
Volt) als eine 1 und kleinere Spannungen als eine 0. Ist der Taster/
Schalter gedrückt, wird der PIN des Arduino mit GND verbunden,
die gemessene Spannung ist also null.

88 Kapitel 3: Workshop LED-Licht


Abbildung 3-5
Schalteraufbau

Programmierung
Der Schalter wird, wie auch die LEDs, auf eine Variable gelegt. Im
Setup wird er als Eingang definiert:
pinMode(schalter, INPUT); // setze den digitalen Pin auf Input

Ist der Taster/Schalter nicht gedrückt, ist der Stromkreis unter-


brochen. Der IO-Pin hat dann keine Verbindung, weder mit GND
(0 Volt) noch mit VDD (5 Volt) – die vom Arduino gemessene
Spannung ist dann von vielen Umweltfaktoren abhängig und
schwankt zufällig hin und her. Um auch hier eine definierte Span-
nung an diesem PIN zu haben, wird ein sogenannter Pull-up-
Widerstand eingesetzt, der den Spannungspegel nach oben zieht.
Dieser kann entweder als richtiger Widerstand mit einem Wert von
1.000–100.000 verwendet werden, oder man verwendet im Ardu-
ino bereits integrierte Pull-up-Widerstände. Je größer der Wider-
stand, desto stromsparender, aber auch umso anfälliger für
elektromagnetische Störungen wird unsere Schaltung.

Eine blinkende LED – das »Hello World« des Physical Computing 89


Die internen Pull-up-Widerstände werden mit
digitalWrite(schalter, HIGH);

eingeschaltet.
Im Hauptteil wird durch digitalRead die Eingabe gelesen. Nun
wird eine if-else-Abfrage benutzt. Sie steht für eine Verzweigung im
Programmablauf: Wenn der Strom durch den Schalter fließt, ist das
Eingangssignal mit GND verbunden, also LOW, und der zweite Pro-
grammblock wird ausgeführt, der durch die geschweiften Klam-
mern begrenzt ist. Ansonsten liegt am Eingang durch den Pull-up
ein HIGH-Signal vor, also wird der erste Programmblock ausgeführt.
Vergleiche in if-Abfragen werden dabei immer mit zwei Gleich-
heitszeichen vorgenommen. Wird das Gegenteil benötigt, steht !=
für »ungleich«.
int ledPin1 = 13; // LED an digitalen Pin 13 angeschlossen
int ledPin2 = 12; // LED an digitalen Pin 12 angeschlossen
int schalter = 2; // Schalter an digitalen Pin 2 angeschlossen
void setup()
{
pinMode(ledPin1, OUTPUT); // setze digitalen Pin als Output
pinMode(ledPin2, OUTPUT); // setze digitalen Pin als Output
pinMode(schalter, INPUT); // setze digitalen Pin auf Input
digitalWrite(schalter, HIGH); // setze pullup-widerstand
}
void loop() {
int val = digitalRead(schalter); // lies Input vom Schalter
if (val == HIGH) { // wenn der Wert von val gleich HIGH ist
digitalWrite(ledPin1, HIGH); // schaltet LED1 ein
digitalWrite(ledPin2, LOW); // schaltet LED2 aus
}
else {
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
}
}

Vier LEDs nacheinander blinken lassen


Schließt man mehr als zwei LEDs an den Arduino an, wird es
schnell unübersichtlich: An jeder Stelle muss mehrfach der gleiche
Code geschrieben werden. Muss dieser Code nachträglich verän-
dert werden, treten schnell Probleme auf: Versteckt sich in einer
Zeile ein Fehler, müssen gleich mehrere ähnliche Zeilen angepasst
werden, um ihn zu korrigieren. Schnell wird dadurch auch eine der
duplizierten Zeilen übersehen. Generell gilt: Je kleiner der Pro-

90 Kapitel 3: Workshop LED-Licht


grammcode, desto einfacher ist er zu lesen und zu modifizieren,
und umso geringer ist auch die Gefahr, dass sich Fehler einschlei-
chen.
Im weiteren Verlauf dieses Beispiels wird erklärt, wie for-Schleifen
benutzt werden.

Setup
Vier LEDs werden an die digitalen Pins 10, 11, 12, 13 angeschlos-
sen, und ein Taster an Pin 2 (so wie der Schalter aus dem vorigen
Beispiel).

Programmierung
Ein Array (also eine Tabelle) fasst mehrere Variablen in einer
zusammen. Über sogenannte Indizes können die einzelnen Werte
dann als Elemente angesprochen werden.
Ein Array wird ähnlich wie eine Variable initialisiert. Mit
int led[4] = { 10,11,12,13};

werden die vier Werte 10, 11, 12 und 13 auf ein Array mit vier Ele-
menten gelegt. Da die Indizes bei 0 beginnen, ist der Wert von
led[0] nun also 10, der von led[1] 11 und so weiter.
Nun können diese Werte mit einer Schleife durchlaufen (»iteriert«)
werden. In diesem Fall wird for() zusammen mit einer Zählvari-
able i verwendet, die pro Schleifendurchlauf mit i++ um eins
erhöht wird.
Schleifen sind ein weiterer häufig benutzter Bestandteil von Pro-
grammiersprachen. Im Arduino-Hauptteil wird eine loop()-Schleife
verwendet, die unendlich lange weiterläuft (sofern kein Programm-
abbruch festgelegt wird). Hinzu kommt nun die for()-Schleife, der
drei Bestandteile hinzugefügt werden: Die Startbedingung (z.B.
»beginn bei null«), die Endbedingung (z.B. »zähl bis vier«) und die
Zählbedingung (z.B. »zähl immer eins dazu«).
Um Codezeilen zu sparen, wird die Zählvariable direkt in der
Schleife initialisiert:
for (int i = 0; i<4; i++) {
pinMode(led[i], OUTPUT);
}

Das bedeutet: Definiere i = 0, solange i kleiner als 4 ist, und erhöhe


i um 1 pro Schleifendurchlauf.

Eine blinkende LED – das »Hello World« des Physical Computing 91


Innerhalb der Schleife wird jeder der zuvor eingetragenen Pins als
Output festgelegt.

Funktionen
Um eine LED leuchten zu lassen, kann der Code der zweiten
Übung benutzt werden. Allerdings wäre dieser nun pro Schritt vier
statt bisher zwei Zeilen lang. Bei allen vier LEDs, die nacheinander
leuchten sollen, wären das also 16 Zeilen und nicht mehr vier. Zeit
für eine Vereinfachung!
Eine Funktion ist eine einzelne Einheit innerhalb eines Programms,
die fast überall aufgerufen werden kann. Sie erledigt selbstständig
eine Aufgabe und gibt, wenn gewünscht, einen Wert zurück. Je
nach Typ dieses Werts werden Funktionen und Variablen, also
Typen zugewiesen. Geben sie keinen Wert zurück, ist der Typ void.
Zudem nimmt eine Funktion Werte an, mit denen sie arbeiten soll
– sogenannte »Argumente«.
Um eine LED blinken zu lassen und die anderen auszuschalten,
muss der Funktion mitgeteilt werden, um welche LED es sich han-
delt. Gleichzeitig ist die Aufgabe der Funktion lediglich die Aus-
gabe von Signalen. Sie gibt also keinen Wert zurück.
Der Code
void setLED(int ledNr) {
}

deklariert eine Funktion setLED, die keinen Wert zurückgibt (also


void) und ein Argument vom Typ int annimmt. Das bedeutet, dass
dieser Funktion ein Wert mit dem Namen ledNr mitgegeben wird,
den diese Funktion nun verwenden kann. Dabei wird im Speicher
eine Kopie der Variablen angelegt und während der Funktion ver-
wendet. So kann die Funktion zwar mit dem Wert arbeiten, verän-
dert ihn aber nicht dauerhaft.
Nun wird jede LED durchlaufen und auf LOW gesetzt, sofern sie
nicht diejenige ist, die angeschaltet werden soll:
for (int i = 0;i<4;i++) {
if (i == ledNr) {
digitalWrite(led[i], HIGH);
}
else {
digitalWrite(led[i], LOW);
}

92 Kapitel 3: Workshop LED-Licht


Damit alles nach einem Durchlauf wieder von vorn beginnt, wird
nun eine weitere Funktion benötigt, die einen Zähler auf 0 zurück-
setzt, sobald sie 4 erreicht. Diese Funktion muss den Zähler, mit
dem sie arbeitet, wieder zurückgeben, sie ist also vom Typ int.
int setCount(int count) {
if (count == 3) {
count = 0;
}
else {
count++;
}
return count;
}

Hinweis Noch einfacher ließe sich das Problem mit dem »Modulo«
lösen, dem Rest, der beim Teilen durch eine Zahl entsteht.
Erhöht man pro loop()-Durchlauf die Variable count um eins,
kann man setLED jederzeit mit setLed(count mod 4) oder
auch setLed(count % 4) aufrufen. Es wird immer eine Zahl
zwischen 0 und 3 übergeben.

Da der Taster sehr schnell abgefragt wird, soll sein Impuls nur dann
zu einem Lichtwechsel führen, wenn er gerade gedrückt wurde.
Dazu wird eine Variable oldVal eingeführt, auf die pro loop()-
Durchlauf der aktuelle Wert des Eingangs geschrieben wird. Nur
wenn diese sich im Vergleich zum vorigen Durchlauf ändert, wird
die Funktion setLED wirklich aufgerufen.
Das sieht nun also wie folgt aus:
int led[4] = { 10,11,12,13};
int oldVal = 0;
int counter = 0;
int taster = 2;
void setup() {
for (int i = 0; i<4; i++) {
pinMode(led[i], OUTPUT);
}
void setLED(int ledNr) {
for (int i = 0;i<4;i++) {
if (i == ledNr) {
digitalWrite(led[i], HIGH);
}
else {
digitalWrite(led[i], LOW);
}
}
}

Eine blinkende LED – das »Hello World« des Physical Computing 93


int setCounter(int counter) {
if (counter == 3) {
counter = 0;
}
else {
counter++;
}
return counter;
}
void loop()
{
int val = digitalRead(taster); // lies Input vom Taster
if (val != oldVal && val == HIGH) {
counter = setCounter();
setLED(counter);
delay(10); // warte ein wenig
}
oldVal = val;
}

Die Debounce-Bibliothek
Möchte man den Taster als Umschalter verwenden, kann es oft zu
mehrfachen Betätigungen kommen, selbst wenn man eine Abfrage
wie die obige einbaut. Gegen dieses sogenannte »Prellen« hilft die
Debounce-Bibliothek, mit der wir jetzt einen kurzen Ausflug in die
Welt der Libraries machen.
Viele Anwendungen rund um Arduino sind im Prinzip recht ein-
fach, benötigen aber hohen Programmieraufwand. Zum Beispiel
möchte man einen bestimmten Sensor eigentlich einfach nur ausle-
sen oder einen Motor nur mit einer bestimmten Geschwindigkeit
betreiben. Die Technik dahinter ist aber recht komplex und benö-
tigt verschiedene Signale und Voreinstellungen vom Arduino.
Bibliotheken fassen diese Funktionen zusammen. Denn wer einmal
die Arbeit gemacht hat, kann sie auch anderen zur Verfügung stel-
len und sie über eine sogenannte API benutzen lassen. Der Begriff
API steht für »Application Programming Interface« und ist quasi
das Tor zur Bibliothek: ein Satz von Funktionen, mit denen die
komplexeren Funktionalitäten der Bibliothek verwendet werden
können. Für den Arduino gibt es eine ganze Reihe von Bibliothe-
ken, die zum Teil die Programmierung einfacher machen, so wie
die Debounce-Bibliothek, um die es hier geht. Wichtiger sind aber
diejenigen Bibliotheken, die Bauteile und Geräte ansteuern können.
Auf der Arduino-Webseite finden Sie Listen von Bibliotheken,
genauso wie im Verzeichnis von [Link]

94 Kapitel 3: Workshop LED-Licht


Unter Prellen oder »Bouncing« versteht man ein mechanisches Pro-
blem, das durch die Eigenschaft von Schaltern und Tastern hervor-
gerufen wird: Weil in diesen Bauteilen federnde Effekte auftreten,
öffnen und schließen sie sich beim Betätigen und Loslassen mehr-
mals, statt dass sofort ein elektrischer Kontakt zustande kommt.
Hiergegen hilft nur, dass nach einem Kontakt zunächst jede weitere
Eingabe vom Taster/Schalter für einige Millisekunden gesperrt
wird.
Bibliotheken werden mit dem Befehl include in den aktuellen
Sketch eingebunden. Damit sie beim Kompilieren auch gefunden
werden, muss der komplette Ordner mit der Bibliothek ins Ardu-
ino-Verzeichnis unter hardware\libraries kopiert werden. Nun kann
die Bibliothek auch in der Programmierumgebung über SKETCH →
IMPORT LIBRARIES eingefügt werden. Hat man die Debounce-Bibli-
othek von [Link] her-
untergeladen, entpackt und in das entsprechende Verzeichnis
kopiert, bindet man sie mit
#import <debounce.h>

in den Sketch ein. Nun stehen drei Funktionen zur Verfügung, die
es bisher in der Arduino-Programmiersprache noch nicht gab:
read(), update() und write(). Diese Funktionen gehören zu einem
Objekt, das die aktive Bibliothek repräsentiert. Objekte sind Daten-
und Funktionssammlungen. Das heißt, sie beherbergen neben den
API-Funktionen auch weitere Funktionalitäten und Datenstruktu-
ren. Man kann ein Objekt also mit einer Küche vergleichen, in der
Essen vorbereitet wird. Dabei werden Herde und Öfen bedient,
Teig vorgehalten und einzelne Gerichte gestapelt, bis eine Bestel-
lung beisammen ist. Über eine oder mehrere Luken, Türen oder
Zettelsysteme spricht die Bedienung mit dieser Küche und tauscht
Informationen oder Nahrungsmittel aus. Dabei bleibt natürlich
auch nicht alles zwischen Küche und Bedienung. Vielmehr gibt es
einen Hinterausgang, über den neue Rohstoffe bestellt und geliefert
werden.
Ein Objekt ist dabei immer die Instanz einer sogenannten Klasse.
Das bedeutet, dass die importierte Bibliothek auch mehrfach ver-
wendet werden kann, beispielsweise wenn man mehrere gleiche
Geräte an einen Arduino hängen möchte. Klassen sind die eigentli-
chen Programmierkonstrukte, die im laufenden Betrieb zu Objek-
ten werden. Sie verfügen zusätzlich über besondere Funktionen.

Eine blinkende LED – das »Hello World« des Physical Computing 95


Der Konstruktor wird zum Beispiel aufgerufen, wenn das Objekt
instanziiert, also erzeugt wird. Im Falle des Debouncers wird nun
ein Objekt erstellt, dem 20 Millisekunden Debounce-Zeit einge-
räumt werden:
// verbinde Taster mit Pin 5
int taster = 5;
// erschaffe ein neues Objekt vom Typ "debounce" mit 20
// Millisekunden Debounce-Zeit, verbunden an Pin 5
Debounce debouncer = Debounce( 20 , taster );

Im eigentlichen Programm können nun die oben erwähnten Funk-


tionen aufgerufen werden. Die Funktion update() prüft nach, ob
sich der Status geändert hat, und vermeldet das Ergebnis mit dem
Rückgabewert TRUE oder FALSE. Mit read() kann dann der derzei-
tige Pin-Status gelesen werden, man erhält also HIGH oder LOW
zurück. Um nun also die Informationen des Tasters korrekt zu
lesen, benötigt man
// Debouncer-Status updaten
[Link]();
// Wert über den Debouncer auslesen
int tasterVal = [Link]();

Die anderen Funktionen in der Biblitohek sind write() und inter-


val(). write() erlaubt das Senden eines digitalen Signals über den
Debouncer. Da der Pin schon festgelegt ist, wird als Argument nur
das Signal, also HIGH oder LOW, benötigt. Mit interval() lässt sich
schließlich das Debounce-Intervall ändern, ohne dass das Objekt
neu instanziiert werden muss.
Das gesamte Programm mit einer LED und der Debouncer-Biblio-
thek sieht also so aus:
#import <debounce.h>
// verbinde Taster mit Pin 5
int taster = 5;
// erschaffe ein neues Objekt vom Typ "debounce" mit 20
// Millisekunden Debounce-Zeit, verbunden an Pin 5
Debounce debouncer = Debounce( 20 , taster );
int ledPin1 = 13; // LED an digitalen Pin 13
// angeschlossen
int schalter = 2; // Schalter an digitalen Pin 2
// angeschlossen
void setup()
{
pinMode(ledPin1, OUTPUT); // setze digitalen Pin als Output
pinMode(schalter, INPUT); // setze digitalen Pin auf Input
digitalWrite(schalter, HIGH);
}

96 Kapitel 3: Workshop LED-Licht


void loop() {
// Debouncer-Status updaten
[Link]();
// Wert über den Debouncer auslesen
int tasterVal = [Link]();
if (tasterVal == HIGH) { // wenn der Wert von tasterVal
// gleich HIGH ist
digitalWrite(ledPin1, HIGH); // schaltet LED1 ein
digitalWrite(ledPin2, LOW); // schaltet LED2 aus
}
else {
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
}
}

Aufgabe:
Einen »Funkenhimmel« bauen, der so viele LEDs wie möglich
verwendet und sie zufällig blinken lässt.

Hinweis Die Funktion random(13) gibt bei jedem Aufruf eine neue zufäl-
lige Zahl zwischen 0 und 12 zurück.

LEDs mit Pulsweitenmodulation


verschieden hell leuchten lassen
Bis zu diesem Punkt gab es für die LEDs nur die zwei Zustände HIGH
und LOW, also An und Aus. Das liegt daran, dass über den Arduino
keine unterschiedlichen Stromstärken ausgegeben werden können.
Das menschliche Auge hingegen lässt sich recht leicht austricksen.
Da es nur 25 Bilder pro Sekunde wahrnehmen kann, kommt Fla-
ckern in Frequenzen, die weit darüber liegen, nicht mehr als sol-
ches an. Vielmehr erscheint uns das Licht als heller oder dunkler, je
nach Häufigkeit des Flackerns. Der Arduino hat diese sogenannte
Pulsweitenmodulation (PWM) auf sechs Pins direkt eingebaut.
Diese lassen sich nicht nur mit digitalWrite() ansprechen, son-
dern auch mit der Funktion analogWrite(), die nicht nur die Sig-
nale LOW und HIGH als Argumente annimmt, sondern 8 Bit
verarbeiten kann, also 255 unterschiedliche Werte.

Hardware
Eine LED an Pin 10 anschließen.

Eine blinkende LED – das »Hello World« des Physical Computing 97


Software
Die LED wird mit Pin 10 verbunden und als OUTPUT definiert. Das
Programm soll nun von 0 bis 255 zählen und pro Schritt ein »stär-
keres«, also schneller gepulstes Signal an den Ausgang senden.
Anschließend soll der Zähler wieder von 255 bis 0 laufen.
Dafür werden ein Zähler (counter) und ein Vorzeichenmarker
(changeMarker) initialisiert:
int counter = 0;
int changeMarker = 1;

Die Funktion changeCounter addiert nun pro Aufruf einmal change-


Marker zum counter. Erreicht der Counter den Wert 255 oder 0,
wird der changeMarker auf -1 bzw. 1 gesetzt:
int ledPin = 10
void setup() {
pinMode(ledPin, OUTPUT);
}
int counter = 0;
int changeMarker = 1;
int changeCounter() {
if (counter == 255) {
changeMarker = -1;
}
if (counter == 0) {
changeMarker = 1;
}
counter = counter + changeMarker;
return counter;
}

Nun steht einem pulsierenden Licht nichts mehr im Wege:


void loop()
{
counter = changeCounter();
analogWrite(led, counter);
delay(10); // ein bisschen warten ...
}

Beim genauen Hinsehen stellt man fest, dass das Licht nicht gleich-
mäßig pulsiert. Das liegt daran, dass das Auge das Licht nicht linear
wahrnimmt, also geradlinig, sondern als logarithmische Funktion.
Wenn die LED fast aus ist, sieht man kleinere Veränderungen sehr
stark; ist die LED fast ganz eingeschaltet, ändert sich praktisch gar
nichts mehr. Um diesem Umstand entgegenzuwirken, kann chan-
geCounter() zu einer aufwendigeren Version ausgebaut werden,
sodass der Logarithmus korrekt errechnet wird. Viel einfacher ist

98 Kapitel 3: Workshop LED-Licht


jedoch eine Wertetabelle, die uns diese Übersetzung abnimmt, sie
gilt für alle Projekte mit gedimmten LEDs. Für diesen Zweck rei-
chen 64 Werte aus, da die PWM mit ihren 256 Stufen keine weitere
Verfeinerung erlaubt:
int loga[64] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
16, 18, 20, 22, 25, 28, 30, 33, 36, 39, 42, 46, 49, 53, 56, 60,
64, 68, 72, 77, 81, 86, 90, 95, 100, 105, 110, 116, 121, 127, 132,
138, 144, 150, 156, 163, 169, 176, 182, 189, 196, 203, 210, 218,
225, 233, 240, 248, 255};

Das Programm muss nun an zwei Stellen geändert werden. In der


Hauptfunktion wird
analogWrite(led, counter)

ersetzt durch
analogWrite(led, loga[counter]);

Schließt man vier LEDs an, verändert sich im Prinzip nicht viel. Um
die LEDs in einer Welle pulsieren zu lassen, benötigt man vier
Counter und vier Marker:
int counter[4] = {0,32,63,32};
int changeMarker[4] = {1, 1, -1, -1};

Das wird nun auch in die Funktion changeCounter() eingebaut, die


nun in der Lage ist, einen der vier Counter bzw. Marker zu verän-
dern. Zudem werden die ersten beiden Zeilen geändert, sodass die
Funktion nun wie folgt aussieht:
void changeCounter(int i) {
if (counter[i] == 63) {
changeMarker[i] = -1;
}
if (counter[i] == 0) {
changeMarker[i] = 1;
}
counter[i] = counter[i] + changeMarker[i];
}

So wird nun auch die Hauptfunktion verändert:


void loop()
{
for (int i = 0;i<4;i++)
{
changeCounter(i); // verändere den Counter der LED i
analogWrite(led[i], loga[counter[i]]);
// setze die neue Helligkeit der LED i
}
delay(10); // ein bisschen warten ...
}

Eine blinkende LED – das »Hello World« des Physical Computing 99


Aufgabe:
Den Taster wieder anschließen und die Lichtstärke damit regulie-
ren lassen.

Mach es bunt
Nun kann schon die erste Lampe gebaut werden, die mit Farbver-
läufen eine gemütliche Atmosphäre im Raum schafft. Dazu werden
drei LEDs in den Grundfarben Rot, Grün und Blau benötigt. Mit
diesen Farben lassen sich durch Mischung alle weiteren Farben des
sichtbaren Spektrums erzeugen, indem man jede LED mit einer
entsprechenden Helligkeit pulst. Die folgende Lampe wählt zufällig
Farben aus und dimmt sich langsam von der einen zur anderen und
weiter zur nächsten.

Hardware
Drei LEDs in den Grundfarben Rot, Grün und Blau werden über
einen passenden Widerstand (100 Ohm) mit dem Arduino verbun-
den. Welcher Widerstand genau benötigt wird und mit welcher
Eingangsspannung und Stromstärke die LEDs betrieben werden,
hängt von der Bauart ab. Genauere Daten können Sie dem Daten-
blatt entnehmen. Es gibt auch fertige RGB-LEDs, die mit sechs
Beinen ausgestattet sind und somit auf die gleiche Weise ange-
schlossen werden wie drei einzelne. Je nach Stromstärke müssen
die Leuchtdioden an einen anderen Stromkreis angeschlossen wer-
den, besonders wenn eine stärkere Leistung erwartet wird. Am
Ende dieses Kapitels wird unter dem Stichwort »Mehr Power«
erläutert, wie man das zum Beispiel mit Transistoren machen
kann. Das folgende Programm geht davon aus, dass die rote LED
an Pin 9, die grüne an 10 und die blaue an 11 angeschlossen ist.

Programmierung
Wie weiter oben beschrieben, werden drei LEDs in einer Tabelle
initialisiert und mit den passenden Pins verbunden. Auch die Loga-
rithmustabelle wird benötigt. Zudem braucht man zwei Tabellen,
die Quell- und Zielfarbwert speichern.
// PINs für die RGB-LED
int ledPin[3] = { 9, 10, 11};
// Startfarbe

100 Kapitel 3: Workshop LED-Licht


int sourceValue[3] = { 0, 0, 0};
// Zielfarbe
int targetValue[3] = { 0, 0, 0};
// Überblendposition
int currentPos = 0;

In der Setup-Funktion werden die beiden Farben mit zufälligen Wer-


ten initialisiert und die verwendeten PINs als Ausgang geschaltet.
void setup()
{
for (int i = 0; i < 3; i++) {
// Startfarbe zufällig wählen
sourceValue[i] = random(64);
// Zielfarbe zufällig wählen
targetValue[i] = random(64);
// LED-Pin = Ausgang
pinMode(ledPin[i], OUTPUT);
}
}

currentPos wird jetzt der Mittelwert nach der Formel farbe = start ×
(128-currentPos) + ende × currentPos auf ihre entsprechende LED
geschrieben und die loop()-Funktion abgeschlossen:
void loop()
{
// für alle drei Grundfarben Mittelwert an der
// Stelle currentPos berechnen und ausgeben
for (int i = 0; i < 3; i++) {
int helligkeit = (sourceValue[i] * (128 – currentPos) +
targetValue[i] * currentPos)/128;
analogWrite(ledPin[i],helligkeit);
}
currentPos++;
if (currentPos > 128) {
for (int i = 0; i < 3; i++) {
sourceValue[i] = targetValue[i];
targetValue[i] = random(64);
}
currentPos = 0;
}
// 10ms warten.
delay(10);
}

Und fertig ist die Lampe! Nun kann damit experimentiert werden.
Mit Sicherheit finden sich viele Möglichkeiten, dieses Projekt zu
erweitern und anzupassen. Zum Beispiel könnte man eine weitere
RGB-LED anschließen und die aktuelle Farbe von einer zur ande-
ren wandern lassen.

Eine blinkende LED – das »Hello World« des Physical Computing 101
Helligkeit mit einem Drehknopf steuern
Zum Abschluss dieses Workshops soll nun die Helligkeit einer LED
mit einem Drehknopf gesteuert werden. Dazu wird ein sogenanntes
Potentiometer verwendet. Es besteht aus einem Metallstift, der auf
einer Fläche angebracht ist. Wird diese Fläche durch Drehen ent-
lang des Stiftes bewegt, verändert sich der Widerstand und es fließt
weniger Spannung an den Ausgang. Ein Potentiometer ist somit ein
sogenannter resistiver Sensor. Mehr Informationen über resistive
Sensoren finden Sie auch in Kapitel 7.
Die Messung erfolgt über den analogen Eingang, wobei das Signal
niemals genau ist. Abweichungen im Wert müssen bei der Pro-
grammierung berücksichtigt werden. Somit können nicht die vollen
1.024 Stufen ausgeschöpft werden, was angesichts von 256 mögli-
chen Helligkeitsstufen bei den pulsweitenmodulierten Digitalaus-
gängen allerdings kein Problem darstellt, zumal ohnehin nur die 64
Stufen aus der Tabelle verwendet werden sollen.

Hardware
An den Arduino wird zunächst eine LED an einen PWM-fähigen
Digitalausgang angeschlossen, in diesem Fall Ausgang 9. Zudem
wird ein Potentiometer mit dem mittleren Pin an den analogen Ein-
gang 0 angeschlossen, die anderen beiden Pins an GND und den 5-
Volt-Anschluss. Dabei kommt es darauf an, wie der Knopf gedreht
werden soll: Je nachdem, wie der Strom fließt (von links nach
rechts oder umgekehrt), muss auch gedreht werden, um die Span-
nung zu erhöhen oder zu senken.

Programmierung
Zunächst werden die beiden Pins festgelegt und im Setup als Ein-
bzw. Ausgang definiert. Zudem wird wieder die Tabelle für die Hel-
ligkeitsstufen verwendet.
int potPin = 0; // lege potPin als Pin 0 fest
int ledPin = 9; // lege ledPin als Pin 9 fest
int potiVal = 0; // eine Variable, um den Input zu speichern
int loga[64] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
16, 18, 20, 22, 25, 28, 30, 33, 36, 39, 42, 46, 49, 53, 56, 60,
64, 68, 72, 77, 81, 86, 90, 95, 100, 105, 110, 116, 121, 127, 132,
138, 144, 150, 156, 163, 169, 176, 182, 189, 196, 203, 210, 218,
225, 233, 240, 248, 255};
void setup() {
pinMode(ledPin, OUTPUT); // initialisiere ledPin als Output
}

102 Kapitel 3: Workshop LED-Licht


Abbildung 3-6
Aufbau für PWM-LE

Nun können der analoge Eingang gelesen und das Signal gespei-
chert werden. Anschließend werden das Signal durch 16 geteilt und
der Ausgangswert anhand des oben erklärten Sinus berechnet.
Schließlich wird der entsprechende Wert in der Logarithmustabelle
auf den digitalen Ausgang geschrieben, die LED wird nun vom
Potentiometer gesteuert.
void loop()
{
int potiVal = analogRead(potPin); // lies analoges
// Eingangssignal
potiVal = potiVal / 16; // teile den Signalwert durch 16
analogWrite(led, loga[potiVal]); // schreibe den Tabellenwert
// auf den Ausgang
delay(10);
}

Flower Power
Nicht nur die Helligkeit kann mit einem Potentiometer geregelt
werden, sondern auch die Wunschfarbe, passend zum Abendkleid.

Eine blinkende LED – das »Hello World« des Physical Computing 103
Dazu verwenden wir den Quellcode von »Mach es bunt« in diesem
Kapitel und verändern nur die Funktion loop(), sodass abhängig
von der Reglerstellung eine Farbe ausgewählt wird. Nun gibt es kei-
nen einfachen Weg durch alle Farben, es muss also ein bestimmter
Verlauf einprogrammiert werden. Die 1.024, die maximal vom
Potentiometer zurückgeliefert werden, teilen wir dazu in vier Teile
auf. Im ersten Teil dimmen wir von Rot nach Grün, im zweiten Teil
von Grün nach Blau, im dritten von Blau nach Rot, und mit dem
verbleibenden Teil dimmen wir nach Weiß. Durch die Logarith-
mustabelle benötigen wir Werte von 0–63 für jede Farbe, wir kön-
nen den Potentiometerwert also noch durch 4 teilen, um in jedem
Teilabschnitt 64 Punkte zu haben.
void loop() {
int potiVal = analogRead(potPin) / 4; // lies analoges
// Eingangssignal

if (potiVal < 64)


{ // fade Rot zu Grün
analogWrite(ledPin[0], loga[63-potiVal]);// Rot
analogWrite(ledPin[1], loga[potiVal]);// Grün
analogWrite(ledPin[2], loga[0]);// Blau
}
else if (potiVal < 128)
{ // fade Grün zu Blau
analogWrite(ledPin[0], loga[0]);// Rot
analogWrite(ledPin[1], loga[127 – potiVal)]);// Grün
analogWrite(ledPin[2], loga[potiVal – 64]);// Blau
}
else if (potiVal < 192)
{ // fade Blau zu Rot
analogWrite(ledPin[0], loga[potiVal – 128]);// Rot
analogWrite(ledPin[1], loga[0]);// Grün
analogWrite(ledPin[2], loga[191 – potiVal]);// Blau
}
else
{ // fade Rot zu Weiß
analogWrite(ledPin[0], loga[63]); // Rot
analogWrite(ledPin[1], loga[255-potiVal]);// Grün
analogWrite(ledPin[2], loga[255-potiVal]);// Blau
}
}

Mehr Power
Bis jetzt wurden nur sehr kleine LEDs mit dem Arduino gesteuert,
ein Pin kann nur ca. 20 mA Strom liefern. Bei einer 3-Volt-LED ent-
spricht das 0,06 Watt. Damit bekommt man natürlich kein Zimmer
erleuchtet.

104 Kapitel 3: Workshop LED-Licht


Für größere LED können Transistoren oder Mosfets (Metalloxid-
Halbleiter-Feldeffekttransistoren) verwendet werden, die schnell
genug sind, um auch PWM für das Dimmen der LEDs zu ermögli-
chen. Transistoren sind in der Lage, mit einem kleinen Signal auf
der einen Seite einen großen Stromkreis auf der anderen zu schalten.
Transistoren haben ihren Aufschwung in den 1960er Jahren erlebt,
als sie zum ersten Mal in Form von Feldeffekttransistoren auf Gal-
liumarsenid praktikabel genug wurden. Vorher hatte man Compu-
ter mit Vakuumröhren gebaut, die man günstig herstellen konnte
und die das einzige Schaltelement waren, das auch schnell genug
für diese Anforderungen war. Ein Transistor besteht aus drei
Anschlüssen: Basis, Emitter und Kollektor. Transistoren gibt es in
den beiden Polungen NPN und PNP. Ein NPN-Transistor als
Schalter ist am besten für die negative Seite der Last geeignet (LED,
Lampe, Motor usw.), PNP für die positive. Mehr Informationenen
zu Relais und größeren Stromstärken findet man unter anderem auf
der Arduino-Seite unter: [Link]
Learning/[Link] sowie bei der New York University unter http://
[Link]/physcomp/Tutorials/HighCurrentLoads.

Abbildung 3-7
Transistorausgangsschaltung

Gesteuert wird der Transistor über den Stromfluss, der in die Basis
hineinfließt. Dabei muss der Basisanschluss mindestens 0,7 Volt

Eine blinkende LED – das »Hello World« des Physical Computing 105
höher liegen als der Emitter. Dazu wird die Basis über einen Wider-
stand von 1.000–10.000 mit dem Ausgangspin des Arduino ange-
schlossen. Der Emitter wird direkt mit GND verbunden, und an
den Kollektor kommt dann die eine Seite der Last, die andere Seite
wird mit 5V verbunden. Das Schöne an dieser Schaltung ist, dass
die Spannung auch viel größer sein kann, ohne dem Arduino zu
schaden (das Maximum entnehmen Sie bitte dem Datenblatt des
Transistors). Dadurch kann man viele LEDs in einer Reihe verbin-
den oder besonders starke LEDs verwenden, um den Raum hell zu
erleuchten.

Und nun wird losgebastelt


Nun sollte es möglich sein, eine Lampe zu basteln. In den letzten
Jahren sind LEDs immer günstiger und auch heller geworden,
sodass inzwischen auch Lampen erschwinglich sind, die einen gan-
zen Raum erleuchten können. Interessant ist das insbesondere,
wenn RGB-LEDs verwendet werden, die mit der oben gezeigten
Logarithmustabelle immerhin 262.144 Farben darstellen können.
Um noch weichere Farbübergänge zu erzeugen, müsste eine PWM
von mehr als 8 Bit verwendet werden. Ein weiterer Vorteil von
LEDs ist ihre Größe: Glühbirnen oder Leuchtstofflampen benöti-
gen recht viel Platz, während Leuchtdioden sehr klein sind und in
Tischtennisbälle, kleine Kästen, Flaschen und allerhand andere
Behältnisse passen. Doch Vorsicht: Auch LEDs können je nach
Stärke sehr heiß werden und müssen womöglich auf einen Kühl-
körper aufgebracht werden (die gibt es inzwischen auch im Fach-
handel, zum Beispiel in Onlineshops, die LEDs verkaufen). Man
kann aber auch einen CPU-Kühler aus einem alten PC verbauen.
Wichtig ist dabei allerdings, dass der Körper auch ausreichend groß
ist und man Wärmeleitpaste verwendet.
Mit den sechs PWM-fähigen Pins des Arduino können zwei RGB-
LEDs angeschlossen und entsprechend gepulst werden. Bringt man
diese Lichter in entsprechender Stärke an zwei Enden des Raumes
an oder lässt sie in entgegengesetzte Richtungen entlang einer
Wand leuchten, ergeben sich schöne und stimmungsvolle Effekte.
Diese Lampe lässt sich natürlich auch mit weiteren Sensoren aus-
statten. Möglich ist zum Beispiel ein Mikrofon, das an einen Tief-
passfilter angeschlossen wird und die Lampe pulsen lässt, wenn ein
Bass ertönt. Oder man nimmt einen passenden Gassensor, der das
Licht melden lässt, wenn die Konzentration eines bestimmten Stof-
fes in der Luft zu hoch wird. Eine entsprechende Anleitung finden

106 Kapitel 3: Workshop LED-Licht


Sie z.B. unter [Link]
lutants/?ALLSTEPS.
Ein anderes mögliches Projekt könnte ein Lichtwecker sein, wie er
für viel Geld auch im Handel erhältlich ist. Dabei wird eine Lampe
ab einer festgelegten Uhrzeit allmählich immer heller, um Dämme-
rung und Sonnenaufgang zu simulieren. Einen solchen Wecker hat
zum Beispiel Mark Ivey gebaut und unter [Link]
11/arduino-prototype-for-a-sunrise-alarm/ erläutert.
Ein gelungenes Beispiel ist die Milk Lamp von David Hayward, die
aus einer Reihe an der Decke hängender Milchlampen mit weißen
LEDs darin besteht. Beim Dimmen werden diese nicht wie gewohnt
heller und dunkler geregelt, sondern sie werden der Reihe nach ein-
und ausgeschaltet. Eine genaue Beschreibung des Projekts, das mit-
hilfe der Informationen aus diesem Kapitel auch nachprogrammiert
werden kann, finden Sie unter [Link]
?p=442.

Eine blinkende LED – das »Hello World« des Physical Computing 107
KAPITEL 4 In diesem Kapitel:
• LED-Matrix
LEDs für Fortgeschrittene • Animationen
• Interrupts
• Tamagotchi
• Brainwave und Biofeedback

Nun soll mit LEDs ein wenig mehr passieren, als nur Licht zu
machen. In diesem Kapitel wird es zunächst darum gehen, viele
LEDs zu steuern, wozu diese in einer sogenannten Matrix verschal-
tet werden. Damit soll dann eine kleine Art Tamagotchi selbst
gebaut werden. Den Abschluss macht eine Gehirnwellenmaschine,
die mit blinkendem Licht und Ton für Entspannung im Gehirn des
Benutzers sorgen soll.

LED-Matrix
Reichen die 14 digitalen Pins nicht aus, gibt es die Möglichkeit, mit
einer Matrix zu arbeiten. Dabei werden Reihen und Zeilen jeweils
an einen Pin angeschlossen und die einzelnen Elemente der Matrix
über eine Kombination der beiden angesprochen. Die einfachste
Darstellungsform ist natürlich, wenn diese Matrizes auch als solche
sichtbar sind, die LEDs also in Rechteckform angeordnet sind. Für
7x5 Bildpunkte benötigt man zwölf digitale Pins; damit kann man
kleine Piktogramme oder Laufschrift anzeigen. Oder man program-
miert kleine Spiele, die nicht mehr als diese 35 Punkte benötigen,
wie das bekannte Schlangenspiel, in dem eine sich bewegende
Schlange aus Punkten größer wird, wenn sie andere leuchtende
Bildpunkte auffrisst. Die wohl größte Matrix dieser Art wurde beim
Blinkenlights-Projekt konstruiert, das schon in Kapitel 1 erwähnt
wurde: 18x8 Fenster eines Hochhauses dienten dabei als Bild-
punkte eines Displays. Dort wurden kleine Animationen angezeigt,
die man mit einem eigenen Programm erschaffen und hochladen
konnte. Zudem war es möglich, mit einem Handy auf einer Num-
mer anzurufen und die Paddel eines Pong-Spiels mit den Tastentö-

109
nen zu steuern. In weiteren Varianten wurde das Projekt sogar noch
ausgebaut und 2008 wurde das Rathaus von Toronto in ein Display
von insgesamt 960 Bildpunkten verwandelt.
Im Alltag findet man solche LED-Matrizen zum Beispiel in den
Laufschrift-Displays, mit denen kleinere Geschäfte für aktuelle
Angebote werben. Es gibt aber zum Beispiel auch Gürtelschnallen,
auf denen man Laufschriften anzeigen kann. Diese können meist
direkt programmiert werden, es spricht aber auch nichts dagegen,
sie an einen Arduino anzuschließen. Neben kleinen Blinkprojekten
kann man solche Displays auch verwenden, um Informationen dar-
zustellen. Oft reichen die im Vergleich zu LC-Displays viel günsti-
geren LEDs aus.
Für den nun folgenden Workshop wurde eine Kingbright TA20-
11EWA LED-Matrix verwendet. Sie besteht aus sieben Reihen und
fünf Spalten; diese oder baugleiche LED-Matrizes sind für wenig
Geld in fast jedem Fachgeschäft und -Versand erhältlich. Natürlich
funktioniert das auch mit einzelnen LEDs, nur ist der Lötaufwand
dabei größer. Mit einer einfachen Google-Suche findet man das
entsprechende Datenblatt, unter anderem direkt beim Hersteller
Kingbright oder bei [Link] ([Link]
com/datasheet-pdf/pdf/232968/KINGBRIGHT/[Link]).
Die Matrix ist in Deutschland unter anderem bei Reichelt (http://
[Link]) erhältlich.
Die Funktionsweise ist recht einfach: Strom kann bei einer LED nur
von der Anode zur Kathode fließen. Wird also eine höhere Span-
nung an die Kathode als an die Anode angelegt, kann kein Strom
fließen, die LED bleibt dunkel. Schließt man die Anoden der LEDs
spaltenweise und die Kathoden zeilenweise an eine Spannungs-
quelle an, kann man einzelne Dioden individuell ansteuern, indem
man ein Signal auf eine Spalte gibt und einzelne Zeilen auf LOW
schaltet.
Würde man es dabei belassen, könnte man immer nur bestimmte
Muster anzeigen, denn ist eine Zeile auf LOW geschaltet, leuchten
alle LEDs in dieser Zeile bei entsprechendem Signal auf der Spalte
auf. Abhilfe schafft die Darstellung des gewünschten Bildes Zeile
für Zeile in einer schnell durchlaufenden Schleife, die für das Auge
den gleichen Effekt hat wie die in Kapitel 3 beschriebene Pulswei-
tenmodulation: Bei entsprechend schneller Wiederholung kann das
menschliche Auge kein Flackern mehr erkennen.

110 Kapitel 4: LEDs für Fortgeschrittene


Eine andere Form des LED-Displays ist das sogenannte Siebenseg-
ment. Dabei handelt es sich um die von vielen Anzeigen bekannten
kastenförmigen Zahlenanzeigen, die aus sieben einzelnen Segmen-
ten (vier vertikal und drei horizontal) bestehen. Diese Displays kön-
nen nach dem gleichen Prinzip wie die Matrix programmiert
werden. Für den Arduino gibt es in den USA schon fertige Shields,
die für 49 Dollar mit einem solchen Display und einem Tempera-
tursensor ausgestattet sind. Wer den teuren Import nicht bezahlen
möchte, kann auch im hiesigen Elektronikfachhandel einzelne Dis-
plays beziehen, muss sie allerdings selbst anbringen.
Diese Anzeigen eignen sich besonders gut dazu, Sensordaten direkt
darzustellen. Man kann sie also zum Beispiel für ein eigenes Ther-
mometer oder einen Luftfeuchtigkeitssensor verwenden, oder man
bastelt sich einen Tacho fürs Fahrrad, wenn man auf ein LCD ver-
zichten möchte.

Hardware
Das Datenblatt zeigt für die Reihen eine Belegung für die Matrix-
Pins 9, 14, 8, 12/5, 1, 7 und 2 an. Die Spalten werden an 13, 3,
4/11, 10 und 6 angeschlossen. Zwei Pins sind damit doppelt
verfügbar, was beim Verlöten mehr Freiheiten erlaubt. In diesem
Beispiel werden die Reihen an die Arduino-Pins 1–7, die Spalten an
8–12 angeschlossen. Die Schaltung lässt sich am besten auf eine
Lochrasterplatine löten.

Abbildung 4-1
LED-Matrix, Lochrasterplatine

LED-Matrix 111
Abbildung 4-2
LED-Matrix, Lochrasterplatine

Software
Zunächst werden die Reihen in Arrays dargestellt und mit den ent-
sprechenden Pins verbunden:
// definiere Zeilen und Spalten als Array vom Typ uint8_t
uint8_t rows[7] = {1, 2, 3, 4, 5, 6, 7};
uint8_t columns[5] = {8, 9, 10, 11, 12};
void setup() {
for (int i = 0; i < 7; i++) {
pinMode(rows[i], OUTPUT);
}
for (int i = 0; i < 5; i++) {
pinMode(columns[i], OUTPUT);
}
}

Zudem wird eine Datenstruktur benötigt, die abbilden kann, was


die Matrix darstellen soll. Da die Elemente von Arrays nicht aus
Variablen bestehen müssen, können Arrays auch wiederum Arrays
enthalten. Man spricht von mehrdimensionalen Arrays, in diesem
Fall von zweidimensionalen. In unserem Projekt soll zunächst eine
Diagonale leuchten, die entsprechenden Werte des Arrays werden
also auf 1 gesetzt, der Rest auf 0. Eine genaue Beschreibung von
ein- und mehrdimensionalen Arrays finden Sie im Anhang.
// Definiere eine 7x5-Matrix. uint8_t ist eine vorzeichenlose
// 8-Bit-Integer-Variable. Setze das Muster so, dass eine
// Diagonale angezeigt wird.
uint8_t matrix[7][5] = {
{ 1, 0, 0, 0, 0},
{ 0, 1, 0, 0, 0},
{ 0, 1, 0, 0, 0},
{ 0, 0, 1, 0, 0},
{ 0, 0, 1, 0, 0},
{ 0, 0, 0, 1, 0},
{ 0, 0, 0, 0, 1},
};

112 Kapitel 4: LEDs für Fortgeschrittene


Nun muss die Matrix nur noch spaltenweise angezeigt werden.
Dazu wird eine Funktion showMatrix definiert, die aus einer Schleife
besteht. Für jede Spalte wird ein Schleifendurchlauf benötigt.
Zunächst werden alle Zeilenwerte für die entsprechende Spalte aus-
gegeben, indem der negative Wert des entsprechenden Matrixein-
trags als Signal geschrieben wird. Das geschieht durch den
sogenannten Negationsoperator, das Ausrufezeichen. Danach wird
die aktuelle Zeile eingeschaltet; die Funktion wartet eine Milli-
sekunde und schaltet sie danach wieder aus, um keinen Konflikt
mit der nächsten Zeile, also dem nächsten Schleifendurchlauf zu
produzieren.
void showMatrix() {
// durchlaufe alle fünf Spalten
for (int x = 0; x < 5; x++) {
// setze vorherige Zeile auf 0
// für jede Zeile setze den Wert der Matrix auf den
//entsprechenden Pin
for (int y = 0; y < 7; y++) {
digitalWrite(rows[y], !matrix[y][x]);
}
// setze aktuelle Spalte auf 1
digitalWrite(columns[x], 1);
delay(1);
// Lösche aktuelle Spalte
digitalWrite(columns[x], 0);
}
}

Nun muss diese Funktion nur noch in loop() aufgerufen werden,


um die Matrix anzuzeigen.

Aufgabe:
Die Werte der Matrix verändern und somit ein Muster anzeigen.

Animationen
Nun sollen nicht nur statische Muster angezeigt werden, sondern
eine kleine Animation. Das Setup soll zunächst gleich bleiben,
hinzu kommen einige Funktionen, um die Anzeige zu verändern.

Programmierung
Zunächst wird eine Funktion benötigt, die die Matrix löscht und
neu initialisiert. Es ist wichtig, die Matrix immer wieder komplett

Animationen 113
auf null zu setzen, weil es sonst möglich ist, dass alte Pixel ihren
Wert behalten. Um die Matrix zu löschen, wird eine geschachtelte
Schleife verwendet, um beide Dimensionen zu durchlaufen, also
die x- und die y-Achse der Matrix.
// setze die Matrix auf 0
void clearMatrix() {
// für jede Reihe
for (int x = 0; x < 7; x++) {
// für jede Spalte
for (int y = 0; y < 5; y++) {
// setze das Matrixelement auf 0
matrix[x][y] = 0;
}
}
}

Nun soll in jedem Durchlauf von changeMatrix eine weitere LED


angeschaltet werden. Dazu werden wiederum eine Schleife für die
Reihen und eine für die Spalten benötigt. In der Spaltenschleife
wird pro Durchlauf ein weiteres Matrixelement auf 1 gesetzt, die
Lichter gehen also nacheinander an. Anschließend wird die Matrix
angezeigt. Um diese Anzeige ein wenig zu verzögern, wird jeder
Schritt 50 Mal angezeigt und am Ende der Funktion showMatrix
eine zusätzliche Verzögerung von einer Millisekunde pro Reihe ein-
gebaut:
void loop() {
// setze die Matrix auf 0
clearMatrix();
// für jede Reihe
for (int x = 0; x < 7; x++) {
// für jede Spalte
for (int y = 0; y < 5; y++) {
// setze den Wert des aktuellen Elements auf 1
matrix[x][y] = 1;
// zeige die aktuelle Matrix 50 Mal an
for (int i = 0; i < 50; i++) {
showMatrix();
}
}
}

Aufgabe:
Eine Animation erstellen, bei der eine leuchtende Zeile von oben
nach unten wandert.

114 Kapitel 4: LEDs für Fortgeschrittene


Interrupts
Betrachtet man die Matrix genauer, die oben angesteuert wird, fällt
auf, dass die LEDs sehr instabil blinken. Manche sind heller als
andere, und wenn man genauer hinsieht, erkennt man manchmal
ein Flackern. Das liegt daran, dass beim Kompilieren noch viel
mehr Code hinzugefügt wird. Der Prozessor arbeitet also keines-
wegs nur die im Programm angegebenen Anweisungen ab.
Will man nun die Matrix parallel zu etwas anderem laufen lassen,
etwa während Sensoren abgefragt werden, verschlimmert sich das
Problem weiterhin. Abhilfe schaffen sogenannte Interrupts, die die
Prioritäten im Programmablauf verändern können. Interrupts unter-
brechen das Programm abhängig von externen Ereignissen wie
Timer (eine Art Wecker) oder wenn zum Beispiel Daten über die
serielle Schnittstelle angekommen sind. Nachdem der Interrupt sei-
nen Code ausgeführt hat, fährt das Programm dort fort, wo es auf-
gehört hat. Interrupts sind allerdings mit Vorsicht zu behandeln und
können besonders für Einsteiger reichlich komplex sein. Es emp-
fiehlt sich also, zunächst einige Erfahrung mit dem Arduino – oder
generell mit Programmierung – zu sammeln, bevor man sich daran
setzt.
Interrupts sind kein eigentlicher Bestandteil der Arduino-Program-
miersprache. Es wird also eine externe Library benötigt, die
Bestandteil des avr-Pakets ist, das wiederum schon bei der Pro-
grammierumgebung dabei ist. Mit
#include <avr/interrupt.h>
#include <avr/io.h>

werden die beiden nötigen Bibliotheken eingebunden.


Als Nächstes werden, wie schon zuvor, die Zeilen und Spalten der
Matrix auf die Pins gelegt. Dabei ist es wichtig, dass die Pins der
Reihen nicht verändert werden. Das hängt damit zusammen, dass
dann alle Pins auf einen Rutsch geschrieben werden können. Die
Funktion digitalWrite() wäre an dieser Stelle viel zu langsam.
uint8_t matrix_rows[7] = {
1, 2, 3, 4, 5, 6, 7};
uint8_t matrix_columns[5] = {
8, 9, 10, 11, 12};

Nun muss dem Arduino noch mitgeteilt werden, dass ein soge-
nannter Timer-Interrupt benötigt wird. Dazu werden ein paar
Werte in spezielle Register geschrieben. Diese starten einen inter-

Interrupts 115
nen Zähler, der das Programm dann regelmäßig unterbricht und
die Interrupt-Funktion aufruft.
unsigned char Matrix_SetupTimer2(){
// Timer2 Settings: Timer Prescaler /8, mode 0
// Timer clock = 16MHz/8 = 2Mhz or 0.5us
TCCR2A = 0;
TCCR2B = 0<<CS22 | 1<<CS21 | 1<<CS20;
// Timer2 Overflow Interrupt Enable
TIMSK2 = 1<<TOIE2;
}

Es folgt die eigentliche Interrupt-Funktion:


// Bildspeicher für die Matrix
// gefüllt mit einer diagonalen Linie zum Testen
uint8_t matrix[5] = {
2+64, 4+128, 8, 16, 32};
// aktuelle Spalte für die Interruptausgabe
uint8_t matrix_col;
// Timer2 Interruptfunktion / wird in regelmäßigen Abständen
// aufgerufen, ohne dass man sich darum kümmern muss
ISR(TIMER2_OVF_vect) {
// setze aktuelle Spalte auf 0
digitalWrite(matrix_columns[matrix_col], 0);
matrix_col++;
if (matrix_col >= 5) matrix_col = 0;
PORTD = ~ matrix[matrix_col];
// setze aktuelle Spalte auf 1
digitalWrite(matrix_columns[matrix_col], 1);
}

Hier passiert die eigentliche Arbeit: Als Erstes wird die zuletzt
aktive Zeile ausgeschaltet. Dann wird die nächste bestimmt und die
Daten dafür ausgegeben, und gleich danach wird diese Zeile dann
aktiviert.
Relativ ungewohnt für ein Arduino-Programm ist die Zeile, die mit
PORTD beginnt. PORTD ist eine acht Bit breite Speicherstelle im
Atmel (dem Arduino-Mikrocontroller), die direkt den Zustand der
Pins 0–7 beschreibt. Alle Werte, die dorthin geschrieben werden,
erscheinen direkt als HIGH- und LOW-Signal auf den entsprechenden
Pins. Eine Null würde zum Beispiel alle Pins auf null setzen. Eine 85
würde jeden zweiten Pin auf HIGH und alle anderen auf null setzen,
da die 85 binär geschrieben 01010101 entspricht.
Der Tildenoperator (~) hat hier die Aufgabe, alle Bits umzudrehen:
Aus Einsen macht er Nullen und umgekehrt. Das ist notwendig,
weil an diesen Pins ja die Kathoden der LEDs angeschlossen sind,
die leuchten, wenn die Kathode LOW = 0 ist, und nicht (wie man
zuerst erwarten würde) bei HIGH = 1. Im Programmiersprachenan-

116 Kapitel 4: LEDs für Fortgeschrittene


hang finden Sie noch mehr Informationen über Operatoren und ihr
Verhalten und ihre Verwendung. Um Operatoren zu verstehen,
sollten Sie sich also dort weiter informieren.
Das Schöne an dieser Lösung ist, dass alles, was in die Matrixvari-
able geschrieben wird, einfach dargestellt wird und man dann in
der Funktion loop() keine Einschränkungen mehr hat, die das
Timing der Matrix betreffen.

Buchstaben
Nun macht es keinen Spaß, Buchstaben und Symbole Pixel für
Pixel mit SetPixel(x,y) zu zeichnen; deshalb gibt es dafür eine
kleine Tabelle, die alle kleinen und großen Buchstaben und die
Zahlen enthält. Die Funktion DisplayChar() holt diese dann aus
dem Speicher und kopiert sie in die Variable matrix.
Damit können kleinere Texte und Symbole auf der LED-Matrix
ausgegeben werden.
void SetPixel(uint8_t x, uint8_t y)
{
matrix[x] |= _BV(y+1);
}
void ClrPixel(uint8_t x, uint8_t y)
{
matrix[x] &= ~_BV(y+1);
}
void ClrMatrix(void)
{
for(uint8_t x = 0; x <= 5; x++){
matrix[x] = 0;
}
}
static unsigned char __attribute__ ((progmem)) Font5x7[] = {
0x7E, 0x11, 0x11, 0x11, 0x7E,// A
0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x7F, 0x09, 0x09, 0x01, 0x01,// F
(....komplettes Listing auf der Webseite....)
};
void DisplayChar(uint8_t c)
{
for(uint8_t i = 0; i <= 4; i++)
{
matrix[i] = pgm_read_byte(&Font5x7[((c – 0x10) * 5) + i])
<< 1;

Interrupts 117
Hinweis Die Daten für das Aussehen der Buchstaben werden im Flash-
speicher des Arduinos gespeichert, anders als beim Ramspei-
cher kann auf das Flash leider nicht direkt zugegriffen werden.
Dazu wird die Funktion pgm_read_byte(adresse) benötigt. Diese
bekommt als Parameter die Adresse, welche gelesen werden
soll, und liefert dann den Wert an dieser Stelle in Flash zurück.
Im ASCII-Zeichensatz (Das ist die Tabelle, die der Computer ver-
wendet, um Zahlen zu Buchstaben zuzuordnen) sind für uns
nicht alle Bereiche wichtig, die Tabelle fängt deswegen erst
beim 16ten Buchstaben an. Also wird als erstes 16 oder 0x10
(Hexadezimale Schreibweise) vom gewünschten Zeichen »c«
subtrahiert.
Da jeder einzelne Buchstabe aus 5 Bytes besteht, wird das
Resultat jetzt mit 5 multipliziert, das ist jetzt die Nummer des
ersten Eintrags in der Tabelle Font5x7 für den Buchstaben »c«.
Bei jedem der 5 Schleifendurchläufe (für einen Buchstaben)
erhöht sich i um eins, so das nach und nach alle 5 Bytes eines
Buchstabens verarbeitet werden.
Das Zeichen »&« vor dem Font5x7[...] bewirkt dabei, dass die
Adresse des Bytes innerhalb der Tabelle zurückgeliefert wird
um dann mit der Funktion pgm_read_byte das tatsächliche Byte
lesen zu können.
}
}
void loop() {
for (uint8_t i = 0; i < 32; i++)
{
DisplayChar('A'+i); // Zeige
Buchstaben an.
delay(500);
DisplayChar(0x10+i); // Zeige
Gesichter an.
delay(500);
}
}

Tamagotchi
Tamagotchis sorgten im Jahr 1997 für einen Ansturm auf Kaufhäu-
ser und Spielzeugläden in Deutschland und verschwanden dann
fast ebenso schnell in der Versenkung, wie sie gekommen waren.
Im Jahr 2004 wurde die Serie noch einmal aufgelegt, wenn auch mit
keinem zur Urversion vergleichbaren Erfolg in Deutschland. Ein
Tamagotchi ist ein kleines Plastikei mit einem LCD, auf dem ein
kleines Küken dargestellt ist. Dieses Küken gibt vor zu leben und
benötigt regelmäßig Wasser, Futter und Zuneigung. Nach und
nach entwickelt es eine eigene kleine Persönlichkeit, die individuell

118 Kapitel 4: LEDs für Fortgeschrittene


festlegt, wann das Tamagotchi um Aufmerksamkeit piepst. Die
neueren Versionen sind in der Lage, sich auch mit anderen zu ver-
binden und zum Beispiel zu heiraten. Die Grundidee bleibt aber die
gleiche: ein virtuelles Haustier, das nicht so anspruchsvoll ist wie
ein echtes und damit auch für diejenigen Kinder geeignet, deren
Eltern einem echten Lebewesen kein Risiko zumuten wollen. Hier
soll nun ein eigenes kleines Haustier gebaut werden, das die oben
beschriebene LED-Matrix verwendet. Um das Projekt von dem im
Handel verfügbaren Spielzeug abzuheben, soll es »Ardugotchi« hei-
ßen. Das Ardugotchi ist ein sehr glückliches Lebewesen; es ernährt
sich von Elektronen, braucht also nie gefüttert zu werden, freut sich
allerdings über Geräusche und Musik.

Hardware
Wir verbinden das Mikrofon wie auf der Zeichnung mit dem Tran-
sistor und dem Arduino-Board, damit das Ardugotchi auch etwas
hören kann. Ansonsten bleibt die Matrix aus den vorigen Projekten
bestehen.

Abbildung 4-3
Tamagotchi-Schaltung

Software
Zunächst kann der Programmcode des vorigen Beispiels übernom-
men werden, mit dem die Matrix angezeigt wird. Einige Bilder kön-
nen hineingeladen werden, die die verschiedenen Gefühlszustände
des Tierchens beschreiben. Sie sind bereits in der Zeichentabelle
enthalten und unter den Codes 0x10 bis 0x1f zu finden. Den kom-
pletten Code finden Sie auf der entsprechenden Buchseite bei http://
[Link].

Tamagotchi 119
Die Spannung am analogen Eingang 0, an den das Mikrofon ange-
schlossen ist, wird eingelesen und mit dem Mittelwert der letzten
100 Messungen verglichen. Ist der Wert deutlich größer, so wechselt
das Ardugotchi seinen Gesichtsausdruck. Um Gesichter darstellen
zu können, enthält die Zeichentabelle 16 verschiedene Muster, sie
können mit DisplayChar(0x10+gesicht) angezeigt werden.
int laut;
int laut_mittelwert;
int sad;
int gesicht;
// Dieser Wert muss je nach verwendetem Mikrofon angepasst werden.

// Kleinere Werte machen den Ardugotchi dabei empfindlicher.


int schwelle = 50;
void loop() {
laut = analogRead(0);

// Mittelwert über die letzten gemessenen Werte, wobei der neue


// jeweils 1/100 zählt.
laut_mittelwert = (laut_mittelwert*99 + laut)/100;

if ((laut – laut_mittelwert) > schwelle)


{
// nächstes Gesicht auswählen, am Ende wieder zum Anfang
// springen
gesicht++;
if (gesicht > 15) gesicht = 1;

// Mittelwert anpassen, damit nicht gleich wieder ein Peak


// erkannt wird.
laut_mittelwert = laut;

// Den Zähler für die schlechte Laune wieder auf 0 setzen


sad = 0;
}

// Hört das Ardugotchi lange genug kein Geräusch, soll es sich


// einsam fühlen und ein entsprechendes Gesicht anzeigen.
sad++;
if (sad > 10000)
{
// den Wert auf 10000 begrenzen, sonst ensteht ein Überlauf
sad = 10000;

// Schlecht gelauntes Gesicht auswählen


gesicht = 0;
}

DisplayChar(0x10+gesicht); // Zeige Gesichter an.

// Geschwindigkeit auf 10x Sekunde begrenzen


delay(100);
}

120 Kapitel 4: LEDs für Fortgeschrittene


Brainwave und Biofeedback
Da ein Teil der Kommunikation unserer Nervenzellen mit kleinen
Spannungsimpulsen funktioniert, können mit empfindlichen Elek-
troden am Kopf verschiedene Aktivitätslevel gemessen werden.
Diese Messung erlaubt allerdings keine genauere Auswertung. Man
kann sich das ungefähr so vorstellen wie wenn man anhand des
Geräuschpegels eines Stadions erkennt, dass ein Tor gefallen ist.
Interessant ist, dass die Aktivitätslevel in periodischen Wellen auf-
treten. Die Abstände dieser Wellen werden grob verschiedenen
Gehirnzuständen zugeordnet.
• Deltawellen weisen die niedrigste Frequenz auf (1–4 Hertz).
Sie werden zum Beispiel in der Tiefschlafphase emittiert, wenn
das Gehirn nicht träumt. Auch werden diese Wellen bei
Bewusstlosigkeit oder intuitivem, unbewusstem Verhalten
gemessen. In diesem Zustand wird das Gehirn nur bei starken
Reizen aktiv.
• Thetawellen liegen zwischen 4 und 7 Hertz und treten vor
allem in leichten Schlafphasen auf, aber auch bei unbewussten,
kreativen Denkprozessen oder Zuständen tiefer Entspannung
wie etwa Meditation.
• Alphawellen liegen im Bereich zwischen 8 und 13 Hertz. Ein
großer Teil dieser Wellen wird mit leichter Entspannung asso-
ziiert, zum Beispiel mit geschlossenen Augen. Das Gehirn ist
im Empfangsmodus, verhält sich aber passiv.
• Betawellen (14–30 Hz) sind der normale, aktive Zustand. Das
Gehirn ist wach und bei vollem Bewusstsein. Nachdenken und
Konzentration gehören ebenfalls dazu. Sie treten aber auch
zum Beispiel im REM-Schlaf auf.
• Als Gammawellen wird der Frequenzbereich über 30 Hertz
bezeichnet. Sie treten zum Beispiel bei starker Konzentration
und Lernprozessen auf, aber auch in Angst- und Stresszustän-
den. Gammawellen sind allerdings bislang nicht gut erforscht.
• Oft geschieht es nun, dass man selbst Entspannung sucht, aber
aufgrund der Hektik des Tages und der Umgebung nicht ruhig
genug wird, um von der aktiven Betawellenphase auf Alpha
herunterzukommen. Diesen Zustand kann man nun errei-
chen, indem man meditiert oder beispielsweise Yoga macht.
Man kann versuchen, diesen Zustand auch mit externen Mit-
teln wie Lichtimpulsen oder Musik herbeizuführen.

Brainwave und Biofeedback 121


Die Brain Machine
Die Theorie, die dieser Brain Machine zugrunde liegt, geht davon
aus, dass über das Auge aufgenommene Lichtblitze die Aktivitäts-
wellen im Gehirn verändern können. Treffen Lichtblitze mit 2,2
Hertz aufs Auge auf, werden vom Gehirn Deltawellen emittiert.
Natürlich bedeutet das nicht automatisch, dass das Gehirn in die-
sen Zustand fällt, nur weil es mit entsprechendem Licht bombar-
diert wird. Aber eine geschickte Programmierung und ein bisschen
Training können durchaus zu gewünschten Ergebnissen führen.
Eine interessante Ressource zu Gehirnforschung und verwandten
themen bietet Arvid Leyh unter [Link].

Abbildung 4-4 Im Folgenden soll nun eine Gehirnmaschine gebaut werden, die in
BrainMachine der Lage ist, das menschliche Gehirn in einen Zustand der Entspan-
nung zu versetzen. Dabei sorgen an einer Brille angebrachte LEDs
für die Lichtimpulse. Zudem wird versucht, das Ergebnis mit
binauralen Klängen auf Kopfhörern noch zu steigern. Binaural
bedeutet wörtlich übersetzt »Zwei-ohrig«, man hört Unterschiedli-
ches auf beiden Ohren. Da wir so tiefe Frequenzen wie Deltawellen
nicht hören können, spielen wir einen höheren Ton, der vom rech-
ten zum linken Ohr genau um die gewünschte Frequenz auseinan-
derliegt. Die Überlagerung dieser zwei Töne erzeugt ein Pulsieren
in der gewünschten Frequenz.

Setup
Für die Brain Machine werden einige Bauteile benötigt, allem voran
eine Brille, um die LEDs vor dem Auge zu positionieren. Dafür
genügt eine einfache Schutzbrille aus dem Baumarkt. Um die Elek-

122 Kapitel 4: LEDs für Fortgeschrittene


tronik auf dieser Brille anzubringen, sollten Sie mit Silikonkleber
oder Heißkleber arbeiten. Zudem werden zwei helle rote LEDs,
passende Widerstände (siehe Kapitel 3), ein Kopfhörer und eine
passende Klinkenbuchse benötigt.
Zunächst markiert man auf jedem Brillenglas einen Punkt, der
direkt vor den Augen sitzt. Dort wird anschließend ein Loch
gebohrt, durch das die LED gesteckt wird. Wenn die LED also
direkt in die Pupille zeigt, wird sie mit Klebematerial fixiert und
über einen Widerstand mit einem digitalen Arduino-Pin verbunden.
Als Nächstes muss die Klinkenbuchse korrekt angeschlossen wer-
den. Sie besteht aus drei Anschlüssen: Der äußerste ist für die
Masse, wird also mit GND verbunden. Die anderen beiden sind für
die Tonsignale. Bei der Brain Machine ist es unwichtig, welche Fre-
quenz auf welchem Ohr ertönt. Die Töne werden durch eine
schnelle Pulsweitenmodulation erzeugt, wobei es angenehmer sein
kann, sie noch ein wenig zu filtern, bevor sie auf den Kopfhörer
gegeben werden. Andernfalls kann das Ergebnis relativ schrill klin-
gen. Für den Tiefpass kann man einen Widerstand von 1.000 Ohm
und einen 100-nF-Kondensator verwenden.

Damit ist die Brain Machine im Grunde fertig. Für den ersten Test Abbildung 4-5
empfiehlt es sich, alles unberührt zu lassen; möchte man die Brille BrainMachine-Schaltung

Brainwave und Biofeedback 123


dann permanent verwenden, sollte man mit Schrumpfschläuchen,
Klebeband und Heiß- oder Silikonkleber alles so anbringen, dass es
stabil sitzt. Zum Schluss kann man die Brillengläser noch mit
Papier oder Pappe abdichten. Unter [Link]
wave können Sie ein passendes Muster herunterladen, das die Brille
ein wenig psychedelisch aussehen lässt.

Programmierung
Wie eingangs erwähnt, müssen für die verschiedenen Gehirnwellen
passende Frequenzen auf den LEDs und im Kopfhörer erzeugt wer-
den. Dazu werden zunächst die nötigen Pins deklariert:
int ledPin1 = 4; // LED rechtes Auge
int ledPin2 = 5; // LED linkes Auge
int speakerPin1 = 11; // Kopfhörer rechtes Ohr
int speakerPin2 = 3; // Kopfhörer linkes Ohr
volatile uint16_t sample1; // welches ist das nächste Sample aus
// der Sinustabelle
volatile uint16_t sample2; // die oberen 7 Bit zeigen in die
// Tabelle, die restlichen Bits sind
// Kommastellen
int diff = 5; // Differenz der beiden Töne in
// update-ticks
int tone = 500; // Frequenz der beiden Töne in
// update-ticks
int vol = 0; // aktuelle Lautstärke
int set_vol = 0; // gewünschte Lautstärke

Um Daten mit der Interrupt-Funktion auszutauschen, werden diese


in gemeinsam mit dem normalen Programm genutzte Variablen
geschrieben. diff gibt den Frequenzunterschied der beiden Tonka-
näle und die Pulsfrequenz der LED an. Der Maßstab dieser Variab-
len ist, um wie viel der Sample-Zähler 8.000 Mal pro Sekunde
erhöht werden muss, um die gewünschte Frequenz zu erreichen.
Diese Berechnung unternimmt eine gesonderte Funktion. Dadurch
braucht diese Berechnung nur bei einer Tonänderung durchgeführt
zu werden, was Rechenkapazität spart.
Schön weich klingende Töne erhält man mit einer Sinusfunktion.
Da das Berechnen eines Sinus viel Zeit beansprucht, wird hier eine
Vorberechnung auf dem PC verwendet, sodass die folgende Tabelle
exakt 128 Werte lang ist. Da die Sinusfunktion sich nach 2ð wie-
derholt, erhält man den Sinus einer Zahl, wenn man an der Stelle
Zahl modulo 128 in der Tabelle nachschlägt. Modulo 128 bedeutet,
dass die Zahl durch 128 geteilt und der Rest zurückgegeben wird.
Das ist für einen Prozessor wiederum besonders einfach zu berech-
nen, es müssen nur alle Bits größer 128 weggelassen werden.

124 Kapitel 4: LEDs für Fortgeschrittene


//prog_uint8_t sintab[] = {
const unsigned char sintab[] PROGMEM = {
0x01,0x01,0x01,0x01,0x02,0x03,0x05,0x07,
0x09,0x0c,0x0f,0x12,0x15,0x19,0x1c,0x21,
0x25,0x29,0x2e,0x33,0x38,0x3d,0x43,0x48,
0x4e,0x54,0x5a,0x60,0x66,0x6c,0x73,0x79,
0x7f,0x85,0x8b,0x92,0x98,0x9e,0xa4,0xaa,
0xb0,0xb6,0xbb,0xc1,0xc6,0xcb,0xd0,0xd5,
0xd9,0xdd,0xe2,0xe5,0xe9,0xec,0xef,0xf2,
0xf5,0xf7,0xf9,0xfb,0xfc,0xfd,0xfe,0xfe,
0xfe,0xfe,0xfe,0xfd,0xfc,0xfb,0xf9,0xf7,
0xf5,0xf2,0xef,0xec,0xe9,0xe5,0xe2,0xdd,
0xd9,0xd5,0xd0,0xcb,0xc6,0xc1,0xbb,0xb6,
0xb0,0xaa,0xa4,0x9e,0x98,0x92,0x8b,0x85,
0x7f,0x79,0x73,0x6c,0x66,0x60,0x5a,0x54,
0x4e,0x48,0x43,0x3d,0x38,0x33,0x2e,0x29,
0x25,0x21,0x1c,0x19,0x15,0x12,0x0f,0x0c,
0x09,0x07,0x05,0x03,0x02,0x01,0x01,0x01
};

Diese Tabelle gibt es auch auf der Webseite zum Buch: [Link]
[Link] herunterzuladen.
Nun folgt schon die komplizierteste Funktion im Programm, die
Interrupt-Funktion: Sie wird von der Hardware automatisch 8.000
Mal pro Sekunde aufgerufen, hier werden die LEDs ein- und ausge-
schaltet und die Werte für die Töne ausgegeben.
ISR(TIMER1_COMPA_vect) {
// Zähler, um Lautstärkeänderung langsamer zu machen
static int timer1counter;
int wert;
// Wert an der Stelle sample1/512 aus der sinus-Tabelle lesen
wert = pgm_read_byte(&sintab[(sample1 >> 9)]);
// Wert mit der aktuellen Lautstärke multiplizieren
wert = (wert * vol) / 256;
// PWM-Hardware anweisen, ab jetzt diesen Wert auszugeben
OCR2A = wert;
// das Gleiche für das andere Ohr
wert = pgm_read_byte(&sintab[(sample2 >> 9)]);
wert = (wert * vol) / 256;
OCR2B = wert;
// berechnen der LED-Pulse in Abhängigkeit vom gespielten Ton
if (((sample1 & 0x8000) != 0) && ((sample2 & 0x8000) !=0)) {
PORTD |= _BV(5) | _BV(4); // LEDs einschalten
}
else {
PORTD &= !(_BV(5) | _BV(4)); // LEDs ausschalten
}
// nächstes Sample in der Sinustabelle abhängig vom gewünschten
// Ton auswählen
sample1 += tone;
sample2 += tone + diff;

Brainwave und Biofeedback 125


// Lautstärke anpassen, wenn gewünscht (nur alle 50 Interrupts,
// damit es schön langsam passiert
timer1counter++;
if (timer1counter > 50)
{
timer1counter = 0;
if (vol < set_vol) vol++;
if (vol > set_vol) vol--;
}
}

Als Nächstes kommt die Funktion startPlayback(). Hier werden


die Interrupt-Funktion und die Timer des Arduino so eingestellt,
dass der Interrupt 8.000 Mal pro Sekunde aufgerufen wird und die
PWM-Ausgabe mit 62.500 KHz läuft.
void startPlayback()
{
pinMode(speakerPin1, OUTPUT);
pinMode(speakerPin2, OUTPUT);
// initialisiere den Timer 2 für die schnelle PWM zur
// Soundausgabe auf Pin 11 & 3
// verwende den internen Takt (Datenblatt Seite 160)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// fast PWM mode (Seite 157)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
// wähle die nicht invertierende PWM für pin OC2A und OC2B,
// am Arduino ist das Pin 11 und 3
TCCR2A = (TCCR2A | _BV(COM2A1) | _BV(COM2B1));
// keine Vorteiler, denn wir wollen es schnell (Seite 158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Startwert = 0, sonst gibt es ein hässliches Plopp-Geräusch
OCR2A = 0;
OCR2B = 0;
// initialisiere Timer 1 für 8.000 Interrupts/Sekunde
cli();
// set CTC mode (Clear Timer on Compare Match) (Seite 133)
TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
// kein Vorteiler (Seite 134)
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// gewünschte Frequenz: 8.000 KHz
OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
// aktiviere den Interrupt für TCNT1 == OCR1A (Seite 136)
TIMSK1 |= _BV(OCIE1A);
// Startwerte
sample1 = 0;
sample2 = 0;

// globale Interrupts wieder einschalten


sei();
}

126 Kapitel 4: LEDs für Fortgeschrittene


Vieles in dieser Funktion muss man nicht unbedingt auf Anhieb
verstehen, in den meisten Fällen sind diese Hardwaredetails auf
dem Arduino in Bibliotheken versteckt. Hier hilft nur das Lesen des
Datenblatts vom verwendeten Mikrocontroller Atmega168 oder
Atmega328, das direkt bei [Link] eingesehen werden
kann.
In der Setup-Funktion werden nur noch die Pins für die LEDs initi-
alisiert und die Funktion startPlayback aufgerufen.
void setup()
{
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
startPlayback();
}

Damit die gewünschte Tonhöhe und Hirnwellenfrequenz nicht in


der Einheit Timer Additions angegeben werden muss, gibt es diese
Hilfsfunktion:
// ändert die Ton und die LED-Frequenz
// ton (50-4.000 Hz)
// brainwave (0-30 Hz)
// volume (0-256);
void SetFreq(int ton, int brainwave, int volume)
{
tone = (128ul*512ul*ton)/8000;
diff = (128ul*512ul*brainwave)/8000;
set_vol = volume;
}

In der loop()-Funktion kann jetzt die Gehirnwellensequenz pro-


grammiert werden, im Beispiel eine Einschlafmeditation ohne Auf-
weckfunktion am Ende, also genau das Richtige, um nach einem
anstrengenden Tag einzuschlafen.
Als Erstes werden immer wieder gebrauchte Werte in Konstanten
gespeichert, danach folgt die Gehirnwellensequenz, die aber hier
auf Grund ihrer Länge nicht komplett abgedruckt ist.
float DELTA = 2.2; // tiefe Bewusstlosigkeit, Intuition und
// insight
float THETA = 6.0; // Unterbewusstsein, Kreativität,
// Tiefenentspannung
float ALPHA = 11.0; // Träumerisch, empfangsbereit und passiv
float BETA = 14.4; // bewusstes Denken, externer Fokus
int grundton = 200;

void loop()
{
SetFreq(grundton,0.7,0); // Einstimmung, langsames Pulsen ohne
// Ton

Brainwave und Biofeedback 127


delay(10000); // Dauer 10 Sekunden
SetFreq(grundton,BETA,10); // BETA langsam lauter werden
delay(10000);
SetFreq(grundton,BETA,20);
delay(10000);
SetFreq(grundton,BETA,30);
delay(10000);
SetFreq(grundton,BETA,40);
delay(10000);
SetFreq(grundton,ALPHA,50); // 10 Sekunden Alphawellen
delay(10000);
SetFreq(grundton,BETA,60); // 20 Sekunden Betawellen
delay(20000);
// (.....) – der Rest findet sich wiederum im Listing auf der
// Webseite zum Buch
SetFreq(grundton,DELTA, 2); // Deltawellen immer leiser werden
delay(5000);
SetFreq(grundton,DELTA, 1); // Deltawellen immer leiser werden
delay(5000);
SetFreq(grundton,DELTA, 0); // Deltawellen immer leiser werden
delay(5000);
// ende
for (;;) ;
}

Den genauen Ablauf einer kompletten Brainwave-Session können


Sie auf der Website des Make Magazine sehen: [Link]
com/10/brainwave/. Dort finden Sie auch weitere Informationen
über die Wirkungsweise dieser Gehirnwellenmaschine.

128 Kapitel 4: LEDs für Fortgeschrittene


KAPITEL 5 In diesem Kapitel:
• Nach Hause telefonieren
Sprich mit mir, Arduino! mit der seriellen Konsole
• Automatisierung mit
Gobetwino
• Processing

Der Arduino ist beileibe keine einsame Insel, auf der nur einmal
Passagiere abgeladen werden, ohne dass sie die Außenwelt infor-
mieren können. Bleibt das Board mit einem USB-Kabel (oder in der
Bluetooth-Variante über Funk) mit einem PC verbunden, kann es
auch Daten zurücksenden. Das folgende Kapitel soll zunächst
erklären, wie einfache Statusmitteilungen über die serielle Konsole
an die Arduino-Entwicklungsumgebung gesendet werden können.
Anschließend wird die Kommunikation noch etwas ausgebaut: Die
Processing-Programmiersprache etwa besitzt eine Bibliothek, die es
sehr einfach macht, mit dem Arduino Daten auszutauschen. So
können das Board und seine angeschlossenen Sensoren oder Taster
benutzt werden, um Processing-Programme zu steuern.
Unter »digitaler Kommunikation« versteht man den Austausch von
Daten zwischen zwei oder mehr Geräten über eine festgelegte Ver-
bindung. Dabei bestimmt ein sogenanntes Protokoll alle Details.
Alle Kommunikationsteilnehmer müssen sich dabei genau an die-
ses Protokoll halten, damit die Daten auch korrekt verstanden und
weiterverarbeitet werden können. Protokolle können unterschiedli-
che Bereiche umfassen, und meistens werden mehrere Protokolle
zusammen verwendet. Zu diesem Zweck werden Netzwerke in
ihrem Aufbau nach Schichten getrennt, die im sogenannten Open
Systems Interconnection Model, kurz OSI-Modell, festgeschrieben
sind. Diese Schichten bauen aufeinander auf und beschreiben die
komplette Kommunikation vom physischen Träger bis hin zu den
Datenpaketen. Im Folgenden werden wir eine serielle Verbindung
in ihren Grundzügen erklären.
Die unterste Schicht beschreibt, wie die beiden kommunizierenden
Seiten physisch miteinander verbunden sind, wie die entsprechen-

129
den Anschlüsse aufgebaut und wie viele Verbindungen nötig sind,
um Daten hin und her zu senden. Beim Arduino sind es eigentlich
zwei Verbindungen über die RX- und TX-Pins. Da viele Rechner –
insbesondere Laptops – keine RS232-Schnittstelle mehr besitzen,
wird diese über USB emuliert. Dabei sorgt ein USB-Controller
dafür, dass das entsprechende, deutlich kompliziertere USB-Proto-
koll verwendet werden kann. Die serielle Verbindung wird also
quasi darin eingebettet. Einer der besonderen Vorteile von USB
gegenüber einem seriellen Port (RS232), wie er in älteren Compu-
tern verwendet wurde, ist, dass an einem einzelnen Anschluss eine
Vielzahl von Verbindungen registriert werden kann. USB-Hubs
nutzen diese Technik zum Beispiel, um an die üblicherweise zwei
oder drei Steckplätze viele Geräte anzuschließen. Jedes weitere
Gerät, das sich am USB-Bus anmeldet, wird im Betriebssystem als
ein neues serielles Gerät festgestellt. Unter Windows können zum
Beispiel drei Geräte als COM8, COM9 und COM10 angesprochen
werden, Mac OS X würde sie als
/dev/[Link]-5B21
/dev/[Link]-5B22
/dev/[Link]-5B24

auflisten. Es ist also kein Problem, mehrere Arduinos an einen


Rechner anzuschließen. In der Programmierumgebung können
diese dann unter TOOLS → SERIAL PORT ausgewählt werden, und in
Processing steht die Funktion [Link]() zur Verfügung (siehe
unten).
Darauf folgt die elektrische Schicht, die festlegt, mit welchen Span-
nungen die Daten übertragen werden, also wie viel Volt nötig sind,
um eine Kommunikation aufrechtzuerhalten.
Die dritte Schicht bezeichnet die Logik der Verbindung. Sie legt
fest, ob eine Zunahme der Spannung eine Null oder eine Eins
bedeutet. Bei der seriellen Verbindung wird ein 5-Volt-Signal als
eine Eins interpretiert, ein 0-Volt-Signal dementsprechend als eine
Null.
Die Datenschicht wiederum regelt das Timing der Bits, also wie
viele Signale in einem bestimmten Zeitabstand gesendet werden.
Das ist sehr wichtig, um die Daten auf der Gegenseite auch korrekt
interpretieren zu können. Zudem wird hier festgelegt, ob die Daten
einer Gruppe mit einer bestimmten Bitfolge gekennzeichnet oder
abgeschlossen werden. Die serielle Verbindung überträgt 9.600 Bit
pro Sekunde. Jedes Byte, also jedes Paket, enthält acht Bits und
wird jeweils mit einem Start- und einem Stop-Bit markiert. Diese

130 Kapitel 5: Sprich mit mir, Arduino!


Bits werden vom Arduino direkt verarbeitet und kommen hier
nicht weiter vor. Sollen viele Daten pro Sekunde verarbeitet wer-
den, ist es wichtig zu wissen, dass ein übertragenes Byte also eigent-
lich aus zehn Bit besteht, pro Sekunde also nicht mehr als 960 Bytes
(z.B. Buchstaben) übertragen werden können.
Die Anwendungsschicht beschreibt, wie die einzelnen Bytes zu ver-
stehen sind. Sowohl die Programmierumgebung (oder später die
Processing-Sprache) als auch das Arduino-Programm, das auf das
Board geladen wird, nehmen jeweils ein Byte an und verarbeiten es
anschließend.
Die Kommunikation mit dem Arduino Duemilanove geschieht
dabei über die digitalen Pins 0 und 1, die auch als RX und TX mar-
kiert sind. Nutzt man also die serielle Kommunikation, sollten
diese Pins nicht anderweitig belegt werden, da sonst seltsame Feh-
ler auftreten können. LEDs beispielsweise würden jedes Mal blin-
ken, wenn Daten über die serielle Verbindung gesendet werden.
Andersherum kämen auf dem PC Daten heraus, die nicht verarbei-
tet werden könnten, sobald auf dem Pin ein digitales Signal ange-
legt würde.
In diesem Kapitel wird nur die sehr einfach aufgebaute serielle Ver-
bindung behandelt. Wird zum Beispiel über Ethernet kommuni-
ziert, ist das Schichtenmodell deutlich komplexer, es bauen mehr
Protokolle aufeinander auf.

Nach Hause telefonieren


mit der seriellen Konsole
Der Arduino verfügt mit der beschriebenen seriellen Verbindung
über einen Rückkanal, kann also Ereignisse an die Arduino-IDE
zurückmelden. »Seriell« bedeutet dabei, dass die Daten bitweise
nacheinander übertragen werden. Als Konsole wird das schwarze
Fenster in der Arduino-Entwicklungsumgebung bezeichnet, das die
Statusmeldungen des Arduino anzeigt. Lädt man etwa ein Pro-
gramm auf das Board, wird dort wiedergegeben, ob alles in Ord-
nung war (z.B. »Binary sketch size: 1694 bytes (of a 14336 byte
maximum)«) oder Fehler aufgetreten sind. Ist das USB-Kabel nicht
richtig verbunden oder enthält der hochzuladende Arduino-Sketch
Syntaxfehler, erscheint in der Konsole eine Reihe von roten Mel-
dungen, die über die Natur des Fehlers Auskunft geben sollen. Dar-
über hinaus gibt es noch eine Reihe weiterer Fehlerquellen, etwa

Nach Hause telefonieren mit der seriellen Konsole 131


wenn die Übertragung unterbrochen wurde. Aber auch wenn das
Programm einmal hochgeladen ist, kann der Arduino sich noch
melden, um beispielsweise Sensorwerte an den PC zu senden. Das
kann zum einen genutzt werden, um Daten weiterzuverarbeiten,
also z.B. zu speichern oder auf abnormale Messwerte zu reagieren.
Zum anderen können vom Arduino geschriebene Nachrichten aber
auch zur Fehlersuche verwendet werden.
Die serielle Verbindung arbeitet dabei standardmäßig mit 9.600
Baud. Als ein Baud wird die Einheit »ein Zeichen pro Sekunde«
bezeichnet. Da hier ein Zeichen einem Bit entspricht, könnte man
also auch »9.600 Bit pro Sekunde« sagen. Es gibt allerdings auch
Kommunikationswege, bei denen ein Zeichen aus mehreren Bits
besteht, indem das Signal moduliert wird.

Die serielle Konsole einrichten


Die serielle Konsole ist kein eigentlicher Bestandteil des Arduino.
Vielmehr muss die Bibliothek Serial verwendet werden, die aller-
dings in der Programmierumgebung schon vorhanden ist. Es ist
also nicht nötig, diese Bibliothek gesondert zu laden. Es reicht aus,
im Setup-Abschnitt eine Verbindung zu erstellen:
void setup() {
[Link](9600); // öffne seriellen Port, setze Datenrate
// auf 9.600 Baud
}

Nun können ankommende Daten gelesen und ausgehende Daten


geschrieben werden. Zunächst sollen einfache Informationen in der
Konsole der Entwicklungsumgebung angezeigt werden. Das
geschieht mit der Funktion [Link](), die eine Zeile an den
angeschlossenen PC sendet, oder auch print(), das an die Daten
keinen Zeilenumbruch anhängt.
Die Funktionen können dabei vom Nutzer vorgegebenen Text ver-
arbeiten, z.B. so:
[Link]("Hallo")

Oder sie verarbeiten Variablen:


int zahl = 10;
[Link](zahl);

Dabei kann einer Variable noch ihre Darstellungsform mitgegeben


werden, wenn die Zahl explizit in Dezimaldarstellung angezeigt
werden soll, oder in binärer oder hexadezimaler Form:

132 Kapitel 5: Sprich mit mir, Arduino!


int zahl = 10;
[Link](zahl, DEC); // sende "10" an den PC
[Link](zahl, BIN); // sende "1010" an den PC
[Link](zahl, HEX); // sende "A" an den PC

Der Testlauf für das Programm sieht so aus:


void loop() {
int zahl = 10;
[Link]("Hallo");
[Link](zahl);
[Link](zahl, DEC);
[Link](zahl, BIN);
[Link](zahl, HEX);
[Link]("-----------");
delay(10000);
}

Er bringt folgendes Ergebnis:

Abbildung 5-1
Serieller Monitor

Fehlersuche mit der seriellen Konsole


Oft geschieht es beim Programmieren, dass sich Fehler einschlei-
chen, die nicht mehr durch einfaches Durchlesen des Codes zu
beheben sind. Je komplexer der Code, desto anfälliger wird er, aber
auch gerade im Zusammenspiel mit Sensoren können beispiels-
weise unerwartete Werte auftauchen. Diese können eine if-Abfrage
dazu bringen, einen bestimmten Programmteil gar nicht auszufüh-
ren, obwohl die Programmierung es eigentlich vorgesehen hat.
In diesem Beispiel nehmen wir an, von einem Drehknopf wird
erwartet, dass er im »Aus-Zustand« eine Null sendet. Ist das der
Fall, wird eine LED angeschaltet, ansonsten nicht.

Setup
Wie schon in Kapitel 3 wird ein Drehknopf an den digitalen Pin 11
angeschlossen. Für die Kommunikation bleibt der Arduino per USB
mit dem Rechner verbunden.
int ledPin = 11;
int drehKnopf = 0;

Nach Hause telefonieren mit der seriellen Konsole 133


void loop() {
potiWert = analogRead(drehknopf);
if (potiWert == 0) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
}

Nun sei für dieses Beispiel angenommen, die LED flackere nun
gelegentlich, weil der Sensor nicht präzise arbeitet. Es kann recht
lange dauern, das herauszufinden. Sendet man nun den Wert des
Drehknopfs an die serielle Konsole und zeigt zudem an, welche
Verzweigung das Programm nimmt, kommt man viel schneller zu
einem Ergebnis:
void loop() {
potiWert = analogRead(drehknopf);
[Link](potiWert);
if (potiWert == 0) {
[Link]("Poti ist auf null.");
digitalWrite(LED, HIGH);
}
else {
[Link]("Poti ist nicht auf null.");
digitalWrite(LED, LOW);
}
delay(1000);
}

Nachrichten empfangen
Die serielle Konsole eignet sich nicht nur zum Senden von Nach-
richten, sondern kann in beide Richtungen kommunizieren. Somit
kann der Computer den Arduino auch steuern, nachdem das Pro-
gramm kompiliert und hochgeladen wurde. Das ist zum Beispiel
nötig, um eine volle Steuerung durch Processing zu ermöglichen.
Für den Empfang von Daten wird der TX-Pin genutzt, der bei der
Programmierung funktioniert wie die anderen Eingänge auch: Hat
man Serial initialisiert, kann man über die Funktion available()
prüfen, ob und wie viele Bytes von Daten an das Board gesendet
wurden. Die Funktion read() kann diese Daten nun byteweise aus-
lesen und z.B. in einer Variable speichern. In einem einfachen Bei-
spiel werden nun die Daten, die über den seriellen Port empfangen
wurden, gelesen und wieder über die Konsole ausgegeben:

134 Kapitel 5: Sprich mit mir, Arduino!


char incomingByte = 0; // Variable für die einkommenden Daten
void setup() {
[Link](9600); // initialisiere seriellen Port auf
// 9.600 Baud
}
void loop() {
// wenn serielle Daten vorhanden sind
if ([Link]() > 0) {
// lies das einkommende Byte
incomingByte = [Link]();
// sende die Daten zurück an den PC
[Link]("Empfangen: ");
[Link](incomingByte);
}
}

Um diese Daten zu senden, muss wieder einmal die serielle Konsole


in der Arduino-Programmierumgebung geöffnet werden. Über dem
schwarzen Ausgabefenster befindet sich eine kleine Textzeile mit
einem SEND-Button, der dafür genutzt werden kann.

Abbildung 5-2
Eingabezeile, Send-Button

Gibt man nun test ein, erscheinen die vier Buchstaben nacheinan-
der auf dem Bildschirm, da read() immer nur ein Byte auf einmal
empfängt und die darauf folgenden Bytes in einem so genannten
Ringpuffer zwischenhält, der nach und nach ausgelesen werden
kann. Ein Ringpuffer ist eine Datenstruktur, die mehrere Elemente
(zum Beispiel Bytes) speichert und nach und nach bei jedem Aufruf
zurückgibt.

Abbildung 5-3
Empfangen im Monitor

Möchte man nun die gesamten Eingaben zusammen speichern,


benötigt man ein Array, das man langsam füllt.
Legt man also
char incomingByte[255] = {};

fest, kann man den einkommenden Text auch so abspeichern, um


ihn dann weiterzuverwenden, wenn man den Ringpuffer so lange
aufruft, bis er leer ist.

Nach Hause telefonieren mit der seriellen Konsole 135


while ([Link]() > 0) {
// lies das einkommende Byte
incomingByte[i] = [Link]();
i++;
// ein wenig warten, damit das nächste Byte auch sicher
// übertragen wird
delay(3);
}

Möchte man nun auch das nächste Wort korrekt anzeigen, muss
das Array geleert werden, da sonst noch unerwünschte Zeichen
gespeichert sind. Das geschieht, indem das komplette Array durch-
laufen und alle Elemente mit NULL, also einem leeren Zeichen über-
schrieben werden:
for (int i=0; i<=255; i++) {
incomingByte[i] = NULL;
}

Steuerungseingaben
Jetzt können diese Eingaben verwendet werden, um zum Beispiel
die LED auf dem Arduino-Board einzuschalten. Dazu müssen Pin
13 als Ausgang definiert und die serielle Konsole initialisiert werden:
int ledPin = 13;
void setup() {
[Link](9600); // initialisiere seriellen Port auf 9.600
// Baud
pinMode(ledPin, OUTPUT); // setze ledPin auf OUTPUT
}

Nun kann man beispielsweise die LED einschalten, sobald eine 1


empfangen wird. Eine 0 schaltet sie wieder aus:
void loop()
{
if ([Link]() > 0) {
if ([Link]() == '1') {
digitalWrite(ledPin, HIGH);
}
else if ([Link]() == '0') {
digitalWrite(ledPin, LOW);
}
}
}

Dabei ist zu beachten, dass die Texteingabe in der Programmierum-


gebung als Buchstaben gesendet werden. Eine eingetippte »0« hat
in der dabei verwendeten ASCII-Tabelle den Wert 48. Es kann also
entweder mit 48 oder mit '0' verglichen werden, wobei der Compi-
ler '0' durch 48 ersetzt.

136 Kapitel 5: Sprich mit mir, Arduino!


Automatisierung mit Gobetwino
Gobetwino wurde vom Dänen Mikael Morup entwickelt, um sich
größere Mühen zu ersparen, wenn ein PC mit dem Arduino kom-
munizieren soll. Es erlaubt zum Beispiel, Mails oder Chatnachrich-
ten mit einer Ampel anzuzeigen. Nicht immer will man dafür das
teure Ethernet-Shield aus Kapitel 6 verwenden oder speziell eine
Anwendung in Processing programmieren, wie es am Ende dieses
Kapitels beschrieben wird. Ist der Arduino bereits mit einem PC
über USB verbunden, kann man unter Windows das Programm
Gobetwino verwenden, das die serielle Verbindung verwendet. Die
Software fungiert dabei als sogenannter Proxy, ein Vermittler, der
die serielle Kommunikation übernimmt. Er ist in der Lage, Kom-
mandos zu senden und zu empfangen. Diese können dann verwen-
det werden, um verschiedene Aufgaben abzubilden. So muss
Gobetwino nicht erst umständlich programmiert werden. Stattdes-
sen legt man über ein Drop-down-Menü fest, welche Aktionen
wann ausgeführt werden sollen. Gobetwino kann
• ein Programm starten (und wenn gewünscht auf das Beenden
warten),
• Daten vom Arduino zu einem Programm als Tastendrücke sen-
den,
• E-Mails mit Daten vom Arduino versenden,
• Dateien aus dem Internet herunterladen und Teile davon an
den Arduino senden,
• Daten aus dem Arduino in ein File schreiben (mit Timestamp)
und
• eingehende E-Mails überprüfen.
Das funktioniert recht einfach, indem im Gobetwino-Programm
mit einer Eingabemaske Funktionen angelegt werden. Dazu wählt
man den Funktionstyp aus einer Drop-down-Box aus und gibt die
dazu nötigen Parameter wie »Datei, in der Daten gespeichert wer-
den sollen« an. Das genügt, um den Gobetwino zu konfigurieren,
alles Weitere regelt das Programm von allein. Gobetwino können
Sie unter [Link] herunter-
laden. Neben dem kompletten Programm enthält das ZIP-Archiv
ein englischsprachiges Handbuch, in dem genau erklärt wird, wie
man neue Befehle anlegt.

Automatisierung mit Gobetwino 137


Damit Gobetwino erkennen kann, wo Nachrichten vom Arduino
anfangen und aufhören, sind diese in Rauten (#) eingeschlossen.
Nach dem ersten # kommt immer ein großes S und danach eine
Pipe (|); darauf folgt dann der groß geschriebene Kommandoname,
der in Gobetwino festgelegt werden kann. Nach einer weiteren Pipe
folgen die Parameter, die von eckigen Klammern umschlossen wer-
den und durch & getrennt sind.
Um zum Beispiel Messwerte in eine Logdatei zu speichern, genügt
folgende Zeile:
#S|LOGTEST|[877]#

In Gobetwino müssen dann nur noch das Kommando LOGTEST


angelegt und festgelegt werden, in welches File die Daten gespei-
chert werden sollen. Optional kann ein Zeitstempel hinzugefügt
werden.
Auf dem Arduino sieht der passende Code dann so aus:
int value = 877;
char buffer[5];
[Link]("#S|LOGTEST|[");
[Link](value);
[Link]("]#");

Wichtig ist in diesem Beispiel, dass die letzte Zeile println()


anstatt print() verwendet, wodurch ein Zeilenumbruch gesendet
wird, der Gobetwino das Ende der Nachricht signalisiert.
In Gobetwino kann man danach sehr schön sehen, wie diese Nach-
richt eingelesen und verarbeitet wird. Hier erkennt man dann auch,
wenn einmal etwas nicht ganz so läuft, wie es sollte.

Lebst du noch?
Wir wollen mit einem Ping die Erreichbarkeit unseres Webservers
überprüfen und im Fehlerfall eine rote Fahne mit einem Servomo-
tor (kurz: Servo) hissen. Das ist ein kleiner Motor aus dem Modell-
bauladen, den man in Geschwindigkeit und Position steuern kann.
Das ist notwendig, damit der Motor am Ende der Fahnenstange
auch wieder anhält. Die Fahnenstange kann man dabei wie eine
echte basteln: Auf der einen Seite ist eine Fahne an einem kleinen
Draht angebracht, der um eine Rolle gewickelt wird. Diese Rolle
wird dann vom Servo gedreht.

138 Kapitel 5: Sprich mit mir, Arduino!


Abbildung 5-4
Gobetwino-Aufbau

Hardware
Als Erstes wird der Servo angeschlossen. Ein Servo hat die drei
Anschlüsse GND (schwarz oder braun), VDD (rot) und SIGNAL.
GND wird mit GND auf dem Arduino-Board verbunden, VDD mit
5V und SIGNAL mit PIN9. Servos werden über kurze Impulse von
1–2 ms Dauer gesteuert, die sich mit ca. 50 Hz wiederholen. Die
Länge der Pulse ergibt die Position, die der Servo anfahren soll.

Automatisierung mit Gobetwino 139


Man kann sich vorstellen, dass die Pulsdauer ziemlich exakt sein
sollte, weil der Servo sonst hin- und her- ruckelt. Da ist es am bes-
ten, den PWM-Schaltkreis auf dem Arduino-Board zu verwenden,
der unterschiedlich lange Pulse erzeugen kann. Da das PWM-Signal
für PIN10 und PIN9 mit demselben PWM-Schaltkreis des Atmel
erzeugt wird, können beide PINs nur entweder für analogWrite()
oder [Link]() verwendet werden.

Abbildung 5-5 Am Drehrad des Servos befestigt man jetzt noch die Fahne, und
Gobetwino-Schaltung schon kann es losgehen mit dem Schreiben der Software.

140 Kapitel 5: Sprich mit mir, Arduino!


Software
Als Erstes werden ein paar globale Variablen und eine Instanz der
Servo-Klasse benötigt. Diese wird mit dem PIN9 des Arduino ver-
bunden, an dem der Servo angeschlossen ist.
#include <Servo.h>
Servo myservo; // erzeuge ein Servo-Objekt
int pos; // gewünschte Position des Servos
int serInStringLen = 25; // wie viele Zeichen darf eine
// Nachricht vom PC maximal lang sein
char serInString[serInStringLen]; // Speicherplatz für
// Nachrichten
void setup()
{
[Link](9); // verbinde das Servo-Objekt mit Pin 9
[Link](9600); // initialisiere RS23-Verbindung zum PC
delay(3000); // warte ein wenig
}

Für die Kommunikation mit dem PC ist es hilfreich, wenn es eine


Funktion gibt, die auf eine ganze Zeile Daten vom PC wartet, um
diese am Stück auswerten zu können. Zunächst wird geprüft, ob
die Zeit abgelaufen ist; ist das der Fall, beendet die Funktion sich,
allerdings nicht ohne an das Ende des String noch eine 0 zu schrei-
ben: Das ist das Zeichen dafür, dass ein String an dieser Stelle zu
Ende ist, andernfalls könnten spätere Funktionen darüber stolpern.
Dann wird mit [Link]() geprüft, ob überhaupt Zeichen
vom PC aus gesendet worden sind; wenn ja, werden sie abgeholt
und in das String-Array gespeichert, sofern es kein Zeilenendzei-
chen (ASCII-Code 13) war.
void readSerialString (char *strArray, int serInLen, long timeOut)
{
// warte timeOut Milisekunden auf Daten
long startTime=millis();
int i = 0;
char ch;
while ((millis()-startTime < timeOut)) {
if ([Link]()) {
ch = [Link]();
if (ch == 13) {
strArray[i] = 0;
return;
}
strArray[i] = ch;
if (i < serInLen) i++;
}
strArray[i] = 0;
}

Automatisierung mit Gobetwino 141


In der loop()-Funktion wird nun regelmäßig über Gobetwino abge-
fragt, ob der Server erreichbar ist:
void loop()
{
[Link]("#S|PING|[]");
readSerialString (serInString, serInStringLen, 10000);
int val = atoi(serInString);
if (val == 0) {
if (pos < 255) pos++;
} else {
if (pos > 0) pos--;
}
[Link](pos);
delay(100);
}

Dieser Code erwartet, dass in Gobetwino ein Kommando mit dem


Namen PING angelegt wird, das den zu überwachenden Server
anpingt. Es sendet dann eine 0, wenn alles okay ist, und eine –1,
wenn der Ping fehlschlägt. Als Reaktion darauf hebt oder senkt sich
dann unsere Fahne, sodass man immer auf den ersten Blick den
Zustand unseres Servers erkennen kann.
Dazu öffnet man Gobetwino und erzeugt über COMMANDS → NEW
COMMAND ein neues Kommando. Als Typ wählt man PING und
trägt die zu testende Adresse ein. Damit ist Gobetwino auch schon
so weit konfiguriert, dass das Projekt getestet werden kann.

Processing
Processing ist in vielerlei Hinsicht eines der Vorbilder für Arduino,
dessen Programmierumgebung und -sprache sehr ähnlich model-
liert sind. Wie Arduino wurde Processing entwickelt, um Schülern
und Studenten eine einfache Möglichkeit zu geben, programmieren
zu lernen und Ideen auszuprobieren, um zu schnellen Ergebnissen
zu gelangen. Und natürlich gibt es auch hier mittlerweile eine große
Anhängerschaft, vor allem unter Künstlern und Bastlern.
Dabei hat Processing zunächst rein gar nichts mit Physical Compu-
ting und Mikrocontrollern zu tun; vielmehr wurde es geschaffen,
um möglichst einfache Programmierung von Grafik zu ermögli-
chen. So läuft der Einstieg dort nicht über eine blinkende LED, son-
dern vielmehr über die Anzeige des Textes »Hello World« in einer
großen, bunten Schrift. Mittlerweile gibt es eine Vielzahl unter-
schiedlicher Projekte, die auf Processing basieren. Längst gibt es
Bibliotheken, die es sogar Bands wie R.E.M. ermöglichen, ihre Kon-

142 Kapitel 5: Sprich mit mir, Arduino!


zerte visuell zu untermalen oder eigene Musikvideos zu erschaffen.
Andere Module erlauben eine Nutzung, die noch viel weiter geht als
das Bespielen eines Bildschirms. Sounds werden gesteuert und
Daten visualisiert, zum Beispiel in Form eines Oszillators. Die Spi-
kenzie Labs verwenden Processing, um Signale auszuwerten und in
Midi umzuwandeln (siehe [Link]
zieLabs/Serial_MIDI.html). So kann aus dem Arduino ein Midi-
Controller gebaut werden, ohne entsprechende Bauteile zu benö-
tigen. Processing übernimmt die weitere Kommunikation mit
einem Midi-Programm. Das Augmentation-Blog ([Link]
[Link]/) verwendet einen selbstgebauten Datenhand-
schuh und Arduino, um im Zusammenspiel mit Processing ein
selbstgebautes Motion-Capturing-System zu schaffen. Anders-
herum kann man zum Beispiel Processing verwenden, um einen
Arduino zu steuern. In diesem Fall wird Musik in Daten umgewan-
delt, die die Helligkeit von LEDs steuern (siehe dazu [Link]
[Link]/[Link]/2009/03/arduino-controlled-music-lights/).
Auch wenn Processing auf Java basiert und somit einige Programm-
konstrukte deutlich anders sind als beim auf C++ basierenden
Arduino, gibt es einige Gemeinsamkeiten in der Sprache.
So werden die zum Programmablauf benötigten Teile ebenfalls in
einer Setup-Funktion geladen. Hier werden Variablen deklariert
und initialisiert und Elemente, die für das Programm nötig sind,
eingerichtet. Möchte man beispielsweise einen Text in einer ent-
sprechenden Größe und mit einer entsprechenden Schriftart anzei-
gen, legt man genau diese beiden Parameter in setup() fest:
void setup()
{
PFont font = loadFont("[Link]");
textFont(font,20);
}

Nun sind alle Variablen festgelegt und können so in der Haupt-


funktion, die in Processing draw() heißt, verwendet werden. In die-
sem Beispiel wird die Funktion text() verwendet, um einen Text
anzuzeigen. Die beiden weiteren Parameter stellen die Position auf
der x- und y-Achse dar, also wird »Hello World!« auf Position 30:
50 in Schriftgröße 20 und der Schriftart myFont ausgegeben.
void draw()
{
text("Hello World!", 30,50);
}

Processing 143
Möchte man nun Arduino und Processing verbinden, benötigt man
zunächst Bibliotheken für beide Seiten. Beim Arduino ist diese
Bibliothek schon in der Programmierumgebung enthalten. Sie
nennt sich Firmata und kann mit #include <Firmata.h> ins Pro-
gramm eingebunden werden. Alternativ kann man das unter
SKETCH → IMPORT LIBRARY → FIRMATA tun. Unter FILE →
SKETCHBOOK → EXAMPLES → LIBRARYFIRMATA finden Sie den
gesamten passenden Firmata-Sketch, der alles kann, was in diesem
Workshop benötigt wird.
Lädt man diesen Beispielsketch auf das Arduino-Board, ist es konfi-
guriert, um mit Processing zusammenzuarbeiten. Dabei muss im
Prinzip keine weitere Programmierung auf dem Arduino vorgenom-
men werden. Wie das folgende Beispiel zeigt, kann Processing die
Pins des Arduino selbstständig steuern und so auch die Signale ver-
arbeiten.
Zunächst muss also die Arduino-Bibliothek in Processing einge-
bunden werden. Sie ist auf der Arduino-Website unter [Link]
[Link]/playground/Interfacing/Processing erhältlich. Nachdem
sie heruntergeladen wurde, wird sie entpackt und der Ordner ardu-
ino in den Ordner libraries der Processing-Programmierumgebung
kopiert.
Nun können im Processing-Sketch die beiden Bibliotheken serial
und arduino geladen und ein Arduino-Objekt erstellt werden:
import [Link].*;
import [Link].*;
// initialisiere Arduino-Objekt
Arduino arduino;

Nun soll die LED 13 zum Blinken gebracht werden, wie auch
schon im ersten Workshop dieses Buches. Zunächst wird also die
Variable ledPin auf 13 gesetzt. Anschließend wird im Setup die
Verbindung hergestellt. Dazu wird die Funktion [Link]()
verwendet, die alle verfügbaren seriellen Geräte auf diesem Com-
puter anzeigt. Wenn das Arduino-Board verbunden ist, sollte dort
eine passende serielle Verbindung in dieser Liste auftauchen. Hier-
bei wird nun angenommen, dass es sich um das einzige Gerät han-
delt und somit an Stelle 0 in der Liste befindet. Funktioniert
[Link]()[0] nicht auf Anhieb, empfiehlt es sich, in der Kon-
sole diese Liste auszugeben und die richtige Verbindung zu suchen.
Anschließend wird, wie schon bekannt, ledPin als Ausgang defi-
niert.

144 Kapitel 5: Sprich mit mir, Arduino!


void setup()
{
// falls Arduino nicht das erste serielle Gerät ist,
// die Kommentar-Slashes der nächsten Zeile entfernen und die
// Liste anzeigen lassen
// println([Link]());
// initialisiere die Arduino-Verbindung
arduino = new Arduino(this, [Link]()[0]); // v2
// setze ledPin auf OUTPUT
[Link](ledPin, [Link]);
}

Auch der Rest des Programms verhält sich ähnlich wie schon im
Workshop 3: Nun kann die LED alle 1.000 Millisekunden blinken,
indem ein HIGH- bzw. LOW-Signal auf den entsprechenden Pin gesetzt
wird:
void draw()
{
[Link](ledPin, [Link]);
delay(1000);
[Link](ledPin, [Link]);
delay(1000);
}

Processing mit einem Drehknopf steuern


Nun soll ein Drehknopf (also ein Potentiometer) dazu verwendet
werden, die Größe eines einfachen Kreises in Processing zu steuern.
Das Setup ist ebenfalls schon bekannt: ein Potentiometer wird mit
einem analogen Pin (in diesem Falle Pin 0) verbunden, der als ana-
loger Eingang nicht gesondert eingerichtet werden muss. Um den
Drehknopf später besser verwenden zu können, wird die Variable
int potiPin = 0 definiert.
Nun kann der Input dieses Knopfes mit [Link](poti-
Pin); von Processing eingelesen werden. Für dieses Beispiel soll ein
Kreis eine Größe von 0 bis 100 Pixeln Durchmesser annehmen.
Dafür wird die Funktion ellipse() verwendet, die eine Ellipse
zeichnet, bei der beide Achsen gleich lang sind. Da der Drehknopf
1.024 Werte übermitteln kann, soll der Kreis alle 10 Werte (abge-
rundet) um einen Pixel anwachsen. Diese grobe Übersetzung hilft
auch, kleinere Ungenauigkeiten bei der Messung abzumildern,
denn die werden unweigerlich auftreten.
Damit Processing die Kreise nicht übereinanderlegt, muss zudem
pro Zeichenschritt der Bildschirm gelöscht werden. In diesem Fall

Processing 145
geschieht das, indem der Hintergrund mit background(204); in
Grau neu gezeichnet wird. Um ein wenig mehr Farbe hineinzubrin-
gen, wird der Kreis selbst in einem satten Rot gezeichnet (RGB-
Werte: 255, 0, 0).
Die fertige Draw-Routine sieht also wie folgt aus:
int potiPin = 0;
int potiVal = 0;
void draw() {
potiVal = [Link](potiPin);
background(204);
fill(255, 0, 0);
ellipse(50, 50, floor(potiVal/10), floor(potiVal/10));
}

Let's Play – ein Spiel mit Lichtsensor


Zum Abschluss dieses Kapitels folgt nun ein kleines Processing-
Spiel, das über einen am Arduino angeschlossenen Lichtsensor
gesteuert werden soll. Dieser Sensor steuert einen kleinen Punkt
(oder Ball), der langsam auf der Horizontale durch den Bildschirm
fliegt. Fällt dabei mehr Licht auf den Sensor, fliegt der Ball nach
oben, wird es dunkler, senkt er sich. Auf dem Bildschirm wird nun
ein Bereich angezeigt, der durchflogen werden darf. Verlässt der
Ball diesen Bereich, ist das Spiel beendet, und die Punkte werden
angezeigt.

Setup
Ein Fotowiderstand wird an den analogen Eingang 0 des Arduino
angeschlossen.

Abbildung 5-6
Lichtsensor-Aufbau

146 Kapitel 5: Sprich mit mir, Arduino!


Programmierung
Zunächst werden alle Parameter des Spiels (also Durchmesser,
Fenstergröße und Startposition) festgelegt und die Bibliotheken
importiert:
import [Link].*;
import [Link].*;
// initialisiere Arduino-Objekt
Arduino arduino;
// lege Fenstergröße fest
int windowWidth = 600;
int windowHeight = 400;
// horizontale Position
int x = 0;
// fand eine Kollision statt?
boolean collision = false;
// Durchmesser, Startzeit und Endzeit (für die Punktezahl)
int durchm = 20;
int startTime = 0;
int endTime = 0;
PFont fontA;
// Startposition und Startwert
int arduinoPos = 200;
boolean start = false;
// Pin für den Lichtsensor
int sensorPin = 0;

Anschließend werden in der Setup-Routine der Arduino initialisiert


und das Fenster gezeichnet. Zudem wird ein Font festgelegt, mit
dem am Ende des Spiels die Punktezahl angezeigt wird.
void setup() {
size(windowWidth, windowHeight); // Fenstergröße
background(0); // Hintergrundfarbe
createScene(); // Funktion, die den
// Tunnel zeichnet
// setze Font fest (muss im Datenverzeichnis liegen)
fontA = loadFont("[Link]");
// initialisiere den Font und seine Größe (in Pixeln)
textFont(fontA, 16);
}

Als Nächstes werden Funktionen benötigt, um die »Kugel« (also


einen Kreis) und den Tunnel zu zeichnen. Aus Platzgründen läuft
dieser Tunnel nur schräg von links oben nach rechts unten. Natür-
lich können auch mit der Vertex-Funktion kompliziertere Level
gebaut werden.
// zeichne den Ball
void drawCircle(int x, int y) {
fill(255);
ellipse(x, y, durchm, durchm);

Processing 147
noFill();
}
// zeichne den Tunnel mit drei Vertexen
void createScene() {

stroke(204, 102, 0);


fill(204, 102, 0);
// Oberes Feld
beginShape();
vertex(0, 0);
vertex(0, 100);
vertex(windowWidth,300);
vertex(windowWidth,0);
endShape(CLOSE);

// unteres Feld
stroke(204, 102, 0);
fill(204, 102, 0);
beginShape();
vertex(0, windowHeight);
vertex(0, 200);
vertex(windowWidth, 400);
vertex(windowWidth, windowHeight);
endShape(CLOSE);

// mittleres Feld
fill(125);
stroke(0);
beginShape();
vertex(0, 100);
vertex(windowWidth, 300);
vertex(windowWidth, 400);
vertex(0, 200);
endShape();
}

Schließlich wird noch eine Kollisionskontrolle benötigt. Eine Kolli-


sion findet statt, wenn die Kugel außerhalb des mittleren Feldes
fliegt. Das Feld ist dabei durch zwei schräge Geraden bestimmt.
Durch einfache Geometrie findet man heraus, dass die Gerade
genau proportional zum aktuellen x-Wert verläuft. Das Feld ist also
begrenzt durch x / Fensterbreite * Höhenunterschied + y-Anfangs-
wert, also x/windowWidth*200+100. Zudem findet eine Kollision
statt, wenn die Kugel den rechten Rand des Fensters erreicht.
// prüfe, ob die Kugel eine der Linien berührt
boolean detectCollision(int x, int y){
// Ergebnis ist entweder wahr oder falsch
boolean result = false;
// wenn der Mittelpunkt der Kugel den rechten Rand berührt hat
if (x >= windowWidth-durchm/2) {
result = true;

148 Kapitel 5: Sprich mit mir, Arduino!


}
// wenn die Kugel über der oberen Linie liegt
if (y < (((x/windowWidth) * 100)+100)) {
result = true;
}
// wenn die Kugel unter der unteren Linie liegt
if (y > (((x/windowWidth) * 100) + 200)) {
result = true;
}
return result;
}

Nun sind alle Voraussetzungen für das Spiel gegeben. Die Funktion
endGame() zeigt einen Text mit der Punktezahl an, die sich aus der
Dauer in Millisekunden ergibt, die das Spiel gelaufen ist. Die
Hauptfunktion lädt nun die Grafik und beginnt das Spiel nach
Druck der Taste S.
// Anzeige beim Ende des Spiels
void endGame(){
// berechne die Endzeit
endTime = millis();
// beende die Draw-Funktion
noLoop();
// zeige weißen Text an
fill(0);
text("your score: ", 50, 60);
// Punktezahl berechnen in Millisekunden seit Startzeit
text(endTime-startTime, 200, 60);
// Hier wäre noch platz für einen Restart-Knopf ;-)
}
// Hauptfunktion
void draw() {
// lies Arduino-Eingabe und wandle sie um
int arduino = [Link](sensorPin);
// wenn Taste S gedrückt wird, beginn und miss Startzeit
if(keyPressed) {
if (key == 's') {
start = true;
// miss Startzeit
startTime = millis();
}
}
// wenn das Startsignal gegeben wurde
if (start) {
// wenn keine Kollision geschehen ist
if (!collision) {
createScene();
stroke(0); // setz die Farbe für den Ball
drawCircle(x, arduino); // zeichne den Ball
collision = detectCollision(x, arduino); // prüf, ob es eine
// Kollision gab

Processing 149
x++; // erhöhe die Ballposition
// wenn es eine Kollision gab
} else {
// rufe Endfunktion auf
endGame();
}
// wenn das Startsignal noch nicht gegeben wurde
} else {
// zeichne den Tunnel und den Ball
createScene();
drawCircle(0, arduino);
}
}

Nun ist das Spiel fertig zum Ausprobieren. Wahrscheinlich muss je


nach Lichteinfluss ein wenig mit den Werten des Sensors herum-
probiert werden, indem man sie zum Beispiel teilt. Nur so kann je
nach Sensor das Spiel auch bei der gewünschten Höhe der Hand
funktionieren, ansonsten kann es sein, dass die Kugel sich nur
innerhalb weniger Millimeter bewegt. Für mehr Spielspaß emp-
fiehlt es sich aber ohnehin, das Spiel ein ganzes Stück zu erweitern.

Aufgaben:
Ein Labyrinth basteln, sodass x- und y-Achse ab einem bestimm-
ten Punkt wechseln und die Kugel vertikal am Labyrinth entlang
nach unten fliegt.Überschreitet die Kugel also einen gewissen x-
oder y-Wert, wird ihre Richtung geändert.
Eine Reset-Funktion einbauen, die zum Beispiel auf Knopfdruck
das Spiel von vorn beginnen lässt.
Einen Piezo-Lautsprecher an den Arduino anschließen und bei
einer Kollision einen Ton ausgeben lassen.

Flusskontrolle
Ein Programm, dessen Ablauf stark von der Übertragung serieller
Daten abhängig ist, kann schnell ins Stocken geraten, wenn die
Kommunikation asynchron läuft. Obwohl klar ist, welche Daten
übertragen werden, kann es sein, dass zum Beispiel Daten vom
Arduino zu einem falschen Zeitpunkt an den PC gesendet werden.
Wenn zum Beispiel ein Processing-Programm Daten empfängt, die
schon vor einiger Zeit gesendet wurden, können diese schon längst
ungenau oder falsch sein. Möglicherweise hat der Arduino schon ein
zweites Byte gesendet, das nun im Ringpuffer hängen geblieben ist.

150 Kapitel 5: Sprich mit mir, Arduino!


Um dieses Problem zu vermeiden, wird eine Flusskontrolle ein-
gesetzt. Das bedeutet, dass der Datenfluss zeitweise unterbrochen
wird, damit der schnellere Sender keinen Datenüberfluss produ-
ziert. Beim Beispiel des Spiels wird der Arduino-Sensor direkt gele-
sen. Würden die Daten aber über eine serielle Verbindung
übertragen, etwa weil sie vorher zunächst verarbeitet werden müs-
sen, könnte es sein, dass eine schnelle Reaktion des Spielers
möglicherweise zu spät ankommt; eine Kollision würde nicht ver-
mieden, obwohl der Spieler es eigentlich geschafft hätte.
Nun könnte man den Arduino natürlich in seiner Sendefrequenz
beschränken, indem man ihm Pausen auferlegt. Viel sinnvoller ist
es aber, wenn er auf ein Signal von Processing wartet, um selbst
aktiv zu werden. Das Arduino-Programm wird also verändert,
sodass das Signal erst gesendet wird, wenn ein Byte von Processing
empfangen wurde. Die Sensorabfrage geschieht jedoch weiterhin
kontinuierlich, um die Reaktionszeit des Boards zu verringern:
void loop() {
// lies Sensor
sensor = analogRead(sensorPin);
// verarbeite Sensordaten ...
. . .
if [Link]() > 0) {
int seriellesByte = [Link]();
[Link](sensorInfo, HEX);
}
}

Das Processing-Programm muss nun erweitert werden, um vor dem


Empfang der Daten selbst ein [Link]() abzusetzen. Das kann
eine Null oder auch ein Zeilenumbruch sein.
[Link]('\r', BYTE);
arduinodaten = [Link]();

Mangelnde Flusskontrolle führt häufig zu schwer erkennbaren Feh-


lern. Da die falschen Daten oft vom Menschen nicht bemerkt wer-
den, treten subtile Probleme auf, die nur spät oder gar nicht
entdeckt werden.

Weiter mit dem dynamischen Duo


Wie gezeigt wurde, erweitert Processing den Arduino und eröffnet
hervorragende Möglichkeiten. Viele Projekte verwenden diese Kom-
bination z.B., um Sensorinformationen zu visualisieren, ob nun in
ernsthaften Anwendungen oder für ästhetische Effekte. Andere nut-
zen den Arduino wiederum als Eingabegerät, um Drehknöpfe oder

Processing 151
Schieberegler an einen PC anzuschließen, oder – wie eben gesehen –
Spiele zu steuern. Bei der Entwicklung komplexerer Systeme, etwa
von Flugobjekten, können die durch Processing verarbeiteten Daten
auch dabei helfen, Fehler zu finden oder Feineinstellungen vorzu-
nehmen. So werden mögliche Probleme schon vermieden, bevor sie
auftreten und Schaden anrichten können. Man denke dabei zum
Beispiel an Beschleunigungs- und Neigungssensoren in einer Flug-
drohne, die bei falscher Konfiguration abstürzen würde. Auch in der
Wissenschaft wird Processing in Verbindung mit Mikrocontrollern
wie Arduino immer beliebter, um Versuchsreihen möglichst einfach
zu gestalten und sich so auf das Wesentliche zu konzentrieren.
Im folgenden Kapitel soll nun die Kommunikation des Arduino
nicht mehr nur über die serielle Schnittstelle geschehen. Mit einem
Ethernet-Shield, also einer »Netzwerkkarte«, die auf das Board
gesteckt wird, können Daten auch über das Internet übertragen
werden. Damit lässt sich ein Arduino-Projekt auch aus der Ferne
warten oder abfragen, was insbesondere dann sinnvoll ist, wenn es
das tägliche Leben in der eigenen Wohnung automatisieren soll,
auch während man gar nicht zu Hause ist.

152 Kapitel 5: Sprich mit mir, Arduino!


KAPITEL 6 In diesem Kapitel:
• Hello World – ein Mini-
Arduino im Netz Webserver
• Sag´s der Welt mit Twitter
• Fang die Bytes – Datalogger

Das Internet wird immer mehr zu einem ständigen Begleiter. So ist


es nicht verwunderlich, dass es vermehrt den Wunsch gibt, auch
ohne ständig laufenden Rechner Daten aus dem Internet zu emp-
fangen und über es zu versenden. Mit einem aufgesteckten Ether-
net-Shield kann Arduino auch ganz ohne PC online gehen. Das
schafft viele Möglichkeiten, um die physische Welt mit dem Netz
kommunizieren zu lassen. Vorstellbar sind z.B. Sensoren, die ihren
aktuellen Status bekannt geben und somit ihren Besitzer auch
unabhängig von seinem Aufenthaltsort informieren können. Das
folgende Kapitel erklärt zunächst den Ethernet-Shield und die ein-
fache Kommunikation über das Internet. Danach soll der Arduino
einfache Nachrichten über Twitter versenden.
Im in Kapitel 5 erwähnten Schichtenmodell basiert eine Internet-
verbindung zunächst auf Ethernet. Die physikalische und logische
Schicht werden offiziell als »Bitübertragungsschicht« zusammenge-
fasst, was einen Teil von Ethernet ausmacht. Der andere Teil ist die
Datensicherungsschicht, die beschreibt, wie eine fehlerfreie Über-
tragung gewährleistet werden kann. Dazu werden die Daten in Blö-
cke eingeteilt und mit Folgenummern und Prüfsummen versehen.
In der Bitübertragungsschicht wird das Gerät über eine Hardware-
Adresse, die sogenannten MAC-Adresse, identifiziert. Diese Adresse
ist in der Regel vom Hersteller für jedes Gerät fest vorgegeben und
ändert sich auch dann nicht, wenn es seinen Standort wechselt und
sich zum Beispiel in einem anderen lokalen Netzwerk befindet oder
an einer anderen Stelle mit dem Internet verbunden wird. Diese
Hardware-Adresse besteht aus sechs hexadezimalen Zahlen, zum
Beispiel 00:11:43:8C:D3:91.
Über der Ethernet-Schicht sorgt das Internet Protocol (IP) für eine
Identifikation des Gerätes mithilfe der Netzwerkadresse. Netzwerk-

153
oder IP-Adressen dürften vielen Nutzern bekannt sein, die sich
schon einmal beispielsweise mit der Einrichtung ihres heimischen
PCs im lokalen Netzwerk beschäftigt haben. Um eine hierarchische
Ordnung zu erhalten, gibt es zusätzlich noch die Subnetz-Adresse,
die bestimmt, wie viele Geräte in einem Subnetz zusammengefasst
werden. In einem kleinen Heimnetzwerk ist das meistens die 255.
255.255.0, was bedeutet, es bis zu 256 Geräte fassen kann. Die IP-
Adresse selbst besteht aus vier Bytes. Dabei wird unterschieden
zwischen dem globalen Adressraum, der von der Internet Assigned
Numbers Authority vergeben wird, und lokalen Adressbereichen,
die für lokale Netzwerke reserviert sind und dort von jedem Nutzer
selbst gewählt werden können. Das bedeutet, dass zum Beispiel
eine Adresse, die mit 192.168 beginnt (z.B. die [Link]), nicht
vom gesamten Internet aus erreichbar ist. Dafür können mehrere
Netzwerke jeweils die gleichen Adressen besitzen. Im Gegensatz
dazu ist die Adresse [Link] weltweit eindeutig und gehört
dem deutschen Webserver des O’Reilly Verlags.
Die Verbindung von einem Netzwerk in ein anderes übernimmt ein
sogenannter Router. Das sind für den Heimgebrauch meistens
kleine Geräte, die heutzutage über mehrere Ethernet-Kabelan-
schlüsse und ein WLAN-Modul verfügen und die Übersetzung vom
lokalen Netzwerk ins Internet übernehmen. Generell sind Router
Geräte, die das Internet in Subnetze einteilen und so die Verteilung
der Datenpakete übernehmen.
Die Übertragung von Daten übernehmen im Internet entweder das
TCP- oder das UDP-Protokoll. Das UDP-Protokoll sendet munter
Daten, ohne auf eine Antwort zu warten oder zu prüfen, ob sie auch
wirklich ankommen. Man spricht von einer zustandslosen Datenü-
bertragung. Bei UDP kann es vorkommen, dass Daten auf dem Weg
verloren gehen, was aber für bestimmte Daten nicht weiter wichtig
ist. Weil die Überprüfung nicht stattfindet, ist UDP schneller als
TCP. Letzteres basiert auf dem sogenannten Drei-Wege-Handshake.
Das bedeutet, dass jede Übertragung, also zum Beispiel die Ausliefe-
rung einer Website mit einem Anfrage-Paket (SYN) begonnen und
von der Gegenseite mit einem »Acknowledged« (ACK) quittiert
wird. Um diese Quittierung zu bestätigen, sendet sie zusätzlich noch
ein weiteres SYN, auf das schließlich ein weiteres ACK von der
Senderseite folgt. Meist geschieht diese Antwort in einem kombi-
nierten ACK/SYN-Paket. Der Abbau einer Verbindung sieht ähnlich
aus, statt SYN heißt das entsprechende Paket aber FIN.
Natürlich muss man im Internet kaum noch eine IP-Adresse einge-
ben, um sich mit einem bestimmten Rechner zu verbinden. Dafür

154 Kapitel 6: Arduino im Netz


sorgt das Domain Name System (kurz DNS), das Domainnamen
(wie etwa [Link]) in Adressen umwandelt. Da DNS-Abfragen
keine sensiblen Daten darstellen, werden dafür UDP-Pakete ver-
wendet. Für Physical-Computing-Projekte ist das DNS relativ
unwichtig (man sollte nur wissen, dass es existiert), weswegen es
hier nicht weiter behandelt wird. Umfassende Erläuterungen finden
Sie unter anderem in der Wikipedia.
Nun können weitere Protokolle die eigentliche Anwendung reprä-
sentieren. Das World Wide Web beispielsweise verwendet das
Hypertext Transport Protocol (HTTP), um Daten zwischen Web-
server und Browser auszutauschen, E-Mail läuft über die Protokolle
POP3 (oder IMAP) und SMTP. Damit ein Gerät mit einer IP-
Adresse eingehende Daten unterscheiden kann, werden sogenannte
Ports verwendet. Die Portnummer wird als Teil des TCP/IP-Paketes
versendet. HTTP läuft dabei standardmäßig auf Port 80 (bzw. 443
bei sicheren Verbindungen), das zum Versenden von Mails verwen-
dete SMTP auf 25.
Die unterschiedlichen Protokolle werden ineinander gekapselt. Ein
HTTP-Paket ist also Teil eines TCP-Paketes, das wiederum Teil
eines IP-Paketes ist. Dieses befindet sich schließlich in einem Ether-
net-Paket. Die Informationsdaten der einzelnen Bestandteile nennt
man dabei Header, im Gegensatz zu den Nutzdaten, die das eigent-
liche Paket ausmachen.
Manchmal kann es vorkommen, dass die Netzwerkverbindung
Fehler aufweist. Es ist besonders schwer, die Ursache des Problems
aufzuspüren, wenn ein Protokoll falsch implementiert ist. Ein
Browser würde zum Beispiel bei einem fehlerhaften HTTP-Proto-
koll nicht ausreichend Informationen liefern. Abhilfe schaffen hier
sogenannte Sniffer, mit denen man eine Ethernet-Verbindung über-
wachen und alle übertragenen Daten auswerten kann. Besonders
empfohlen sei hier das Open-Source-Projekt Wireshark (http://
[Link]/).

Hardware
Zunächst wird der Ethernet-Shield mit dem Arduino-Board ver-
bunden, indem beide zusammengesteckt werden. Alle Pins sind
auch über den Shield zugänglich. Selbst die LEDs und der Reset-
Taste sind auf dem Ethernet-Shield noch einmal vorhanden, sodass
man sie bequem bedienen kann. Die Pins 10 bis 13 werden aller-
dings schon für den Ethernet-Controller verwendet und sollten
deshalb nicht für eigene Anwendungen eingesetzt werden, wäh-

Arduino im Netz 155


rend das Netzwerk benutzt wird (das könnte zu merkwürdigen
Effekten führen).

Abbildung 6-1
Ethernet-Shield

Der auf dem Board verbaute Chip Wiznet W1500 enthält einen
kompletten Ethernet- und IP-Stack für TCP und UDP. Das bedeu-
tet, dass er kein zusätzliches Betriebssystem benötigt, um mit dem
Internet zu kommunizieren. Er kann somit direkt mit dem Arduino
verwendet werden, bei der Programmierung muss man sich um
nichts mehr kümmern. Den weiteren Aufwand übernimmt die
Arduino-Ethernet-Bibliothek, die allerdings weder DNS noch
DHCP implementiert hat, sodass man derzeit noch auf statische IPs
zurückgreifen muss.

Software
In der Arduino-Entwicklungsumgebung und der Ethernet-Biblio-
thek ist bereits alles vorhanden, was man benötigt, um mit dem
Ethernet-Shield zu arbeiten.
Das Board kann mit [Link](mac,ip[,gateway,subnet] initi-
alisiert werden. Die MAC-Adresse (oder Ethernet-ID) ist dabei die
physische Adresse des Boards, die in diesem Fall vom Nutzer selbst
festgelegt werden kann, da der Hersteller des Shield diese Adresse
nicht vergeben hat. Die IP-Adresse muss je nach Netzwerk gewählt
werden, in dem der Arduino eingesetzt wird. Befindet man sich in
einem unbekannten Netzwerk, sollte man über den PC den IP-
Adressbereich herausfinden und eine Adresse wählen, die mit
Sicherheit in keinem Konflikt mit anderen steht. Die meisten Heim-

156 Kapitel 6: Arduino im Netz


netzwerke haben einen Adressbereich von [Link]. Wählt
man eine eigene IP-Adresse, darf diese sich nur im letzten Byte, also
im letzten Abschnitt, von anderen unterscheiden; hat also der PC
etwa die Adresse [Link] und der Netzwerkrouter [Link],
so sind für den Arduino die Adressen [Link] bis 255 möglich,
je nachdem, welche anderen Netzwerkgeräte sich noch im selben
Adressbereich befinden. Viel kann man allerdings nicht kaputt
machen, wenn man die Adressen ausprobiert, im Falle eines Kon-
fliktes funktioniert das Netz einzelner Geräte einfach nicht – dann
muss man eben umstellen.
Verwendet man mehrere Ethernet-Shields, sollte man darauf ach-
ten, dass sowohl MAC- als auch IP-Adresse unterschiedlich sind;
wenn man den einmal geschriebenen Code einfach nur auf andere
Arduino-Boards lädt, können besonders schnell Fehler auftreten.
Will man das Board mit dem Internet kommunizieren lassen, benö-
tigt man zusätzlich eine Gateway-Adresse. Diese ist in der Arduino-
Bibliothek schon voreingestellt, auf den aktuell eingestellten Netz-
werkadressbereich mit der Endung 1, also beispielsweise auf 192.
168.1.1. Sollte das nicht funktionieren, muss eine andere Adresse
eingestellt werden. Im Regelfall, also bei den heutzutage üblichen
Heimnetzwerken, ist das die Adresse des Netzwerkrouters. Meist
lässt sich auch diese über die Netzwerkinformationen des PCs her-
ausfinden. Nur selten ist es hingegen nötig, eine zusätzliche Subnet-
Adresse anzugeben. Diese ist im Normalfall auf [Link] ein-
gestellt – für alle Heimnetzwerke der Standard. Nur in großen,
komplexen Netzwerken, kann dieses Subnet ein anderes sein. Sollte
der Ethernet-Shield in einer solchen Umgebung, etwa dem Netz-
werk einer Hochschule, eingesetzt werden, sollte man ein Gespräch
mit dem zuständigen Systemadministrator führen.

Hello World – ein Mini-Webserver


Zunächst soll der Arduino als kleiner Webserver fungieren – ein
guter Anfang für viele Projekte, die aus der Ferne gesteuert werden
sollen. Der Webserver erwartet Anfragen auf dem Datenport 80 und
sendet als Antwort zum Beispiel eine Webseite, die dann im Brow-
ser dargestellt werden kann. Über solch einen Webserver können
Einstellungen vorgenommen werden, indem etwa bestimmte Links
aufgerufen werden, die im Arduino wiederum Aktionen hervorru-
fen. Zudem kann dieser Webserver etwa Informationen über den
Zustand des Arduino oder seine angeschlossenen Sensoren liefern.

Hello World – ein Mini-Webserver 157


Zunächst wird ein leeres Projekt erzeugt und mit #include <Ether-
net.h> die Ethernet-Bibliothek eingebunden, damit alle benötigten
Befehle zur Verfügung stehen.
Zudem werden zur Initialisierung die MAC- und die IP-Adresse des
Boards (siehe oben) benötigt:
// MAC-Adresse des Arduino-Boards, 6 Bytes
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// IP-Adresse des Arduino-Boards, 4 Bytes
byte ip[] = {192, 168, 1, 10 };

Dabei sollten Sie darauf achten, dass beide Adressen passen. Die IP-
Adresse muss ins lokale Netzwerk passen und darf dort keine Kon-
flikte erzeugen, also nicht identisch mit schon bestehenden Geräten
sein. Anschließend wird ein Serverobjekt erzeugt, das später die
Verbindungen auf Port 80, dem Standard-Port für Webserver,
annehmen kann. Das Objekt bietet eine Reihe von Funktionen, die
jederzeit abgerufen werden können.
Server server = Server(80);// Port-Einstellung (Standard 80)

In der Setup-Funktion wird zuerst zuallererst mit Ethernet.


beginn(mac,ip); die W1500-Hardware initialisiert. Danach wird
der Server gestartet:
[Link](); // Server wartet nun auf Clients

Nun muss in der loop()-Funktion auf einkommende Verbindungen


geantwortet und HTML-Code zurückgesendet werden.
Dabei können nicht einfach rohe HTML-Daten über das Netz
geschickt werden. Vielmehr muss der Webserver die Daten in
HTTP verpacken. So verstehen Browser dieselbe Sprache wie Web-
server und wissen, wie welche Daten zu interpretieren sind und was
bei bestimmten Fehlermeldungen zu tun ist.
HTTP wurde 1989 am CERN von Tim Berners-Lee entwickelt, der
damit den Grundstein für das World Wide Web legte. Zudem schuf
er das Konzept von URLs, die eine eindeutige Lage jedes HTML-
Dokuments beschreiben. Eine URL besteht aus dem Protokoll
(http), dem Server, möglichen Unterverzeichnissen und dem Doku-
mentnamen, zum Beispiel [Link] Zu-
dem können einer URL noch weitere Informationen übergeben
werden, wenn der Webserver in der Lage ist, diese zu interpretieren.
Wird eine URL im Browser eingegeben, sendet dieser eine Anfrage
an den passenden Server. Diese Anfrage beinhaltet den Anfragetyp

158 Kapitel 6: Arduino im Netz


(z.B. GET), den Servernamen, die Protokollversion und das ange-
fragte Dokument:
GET /[Link] HTTP/1.1
Host: [Link]

Erreicht diese Anfrage den Webserver, sendet dieser eine Antwort


mit einem Code. War die Anfrage in Ordnung, ist dieser Code 200
OK, aber es gibt eine ganze Reihe von anderen Möglichkeiten, etwa
wenn kein Ergebnis gefunden wurde (404 Not Found).
Zudem beinhaltet die Antwort beispielsweise Informationen über
den Webserver und das Betriebssystem, die Größe des zu übertra-
genden Dokumentes, dessen Sprache und Dokumenttyp und
Anweisungen, was nach Erhalt dieser Antwort zu tun ist.
HTTP/1.1 200 OK
Server: Apache/1.3.29 (Unix) PHP/4.3.4
Content-Length: (Größe von [Link] in Bytes)
Content-Language: de (nach ISO 639 und ISO 3166)
Content-Type: text/html
Connection: close
(Inhalt von [Link])

Nun kann der Browser diese Daten empfangen und anzeigen. Der
kleine Arduino-Webserver kennt allerdings nur einen sehr kleinen
Teil von HTTP: Er liefert immer eine »200 OK«-Antwort und kann
auch keine URLs unterscheiden.
void loop() {
Client client = [Link](); // prüfen, ob Client Seite
// aufruft
if (client) { // Seitenaufruf durch User
// übertrage 200 OK-Code und identifiziere den Server als
// arduino
[Link]("HTTP/1.0 200 OK\r\nServer: arduino\r\n");
// übertrage den Dateityp
[Link]("Content-Type: text/html\r\n\r\n");
//übertrage Daten
[Link]("<HTML><HEAD><TITLE>");
[Link]("Arduino Board");
[Link]("</TITLE>");
[Link]("</HEAD><BODY>");
[Link]("<b>Hello World!</b><br />");
[Link]("Arduino runs for ");
[Link](millis());
[Link](" ms.</BODY></HTML>");
//Datenübertragung zu Ende
delay(10); // kurz warten, um Daten zu senden
[Link](); // Verbindung mit dem Client trennen
}
}

Hello World – ein Mini-Webserver 159


Wenn man nun einen Webserver startet und die URL [Link]
168.1.10 öffnet, erscheint eine Webseite, die anzeigt, wie lange das
Board schon läuft. Die Funktion millis() zeigt dabei die Anzahl
Millisekunden seit dem Start des Programms.
Die Ausgabe könnte beispielsweise so aussehen:
Hello World!
Arduino runs for 14321 ms.

Dieser Webserver ist natürlich sehr einfach gestrickt. Er liefert auf


jede Anfrage die gleiche Antwort und kann deshalb auch nicht dazu
verwendet werden, Einstellungen im laufenden Arduino-Programm
vorzunehmen. Das Projekt Webduino ([Link]
webduino/) bietet hier mehr Möglichkeiten. Die Bibliothek ist in der
Lage, komplexere Browseranfragen zu bearbeiten und Fehlercodes
zurückzusenden. Sie kann also als Webserver eingesetzt werden,
der alle Basisfunktionen versteht. Das sollte für fast alle Arduino-
Projekte ausreichend sein.

Sag´s der Welt mit Twitter


Twitter ist ein Onlinedienst, auf dem Benutzer kurze Nachrichten
(»Tweets«) veröffentlichen können. Dabei ist die Nachrichten-
länge auf 140 Zeichen begrenzt. Jeder Nutzer erhält seine eigene
kleine Webseite unter [Link] Zudem
kann jeder Nutzer angeben, welche anderen Nutzer er regelmäßig
lesen, wem er also »folgen« möchte. So entstehen Kommunikati-
onsnetzwerke, die ein wenig einem Chat ähneln, wobei sich die
einzelnen persönlichen Chaträume der Nutzer teilweise überlap-
pen. Dadurch, dass man mit @username auf die Tweets anderer
antworten kann, entsteht eine neue Form der Kommunikation und
Diskussion. Benutzte man jedoch lediglich die Webseite, würde
alles recht schnell unübersichtlich. Abhilfe schafft die Twitter-API,
eine Schnittstelle, über die es möglich ist, eigene Programme mit
Twitter zu verbinden. Inzwischen dürfte die Mehrzahl aller aktiven
Twitter-Nutzer ein solches Programm verwenden – zwei bekannte
davon sind Tweetdeck oder Tweetie. Diese Programme informie-
ren ihre Nutzer in regelmäßigen Abständen über neue Tweets.
Innerhalb von etwas mehr als zwei Jahren hat sich Twitter von
einem Nischenspielzeug für eingeweihte Web-Enthusiasten zu
einem Mainstream-Dienst entwickelt. Besonders bei Ereignissen
von weltweiter Bedeutung, etwa bei Katastrophen, Terroranschlä-

160 Kapitel 6: Arduino im Netz


gen oder auch Wahlen, wurden besondere Aktivitätssprünge ver-
zeichnet. Der Grund dafür dürften vor allem die Aktualität und die
Geschwindigkeit sein, mit denen sich Neuigkeiten so verbreiten.
Als etwa am 15. Januar 2009 ein Flugzeug im New Yorker Hudson
River notlanden musste, war das erste Bild bereits zwölf Minuten
lang verbreitet worden, als die ersten Nachrichtendienste die Mel-
dung aufschnappten. Bei den Protesten gegen das Wahlergebnis im
Iran wurde Twitter ein nahezu unverzichtbares Kommunikations-
mittel für die aufbegehrenden Studenten.
Diese Eigenschaften von Twitter lassen sich auch für Physical-Com-
puting-Projekte nutzen. So kann ein mit dem Internet verbundener
Arduino beispielsweise Daten von angeschlossenen Sensoren twit-
tern, um seinen Besitzer (oder wen auch immer diese Informationen
interessieren) zu benachrichtigen. Eines der bekanntesten Projekte
dieser Art ist Botanicalls, das die Feuchtigkeit von Pflanzenerde
misst und über Twitter meldet, wenn eine Pflanze gegossen werden
muss.

Dazu wird der Widerstand zwischen zwei in die Erde gesteckten Abbildung 6-2
Drähten gemessen, der analog zur Trockenheit zunimmt. So kann Twitter und Arduino

Sag´s der Welt mit Twitter 161


der Arduino ab einem bestimmten Grenzwert einen Hilferuf über
Twitter absenden. Fertige Bausätze gibt es bei Botanicalls http://
[Link]/kits/ oder bei [Link] Ein
ähnliches Projekt erklärt auch Mats Vanselow unter [Link]
[Link]/2009/02/08/arduino-lernt-twittern/.
Der Fantasie sind hier keine Grenzen gesetzt: Fast alles, was man
messen kann, kann auch in Tweets umgesetzt werden. Es gibt sogar
ein Projekt, bei dem ein Bürostuhl twittert, wenn der »Besitzer«
bestimmte Gase freisetzt. Wer daran Interesse hat, möge das Projekt
unter [Link]
nachlesen. Das Projekt in diesem Buch soll nicht ganz so exotisch
sein, wir wollen nur die Helligkeit im Zimmer vermelden lassen.
Geht das Licht aus, wird ein Tweet abgesendet, möglicherweise ein
Hinweis für Freunde, die nicht wissen, ob sie noch anrufen können.
Noch sinnvoller wird das Ganze, wenn man es in einem von mehre-
ren Menschen genutzten Raum einsetzt. Wenn jemand erwägt, ob
er noch ein gemeinsam genutztes Atelier, einen Vereinsraum oder
Jugendzentrum besuchen soll, freut er sich vielleicht über die Infor-
mation, ob in diesen Räumlichkeiten noch etwas los ist.

Hardware
An den Arduino werden ein LDR (Fotowiderstand) sowie ein wei-
terer Widerstand mit ca. 10.000–100.000 Ohm angeschlossen. Der
Fotowiderstand ändert seinen Widerstand von ca. 1–100 Mio Ohm
(MOhm) im Dunkeln zu 100–2.000 Ohm in der Sonne. Er wird an
die die PINs 5V und A0 angeschlossen, der andere Widerstand an
A0 und GND. So fungieren die Bauteile als Spannungsteiler, und
die Spannung an A0 wird von der Helligkeit am LDR verändert
(siehe Abbildung 6-3).

Software
Den Anfang machen wieder ein paar grundlegende Einstellungen,
die gegebenenfalls angepasst werden müssten. Da der Ethernet-
Shield keine DNS-Abfragen machen kann, muss die IP-Adresse von
Twitter von Hand eingetragen werden. Sollte Twitter seine IPs
ändern, muss diese Adresse angepasst werden.
Die Ethernet-Bibliothek wird beim Arduino-Programm mitgeliefert
und kann dort einfach unter SKETCH → IMPORT LIBRARY eingebun-
den werden:

162 Kapitel 6: Arduino im Netz


Abbildung 6-3
Aufbau des Twitter-Lichtsensors

#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 0, 10 }; // unsere IP/anpassen an
// das lokale Netzwerk
byte gateway[] = { 192, 168, 0, 1 }; // die IP des Routers
byte subnet[] = { 255, 255, 255, 0 };
byte server[] = { 128, 121, 146, 100 }; // IP von Twitter
(default: [Link])
#define TWITTERURL "/statuses/[Link]" // URL zum Update-Skript
#define TWITTERUSERNAMEPW "geheim" // Base64 kodiert USERNAME:
// PASSWORT
Client client(server, 80);
void setup()
{
[Link](mac, ip, gateway, subnet); // Ethernet
// initialisieren
[Link](9600); // serielle Verbindung für Statusmeldungen
}

Zudem werden nun ein Twitter-Nutzername und -Passwort benö-


tigt. Ein entsprechendes Nutzerkonto kann schnell auf [Link]
[Link] angelegt werden. Name und Passwort müssen durch
einen Doppelpunkt getrennt, Base64-kodiert und in der Konstante
TWITTERUSERNAMEPW gespeichert werden. Die Base64-Wand-
lung kann man zum Beispiel online unter [Link]
projekte/kleinkram/[Link] durchführen. Allerdings gibt man
dort sein Twitter-Passwort in fremde Hände, und bei einer entspre-
chenden Suche findet man im Netz auch Downloadangebote mit
Software, die die Umwandlung auf dem Rechner erledigen kann,
ohne vertrauliche Daten durch die Gegend zu senden.

Sag´s der Welt mit Twitter 163


Nun werden zwei Routinen benötigt: Eine zum Senden der Nach-
richt und eine, die die Antwort vom Twitter-Server empfängt und
an den seriellen Port leitet, damit sofort bemerkt werden kann,
wenn etwas nicht funktioniert.
void sendTwitterUpdate(char* tweet) // Nachricht an Twitter
// übermitteln
{
[Link]("connecting...");
if ([Link]())
{
[Link]("connected");
[Link]("POST ");
[Link](TWITTERURL);
[Link](" HTTP/1.1");
[Link]("Host: [Link]");
[Link]("Authorization: Basic ");
[Link](TWITTERUSERNAMEPW);
[Link]("Content-Length: ");
[Link](9+strlen(tweet));
[Link]("");
[Link]("status=");
[Link](tweet);
[Link]("twitter message send");
}
else {
[Link]("connection failed");
}
}
void fetchTwitterUpdate() // Rückmeldung von Twitter auslesen
{
if ([Link]())
{
char c = [Link]();
[Link](c);
}
if (![Link]())
{
[Link]();
[Link]("disconnecting.");
[Link]();
}
}

Es soll nur eine Nachricht getwittert werden, wenn der Lichtzu-


stand sich gerade verändert hat, also wird der aktuelle Zustand in
der Variable licht gespeichert, der letzte Zustand in old_licht. So
kann auf Veränderungen reagiert werden.
int licht = 1;
int old_licht = 1;
int val;

164 Kapitel 6: Arduino im Netz


void loop()
{
delay(30000);
val = analogRead(0); // den Wert vom Sensor lesen
if (val > 400) { licht = 1; } // diese Werte müssen empirisch
// ermittelt werden
if (val < 200) { licht = 0; }
if (old_licht != licht) {
old_licht = licht;
if (licht == 1) {
[Link]("Hell!");
sendTwitterUpdate("Zimmer ist erleuchtet!"); // Nachricht
// versenden
}
else {
[Link]("Dunkel!");
sendTwitterUpdate("alle Photonen aufgebraucht!");
// Nachricht versenden
}
}
fetchTwitterUpdate(); // eingehende Nachrichten durchleiten
}

Fang die Bytes – Datalogger


Viele Daten werden erst richtig interessant, wenn man sie über län-
gere Zeit sammelt und dann gemeinsam auswertet. Dafür kann
man das EEPROM des Arduino nutzen, auf dem in diesem Projekt
die Daten gespeichert und anschließend auf einer Webseite zur
Verfügung gestellt werden sollen. Ein EEPROM ist eine kleine Spei-
cherzelle, die ein paar wenige Daten (beim Arduino sind es 512
Byte) aufnehmen kann. Die einzelnen Bits werden dabei in speziel-
len Transistoren gespeichert, sogenannten Floating Gates. Im
Gegensatz zu den üblichen Transistoren können diese ihren
Zustand, also leitend oder nicht leitend, auch speichern, wenn kein
Strom anliegt. 512 Byte erscheinen auf den ersten Blick nicht viel,
andererseits sollte es für die meisten Daten durchaus reichen, vor
allem wenn man sie sorgfältig auswählt.
Für die Arduino-Programmiersprache sorgt die EEPROM-Biblio-
thek für das Beschreiben und Lesen des Speichers. Es gibt zwei
Funktionen: write() und read(). Um diese zu verwenden, muss die
Bibliothek mit #include <EEPROM.h> eingebunden werden. Da nur
sehr wenige Daten zur Verfügung stehen, wird kein Dateisystem
benötigt. Es können also keine Dateien oder Ordner abgelegt wer-
den, und die Daten sind auch nicht speziell markiert. Beim Lesen

Fang die Bytes – Datalogger 165


und Schreiben muss also bekannt sein, wohin und woher die Daten
kommen.
Um das Ganze zu demonstrieren, soll der Wert eines Lichtsensors
periodisch alle zehn Sekunden auf das EEPROM geschrieben wer-
den. Nach einer Minute wird dann ebenfalls alle zehn Sekunden
der eine Minute alte Wert über die serielle Konsole ausgegeben.
Das Setup dürfte recht klar sein:
// verwende EEPROM-Bibliothek
#include <EEPROM.h>
// initialisiere Pin, Zähler und serielle Konsole
int lichtPin = 0;
int i = 0;
void setup() {
[Link](9600);
}

Nun kann der Wert ausgelesen und gespeichert werden. Der Input
des analogen Pins ist allerdings 10 Bit lang. Zunächst sollen aber
nur ein Byte lange Werte geschrieben werden. Entweder man ver-
wendet also für vier Werte fünf Bytes, was später noch erklärt wer-
den soll. Im einfacheren Falle genügt es, ungefähre Werte aus dem
Sensor zu speichern. Teilt man den aktuellen Wert durch vier,
erhält man die 8 Bit, die man bequem in einem einzelnen
EEPROM-Byte ablegen kann.
void loop() {
i++;
int lichtWert = analogRead(lichtPin);
lichtWert = lichtWert/4;
[Link](i, lichtWert);
if (i > 10) {
int ausgabeWert = [Link](i-10);
[Link](ausgabeWert, DEC);
}
delay(10000);
}

Nun fällt auf, dass der Speicher irgendwann voll sein wird. Es ist
also sinnvoll, nach 5.120 Sekunden wieder bei 0 zu beginnen. Man
fügt also am Anfang der loop()-Funktion Folgendes hinzu:
if (i == 512) {
i = 0;
}

Gleichzeitig ist es dann sinnvoll, einen der hohen Werte auszuge-


ben, wenn die Schleife gerade von vorn begonnen hat. Der Ausga-
beteil wird also ersetzt durch eine Funktion, die vom aktuellen
Zählerwert den passenden Ausgabewert ermittelt und schreibt:

166 Kapitel 6: Arduino im Netz


function ausgabe(int i) {
if (i < 10) {
i = abs(i-512);
}
else {
i = i-10;
}
int ausgabeWert = [Link](i);
[Link](ausgabeWert, DEC);
}

Da man nie weiß, welche Werte sich beim Start noch im EEPROM
befinden, sollte man zusätzlich zu Beginn alle Werte des Speichers
auf null setzen. Dazu werden alle Speicherplätze durchlaufen und
auf 0 gesetzt:
void deleteEEPROM() {
// durchlaufe jedes Byte des EEPROM und setze es auf 0
for (i = 0; i <512; i++) {
[Link](i, 0);
}
}

Angenommen, man benötigt doch die vollen 10 Bit des Sensor-


wertes, würde das bedeuten, dass ein Schreibvorgang immer volle
2 Bytes benötigt. 6 Bit pro Vorgang gingen verloren, bei gerade ein-
mal 512 Byte eigentlich kaum akzeptabel. Betrachtet man die
Werte bitweise, so erkennt man, dass vier Werte in fünf Bytes pas-
sen können. Dafür müssen sie lediglich umcodiert werden.
Die Funktionen bitRead() und bitWrite() können aus einer Vari-
able einzelne Bitwerte auslesen und schreiben. Geht man also den
Sensorwert bitweise durch und schreibt den Strom kontinuierlich
in Bytes, erhält man folgenden Code:
int bitPos = 0;
int currentByte = 0;
int currentBytePos = 0;
void loop() {
// lies Sensorwert ein
int sensorVal = analogRead(sensorPin);
// durchlaufe alle 10 Bits des Sensorwertes
for (int i = 0; i < 10; i++) {
// wenn das aktuelle Byte voll ist, also die Position im
// Byte 7 übersteigt
if (bitPos > 7) {
// springe auf das nächste Byte
currentBytePos++;
// schreibe das Byte an die aktuelle Byteposition
[Link](currentBytePos, currentByte);
// setze das Byte auf 0
sensorByte = 0;

Fang die Bytes – Datalogger 167


// setze die Bitposition auf 0
bitPos = 0;
}
//
// lies das aktuelle Bit des Sensorwertes ein
// und schreibe es an die entsprechende Position im
// aktuellen Byte
bitWrite(currentByte, bitPos, bitRead(sensorVal, i));
// zähle Bitposition nach oben
bitPos++;
}

Um die Daten wieder aus dem EEPROM zu lesen, muss die Funk-
tion umgedreht werden. Da die Größe der Sensordaten (10 Bit)
bekannt ist, weiß man auch, welche Bits sich wo befinden, wenn
man den Anfangswert kennt. Beginnt man bei null, liest man also
zuerst die ersten beiden Bytes aus und liest und schreibt das erste
Byte vollständig sowie die niedrigsten 2 Bits des zweiten Bytes in
die Ausgabevariable. Dazu zählt man die aktuelle Bitposition sowie
die Position des Bytes. Die Bitposition wird in jedem Schritt nach
oben gezählt. Nach 8 Bits wird diese wieder auf 0 gesetzt und die
Byteposition um eins erhöht. Sind 10 Bytes durchlaufen, wird die
Variable ausgelesen und ausgegeben.
Zunächst wird eine Reihe weiterer Zählvariablen benötigt:
int readBytePos = 0;
int readBitPos = 0;
int outByte = 0;

Anschließend kann der folgende Programmteil gesetzt werden.


// lies aktuelles Byte aus dem Speicher
currentByte = [Link](readBytePos);
// durchlaufe die zehn zu schreibenden Bits
for (int i = 0; i < 10; i++) {
// schreib aktuelles Bit aus dem gelesenen Byte in ein
// Ausgabebyte
bitWrite(outByte, i, bitRead(currentByte, readBitPos));
// zähle Bitposition nach oben
readBitPos++;
// nach 8 Bits fange wieder von 0 an
if (readBitPos > 7) {
readBitPos = 0;
readBytePos++;
// lies neues aktuelles Byte aus dem EEPROM
currentByte = [Link](readBytePos);
}
}

Nicht selten kommt es vor, dass mehrere Sensordaten eines Pro-


gramms geschrieben werden sollen. Schreibt man nun in einem

168 Kapitel 6: Arduino im Netz


fort, ist es schwer, die Daten auseinanderzuhalten. Wählt man den
gleichen Zähler, überschreiben sich die Daten gegenseitig. Hier
empfiehlt es sich, das EEPROM aufzuteilen und zum Beispiel eine
Gruppe in die ersten 256 Bytes und die zweite dahinterzusetzen.
Dabei sollte der Speicher je nach Bedürfnis aufgeteilt werden. Benö-
tigt der eine Wert zum Beispiel nur 4 und der andere 8 Bit, sollte
man die Trennung beim 128. Byte vornehmen, um gleich viele
Werte zu speichern.
Ein anderes Problem ist natürlich der Speicherplatz. Neben dem
eben erklärten Ausnutzen aller verfügbaren Bits kann man sich
natürlich auch überlegen, in welchen Abständen die Daten gespei-
chert werden sollen. Bei einem Temperatursensor, der nur die
Raumtemperatur aufzeichnen soll, genügt womöglich auch ein
Speichervorgang alle paar Minuten, bei anderen Werten sollte es
vielleicht jede Sekunde passieren. Wenn nur die letzten Werte
benötigt werden, kann man natürlich auch von vorn beginnen,
wenn der Speicher voll ist, und die alten Daten überschreiben.
Dazu sollte man sich natürlich in einer Variable merken, wo der
aktuellste bzw. jüngste Wert liegen.
Sie sollten dabei beachten, dass das EEPROM nur eine begrenzte
Anzahl von Schreibzyklen verträgt. Die im Datenblatt angegebenen
>100.000 Schreibzyklen können schnell erreicht werden, wenn
man zum Beispiel an einer Stelle im EEPROM abspeichert, welches
der nächste freie Platz zum Schreiben ist, da dieser Wert ja nach
jedem Schreibvorgang aktualisiert werden muss. Speicherte man
jede Sekunde einen Messwert, würde man diese Grenze schon nach
etwas mehr als einem Tag erreichen! Es kann natürlich in Wirklich-
keit viel, viel länger dauern, bis etwas passiert, da die Hersteller hier
sehr konservative Werte angeben, allerdings ist es noch viel besser,
gleich beim Algorithmus anzusetzen, um ein Vielfaches der Lebens-
dauer zu erhalten. Dabei sollte darauf geachtet werden, dass alle
Speicherzellen ungefähr gleich oft beschrieben werden.
Gerade bei Messwerten kann oft darauf verzichtet werden, eine
Null zu speichern; der Unterschied zur Eins bei einem 10-Bit-Mess-
wert beträgt nur 0,01%, bei 8 Bit nur 0,4%, damit ist der Wert
kaum relevant und die Messung kann vernachlässigt werden. Der
aktuelle Messwert wird dann an die erste Stelle im EEPROM
gespeichert, die gleich null ist, die nächste Stelle wird dann auf null
gesetzt, sodass der nächste Zugriff zuverlässig seine Stelle findet. So
kann auch gleich ein sogenannter Ringpuffer implementiert wer-
den: Wenn das nächste Byte außerhalb der EEPROM-Größe liegt,

Fang die Bytes – Datalogger 169


wird stattdessen das erste gelöscht. So hat man immer die zum Bei-
spiel 512 letzten Messwerte zur Verfügung.
Durch diesen Trick kann jetzt die Lebensdauer des EEPROM bei
sekündlichem Speichern auf fast ein Jahr verlängert werden. Reicht
auch dieser Wert nicht aus, kann es eine Lösung sein, die Batterie-
spannung regelmäßig zu messen und die Werte erst dann aus dem
RAM ins EEPROM zu verschieben, wenn die Spannung unter einen
bestimmten Wert fällt. Bei geschickter Programmierung reicht
dafür auch ein etwas größerer Kondensator an der Betriebsspan-
nung, sodass gerade noch genug Zeit bleibt, alle Werte zu sichern.
Dafür sollte diese Routine dann aber über einen Interrupt gestartet
werde, damit der Zeitpunkt nicht verpasst wird.
Die einfachste Möglichkeit ist, einfach seltener zu messen, oder
eventuell sekündliche Messwerte nur im RAM zu speichern und
daraus berechnete Durchschnittswerte der letzten Minute ins
EEPROM zu übertragen.

170 Kapitel 6: Arduino im Netz


KAPITEL 7 In diesem Kapitel:
• Sensoren
Sensoren • Aktoren
• Elektronischer Würfel

Dieses Kapitel beschäftigt sich näher mit verschiedenen Sensoren


und Aktoren. Dabei werden zunächst die häufigsten verwendeten
Bauteile erläutert und ihre möglichen Einsatzgebiete erklärt. Damit
wird eine Grundlage für die darauf folgenden Workshops geschaf-
fen, in denen zum Teil eigene Bauteile gebastelt, zum anderen die
hier beschriebenen Sensoren und Aktoren eingesetzt werden.

Sensoren
Die wohl wichtigste Rolle beim Physical Computing spielen ne-
ben immer günstigeren Mikrocontrollern vor allem die verschie-
denen Sensoren. Ob sie nun selbst angelötet werden, mit einem
Steckbrett an den Arduino angeschlossen, oder ihren Weg über ei-
nen der zahllosen Shields nehmen, die verschiedenen Zwecke die-
nen: Ohne Sensoren ist ein Arduino-Board kaum etwas wert. Hier
werden die wichtigsten Sensorenarten und ihre Ausprägungen
vorgestellt, wobei dieses Kapitel längst nicht alle einzelnen Bau-
teile umfassen kann. Weitere Informationen finden Sie unter an-
derem im Tutorial-Bereich auf der Arduino-Website ([Link]
[Link]/playground/Learning/Tutorials) oder in der ausführli-
chen Zusammenfassung bei Freeduino ([Link]

Schalter und Taster


Schalter und Taster wurden schon detailliert in Kapitel 3 vorge-
stellt. Von den hier vorgestellten Sensoren sind sie diejenigen,
deren Funktionsweise am einfachsten ist: Ist der Schalter oder Tas-
ter »eingeschaltet«, fließt Strom, ansonsten ist der Stromkreis
unterbrochen.

171
Schalter und Taster werden in der Regel mit dem einen Pin an einen
digitalen Arduino-Pin und mit dem anderen an GND angeschlos-
sen. Bei mehrstufigen Schaltern werden natürlich auch mehrstufige
Pins verwendet. Fließt der Strom, liegt am digitalen Eingang eine 1
an, ist der Stromkreis unterbrochen, ist das Ergebnis eine 0. Bei
Schaltern und Tastern empfiehlt es sich, einen Pull-up-Widerstand
zu verwenden (siehe Kapitel 3).
Die Anwendungen von Schaltern und Tastern sind dabei sehr viel-
fältig. So könnte eine LED-Leuchte beispielsweise mit einem Schal-
ter durch verschiedene Modi wechseln oder auch nur ein- und
ausgeschaltet werden. Ein Taster wiederum eignet sich vor allem
zur Eingabe, etwa bei kleinen Spielen, die damit gesteuert werden.
Auch für ein Wecker-Projekt könnte man einen Taster verwenden,
um Uhr- und Weckzeit einzustellen.

Dreh- und Schieberegler


Im folgenden Abschnitt geht es um Bauteile, die in der Lage sind,
für den Benutzer quasi stufenlose Eingaben an den Arduino zu sen-
den. Dabei handelt es sich um Dreh- und Schieberegler, die je nach
Einstellung eine unterschiedliche Spannung an den Ausgang lassen.
Die analogen Input-Pins des Arduino sind in der Lage, bis zu 10 Bit,
also Eingaben von 0 bis 1.023 zu verarbeiten. Je nach Verwendung
empfiehlt es sich jedoch, diese Werte zu teilen (durch 4 oder sogar
8). Damit können die Messungen ein wenig fehlertoleranter wer-
den, da die Eingaben aus analogen Bauteilen niemals konstant bei
einem Wert liegen.

Potentiometer
Potentiometer sind auch als Drehknöpfe oder Drehregler bekannt
und die wohl meisten verbreiteten Bauteile aus der Gruppe der stu-
fenlosen Regler. Sie gehören zur Klasse der resistiven Sensoren, also
derjenigen, bei denen die Spannung durch den Widerstand verän-
dert wird.
Potentiometer gehören, ähnlich wie die vorhin beschrieben Schalter
und Taster, zu den am häufigsten eingesetzten Steuerelementen.
Drehknöpfe gibt es in allen möglichen Formen: als Lautstärkeregler
einer Stereoanlage oder um die Temperatur eines Herdes zu steuern,
aber auch in zahlreichen Physical-Computing-Projekten. Sie können
die Frequenz oder Helligkeit von LEDs steuern oder als Eingabemit-
tel für Processing verwendet werden, um dort zum Beispiel Formen
und Farben einer Animation einzustellen und live zu verändern.

172 Kapitel 7: Sensoren


Joystick
Eine besondere Variante des Potentiometers ist der Joystick. Ein
Joystick ist in der Lage, sich in zwei Achsen und somit alle Richtun-
gen zu bewegen. Dabei nutzt er pro Achse ein Potentiometer,
sodass er nur an zwei analoge Pins des Arduino (sowie an 5V und
GND) angeschlossen werden muss. Gerade um bewegliche Objekte
mit dem Arduino zu steuern, sind Joysticks sehr sinnvoll. So kön-
nen zum Beispiel zwei Joysticks eine Fernbedienung für einen
Roboter oder eine Flugdrohne bilden. Oftmals werden dabei auch
nicht nur einfache Bauteile aus dem Elektronikfachhandel verwen-
det, sondern Computerjoysticks, deren Anschlüsse an den Arduino
gelötet werden, oder der Controller der Nintendo Wii, die soge-
nannte Wiimote bzw. der Nunchuck-Teil. Der Vorteil dabei ist,
dass gleichzeitig noch eine Menge anderer Sensoren dabei sind, die
beim Nunchuck direkt und bei der Wiimote über Bluetooth ange-
sprochen werden können.

Ribbon Controller und Touchpads


Unter einem Touchpad versteht man eine Fläche, die die Position
eines oder mehrerer Finger feststellen und die Daten darüber wei-
tervermitteln kann. Pads mit nur eine Achse nennt man auch Rib-
bon Controller. Diese werden vor allem in der Musik eingesetzt
und sind unter anderem auf Synthesizern zu finden.
Dabei gibt es zwei grundsätzliche Ausprägungen dieser Pads: resis-
tiv und kapazitiv. Erstere verwenden eine leitende Oberfläche,
deren Widerstand durch die Position des Fingers verändert wird.
Ähnlich wie bei den vorher beschriebenen Potentiometern liegt
somit auch mehr oder weniger Spannung am Ausgang an, sodass
ein Wert ermittelt werden kann.
Kapazitive Touchpads bestehen üblicherweise aus einer vertikalen
und einer horizontalen Anordnung von Elektroden, die ein Gitter
bilden. Die Oberfläche des Touchpads ist dabei eine isolierende
Schutzschicht, die verhindert, dass die Finger direkt mit den Elek-
troden in Berührung kommen. Da der menschliche Körper und
damit auch die Finger selbst wie eine Elektrode funktionieren,
verändert sich die Kapazität der einzelnen Elektroden, wenn ein
Finger das Pad berührt. Ein Schaltkreis darunter kann diese Ände-
rungen messen und als veränderte Spannung weitergeben.
Touchpads finden außerhalb von Laptops vor allem in der Musik
Anwendung. So kann ein Pad zum Beispiel für Midi-Eingaben ver-

Sensoren 173
wendet werden; mithilfe eines Arduino könnte man so teure
Musikhardware selbst bauen. Aber auch für kleine Spiele auf dem
Arduino – selbst mit einem Display – oder unter Processing gibt es
einige Möglichkeiten, ein Touchpad einzusetzen.

Resistiver Touchscreen
Ein resistiver Touchscreen besteht aus einer leitfähig beschichteten
Glasscheibe, über der sich eine leitfähige Kunststofffolie befindet.
Auf der Folie sind viele ganz kleine Abstandhalter aufgedruckt
(normalerweise ein Epoxidsiebdruck), sodass im Normalfall die
Folie keinen Kontakt zur Glasscheibe hat. Drückt man mit einem
Finger oder Stift auf die Folie, entsteht eine leitfähige Verbindung,
und der Ort dieser Verbindung kann über die Widerstandswerte
gemessen werden. Dazu hat eine leitfähige Schicht zwei horizontale
und die andere zwei vertikale Anschlüsse. Zuerst wird durch Anle-
gen einer Spannung an die horizontale Schicht auf dieser ein Span-
nungsverlauf (wie bei einem Potentiometer) aufgebaut, über die
beiden vertikalen Anschlüsse kann dann die Position in horizonta-
ler Richtung gemessen werden. Danach wird das Verfahren umge-
dreht und die vertikale Richtung vermessen.
Dafür ist es ganz praktisch, dass die analogen Eingänge des Ardu-
ino-Boards auch als Ausgänge verwendet werden können. An vier
dieser Ein-/Ausgänge kann direkt ein 4-Wire-Touchscreen ange-
schlossen werden.
Größere und langlebigere Touchscreens werden oft in 5-Wire-
Technik ausgeführt, sie haben also fünf Anschlüsse. Die leitfähige
Kunststofffolie wird hier nur als Messeingang verwendet, und die
Potentiale werden mit den vier Elektroden auf der Glasplatte reali-
siert. Dadurch kann die Beschichtung auf der Folie viel dicker und
niederohmiger ausgeführt werden, und Widerstandsschwankungen
in der Folie verändern nicht den Messwert.
Allen resistiven Touchscreens ist gemeinsam, dass sie keine Multi-
touch-Funktion unterstützen, da man nur einen Berührungspunkt
messen kann.

Lichtsensoren
Nach den mehr oder weniger mechanischen oder elektromechani-
schen Sensoren folgen nun jene, die auf optische Impulse wie etwa
Helligkeit reagieren können.

174 Kapitel 7: Sensoren


Fotowiderstand
Ein Fotowiderstand oder LDR (light dependent resistor) besteht
aus einer Halbleiterschicht, deren Widerstand mit zunehmender
Lichtstärke abnimmt. Die Schicht besteht dabei meist aus Cadmi-
umsulfid (CdS), dessen Leitfähigkeit durch den inneren fotoelektri-
schen Effekt zunimmt. Schließt man diesen Sensor nun an den
Arduino an, kann man Werte von 0 (völlig dunkel) bis 1.023 (sehr
hell) messen. In diesem Buch werden zweimal LDR eingesetzt: um
über Twitter zu melden, ob das Licht im Raum an ist, und für ein
kleines Spiel im Zusammenhang mit Processing. Möglich wäre
auch eine selbstregulierende Lampe, die die aktuelle Helligkeit
misst und versucht, sie auf einem Level zu halten. Eine solche
Lampe würde bei Sonnenuntergang langsam angehen. Um festzu-
stellen, ob sie auch wieder ausgeht, müsste langsam herunterge-
dimmt und ab einem gewissen Schwellenwert erneut geprüft
werden. Reicht die Helligkeit aus, bleibt die Lampe auf diesem
Niveau, ist es zu dunkel, wird sie wieder heller gestellt. Andererseits
könnte der Sensor natürlich auch außen angebracht und so von der
Lampe getrennt werden. Weitere Möglichkeiten sind die Verwen-
dung von MAX/MSP zusammen mit einem Arduino und einem
Fotowiderstand, um elektronische Musikinstrumente zu steuern,
oder der Einsatz eines LDR, um einen kleinen Roboter zu lenken.

Light Intensity IC
Ein nicht ganz günstiger Schaltkreis zur Lichtintensitätsmessung ist
der TSL230R-LF von Taos. Dabei liegt der große Vorteil in der line-
aren und vermessenen Ausgangsfunktion. Der Schaltkreis gibt
abhängig von der gemessenen Helligkeit unterschiedlich lange
Impulse aus. Laut Datenblatt ist die Länge der Impulse definiert als
0,77 KHz/W. Damit ist also eine echte Helligkeitsmessung möglich.
Eine ausführliche Referenz findet sich im Blog von Roaming Drone
unter [Link]
the-taos-tsl230r-light-sensor-getting-started/. Diese Adresse findet
sich, wie alle Adressen in diesem Buch und weitere Aktualisierun-
gen im Blog zum Buch, unter [Link]

Fototransistor
Ein Fototransistor ist, wie der Name schon sagt, eine spezielle
Form des Transistors. Bei entsprechendem Lichteinfall lässt er
einen Stromfluss zu. Dabei ist er viel lichtempfindlicher als eine
Diode, da er gleichzeitig als Verstärker wirkt. Das wohl bekannteste

Sensoren 175
Arduino-Projekt, das einen Fototransistor einsetzt, ist eine Schal-
tung, um Gewitterblitze zu fotografieren. Dabei ist der Transistor
schnell genug, um im Falle eines hellen Blitzes in der Natur den
Auslöser zu betätigen. Eine passende Schaltung ist sehr einfach,
wenn die Kamera eine elektrische Auslöseverbindung besitzt. Diese
wird an einen digitalen Ausgangspin angeschlossen, der Transistor
an einen analogen Eingang. Misst man nun konstant die Licht-
werte, kann man bei einem ausreichend starken Anstieg ein digita-
les Signal an den Auslöser geben, sodass die Kamera ein hoffentlich
gutes Foto eines Blitzes machen kann.
Eine Dokumentation dieses Projekts findet sich im Netz unter
[Link]

Lichtschranke
Mithilfe eines handelsüblichen Lasers und einer Fotodiode lässt
sich eine einfache Lichtschranke basteln. Dabei wird der Laser so
ausgerichtet, dass sein Licht direkt auf die Fotodiode fällt. Wird
das Licht des Lasers unterbrochen, sodass es nicht mehr auf die
Diode fällt, fällt das Signal stark ab, und der Arduino ist in der
Lage, dies zu verarbeiten. In der Fotografie gibt es weitaus mehr
Gelegenheiten, Fotos in möglichst kurzer Zeit auszulösen, als nur
bei Blitzen. Eine Lichtschranke ist etwa in der Lage, Tropfen in
einer Flüssigkeit zu erkennen und eine entsprechende Fotografie
auszulösen. Natürlich lassen sich so auch einfache Alarmsysteme
basteln, die vermelden, wenn eine bestimmte Schranke durch-
kreuzt wurde, oder man misst die Geschwindigkeit eines Objektes,
indem man den Zeitabstand zwischen der Durchquerung zweier
Schranken berechnet.

Beschleunigungssensoren
Beschleunigungssensoren messen, wie ihr Name schon verrät, die
aktuelle Beschleunigung in eine oder mehrere Richtungen. Im Fol-
genden werden Drei-Achsen-Beschleunigungssensoren vorgestellt,
die direkt an den Arduino angeschlossen werden können, sowie
weitere Bauteile und Geräte, die einen solchen Sensor beinhalten.

Einfache Beschleunigungssensoren
Moderne Beschleunigungssensoren wie der ADXL320 und der
ADXL330 von SparkFun basieren auf sogenannten mikroelek-
trisch-mechanischen Systemen oder MEMS und werden aus Sili-

176 Kapitel 7: Sensoren


zium hergestellt. Diese Sensoren bestehen aus wenige Mikrometer
breiten Siliziumstegen und einer ebenfalls aus Silizium bestehenden
Masse. Bei einer Beschleunigung lenkt diese Masse aus und führt zu
einer Kapazitätsänderung zwischen ihr und einer Bezugselektrode.
Dabei besteht der gesamte Messbereich nur aus etwa einem pF
(picoFarad, Billionstel Farad). Diese Änderungen können nicht auf
das Arduino-Board übermittelt werden, sondern werden direkt auf
dem Halbleiterbaustein verarbeitet. Der ADXL wird nun an drei
analoge Pins und an 5V angeschlossen, damit die Beschleunigungs-
werte gelesen werden können. Möchte man nun wissen, wie viel G
(Einheit für Beschleunigung) ein bestimmter Wert bedeutet, muss
man diesen anhand einer Tabelle umrechnen. Diese erhält man aus
dem Datenblatt.
Beschleunigungssensoren können auch verwendet werden, um
Neigung festzustellen. Das ist beispielsweise bei einer Flugdrohne
nützlich, die nicht nur von Wegpunkt zu Wegpunkt fliegen, son-
dern sich dabei auch stabil in der Luft halten soll. Natürlich eignen
sich solche Sensoren auch für Spielereien wie das bekannte Mur-
melspiel, das z.B. in Processing implementiert werden kann. Der
Sensor steuert das Brett, auf dem die Murmel liegt, die nun durch
ein Labyrinth finden muss, ohne in eines der Löcher zu fallen.

Wiimote
Als Nintendo Ende 2006 die Wii-Konsole auf den Markt brachte,
sorgte das nicht nur in Spielerkreisen für Aufruhr. Grund dafür war
die Technik, die im Wiimote-Controller und dem angeschlossenen
Nunchuck verbaut ist und einzeln im Elektronikfachhandel viel
teurer ist als in der weißen Hülle.
Freundlicherweise hat Nintendo sich aber nicht darauf beschränkt,
diese Daten verschlüsselt an die Wii zu senden. Vielmehr wird
Bluetooth eingesetzt, um alle nötigen Informationen zu funken; der
Nunchuck benutzt ein serielles Protokoll. Dafür gibt es inzwischen
Bibliotheken, sodass vor allem Beschleunigungssensor und Joy-
stick des Nunchuck, aber auch der daran angebrachte Knopf aus-
gelesen werden können. Nunchucks sind im Handel für 19,95
Euro erhältlich. In Kapitel 10 wird ein Nunchuck an den Arduino
angeschlossen und als MIDI-Kontroller verwendet. Ein ausführli-
ches Tutorial zur Verwendung mit dem Arduino findet sich unter
[Link]
Die wohl nächstliegende Verwendung des Nunchuck liegt in der
Kontrolle von Motoren. Kleine Servos können Roboter antreiben,

Sensoren 177
aber auch andere Geräte wie etwa eine Webcam. Dank Knopf, Joy-
stick und Neigungssensor gibt es aber noch unzählige andere Ein-
satzgebiete. So findet sich im Internet beispielsweise ein Bastler, der
seine Espressomaschine mit einem Nunchuck ausgestattet hat, um
die verschiedenen Parameter wie Druck und Hitze einzustellen und
schließlich mit der Produktion des perfekten Espresso zu beginnen.

Gyroskop
Ein Gyroskop ist ein schnell rotierender Kreisel, der sich in einem
beweglichen Lager dreht, z.B. in einem Käfig. Aufgrund der Dreh-
impulserhaltung behält der Kreisel auch seine Lage im Raum, wenn
der Käfig geneigt wird. Dadurch können Drehungen und Neigun-
gen im Raum gemessen werden. Das Gyroskop kann also als Kom-
pass dienen, um den richtigen Weg nach Norden anzuzeigen –
selbst an den Polen, wo ja magnetische Kompasse versagen. Zudem
liefert es echte Neigungsmesswerte, selbst wenn es sich bewegt.
Beschleunigungssensoren können einen Winkel zur Schwerkraft
nämlich nur dann korrekt messen, wenn sie sich im Ruhezustand
befinden.
Elektronische Gyroskope werden heute ähnlich wie Beschleu-
nigungssensoren als MEMS aufgebaut. Allerdings ist darin kein
sich drehender Kreisel mehr vorhanden, sondern eine vibrierende
Masse, deren Auslenkung bei Drehungen gemessen werden kann.
Beispiele dafür sind der ADXRS300 und der ADXRS610 von Ana-
log Devices. Um eine stabile Lage in der Luft zu halten, benötigen
beispielsweise Quadrokopter drei Gyroskope. Sie werden aller-
dings zusätzlich von einem Beschleunigungssensor unterstützt,
damit sich Messfehler nicht aufaddieren und den Hubschrauber
zum Umkippen bringen.

Abstandssensoren
Es gibt viele Methoden, mit denen sich der Abstand von einem
Objekt zum Sensor messen lässt. Das reicht von recht einfachen
Mitteln wie einem kapazitiven Sensor bis hin zu Radar und Ultra-
schall. Im Folgenden werden die häufigsten Methoden beschrieben.

Ein kapazitiver Sensor zum Selbstbauen


Ein kontaktloser kapazitiver Sensor basiert, wie sein Name schon
beschreibt, auf der elektrischen Eigenschaft der Kapazität. Sie

178 Kapitel 7: Sensoren


beschreibt die Fähigkeit eines Objektes, elektrische Ladungen zu
speichern. Der Sensor zeigt an, wie zwei leitfähige Schichten (zum
Beispiel Metallplatten), die durch eine nicht leitfähige getrennt sind
(z.B. Luft), auf eine angelegte Spannungsdifferenz reagieren. Das
wohl bekannteste Einsatzgebiet dieser Eigenschaft ist der Konden-
sator. Die Kapazität hängt von der Fläche und der Entfernung der
leitfähigen Objekte ab.
Ein solcher Sensor lässt sich einfach selbst basteln, indem auf der
einen Seite eine Antenne (ein Draht oder ein Stück Aluminiumfolie)
verwendet wird, die mit dem Arduino verbunden ist. Die andere
Seite kann zum Beispiel die Hand oder der Körper des Benutzers
sein, da auch diese leitfähig sind.
Kapazitive Sensoren verwenden eine Wechselspannung, die immer
wieder an einem Ende des Sensors angebracht wird. Diese Span-
nung erzeugt wiederum einen elektrischen Strom, der von der
Kapazität abhängt, also vom Abstand zwischen Draht und Hand. Je
größer und näher die Handfläche, desto mehr Strom wird erzeugt,
natürlich auch in Abhängigkeit von der Form der Antenne. So las-
sen sich mit einem großen Stück Folie empfindlichere Bewegungen
messen als mit einem kurzen Stück Draht. Wenn aber z.B. nur ein
kleiner Bereich empfindlich auf Näherung reagieren soll, ist der
Draht praktischer. Hier gilt wie so oft der Grundsatz »Probieren,
Probieren, Probieren!«
Ein kapazitiver Sensor wird jeweils an zwei Arduino-Pins ange-
schlossen Der eine ist der Sendepin, der die Wechselspannung des
Sensors erzeugt. Er wird regelmäßig von 0 auf 1 gesetzt und erzeugt
so eine ständig wechselnde Spannung. Über einen relativ hoch-
ohmigen Widerstand wird er an den Empfangspin angeschlossen.
In diesem Setup verwenden wir einen Widerstand von 5 Megaohm,
es sind aber Werte von ca. 1–10 Megaohm möglich. Je nach Wider-
stand ist der Sensor mehr oder weniger empfindlich, es ist hier also
nicht notwendig, den genauen Wert von 5 Megaohm einzusetzen.
An den Empfangspin wird die Antenne angeschlossen. Dazu lässt
sich entweder ein langes Stück blanker Draht verlöten oder ein
Stück Alufolie, das um etwas Draht gewickelt ist. Möglich sind
auch leitende Gegenstände (wie ein Kochtopf), die mit dem Pin ver-
bunden werden. Wichtig ist, dass der Antennengegenstand elek-
trisch leitend ist. Mit der Entfernung der Antenne zu anderen
leitenden Gegenständen, die mit der Erde verbunden sind (z.B. der
menschliche Körper des Benutzers oder eine Heizung) lässt sich die

Sensoren 179
Kapazität am Empfangspin verändern. Zusammen mit dem Wider-
stand, der Sende- und Empfangspin verbindet, wird ein soge-
nanntes RC-Netzwerk gebildet. RC steht für resistor und
capacitator, also Widerstand und Kondensator. Diese beeinflussen,
wie schnell eine Spannungsänderung am Ausgang des Netzwerks
widergespiegelt wird. Wenn also der Arduino den Sendepin von 0
auf 1 schaltet, bestimmt die Kapazität an der Antenne, wie schnell
diese Veränderung am Empfangspin ankommt. Misst man nun die
Zeit, lässt sich die Entfernung des menschlichen Körpers bestim-
men. Verwendet man mehrere Sensoren, kann man sogar die Posi-
tion berechnen.
Natürlich kann man solche Sensoren auch für wenig Geld kaufen.
In jedem Falle kann die Spannung analog ausgelesen und verarbei-
tet werden.

Hall-Sensor
Ein Hall-Sensor nutzt den nach dem Physiker Edwin Hall benann-
ten Effekt, der das Auftreten von elektrischer Spannung in einem
stromdurchflossenen Leiter beschreibt, wenn dieser sich in einem
stationären Magnetfeld befindet. Die Spannung fällt dabei senk-
recht sowohl zur Stromfluss- als auch zur Magnetfeldrichtung am
Leiter ab und wird Hall-Spannung genannt. Dieser Sensor ist also
kein Abstandssensor im eigentlichen Sinne, kann aber zum Beispiel
als Schalter verwendet werden, ohne dass ein mechanischer Kon-
takt entstehen muss. Er kann aber auch verwendet werden, um
Magnetfelder zu erkennen und ihre Stärke zu messen. Wenn
Strom- und Magnetfeldstärke bekannt sind, funktioniert er auch
als Metalldetektor. Ein recht einfaches Projekt ([Link]
[Link]/2009/03/02/my-first-arduino-project/), das einen Hall-
Sensor verwendet, ist ein Elektromagnet, der durch die Regelung
mittels Arduino ein magnetisches Objekt in der Luft schweben las-
sen kann. Dabei misst ein Hall-Sensor die Stärke des Feldes und der
Arduino reguliert es, sodass das Objekt nicht zu nahe kommt oder
aus dem Feld herausfällt. Andererseits kann der Hall-Sensor zum
Beispiel auch benutzt werden, um die Geschwindigkeit eines Venti-
lators zu messen.

Reed-Relais
Das Reed-Relais schaltet einen Stromkreis, je nachdem, ob sich ein
magnetisches Feld in der Nähe befindet oder nicht. Es besteht aus
zwei Kontakten, die in einem Glaskörper so eingeschmolzen sind,
dass sie sich durch ein externes Magnetfeld anziehen können. Je

180 Kapitel 7: Sensoren


nach Beschaffenheit schließen oder öffnen sie sich, wenn eine mag-
netische Spule oder ein Dauermagnet in die Nähe kommt. Fällt das
Magnetfeld ab oder unterschreitet es eine bestimmte Schwelle, wird
dieser Effekt beendet. Die wohl bekannteste Anwendung ist ein
Tachometer am Fahrrad, bei dem der Magnet am Rad und das
Reed-Relais am Rahmen angebracht sind. Weil der Reifenumfang
bekannt ist, kann man dann die Geschwindigkeit und die zurück-
gelegte Strecke des Rades berechnen, indem man die Zeit zwischen
zwei Kontakten misst. Natürlich kann ein solcher Schalter auch an
einer Tür angebracht werden, um festzustellen, ob sie geöffnet oder
geschlossen ist. Das Ergebnis lässt sich dann digital mit dem Ardu-
ino auslesen.

Sonar
Das Sonar kennt man aus U-Booten (bzw. den entsprechenden Fil-
men), wo es zur Ortung von fremden Gegenständen und Booten in
der Umgebung verwendet wird. Ein Sonarsensor kann aber auch
dazu verwendet werden, den Abstand von einem Objekt zum Sen-
sor zu messen. Das geschieht, indem ein Ultraschallsignal ausge-
sendet und die Zeit gemessen wird, bis das Echo zurückkommt. Ein
Beispiel für einen solchen Sensor ist der Ping))) von Parallax Inc.
([Link]
ProductID/92/List/1/[Link]?SortField=ProductName,Product-
Name). Er ist in der Lage, Objekte in einer Entfernung von 2 cm bis
zu 3 m zu orten. Die Messung übernimmt allerdings das daran
angeschlossene Arduino-Board. Es setzt zunächst den mit dem Sen-
sor verbundenen Pin als Output fest und sendet dann ein Signal
und anschließend den Pin auf Input. Nun kann es die Zeit messen,
bis ein Signal auf dem Pin anliegt, und diese Zeit in Entfernung
umwandeln, da Schall sich in der Luft nahezu konstant bewegt.
Laut Datenblatt sind das 1.130 Fuß (344,424 Meter) pro Sekunde,
also 34,442 Zentimeter pro Millisekunde.

Infrarotsensor
Natürlich lässt sich auch mit Licht die Position relativ zu einem
Objekt bestimmen. Dafür werden Infrarotwellen gemessen, die
vom Sensor ausgesandt werden. Das angepeilte Objekt reflektiert
die Lichtwellen, die in einem bestimmten Winkel wieder auf dem
Sensor auftreffen. Diese Messung samt Abstandsberechnung nennt
man Triangulation. Für einfache Projekte empfiehlt sich zum Bei-
spiel der IR Range Finder GP2D12 von Sharp, der für ca. 14 Euro
im Elektronikfachhandel erhältlich ist. Er kann Objekte in einer
Entfernung zwischen 10 und 80 Zentimetern erkennen.

Sensoren 181
Temperatursensor
Temperatur lässt sich auf viele verschiedene Arten durch die
Anwendung unterschiedlicher physikalischer Prinzipien messen.
Am häufigsten sind Widerstandssensoren. Kaltleiter erhöhen ihren
Widerstand, wenn die Temperatur zunimmt, während Warmleiter
ihn senken. Auf der anderen Seite gibt es auch Halbleitersensoren,
die – je nach Bauweise – zur Temperatur proportionalen Strom
oder Spannung liefern.

Feuchtigkeitssensor
Grundsätzlich gibt es zwei verschiedene Arten von Sensoren, um
Feuchtigkeit zu messen: Hygrometer, die die Luftfeuchtigkeit
anzeigen können, und Messgeräte für die Messung der Feuchtigkeit
in verschiedenen Stoffen (z.B. Tensiometer für die Bodenfeuchtig-
keit).
Die interessanten Hygrometer sind vor allem jene, die die absolute
Luftfeuchtigkeit messen können. Um die relative Luftfeuchtigkeit
und den Taupunkt zu messen, gibt es ebenfalls Verfahren, die hier
aber keine Rolle spielen.
Um die absolute Luftfeuchtigkeit zu messen, wird ein wasseranzie-
hendes Material verwendet. Seine Eigenschaften verändern sich bei
zunehmender Luftfeuchtigkeit. Bei elektrischen Hygrometern ist
das ein Polymer, dessen Widerstand oder Kapazität sich verändern
kann.

Kompass
Kompasse bestehen nicht notwendigerweise aus einer runden Mes-
singdose mit Glasdeckel und einer magnetischen Nadel. Mit dem
HMC6352 von Honeywell ist beispielsweise ein magnetischer Sen-
sor verfügbar, der auch an den Arduino angeschlossen werden
kann. Um die beiden Achsen auszulesen und somit die horizontale
Lage des Sensors zu bestimmen, empfiehlt es sich, die Wire-Biblio-
thek zu verwenden, die auf der Website des Arduino-Projektes
([Link] dokumentiert ist. Eine
andere Bibliothek samt Beispiel finden Sie unter [Link]
com/wp/2009/03/19/arduino-library-for-hmc6352/.
Ein Kompass kann als günstige Methode der Lagebestimmung in
einem Roboter eingesetzt werden, wenn man diesem einen be-

182 Kapitel 7: Sensoren


stimmten Pfad mitgeben will. Man kann damit natürlich auch ein
multifunktionales Gerät basteln, das etwa mit einem Display und
weiteren Sensoren ausgestattet ist und als günstige Hilfe bei Aktivi-
täten in der Natur fungiert, etwa beim Bergwandern.
Allerdings sollte man Eisen in der Nähe des Sensors vermeiden, da
dieser sonst unweigerlich falsche Werte anzeigt. In gewissen Gren-
zen kann dieser Effekt aber weggerechnet werden.

Mikrofone
Mikrofone wandeln Schallwellen in elektrische Wellen um, sodass
man diese messen kann. Das Prinzip besteht immer aus einer Mem-
bran, die sich durch die Druckwellen in der Luft verformt. Diese Ver-
formung kann über verschiedene Mechanismen gemessen werden.

Dynamisches Mikrofon
Ein dynamisches Mikrofon ist die Umkehrung eines Lautsprechers:
Die von den Schallwellen bewegte Membran verschiebt die daran
angebrachte Spule innerhalb eines Magneten, wodurch in der Spule
Ströme induziert werden. Tatsächlich kann man einen Lautspre-
cher auch als Mikrofon verwenden. Vorteilhaft ist dabei, dass
dynamische Mikrofone nicht so leicht übersteuert werden wie Elek-
tret-Kondensatormikrofone (kurz: Elektretmikrofone), was beson-
ders für Lichtorgel-Anwendungen im Bereich der Lautsprecher
wichtig ist.
Der Ausgang eines dynamischen Mikrofons ist zu schwach, um
direkt vom Arduino gemessen zu werden; er muss mit mehreren
Transistoren oder einem Operationsverstärker verstärkt werden.

Elektret- und Kondensatormikrofone


Beim »normalen« Kondensatormikrofon bilden zwei elektrisch leit-
fähige Platten einen Kondensator. Der Abstand der Platten, und
damit die Kapazität, wird vom Schalldruck verändert. Um diese
Veränderung messen zu können, legt man eine hohe Spannung
über einen Widerstand an den Platten an, und die veränderte Kapa-
zität beeinflusst dann die Spannung am Kondensator. Ein Elektret-
mikrofon benötigt diese Spannung nicht, da das Elektret zwischen
den beiden Platten »vorgespannt« ist: Es wird bei der Fertigung
unter einer hohen Spannung abgekühlt, sodass die Elektronen in
diesem Zustand verbleiben.

Sensoren 183
Piezoelektrisches Mikrofon
Der Piezoeffekt beschreibt die Erzeugung einer elektrischen Polari-
sation bei Festkörpern, wenn sie verformt werden. Wird also auf
einen piezoelektrischen Sensor mechanisch eingewirkt, verändert
sich die Spannung auf der Oberfläche des Sensormaterials. Umge-
kehrt kann ein piezoelektrischer Aktor sich verformen, wenn Span-
nung angelegt wird.
Das piezoelektrische Mikrofon reagiert auf Druckveränderungen in
der Luft. Eine Membran folgt den Schwankungen des Schalls. Sie
ist mit einem piezoelektrischen Element gekoppelt, das durch den
Druck minimal verformt wird und so elektrische Spannungs-
schwankungen auslöst. Als Mikrofon ist ein Piezo nicht die beste
Wahl, da die Tonqualität höhenlastig ist. Als Sensor kann es zum
Beispiel in Verbindung mit einem Tiefpass-Filter eingesetzt werden,
um Bassimpulse an den Arduino zu melden. Damit können z.B.
Animationen in Processing gesteuert oder LEDs gepulst werden,
um eine entsprechende Atmosphäre zur Musik zu schaffen. Oder
man nutzt es, um Geräusche zu melden, etwa für eine Alarmanlage.
Einer der Autoren dieses Buches nutzt eine Schaltung mit Piezomi-
krofon, um eine Tonaufnahme zu starten, sobald er wieder einmal
im Schlaf zu reden anfängt.

Biometriesensor
Im eigentlichen Sinn gibt es keine biometrischen Sensoren, aller-
dings können Temperatur-, Spannungsdifferenz-, Druck- und
Kraftsensoren dazu verwendet werden, biometrische Zustände zu
messen.

Fingerabdrucksensor
Fingerabdrücke werden heutzutage nicht mehr nur in Science-Fic-
tion-Filmen verwendet, um beispielsweise Schlüssel zu ersetzen.
Viele Notebooks und auch elektronische Türsysteme besitzen sol-
che Scanner. Diese sind nicht hundertprozentig sicher, sollten also
nicht in hoch sensiblen Einrichtungen verwendet werden. Für den
Gebrauch in der heimischen Umgebung, in der kaum damit gerech-
net werden dürfte, dass das System für kriminelle Machenschaften
missbraucht wird, sind sie allerdings geeignet, wenn auch derzeit
noch etwas teuer. Für 70 bis 100 Euro kann man einen passenden
Sensor für den Arduino erstehen.

184 Kapitel 7: Sensoren


EEG
Die Elektroenzephalografie, bei der Gehirnaktivität gemessen
wird, war lange Zeit teuren Geräten in Krankenhäusern und For-
schungseinrichtungen vorbehalten. So wurden wissenschaftliche
Erkenntnisse gesammelt und klinische Diagnosen durchgeführt.
Mittlerweile werden solche EEG-Geräte aber in einfachen Versio-
nen selbst gebaut, zum Beispiel im Projekt OpenEEG (http://
[Link]/). Die bekannteste Anwendung ist das
BrainPong, eine Version des berühmten Tennis-Computerspiels,
dessen Paddel durch die Gedanken des Spielers gesteuert werden.
Nach kurzem Training ist der Computer in der Lage, verschiedene
aktive Gedanken (wie etwa »oben« oder »unten«) zu unterschei-
den. Dabei werden Elektroden auf dem Kopf angebracht, die die
vom Gehirn ausgesandten elektromagnetischen Wellen messen.
Weil diese Wellen je nach Aktivität in unterschiedlichen Bereichen
emittiert werden, kann man sich mit mehreren Elektroden ein
räumliches Bild davon verschaffen.

Gasdrucksensor
Der Druck in einer Leitung oder einem Gefäß kann über die Verfor-
mung einer Membran gemessen werden. Der dabei gemessene
Wert entspricht dann immer der Differenz der Drücke an den zwei
Seiten der Membran (Differenzdrucksensor). Die physikalische Ein-
heit für Druck ist dabei Pascal (Pa). Fast alle Differenzdrucksenso-
ren funktionieren entweder resistiv (ändern also ihren Widerstand)
oder kapazitiv (ändern ihre Kapazität). Solche Sensoren werden
zum Beispiel im in Kapitel 1 beschriebenen Bierbrauprojekt einge-
setzt, wo der Druck im Brautank reguliert werden muss. Sie eignen
sich aber auch, um große Mengen an Flüssigkeit zu regulieren oder
beispielsweise Wasserschläuche zu steuern. So kann ein Gas-
drucksensor am Ende eines Schlauches, der in eine Wasserzisterne
getaucht wird, denn aktuellen Wasserstand messen.

Kraftsensor
Piezoelektrische Sensoren nutzen den gleichnamigen Effekt, um aus
der Verbiegung eines Kristalls eine Spannung zu erzeugen. In einem
Feuerzeug schlägt ein Federmechanismus auf einen Piezokristall.
Die dabei erzeugte Spannung ist groß genug, um das Gas zu ent-
zünden. EnOcean stellt mit diesem Effekt drahtlose Lichtschalter

Sensoren 185
her, die ihre Energie für das Funksignal nur aus dem Betätigen des
Schalters gewinnen. Da die vom Piezokristall abgegebene Span-
nung aber proportional zur Änderung der Kraft ist, die auf den
Kristall einwirkt, können nur Veränderungen gemessen werden.
Man kann damit also keine Waage bauen, aber zum Beispiel Drum-
pads für ein elektronisches Schlagzeug.
Resistive Sensoren basieren auf Dehnungsmessstreifen (DMS), die
bei Verformung ihren elektrischen Widerstand verändern. Wird
der DMS in die Länge gezogen, verringert sich die Leiterbahnbreite,
und der Widerstand steigt. Dieses Prinzip würde auch mit einem
normalen Draht funktionieren, was aber aus zwei entscheidenden
Gründen nicht praktikabel ist: Die Widerstandsänderung ist sehr
klein, und normaler Kupferdraht würde sich nicht mehr zusam-
menziehen, nachdem die aufgebrachte Kraft wieder verschwunden
ist. Fast alle elektrischen Waagen funktionieren mit DMS-Senso-
ren. Auch im Brückenbau, in Kraftwerken usw. werden sie einge-
setzt, um frühzeitig Verformungen zu erkennen.
Kapazitive Drucksensoren enthalten einen Kondensator, der durch
die aufgebrachte Kraft verformt wird, wodurch sich seine Kapazität
ändert. Diese Änderung ist dann ein Maß für den Druck.
Der einfachste Anwendungsfall für einen Drucksensor ist natürlich
eine Art Tastatur, die mehr als nur einen An/Aus-Wert übergeben
muss. Einfache Sensoren können zum Beispiel in Kleidung einge-
näht werden, um festzustellen, wenn der Träger umarmt wird oder
hinfällt. Sicherlich kennen Sie den »Hau den Lukas« von Jahr-
marktbesuchen. Unter einer Gummimatte und einem Holzbrett
könnte der Drucksensor so die Hammerschläge messen, die der
Arduino dann auf einer langen Linie von LEDs visualisiert. Ein
anderes Beispiel sind Klopfsensoren; ein Drucksensor auf einer Tür
kann diese nach dem richtigen Klopfsignal öffnen.

Biegungssensor
Biegungssensoren verhalten sich ähnlich wie piezoelektrische Kraft-
messer. Sie verändern also ihren Widerstand, wenn sie mechanisch
verändert werden – in diesem Fall gebogen. Diese Sensoren können
beispielsweise in Kleidung eingearbeitet werden und bieten so die
Möglichkeit eines einfachen Motion-Capturing. Auch wenn die
Präzision wahrscheinlich nicht ausreicht, um damit filmreife 3-D-
Modelle zu steuern, gibt es diverse Projekte damit: Die Designer
Mika Satomi und Hannah Perner-Wilson nutzen selbstgebaute

186 Kapitel 7: Sensoren


Neopren-Sensoren (erklärt unter [Link]
Neoprene-Bend-Sensor-IMPROVED/) für eine interaktive Tanzper-
formance. An verschiedenen Stellen in die Kleidung einer Tänzerin
eingearbeitete Biegungssensoren steuern über ein Funksignal
Instrumente, die die Darbietung mit Klängen untermalen. Dieses
Projekt findet sich auf der Webseite der Designer unter [Link]
[Link]/id/Puppeteer_Motion_Capture_Costume/.
Ein anderes Projekt nutzt einen Biegungssensor, um eine heliotrope
Pflanze zu steuern. Diese Pflanzen neigen sich stets nach der Sonne,
sodass ihre Blätter sich im Tagesverlauf von Osten nach Westen
drehen und am Morgen wieder Richtung Osten stehen. Das
genannte Projekt misst die Neigung der Pflanze und dreht sie um
180 Grad, sobald sie einen bestimmten Grenzwert überschritten
hat. So richtet sich der Stamm wieder auf und beginnt erneut seine
Dehnungsübungen. Dieses Projekt ist auf der Webseite des Make
Magazine unter [Link]
sensor_hel.html beschrieben.

Aktoren
Aktoren sind allgemein Elemente, die eine physikalische Eingangs-
größe in eine andersartige Ausgangsgröße umwandeln. In der Welt
des Physical Computing ist diese Eingangsgröße natürlich Elektrizi-
tät. Die möglichen Ausgangsgrößen sind so unterschiedlich, wie die
Physik vielschichtig ist, und reichen von Licht und Ton bis hin zu
Wärme und Bewegung. Die gängigsten Aktoren werden hier nun
kurz vorgestellt.

LEDs
Glühlampen und Leuchtstoffröhren sind zwar sehr hell, können
aber nur schwer geregelt werden. Sie reagieren nur langsam und
sind zudem groß und damit nur begrenzt einsetzbar. LEDs sind,
wie in Kapitel 3 beschrieben wurde, Dioden, die binnen Mikrose-
kunden einen Lichtimpuls abgeben können. Die fortschreitende
technische Entwicklung macht es inzwischen möglich, auch Licht-
dioden mit sehr hohen Helligkeitswerten herzustellen, sodass die
LED langsam auch die privaten Haushalte erobert. Weitere Vorteile
neben den schon erwähnten sind, dass LEDs im Durchschnitt viel
länger halten und über eine deutlich höhere Lichtausbeute pro
Watt verfügen. Waren LEDs lange Zeit nur in weißer und roter
Farbe erhältlich (andere Farben wurden über einen entsprechenden

Aktoren 187
Plastiküberzug erzeugt), gibt es mittlerweile auch grüne und blaue
Leuchtdioden und Kombinationen aller drei Grundfarben (Rot,
Grün und Blau), die gemeinsam auf einen Chip montiert sind.
Kapitel 3 erklärt ausführlich, wie LEDs mit dem Arduino angesteu-
ert und durch Pulsung in ihrer sichtbaren Helligkeit verändert wer-
den können. Am Ende des Kapitels gibt es zudem eine Liste
interessanter LED-Projekte.

Motoren
Kleine Motoren sind der Antrieb für alle Projekte im Bereich der
Robotik. Sie können aber auch benutzt werden, um beispielsweise
Lampen auszurichten oder Sensoren in eine gewünschte Position
zu bringen. Im normalen Gebrauch unterscheidet man zwischen
drei Arten: Gleichstrom-, Servo- und Schrittmotoren.

Gleichstrommotoren
Die günstigsten und einfachsten Motoren basieren auf einer oder
mehreren magnetischen Spulen, die um eine Welle gefasst werden.
Liegt Spannung an diesen Motoren an, bringt das Magnetfeld die
Welle zum Rotieren. Ein normaler Gleichstrommotor kann dabei
nur schwer gesteuert werden. Er bietet keinerlei Rückkopplung,
sodass dem Benutzer weder die Position noch die Geschwindigkeit
genau bekannt sind. Für präzise Operationen, wie etwa die Steue-
rung eines Fluggerätes oder die Drehung eines Objektes um wenige
Grad, eignet er sich also nicht; kann man aber darauf verzichten,
ist der Gleichstrommotor aufgrund seines Preises natürlich zu
empfehlen.

Servomotoren
Benötigt man ein Feedback vom Motor, um seine Geschwindigkeit
genau regeln zu können, empfiehlt sich ein Servomotor. Diese
Motoren sind durch die Rückkopplung außerordentlich präzise,
allerdings auch entsprechend teuer. Ein Servomotor besteht aus
einem Gleich- oder Wechselstrommotor, enthält zusätzlich einen
Rückkopplungsmechanismus, meist auf Basis einer Lichtschranke
oder eines Potentiometers. So ist er in der Lage, genaue Geschwin-
digkeiten und sogar Positionen einzustellen. Die kleine Variante der
Servomotoren sind die Modellbauservos. Diese können sich nur
um ca. 180° drehen, haben aber ein einfaches digitales Interface,
können also ohne weitere Bauteile mit dem Arduino verwendet

188 Kapitel 7: Sensoren


werden. Für Roboteranwendungen werden diese gerne so modifi-
ziert, dass die Rückkopplung entfällt. Dafür erhält man dann für
wenig Geld einen Motor mit integrierter Geschwindigkeitsrege-
lung. Diese sind im Modellbaufachhandel für bezahlbares Geld
erhältlich.

Abbildung 7-1
Servomotor

Schrittmotoren
Ein Schrittmotor basiert auf einem drehbaren Motorteil (Rotor) mit
einer Welle, das sich in einem magnetischen Feld befindet. Dieses
Feld ist in Schritte unterteilt, sodass der Rotor sich um einen oder
mehrere dieser Schritte drehen kann. Dadurch kann man im Prin-
zip Geschwindigkeit und auch Position bestimmen. Allerdings gibt
es keinerlei Rückmeldung über mögliche Schrittverluste. Während
ein Servomotor seine Position wieder einnimmt, wenn er beispiels-
weise durch einen Finger angehalten wurde, ist der Schrittmotor
dazu nicht in der Lage. Zudem kann es bei großen Leistungen zu
Problemen kommen. Dafür ist er deutlich preisgünstiger.
Der Arduino selbst ist nicht in der Lage, Motoren zu steuern, da er
ja nur über digitale Ausgänge verfügt und ein Motor nicht einfach
angeschaltet werden kann. Hier hilft ein Motor-Driver wie der
L293 oder der SN754410NE. Unter [Link]
mshield/ oder auch [Link]
[Link] findet man Shields für den Ardu-
ino, über die Richtung und Geschwindigkeit des Motors gesteuert
werden können. Der Shield von [Link] verwendet dabei
8-Bit-Werte für die Geschwindigkeit und wird über eine der

Aktoren 189
Bibliotheken angesteuert, die auf der Website heruntergeladen
werden können. Der Driver von [Link] verwendet
Pulsweitenmodulation und wird nur über ein entsprechendes ana-
logWrite() angesprochen. Welchen man nun kauft, oder ob man
sich dank verfügbarer Board-Layouts selbst einen Shield baut,
hängt vom Verwendungszweck und dem Preis ab, den man zu zah-
len bereit ist.

Relais
Oft möchte man einen Arduino verwenden, um Stromkreise zu
schalten, die sich weit über der Betriebsspannung des Boards von 5
Volt bewegen. Das ist natürlich zunächst ein Problem, weil starke
Ströme dem Board erheblichen Schaden zufügen können. Um bei-
spielsweise Glühbirnen anzuschalten, werden die vollen 220 Volt
aus der Steckdose benötigt. Abhilfe können hier Relais schaffen.
Das sind Schalter, die durch einen elektronischen Impuls einen
weiteren Stromkreis schalten können. Ein mechanisches Relais
arbeitet meist nach dem Prinzip des Elektromagneten. Liegt Strom
in einer Spule an, zieht diese einen mechanischen Anker an, der als
Schalter im zweiten Stromkreis fungiert. Diese Relais eignen sich
vor allem, um zum Beispiel Geräte im Haushalt anzuschalten. Wie
wäre es mit einem Kaffeewecker, der durch den Duft frischen
Espressos auf sich aufmerksam macht, oder mit einem Lichtschal-
ter, der unter einer Fußmatte neben dem Bett angebracht ist und
den Raum beleuchten lässt, sobald man aufsteht?
Neben diesen mechanischen Relais gibt es auch eine Reihe anderer;
dazu zählen auch Transistoren bzw. Halbleiterrelais, auch wenn
diese streng genommen keine Relais sind. Diese können zum Bei-
spiel recht einfach verwendet werden, um leistungsfähige LEDs zu
schalten (siehe Kapitel 1 und 3), da Transistoren im Gegensatz zur
Mechanik auch schnell genug sind, um die nötige Pulsung zu leisten.
Ein Relais wird – ähnlich wie eine leistungsfähige LED – immer
über einen Transistor an den Arduino angeschlossen. Dabei sollte
man die Diode nicht vergessen, sonst kann die Induktivität des
Relais den Transistor beschädigen.

Solenoide
Ein Solenoid ist eine Zylinderspule, die magnetische Kräfte entwi-
ckelt, wenn Spannung angelegt wird. Diese kann etwa um einen

190 Kapitel 7: Sensoren


Metallstift gewickelt werden, oder aber zum Beispiel als Ventil
funktionieren.
Die Metallstiftvariante des Solenoids besteht aus einem bewegli-
chen Stift, der genau in der Mitte der Spule platziert wird. Wird auf
dieser Spule Spannung angelegt, treibt die magnetische Kraft diesen
Metallstift nach außen. Dieser Impuls ist stark genug, um den Sole-
noid als Aktor zu verwenden. So gibt es Projekte, die daraus ein
Trommelkonzert machen. Entweder hämmert der Solenoid direkt
auf verschiedene Gegenstände, um so unterschiedliche Töne zu
erzeugen, oder er treibt wiederum einen Holzstock an, der bei-
spielsweise auf eine Trommel schlägt. Oder man setzt ihn ein, um
selbst als musikalisch unbegabter Mensch aus einem Glockenspiel
schöne Melodien ertönen zu lassen. Dieser Solenoid benötigt viel
Strom; ein Anschluss über einen Transistor wie in Kapitel 3
beschrieben ist also dringend erforderlich.
Das Solenoid-Ventil eignet sich, um genaue Mengen von Flüssig-
keiten oder Gasen abzugeben. Dazu muss man nur wissen, mit wel-
cher Geschwindigkeit sich welche Menge des gewünschten Stoffes
durch einen vom Solenoid abgeschlossenen Schlauch oder ein Rohr
bewegt. Schließt man dieses Ventil nun über eine entsprechende
Schaltung an den Arduino an, ergeben sich viele Möglichkeiten,
nicht nur für den wissenschaftlichen Bereich. So könnte man etwa
selbst als Hobbyfilmer eine günstige und leicht zu steuernde Regen-
maschine bauen. Oder man verwendet zusätzlich einen Feuchtig-
keitssensor, um Pflanzen vollautomatisch zu bewässern. Natürlich
eignet sich ein solches Ventil auch für einen Roboter, der in der
Lage ist, perfekte Cocktails zu mixen, weil er immer die korrekte
Menge einer Zutat abgibt, sofern es sich dabei nicht um Limetten
oder gestoßenes Eis handelt. Angesteuert werden sie wie Relais mit
einem Transistor.

Elektronischer Würfel
Nun soll ein elektronischer Würfel gebaut werden. Dieser besteht
aus einem elektronischen Display, das die gewürfelte Zahl darstellt,
sowie einem Taster, der den Würfel anstößt. Anschließend wird
mit einem Piezo-Lautsprecher noch ein entsprechender Ton ausge-
geben.
An Material werden dafür sieben LEDs, sieben Widerstände 470R,
eine Lochrasterplatine und ein piezoelektrischer Sensor benötigt.

Elektronischer Würfel 191


Auf den folgenden Bildern sind neun LEDs zu sehen, allerdings
sind die zwei LEDs oben und unten in der Mitte nicht weiter ange-
schlossen. Sie können also weggelassen werden.

Abbildung 7-2
Würfelaufbau, Lochrasterplatine
oben

Setup
Die mittlere LED wird mit einem 470R-Widerstand mit Pin 11 ver-
bunden. Die beiden LEDs oben links und unten rechts mit Pin 10,
die LEDs unten links und rechts mit Pin 9 und die verbleibenden
zwei LEDs mit Pin 8.

Abbildung 7-3
Würfelaufbau,
Lochrasterplatine unten

Es wäre einfach, einen Taster zu verwenden, um den Würfel seine


Zahl wählen zu lassen. Viel näherliegend für den Benutzer ist es

192 Kapitel 7: Sensoren


aber, zu schütteln, um zum Ergebnis zu gelangen. Dazu wird ein
Erschütterungssensor aus den von den Widerständen und LEDs
übrig gebliebenen Anschlussdrähten gebaut, indem ein Ring gebo-
gen und die Enden verlötet werden. Dieser Ring kommt über zwei
nach außen umgebogene Drähte (damit der Ring nicht abfallen
kann) an GND und Pin 12.
Wird die Schaltung bewegt oder geschüttelt, bewegt sich der kleine
Drahtring und öffnet und schließt dabei den Kontakt zwischen die-
sen beiden PINs; die Eingabe kann verwendet werden, um den
Würfel zu steuern.

Abbildung 7-4
Rüttelsensor

Software
Zunächst werden die sieben LEDs in einem leeren Worksheet ange-
bunden (wie auch in Kapitel 3 erklärt), dann wird Pin 12 mit dem
Erschütterungssensor als Eingang definiert und mit einem HIGH-
Signal für den internen Pull-up-Widerstand belegt.
Nun kann durch einzelne HIGH- und LOW-Signale herausgefun-
den werden, wie sich mit dieser Schaltung alle benötigten Augen-
bilder eines Würfels abbilden lassen. Das Ergebnis wird in eine
eigene Funktion geschrieben.
Dabei kann das Konstrukt switch() {.. case …} verwendet werden.
Es erlaubt wie if...else bedingte Sprünge, kann aber abhängig
von einem Wert aus mehreren Verzweigungen wählen:
void display(int num)
{
switch(num)
{

Elektronischer Würfel 193


case 0:
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
break;
case 1:
digitalWrite(led1Pin, HIGH);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
break;
und so weiter...

Dieser Code ist allerdings wenig elegant, zieht er sich doch in die
Länge und wiederholt sich dabei in großen Teilen. Mit ein wenig
Nachdenken kommt man allerdings auf einige Gesetzmäßigkeiten:
LED1 ist immer an, wenn num nicht durch 2 teilbar ist (1, 3, 5).
LED2 ist immer an, wenn num > 1 ist (2, 3, 4, 5, 6).
LED3 ist immer an, wenn num > 3 ist (4, 5, 6).
LED4 ist nur bei num = 6 an.
Also kann das Ganze durch Folgendes ersetzt werden.
// zeigt eine Zahl von 0 bis 6 auf den Würfel-LEDs an
void display(int num)
{
if ((num % 2) == 0) {
digitalWrite(led1Pin, LOW);
} else {
digitalWrite(led1Pin, HIGH);
}
if (num > 1) {
digitalWrite(led2Pin, HIGH);
} else {
digitalWrite(led2Pin, LOW);
}
if (num > 3) {
digitalWrite(led3Pin, HIGH);
} else {
digitalWrite(led3Pin, LOW);
}
if (num == 6) {
digitalWrite(led4Pin, HIGH);
} else {
digitalWrite(led4Pin, LOW);
}
}

Der Erschütterungssensor verhält sich wie ein Taster. Je nachdem,


wie der Drahtring liegen bleibt, ist unbekannt, ob der Stromkreis

194 Kapitel 7: Sensoren


im Ruhezustand offen oder geschlossen ist. Deshalb wird über-
prüft, ob der Zustand sich geändert hat, und nur ein Signal regist-
riert, wenn das der Fall ist.
int getTaster(void)
{
taster = digitalRead(tasterPin);
if (taster != taster_old)
{
taster_old = taster;
return 1;
}
return 0;
}

Die Funktion getTaster() liefert also nur dann eine 1 zurück, wenn
sich der Erschütterungssensor bewegt hat.
Steht der Würfel still, so soll der Wurf erst gestartet werden, wenn
viele Male in kurzer Zeit so eine Veränderung gemessen worden ist,
andernfalls würde der Würfel schon auf leichtes Anstoßen des
Tisches reagieren. Dazu wird eine Zählvariable benutzt: taster_
entprellen wird bei jedem Ereignis um 20 erhöht; tritt nichts ein,
wird eins abgezogen. Erst wenn diese Zahl größer als 1.000 ist, soll
der Wurf gestartet werden.
void loop() // Hauptschleife
{
// warten auf einen Tastendruck zum Starten des Würfels
taster_entprellen = 0;
while( taster_entprellen < 1000)
{
taster_entprellen += getTaster()*20;
if (taster_entprellen > 0) taster_entprellen--;
delay(1);
}

Die Variable speed bestimmt die Geschwindigkeit, mit der sich der
Würfel dreht. Sie wird nun willkürlich auf 100 gesetzt und der
Wurf gestartet. Dabei wird eine do...while-Schleife verwendet.
Diese läuft mindestens einmal durch, maximal so lange, bis eine
bestimmte Bedingung erreicht wird. Setzt man die while-Bedingung
an den Anfang der Schleife, kann es passieren, dass die Schleife
nicht ausgeführt wird, im Falle des Würfels soll aber zumindest ein-
mal eine neue Zahl ermittelt werden.
// nun wird der Würfel gestartet
// setzen der Würfelgeschwindigkeit auf hoch
speed = 100;
do
{

Elektronischer Würfel 195


// immer, wenn der Taster seinen Zustand wechselt,
// Geschwindigkeit wieder hochsetzen
if (getTaster() == 1)
{
speed += 10;
}
// Würfel um eins weiterzählen
// wenn größer als 6, wieder auf 1 setzen
num++;
if (num > 6) num = 1;
// anzeigen
display(num);
// ein bisschen warten; je groeßer "Speed", desto weniger
// wird gewartet
delay(1000/speed);
Speed--; // langsam langsamer werden.
}
while (speed > 1);
// der Würfel ist stehen geblieben
}

Piezolautsprecher
Der Würfel soll nun einen Piezolautsprecher erhalten, um beim
Wurf einen passenden Ton auszugeben.

Abbildung 7-5
Piezo

Piezoelektrische Elemente sind Bauteile, die beim Anlegen von


Spannung ihre Form verändern oder bei einer Veränderung ihrer
Form Spannung erzeugen. Piezolautsprecher gehören in die erste
Kategorie: Liegt eine hohe Spannung an, können sie Ton ausgeben.
Die möglichst hohe Spannung wird erreicht, indem der Piezo gleich
an zwei Ausgangspins angeschlossen wird. Diese werden dann
immer gegensätzlich geschaltet. In unserem Beispiel werden die

196 Kapitel 7: Sensoren


beiden Variablen piezo1 und piezo2 mit den Pins 6 und 7 verbun-
den und als Ausgang definiert.
In der Würfel-Displayfunktion werden nun bei jedem Hochzählen
von num die beiden Pins umgeschaltet, der Piezo gibt ein leises Kna-
cken von sich.
if ((num % 2) == 0)
{
digitalWrite(piezo1, LOW);
digitalWrite(piezo2, HIGH);
} else {
digitalWrite(piezo1, HIGH);
digitalWrite(piezo2, LOW);
}

Diese Schaltung kann dann in ein kleines Gehäuse gebaut werden,


wenn man den Arduino mit einer Batterie ausstattet.

Elektronischer Würfel 197


KAPITEL 8 In diesem Kapitel:
• Alles hört auf mein
Automation Kommando
• DMX
• Barlicht
• RF-Steckdosen
• Gespensterschreck

Alles hört auf mein Kommando


In diesem Kapitel geht es darum, Gegenstände wie Lampen, Hei-
zung, Ventilatoren und Rollläden mit dem Arduino anzusteuern.
Wie in Kapitel 1 und 2 angesprochen kann zur Beeinflussung von
größeren Spannungen und Strömen ein Relais, Transistor oder
Triac verwendet werden. Allerdings kann man dabei nicht vermei-
den, dass man mit gefährlichen Spannungen hantieren muss.
Aus diesem Grund konzentrieren wir uns hier auf zwei ganz andere
Methoden. Erstens DMX, ein weit verbreitetes Protokoll zur
Ansteuerung von Scheinwerfern auf Bühnen und Diskotheken.
Noch etwas universeller, aber mit mehr Bastelei verbunden: das
Ansteuern von Funksteckdosen. Diese können für wenig Geld im
Baumarkt um die Ecke oder beim Discounter erworben werden.
Einige Projekte sollen hier kurz vorgestellt werden, um die ganze
Bandbreite der Möglichkeiten zu zeigen und die Fantasie anzuregen.

Buzzer to DMX
Für eine Quizshow werden an den Arduino mehrere Knöpfe (Buz-
zer) angeschlossen. Wird einer davon betätigt, sendet der Arduino
über DMX den Befehl, den Kandidaten zu beleuchten. Leider sind
z. Zt. auf der Webseite ([Link] weder
Quellcode noch Schaltpläne vorhanden.

Specdrum
Lichtsäulen, die interaktiv von einer Trommelgruppe gesteuert
werden. Sensoren in den drei Trommeln erkennen die einzelnen

199
Schläge. Je nach Tonhöhe werden über DMX verschiedene Farben
zu RGB-Scheinwerfern in großen, matten Plastiktrommeln gesendet.
[Link]

Forcefield Interactive
Mittels verschiedener RFID-Karten kann das »Lichtfeld« dieser
Installation beeinflusst werden. Ein einzelner Arduino kontrolliert
hier 192 Lichtstäbe. Die Farbmuster basieren hauptsächlich auf Per-
linrauschen und den Daten der RFID-Karten der Besucher. Zusätz-
lich können mitgebrachte Gegenstände mittels eines Farbsensors
abgescannt werden ([Link]
01/forcefield_interactive.html).

DMX
DMX ist ein Standard zur Steuerung von Scheinwerfern in der Ver-
anstaltungs- und Bühnentechnik. Er ersetzte die davor übliche
Ansteuerung mit 0-10V Signalen. Bei diesen Systemen benötigte
man zu jedem Scheinwerfer ein eigenes Kabel. Bei 30 oder mehr
Scheinwerfern kann man sich vorstellen, wie die Rückseite des
Lichtmischpults ungefähr ausgesehen haben mag. Dafür war aber
auch nur ein beliebiges Multimeter notwendig, um den Zustand
jedes Kabels inklusive der übertragenen Daten zu kontrollieren.
DMX ersetzt alle diese Kabel durch ein einziges, und die analogen
Signale werden digital übertragen. Bis zu 512 einzelne Geräte kön-
nen in einer langen Kette hintereinander an diesen Bus angeschlos-
sen und darüber gesteuert werden. An jedem kann, meistens über
ein sogenanntes Mäuseklavier, eine individuelle Adresse eingestellt
werden. Benötigt ein Gerät, z.b. ein LED-DMX-Scheinwerfer, meh-
rere Parameter (rot, grün, blau) so belegt dieser drei aufeinander
folgende Adressen. Der nächste Scheinwerfer muss also drei Adres-
sen weiter hinten anfangen. Die meisten LED-RGB-Scheinwerfer
belegen fünf oder sogar sechs Adressen, weil dort noch weitere Son-
derfunktionen vorhanden sind. So kann ein DMX-Bus mit seinen
512 Adressen rund 80–100 dieser Scheinwerfer kontrollieren.
Für rund 30 € stellen diese Scheinwerfer eine einfache und kosten-
günstige Möglichkeit dar, Haus und Hof effektvoll zu beleuchten.
Da DMX für sehr lange Kabel entworfen wurde, werden die Daten
symmetrisch übertragen. Das bedeutet, es gibt zwei Datenleitun-
gen. Ist die eine auf »High« geschaltet, wird die andere auf null

200 Kapitel 8: Automation


gesetzt und umgekehrt. Dadurch werden abgestrahlte Störungen
weitgehend unterbunden, und der Empfänger kann eingestrahlte
Störungen dadurch entfernen, dass er nur auf die Differenz der bei-
den Leitungen horcht. Da eine Störung auf beide Leitungen wirkt,
verschwindet diese beim Differenzbilden wieder. Für ganz kurze
Kabel und nur ein bis zwei Busteilnehmer könnte man dieses Signal
auch mittels zwei Pins des Arduinos erzeugen. Besser ist es aber,
dafür ein geeignetes IC zu verwenden. Dafür kann man den MAX-
485 oder den günstigeren SN75176 einsetzen.
Wer dabei nicht löten möchte, kann ein DMX Shield einsetzen
([Link]

Protokoll
Das DMX-Protokoll basiert wie RS232 auf asynchronen (also ohne
extra Taktleitung) übertragenen Bytes mit Start- und Stopbits. Die
Geschwindigkeit ist mit 250kbit/s festgelegt. Das bedeutet damit
auch, dass nur ca. 40–45 Änderungen pro Sekunde übertragen wer-
den können, wenn alle 512 Adressen auf dem Bus belegt sind. Für
normale Scheinwerfer ist das aber schnell genug.
Alle Daten werden in Paketen, sogenannten Frames, übertragen.
Damit die DMX-Teilnehmer den Beginn eines solchen erkennen
können, sendet der Master mindestens 88 μs lang eine Null auf
den Bus. Durch die Stopbits kann dieser Zustand während einer
normalen Übertragung niemals auftreten, so dass der Beginn eines
Frames zweifelsfrei festgestellt werden kann.
Danach folgt als Erstes das Startbyte, das immer Null und für die
spätere Erweiterung vorgesehen ist. Es folgen die entsprechenden
Bytes, die immer mit der Adresse Null beginnen. Das heißt, ein
DMX-Empfänger wartet auf den Start eines Frames und die darauf
folgende Null. Dann ignoriert er so viele Bytes auf dem Bus, wie es
seiner Adresse entspricht. Die dann folgenden Bytes sind die für ihn
bestimmten Daten.

Software
Von [Link] gibt es eine schöne Bibliothek für das DMX-
Protokoll. Diese kann unter [Link]
DmxSimple heruntergeladen werden. Wie schon von anderen Bibli-
otheken bekannt, werden die Dateien in das Verzeichnis [Arduino-
Verzeichnis]/hardware/libraries/DmxSimple entpackt. Nach dem

DMX 201
Neustart der Arduino-Software kann die Bibliothek dann verwen-
det werden. Sie muss dann auch im Library-Menü auftauchen.
Mit #include <DmxSimple.h> wird die Bibliothek eingebunden
(alternativ über das Menü) .
void setup() {
[Link](3); // Hier muss der Pin angegeben werden an
// welchem das DMX
// Interface angeschlossen ist. Meistens
// ist das PIN3.
}

void loop() {
int brightness;
for (brightness = 0; brightness <= 255; brightness++) {
[Link](1, brightness); // Setze DMX Kanal 1
delay(10); // ein wenig warten, damit es nicht zu schnell wird.
}
}

Bei manchen Geräten kann es vorkommen, dass sie nur funktionie-


ren, wenn alle im Gerät vorhandenen Adressen auch beschrieben
werden.

Barlicht
In diesem Projekt wird eine Thekenbeleuchtung für eine Bar
gebaut. Je nach Länge der Theke besteht diese aus 1 bis 32 einzel-
nen DMX-LED-RGB-Scheinwerfern, die in einer Reihe von der
Decke herab die Bar beleuchten. Solche Scheinwerfer können ab
35 EUR z.B. bei [Link] bezogen werden. Die Grundidee
bei allen abgespielten Animationen sollte dabei sein, dass der Gast
nie im Dunkeln sitzt, und anders als bei einem Discolicht sind eher
langsame, weiche Übergänge sinnvoll.
Hardware: Mehrere DMX-Scheinwerfer, die über das entspre-
chende Kabel und das DMX-Shield mit dem Arduino verbunden
werden.
Je nach Modell des verwendeten Scheinwerfers benötigt dieser 3
bis 6 DMX-Adressen. Bei mehr als einem Scheinwerfer werden die
Adressen so verteilt, dass sie sich nicht überschneiden. Bei Schein-
werfern mit 6 Adressen/Gerät z.B.: 0, 6, 12. Dabei kann es auch
sinnvoll sein, den 6er-Abstand bei Geräten mit kleinerem Adressbe-
reich einzuhalten, weil dann in der Software alle Scheinwerfer mit
dem gleichen Schema angesprochen werden können.

202 Kapitel 8: Automation


#include <DmxSimple.h>

const int AnzahlScheinwerfer = 4;


int color[AnzahlScheinwerfer+1][3];
int update = 0;

void setup() {
[Link](3); // Hier muss der Pin angegeben werden an
// welchem das DMX
// Interface angeschlossen ist. Meistens
// ist das PIN3.

// Beim Start alle Scheinwerfer aus.


for(int i = 0; i <= AnzahlScheinwerfer; i++) {
color[i][0] = 0; // Rot
color[i][1] = 0; // Gruen
color[i][2] = 0; // Blau
}
}

void loop() {
// Immer wenn update = 0 ist, denken wir uns eine neue Farbe aus.
if (update == 0) {
color[0][0] = random(0,256); // Rot
color[0][1] = random(0,256); // Gruen
color[0][2] = random(0,256); // Blau
}

// Beim letzen Scheinwerfer anfangen und jeweils die Farbe


// leicht an den Vorgänger angleichen, dadurch fließen die
// Farben durch die Scheinwerfer-Reihe
for(int i = AnzahlScheinwerfer; i > 0; i--) {
// Farbberechnung getrennt für Rot,Grün,Blau durchführen.
// jeweils 63 Teile alte Farbe + 1 Teil neue Farbe (vom nächst-
// kleineren Nachbarn) geteilt durch 64 als neue Farbe annehmen.
color[i][0] = (63*color[i][0] + color[i-1][0])/64; // Rot
color[i][1] = (63*color[i][1] + color[i-1][1])/64; // Gruen
color[i][2] = (63*color[i][2] + color[i-1][2])/64; // Blau
[Link](i*6+0, color[i][0]); // Setze DMX Kanal rot
[Link](i*6+1, color[i][1]); // Setze DMX Kanal gruen
[Link](i*6+2, color[i][2]); // Setze DMX Kanal blau
}

// Zähler erhöhen, damit wir nach 10 eine neue Farbe setzen


update++;
if (update > 100) update = 0;

delay(100); // ein wenig warten, damit es nicht zu schnell wird.


}

Barlicht 203
Wie in den Kommentaren beschrieben, wird alle 10 Sekunden der
imaginäre Scheinwerfer 0 mit einer zufälligen Farbe geladen. Zehn
mal pro Sekunde wird jetzt immer ein Vierundsechzigstel der Farbe
an den Nachbarscheinwerfer weitergereicht, sodass ein fließender
Farbverlauf erreicht wird.

RF-Steckdosen
In Bau- und Supermärkten werden immer wieder günstige Sets von
Funksteckdosen angeboten. Damit können Lampen und andere
Geräte im ganzen Haushalt kontrolliert werden, ohne dabei mit
230V in Berührung zu kommen oder neue Kabel verlegen zu müs-
sen. Damit folgende Modifikationen durchgeführt werden können,
sollte im dazugehörigen Sender ein HX2262, PT2262 oder LP801-
IC werkeln. Das ist z.B. bei den Sets von Intertechno oder Unitec
der Fall, die man in vielen Baumärkten bekommt.

Protokoll
Die ICs HX2262 und PT2262 gibt es in zwei verschiedenen Baufor-
men. Bei den 18poligen ICs ist der Pin 17 und bei den 20poligen
der Pin 19 der Datenausgang zum eigentlichen Sendemodul. Bei
dem von Intertechno verwendeten LP801 ist es der Pin 1. Wer die
gesendeten Daten also genauer ansehen möchte, sollte hier sein
Oszilloskop anschließen. Aus den Datenblättern und den Beobach-
tungen im Oszilloskop erhält man folgendes Datenprotokoll:
Alle Daten bestehen entweder aus einem kurzen Puls (25%) und
einer langen Pause (75%) oder einem langen Puls (75%) und einer
kurzen Pause (25%). Die erste Variante bezeichnen wir ab hier als
»0«, die zweite als »1«.
Um möglichst viele verschiede Steckdosen mit diesem IC schalten
zu können, hat sich der Hersteller einen interessanten Trick ausge-
dacht: Alle Eingänge können entweder mit Masse (0), oder mit der
Betriebsspannung (1) verbunden werden, zusätzlich können diese
aber auch unbeschaltet gelassen werden (F). Dadurch kann jeder
Eingang drei verschiedene Zustände annehmen.
Bei nur zwei Möglichkeiten (0/1) hätte man bei zwölf Eingängen
2^12 Möglichkeiten, was 4096 Kombinationen entspricht. Hier
sind es aber drei (0/1/F), also 3^12, also 531441 Möglichkeiten.
Wie können aber 3er-Zustände mittels Nullen und Einsen übertra-
gen werden? Für jeden Eingang werden einfach zwei Bits nach fol-
gender Tabelle gesendet:

204 Kapitel 8: Automation


Eingang Daten Datenausgang
Masse (0) 00 kurzer Puls, lange Pause, kurzer Puls, lange Pause
Betriebsspannung (1) 11 langer Puls, kurze Pause, langer Puls, kurze Pause
Offen (F) 01 kurzer Puls, lange Pause, langer Puls, kurze Pause

Es werden bei jedem Tastendruck so lange Telegramme gesendet,


bis der Taster wieder losgelassen wird. Minimal müssen mindes-
tens zwei identische Telegramme empfangen werden, damit der
Schaltvorgang durchgeführt wird. Das soll Störungen vermeiden.
Ein Telegramm besteht aus den Daten der 12 Eingangspins und
einer abschließenden »0«, auf die 32 Takte Pause folgen.

Hardware
Am GND des Senders (da, wo der Minuspol der Batterie ange-
schlossen ist) wird eine Leitung angelötet, welche mit GND vom
Arduino verbunden wird. Der Pin 2 des Arduino wird dann Pin 17
(18polige Bauform) oder Pin 19 (20polige Bauform) des HX2262
verbunden (Pin 1 bei den Intertechno Sendern).

Abbildung 8-1

Abbildung 8-2

RF-Steckdosen 205
Software
Als Erstes brauchen wir die RF-Bibliothek von [Link]
com/overige/browsable/433MHz/ArduinoRemoteSwitchLibrary.7z
(Kopie bei [Link]) welche ins Verzeichnis
Arduino/libraries/RemoteSwitch entpackt wird.
Das wichtigste beiliegende Beispiel ist das Show_received_code-
Script. Es ist eigentlich zur Verwendung mit einem Empfänger und
zum Decodieren von eingehenden Funksignalen gedacht.
Da aber an dem hier verwendeten Pin 2 des Arduino nicht nur von
uns Daten in das Funkmodul eingespeist werden können, sondern
auch die zu sendenden Daten bei jeder Betätigung eine Knopfes auf
der Fernbedienung herauskommen, können wir uns damit anse-
hen, welche Codes mit welcher Datenrate gesendet werden.
Nachdem der Code in den Arduino geladen und der Sender mit dem
Pin 2 des Arduinos verbunden ist, sollte in der seriellen Konsole
(»serial monitor«, letzter Button oben rechts im Arduinofenster) bei
jedem Tastendruck auf der Fernbedienung Folgendes zu sehen sein:
Code: 26, period duration: 362us.
Code: 24, period duration: 362us.
Code: 4400, period duration: 362us.
Code: 4398, period duration: 362us.
Code: 1484, period duration: 362us.
Code: 1482, period duration: 362us.

Code 26 entspricht also der ersten Taste der Fernbedienung, Code 24


der zweiten und so weiter. Die 362us sind ein Maß für die Sendege-
schwindigkeit der jeweiligen Fernbedienung. Alle diese Daten benö-
tigen wir, wenn wir vom Arduino aus Schaltbefehle senden wollen.
Für das Senden von Kommandos ist die Funktion RemoteSwitch::
sendTelegram(code,sendPin) zuständig. Allerdings ist der hier ver-
wendete Code anders aufgebaut als bei der Empfangsfunktion.
Hier hilft die Funktion SendCode, die die benötigten Umwandlun-
gen vornimmt.
void SendCode(unsigned long code, int period) {
// Datenformat:
// pppppppp|prrrdddd|dddddddd|dddddddd (32 bit)
// p = Geschwindigkeit (9 bit unsigned int
// r = Wiederholungen als 2log. r = 3 bedeutet 2^3=8 mal senden.
// d = Code

code |= (unsigned long)period << 23;


code |= 3L << 20; // 3L = 8 mal wiederholen
// 4L = 16 mal wiederholen
RemoteSwitch::sendTelegram(code,sendPin);
}

206 Kapitel 8: Automation


Ein einfaches Beispiel:
void loop() {
// Steckdose A1 an
SendCode(24,362);
delay(5000); // 5 Sekunden warten
// Steckdose A1 aus
SendCode(26,362);
delay(5000); // 5 Sekunden warten
}

Gespensterschreck
Nicht nur Gespenster, sondern auch Diebe und Einbrecher lassen
sich mit unregelmäßig ein- und ausgeschalteten Lichtern vertrei-
ben. Mittels einfacher Zeitschaltuhren lässt sich das zwar auch rea-
lisieren, man müsste dann aber beim Verlassen des Hauses immer
daran denken, sie auch alle zu aktivieren.

Hardware
Zusätzlich zum Arduino werden eine oder mehrere Funksteckdo-
sen-Sets benötigt. Wie unter Hardware beschrieben wird der Sender
der Funksteckdosen modifiziert und mit dem Arduino verbunden.

Abbildung 8-3

Software
Als Erstes benötigen wir eine Tabelle mit allen vorhandenen Steck-
dosen und deren zugehörigen Ein- und Ausschaltcodes. (Der auf-

Gespensterschreck 207
merksame Leser wird hier erkennen, dass der Code für AUS bei der
Intertechno-Fernbedienung immer um zwei kleiner ist als der dazu-
gehörige Code für EIN. Es würde also genügen, nur einen der bei-
den zu speichern, allerdings wäre der Code dann auf genau diese
Fernbedienung festgeschrieben.)
int anzahlSteckdosen = 3;

unsigned long steckdosen[][2] = {


{26,24}, // Steckdose 1 (an/aus)
{4400,4398}, // Steckdose 2 (an/aus)
{1484,1482} // Steckdose 3 (an/aus)
};

Mit der Hilfe der Funktion random(max) werden jetzt beliebige


Steckdosen an- oder ausgeschaltet. Zwischen den Schaltvorgängen
wird jeweils 15 Minuten gewartet, damit es realistisch aussieht.
void loop() {
// zufällig eine Steckdose auswählen.
int steckdose = random(anzahlSteckdosen);
// zufällig entweder an oder aus senden.
int aktion = random(2);
SendCode(steckdosen[steckdose][aktion],period);
// 15 Minuten warten
for (int i = 0; i < 15; i++) {
delay(60*1000); // 1 Minute warten
}
}

Die Erweiterung, dass nur Funksignale gesendet werden, wenn ein


zusätzlicher Helligkeitssensor, am Arduino angeschlossen, Dunkel-
heit meldet, sei dem geneigten Leser als Übung überlassen.

Referenzen
[Link]
RF-Bibliothek
[Link]
Intertechno-Funksteckdosen per AVR steuern
[Link]
ARCTECH-Funksteckdosen
[Link]
Die Ansteuerung von Funksteckdosen
[Link]
Arduino & HT2262

208 Kapitel 8: Automation


KAPITEL 9 In diesem Kapitel:
• Programmierbare
Wearable Computing Kleidung
• Wearable
Komponenten
• Die iPod-Steuerung
im Mantel

Das folgende Kapitel behandelt einen kleinen Exkurs in die Welt


des Wearable Computing. Gleichzeitig soll erklärt werden, wie ein
Arduino mit einem iPod oder iPhone kommunizieren kann. Als
praktisches Beispiel wird eine tragbare Fernbedienung für einen
iPod oder ein iPhone gebaut. Im Folgenden wird das iPhone nicht
mehr gesondert erwähnt, da es keinen für das Projekt relevanten
Unterschied gibt.

Programmierbare Kleidung
Der Trend zur programmierbaren Kleidung hat in den letzten
Monaten stark zugelegt. Gab es bei der Erstellung der ersten Auflage
dieses Buches nur sehr wenige Ressourcen und war Elektronik zum
Anziehen eher ein Nischenthema, gibt es nun eine ganze Reihe von
Webseiten, die sich damit befassen. Unter dem Schlagwort Wea-
rable Computing werden zwei grundsätzliche Bestandteile zusam-
mengefasst: Zum einen Elemente wie Fäden und Stoffe, die auch in
herkömmlicher Kleidung vorkommen. Diese gibt es auch in leiten-
den Varianten und werden als solche in erster Linie in der Industrie
eingesetzt, oder zum Beispiel bei Fechtanzügen. Leitende Fäden
können zum Beispiel von Sparkfun erstanden werden, hier gibt es in
Deutschland einige Händler wie [Link]
Leitende Stoffe sind schwieriger und oft nur über die USA zu bezie-
hen. Sachdienliche Hinweise hierzu nehmen wir gerne auf der
Website zum Buch, [Link] entgegen.
Zum anderen besteht das Wearable Computing aus klassischer
Elektronik, die oftmals angepasst wurde, damit sie besonders gut in

209
Kleidung vernäht werden kann. Die Firma Sparkfun hat in Zusam-
menarbeit mit Leah Buchley ([Link]
Pad/) das LilyPad entworfen, ein Arduino-Board, das sich durch
seine Eigenschaften besonders gut in Kleidung einarbeiten lässt.
Inzwischen ist unter diesem Label eine ganze Reihe an Komponen-
ten entstanden. Dazu gehören LEDs, Temperatursensoren oder
Schalter. Eine ganze Bandbreite dieser Produkte wird unter http://
[Link] angeboten.
Im Internet findet man mittlerweile eine große Reihe an interessan-
ten Projekten, die Kleidung und Computer verbinden. Am häufigs-
ten dürfte dabei die LED vorkommen. Jacken, T-Shirts und
Kleider, die dank Elektronik leuchten, haben schon eine recht lange
Tradition und sind nicht erst seit dem Aufkommen von LilyPad
und Co. aufgetaucht. Ein besonders interessantes Projekt, das
LEDs verwendet, ist eine Jacke für Radfahrer, die Leah Buchley auf
ihrer Seite beschreibt. Zeigt man eine Richtung an, leuchtet ein
Pfeil in die entsprechende Richtung. Besonders im Dunklen eine
sinnvolle Sache. Die koreanische Künstlerin Joo Youn Paek schuf
2006 eine Klanginstallation, die durch das Öffnen und Schließen
verschiedener Reißverschlüsse gesteuert werden konnte.([Link]
[Link]/~jyp243/jy/[Link])
Laura Bioffi, eine Studentin aus Kopenhagen, strickte einen Hand-
schuh, der zusammen mit einem LilyPad in der Lage ist aufzuzeich-
nen, wann immer einem Kommilitonen die Hand gegeben wird.

Abbildung 9-1
T-Shirt mit LilyPad

Madeleine und Chris Ball entwarfen ein T-Shirt, das die Anzahl
ungelesener E-Mails visualisiert. Dazu wurde die LilyPad-Platine
mit einer Bluetooth-Erweiterung verbunden, die damit über ein
Handy die Zahl der ungelesenen E-Mails abrufen kann. Um bis
zu 127 ungelesene EMails visualisieren zu können, wird die

210 Kapitel 9: Wearable Computing


Anzahl binär dargestellt: [Link]
30/email-counting-tshirt.
Andere Projekte basieren auf nützlicheren Konzepten, wie etwa
Vibrationsmodulen, die Menschen mit Gleichgewichtsstörungen
helfen sollen, ihre Balance zu halten. Eine besonders umfangrei-
che Website, die sowohl viele Tipps zum Selbermachen bietet als
auch regelmäßig interessante Projekte vorstellt, ist [Link]
[Link].

Wearable Komponenten
LilyPad
Das LilyPad ist ein abgespeckter Arduino, speziell für das Vernähen
in Wearable-Projekten konzipiert. Da der ganze Programmierteil
des Arduinos fehlt, kann ein vorhandener Arduino Hilfe leisten. Im
Prinzip verwendet man dessen TX- und RX-Pins, muss jedoch auch
beachten, dass man den Mikrocontroller vorher vom Board ent-
fernt hat. Eine genaue Anleitung findet man unter [Link]
[Link]/~leah/LilyPad/01_computer_attach.html. Oder noch einfa-
cher verwendet man das dazu passende FTDI-Breakeout Board,
welches direkt mit dem LilyPad bezogen werden kann.

Abbildung 9-2
LilyPad (Abbildung mit freund-
licher Genehmigung von
Sparkfun Electronics)

Wearable Komponenten 211


Leitender Faden
Einer der wichtigsten Bestandteile von Elektronik in Stoffform ist
der leitende Faden. Er besteht meistens aus metallisch (mit Silber)
bedampften Trägerfäden. Je nach verwendetem Metall und
Schichtdicke erhält man unterschiedliche Widerstände und Halt-
barkeit gegenüber Waschen und Brechen. Gewöhnlich liegt der zu
erwartende Widerstand bei ca. 0,5 Ohm pro Zentimeter. Zu lange
Leitungen, gerade für etwas stromhungrige Bauteile wie LEDs kön-
nen ein Problem darstellen. Dem kann durch mehrfache Fäden
abgeholfen werden. Leitender Faden kann inzwischen bei einigen
Elektronik-Fachhändlern bezogen werden. So führt zum Beispiel
Watterott Elektronik zwei verschiedene Sorten leitenden Faden.
Sparkfun führt auch eine stetig wachsende Zahl von Wearable-
Komponenten.

Abbildung 9-3
Leitender Faden (Abbildung mit
freundlicher Genehmigung von
Sparkfun Electronics)

Leitender Stoff
Für großflächige Kontakte und mehrlagige Konstruktionen ist leit-
fähiger Stoff eine interessante Sache. Allerdings ist er sehr schwer
zu bekommen. Eine Quelle ist der Fechtturnierbedarf. Dort werden
sogenannte Elektrowesten verwendet, um Treffer des Gegners
erkennen zu können. Diese sind aus leitfähigem Stoff hergestellt.

212 Kapitel 9: Wearable Computing


Leitender Schaumstoff
Viele Elektronikkomponenten werden zum ESD-Schutz (das sind
Beschädigungen durch elektrostatische Aufladung) auf schwarzem
oder rosa Schaumstoff ausgeliefert. Je nach Hersteller ist die Leitfä-
higkeit aber leider sehr verschieden, von wenigen 100 Ohm bis zu
mehreren Megaohm. Mit diesem Schaumstoff lassen sich z.B.
Drucksensoren bauen, indem man diesen Schaumstoff zwischen
zwei Stoffschichten vernäht, die jeweils einen leitfähigen Faden
enthalten. Je stärker man auf sie eindrückt, desto niederohmiger
werden sie. Diese Veränderung kann mit einem PullUp als Analog-
signal vom Arduino gelesen und verarbeitet werden.

LEDs
Ganz normale bedrahtete LEDs lassen sich, nachdem man die
Anschlussdrähte zu kleinen Ösen gebogen hat, mit leitendem
Faden vernähen. Besonders kleine SMD-LEDs integrieren sich gut
in Kleidungsstücke (Sie reißen nicht so leicht ab wie ihre großen
Schwestern, wenn sie an den Anschlüssen mit kleinen Ösen aus
Draht versehen werden. Passend zur LilyPad-Platine gibt es von
Sparkfun bereits vorgefertigte kleine LED-Platinen, die ebenfalls
Ösen zum Vernähen haben.

Abbildung 9-4
LilyPad-LED (Abbildung mit
freundlicher Genehmigung von
Sparkfun Electronics)

Beschleunigungssensor
Ebenfalls bei Sparkfun gibt es einen Beschleunigungssensor zum
Annähen. Damit kann man zum Beispiel die Armpositionen mes-
sen oder Bewegungsmuster erkennen, um dann verschiedene LED-
Muster abzuspielen oder einfach nur einen Tagesablauf aufzu-
zeichnen.

Wearable Komponenten 213


Abbildung 9-5
LilyPad-Beschleunigungssensor
(Abbildung mit freundlicher Geneh-
migung von Sparkfun Electronics)

Lautsprecher
Ein kleiner magnetischer Lautsprecher, gerade laut genug, um den
Träger auf wichtige Zustände und Meldungen aufmerksam zu
machen.

Abbildung 9-6
LilyPad-Lautsprecher (Abbildung
mit freundlicher Genehmigung von
Sparkfun Electronics)

Stromversorgung
Verschiedene Batteriefächer können einen Arduino oder ein Lily-
Pad mit Strom versorgen. 3 AA- oder AAA-Batterien/Akkus reichen
dabei für ein LilyPad aus. Ein Arduinoboard benötigt etwas mehr
Spannung, da darauf ein einfacher Spannungsregler verbaut ist.
Dieser benötigt mindesten ca. 7V um den Arduino mit 5V zu ver-
sorgen. Ohne diesen Regler läuft auch das Arduinoboard mit 3 Bat-
terien. Sind diese nicht mehr ganz voll, kann der Mikrocontroller
unter Umständen aber nicht mehr richtig arbeiten. Sparkfun bietet

214 Kapitel 9: Wearable Computing


eine Lösung mit nur einer Batterie, hierbei wird die Spannung mit-
tels eines Schaltreglers von 1,5V auf 5V erhöht.

Abbildung 9-7
LilyPad-Batteriehalterung
(Abbildung mit freundlicher Geneh-
migung von Sparkfun Electronics)

Die iPod-Steuerung im Mantel


Um die grundlegenden Prinzipien des Wearable Computing zu
erläutern, soll im Folgenden nun eine Jacke, ein Mantel oder ein
anderes geeignetes Kleidungsstück mit einer einfachen Steuerung
für den iPod ausgestattet werden.

Materialien
Neben dem Arduino (wenn möglich einem LilyPad) werden die
typischen Utensilien zum Nähen benötigt. Also eine Nähnadel oder
Nähmaschine, leitender Faden oder sehr dünner Draht, metallene
Textil-Druckknöpfe und Schaumstoff. Für die Verbindung mit dem
iPod oder iPhone (was natürlich ebenfalls vorhanden sein sollte)
benötigt man einen iPod-Dock-Konnektor. Außerdem ist es sinn-
voll, gleich daran zu denken, dass man das Kleidungsstück, nennen
wir es hier »die Jacke«, auch unabhängig von einem Netzteil betrei-
ben möchte. Ein Batteriefach für 3 AA- oder AAA-Batterien kann
dabei sehr hilfreich sein.

Technik
Wie oben schon erwähnt, lohnt es sich bei Wearables-Projekten
über den Kauf eines »LilyPad« nachzudenken. Diese Arduino-
Board ist rund, flach und klein, sodass es besonders gut in einem
Kleidungsstück versteckt werden kann. Angeblich ist es waschbar,
auf jeden Fall eignet es sich jedoch besonders gut, um leitenden
Faden anzuknüpfen, weil die Pins mit Löchern versehen sind.

Die iPod-Steuerung im Mantel 215


Druckknöpfe: Der wohl denkbar einfachste vernähbare Schalter ist
ein einfacher, metallener Druckknopf. Solche Knöpfe sind in jedem
Kurzwarenladen oder Kaufhaus erhältlich, meist in 12er-Packun-
gen für unter 3 Euro. Da beide Teile des Knopfes leitend sind, ist
das Prinzip einfach: ist er offen, so fließt kein Strom, wird er
geschlossen, so entsteht auch ein Stromkreis.

Abbildung 9-8
Druckknopfschalter

Abbildung 9-9
Druckknopfschalter plus LED

216 Kapitel 9: Wearable Computing


Schaumstofftaster: Aus Schaumstoff können einfache Taster gebaut
werden. Da sich der Schaumstoff wieder in seine Ausgangsposition
zurückbewegt, nachdem er gedrückt wurde, kann er als Abstand-
halter zwischen zwei leitenden Schichten verwendet werden.
Drückt man ihn zusammen, schließt sich der Stromkreis, lässt man
los, weitet sich der Taster wieder, es fließt kein Strom mehr.

Abbildung 9-10
Vorbereitete Stelle für den Taster

Abbildung 9-11
Abstandhalter aus Schaumstoff
oder anderem dicken Stoff.

Die iPod-Steuerung im Mantel 217


Abbildung 9-12
Vorbereiteter »Deckel« mit
leitfähigem Faden in der Mitte
zur Kontaktierung

Abbildung 9-13
Fertiger Tasterstapel mit
Anschlussfaden.

Abbildung 9-14
Fertiger Taster mit LED

218 Kapitel 9: Wearable Computing


iPod/iPhone: Das Dock des iPods enthält einen Stecker mit 30 Pins
mit unterschiedlichen Funktionen, darunter auch die Möglichkeit
den iPod fernzusteuern. Eine genaue Belegung kann unter http://
[Link]/PortableDevices/ipod_pinout.shtml gefunden werden.
iPod-Dock-Konnektoren können bei einigen Anbietern, etwa Tin-
kersoup, gekauft werden und haben den Vorteil, dass alle Pins ver-
lötet werden können. Sieht man sich den Stecker eines iPod-USB-
Kabels an, stellt man fest, dass nur einige Pins tatsächlich verlötet
sind. Es ist allerdings nicht auszuschließen, dass es, etwa bei eBay,
Kabel von anderen Anbietern gibt, die man verwenden kann. Für
dieses Projekt sind die Pins 1, 12 und 13 relevant. Sie stellen die
TX- und RX-Verbindungen der seriellen Schnittstelle zum iPod
dar. Im verlaufe dieses Projektes wird auch das Protokoll erläutert,
mit dem der iPod ferngesteuert werden kann.

Nähen: Im Rahmen dieses Buches sind wir leider nicht in der Lage,
einen detaillierten Exkurs in die Kunst des Nähens zu bieten. Im
Internet gibt es jedoch hervorragende Tutorials, die jede mögliche
Technik und jeden Stich genau erklären. Hier sei zum Beispiel auf
[Link] verwiesen; aber auch auf der
Webseite von Burda Moden ([Link] gibt es
gut gemachte Videos. Der Einfachheit halber wird im Folgenden
nur von »Nähen« gesprochen. Ob dies mit der Nähmaschine oder
per Hand geschieht, bleibt dem Leser selbst überlassen. Allerdings
gilt Folgendes zu beachten, wenn man leitenden Faden in der Näh-
maschine verwenden will. Dieser neigt dazu, sich sehr schnell zu
verdrehen. Deshalb empfiehlt es sich, den leitenden Faden als
Unterfaden einzunähen. Dazu wird er auf die Unterfadenspule
einer Nähmaschine gerollt und ein einfacher, dünner Faden von
oben durch die Nadel geführt. Die beiden Fäden werden ineinander
verschlungen, sodass der dünne Faden den leitenden auf dem Stoff
festzurrt. Eine genaue Anleitung findet man unter anderem unter
[Link]
faden_aid_1543.html

Aufbau: Dieses Projekt hat den Anspruch, vollständig waschbar zu


sein. Um zu verhindern, dass das Board, sei es nun LilyPad oder ein
anderes, zu großer Belastung ausgesetzt wird, und auch um Korro-
sion am iPod-Konnektor zu vermeiden, empfiehlt es sich, eine
Tasche für all die Elektronik zu nähen. Packt man so viel Elektronik
wie möglich, vor allem Board und Batteriefach, in diese Tasche,
kann man alle Pins über leitenden Faden und Druckknöpfe auf die
äußere Seite der Tasche verbinden. Die Tasche kann also jederzeit

Die iPod-Steuerung im Mantel 219


komplett aus dem Kleidungsstück genommen werden und muss
nicht mitgewaschen werden.

Play-Knopf: Der wohl einfachste Teil dieses Projektes ist ein Play/
Pause-Knopf. Hier dient ein Druckknopf, der auf der einen Seite mit
einem Pin, auf der anderen mit GND verbunden wird. Der Arduino
wird später so programmiert, dass er ein »Play«- oder »Pause«-Kom-
mando an den iPod sendet, sobald der Knopf geschlossen oder
geöffnet wird.

Lautstärke: Das Fernbedienungsprotokoll des iPod kennt nur die


Kommandos »Lautstärke erhöhen« und »Lautstärke verringern«.
Es ist also leider nicht möglich, den aktuellen Status festzuhalten.
Für dieses Projekt empfehlen sich deshalb zwei Taster. Hierzu
wird, wie in Abbildung 9-11 dargestellt, ein Stück Schaumstoff zwi-
schen zwei leitende Stoffschichten genäht. Für diese Schichten
reicht es, leitenden Faden einzunähen, wobei die eine Schicht mit
dem GND-Pin des Arduino, die andere mit einem beliebigen digita-
len Pin verbunden wird. In den Schaumstoff wird ein fingergroßes
Loch geschnitten, durch das sich die beiden Schichten verbinden
können, sobald man mit einem Finger darauf drückt.

Aufbau: Hat man die Einzelteile zusammen, kann man einen ersten
Aufbau versuchen: Der Druckknopf und die beiden Taster werden
mit einem Arduino verbunden. Die beiden TX/RX-Pins des Ardu-
ino werden mit den Pins 12 und 13 des iPod-Konnektors verlötet,
zusätzlich muss der GND des Arduinos mit einem der GND-
Anschlüsse des iPod-Konnektors verbunden werden. Nun kann
mit der Programmierung begonnen werden. Zunächst soll der
Druckknopf als Schalter fungieren. Der entsprechende Pin wird
also auf »Input« gesetzt, und in der loop()-Funktion kontinuier-
lich ausgelesen.

Programmierung
Zunächst empfiehlt es sich, den iPod einmal ohne die selbst gebas-
telten Sensoren anzusteuern. So kann sichergestellt werden, dass
die serielle Verbindung fehlerlos funktioniert. Hierzu wird zunächst
die Bibliothek Serial eingebunden. Anschließend wird im setup()
eine serielle Verbindung mit 19200 Baud gestartet. Die Verbin-
dung läuft nur mit dieser Geschwindigkeit. Anschließend können
Kommandos an den iPod gesendet werden. Diese Kommandos fol-

220 Kapitel 9: Wearable Computing


gen dem iPod Accessory Protocol, das unter anderem unter http://
[Link]/wiki/Apple_Accessory_Protocol dokumentiert ist.

header 2 0xFF 0x55


länge 1 länge des modus + kommando + parameter
modus 1 der Modus, auf den sich das Kommando bezieht
kommando 2–4 das zwei bis vier Byte lange Kommando
parameter 0..n optionaler Parameter, je nach Kommando
checksum 1 0xXX - (8 bit additive checksum) ( 0x100 - (summe aller länge/
modus/kommando/parameter bytes) & 0xFF)

Die Modi beziehen sich dabei auf verschiedene Möglichkeiten, mit


dem iPod zu kommunizieren. In unserem Falle geht es um die ein-
fache Fernbedienung (Simple Remote), die im Vergleich zu anderen
Protokollen (etwa Nike+) vollständig entschlüsselt ist. Die wich-
tigsten Kommandos finden sich in einer verkürzten Tabelle (siehe
Tabelle unten) – für eine erweiterte Liste, die den Rahmen dieses
Buches sprengen würde, empfiehlt sich der oben angegebene Link.

Kommando Funktion
0x00 0x00 Button Released
0x00 0x01 Play/Pause
0x00 0x02 Vol+
0x00 0x04 Vol-
0x00 0x08 Skip >>
0x00 0x10 Skip <<
0x00 0x80 Stop
0x00 0x00 0x01 Play (kein Pause)
0x00 0x00 0x02 Pause (kein Play)

Für dieses Projekt werden vier Kommandos benötigt: 0x00 0x00


0x01 für Play, 0x00 0x00 0x02 für Pause und 0x00 0x02 bzw 0x00
0x04 für Vol+ und Vol-. Diese Kommandos benötigen keine weite-
ren Parameter, also ist dieser Teil 0. Das Längen-Byte des Komman-
dos wird also je nachdem auf 3 oder 4 gesetzt. Für die Checksumme
empfiehlt es sich, eine eigene kleine Funktion zu schreiben, wenn
man mehr als nur ein paar Befehle benötigt:
int checkSum(int* cmd) {
int sum = 0;
for(int i=2; i<=cmd[2]+2;i++) {
sum += cmd[i];

Die iPod-Steuerung im Mantel 221


}
int checksum = 0x100 - (sum & 0xFF);
return checksum;
}

Für den Play-Pause-Befehl gilt demnach zum Beispiel die Checksum


FA, die man sich per [Link](checksum, HEX) auch ausgeben
lassen kann.
So muss man sich keine Gedanken mehr um die benötigte
Checksum machen und kann ein einfaches Kommando an den
iPod schicken. Zu Anfang sollte stets ein »Button release«-Kom-
mando gesendet werden, um zu signalisieren, dass kein Knopf auf
dem iPod (oder auf dem Kleidungsstück) gedrückt ist:
int buttonRelease[] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x00,0xFB};

Diese Tabelle kann nun nach und nach gesendet werden:


for (int i = 0; i < 8; i++) {
[Link](buttonRelease[i],BYTE);
}

Nun können auch die anderen Kommandos in solche Tabellen


geschrieben werden: Hierzu wird eine Funktion genommen, die als
Eingabe die einzelnen Parameter nimmt und die entsprechende
Tabelle zurückgibt. Da verschiedene Kommandos aus einer unter-
schiedlichen Anzahl Bytes bestehen, empfiehlt es sich, diese Infor-
mation dem Array, welches das Kommando speichert, mitzugeben.
In diesem Falle wird einfach die ohnehin später benötigte Längen-
information genutzt, sodass das Kommando ohne Checksum so
aussieht:
int buttonPlay[] = { 0xFF, 0x55, 0x04, 0x02, 0x00,0x00, 0x01};

Nun kann eine Funktion »sendCommand« geschrieben werden, die


das entsprechende Kommando zusammenbaut und gleich versendet:
void sendCommand(int* cmd) {
int cs = checkSum(cmd); //Checksum bauen
for(int i = 0;i<=cmd[2]+2;i++) {
[Link](cmd[i], BYTE); // alle Bytes des Kommandos
übermitteln
}
[Link](cs, BYTE); //Checksum übermitteln
}

Nun kann alles zusammengefügt werden:


#include <Bounce.h>

// IPod Befehle
int buttonRelease[] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x00};

222 Kapitel 9: Wearable Computing


int buttonPlayPause[] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x01};
int buttonPlay[] = {0xFF, 0x55, 0x04, 0x02, 0x00,0x00, 0x01};
int buttonPause[] = {0xFF, 0x55, 0x04, 0x02, 0x00,0x00, 0x02};
int buttonVolPlus[] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x02};
int buttonVolMinus[] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x04};
int buttonVolRelease[] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x00};

// Arduino Pins für Taster und Play/Pause Switch


int volPlusPin = 2;
int volMinusPin = 3;
int playPausePin = 4;
int ledPin = 13;
int playStatus;

// Die Bouncezeit auf 500ms festlegen, damit


// zufällige Berührungen nichts bewirken.
Bounce bouncePlusPin = Bounce( volPlusPin, 500);
Bounce bounceMinusPin = Bounce( volMinusPin, 500);
Bounce bouncePlayPausePin = Bounce( playPausePin, 500);

void setup() {
[Link](19200);

// Eingänge
pinMode(volPlusPin, INPUT);
pinMode(volMinusPin, INPUT);
pinMode(playPausePin, INPUT);

// Ausgang für LED


pinMode(ledPin, OUTPUT);

// Pull-Ups einschalten, dann brauchen wir keine


// externen Widerstände.
// Taster und Schalter werden mit GND verbunden.
digitalWrite(playPausePin, HIGH);
digitalWrite(volMinusPin, HIGH);
digitalWrite(volPlusPin, HIGH);

void sendCommand(int* cmd) {


int cs = checkSum(cmd);
for(int i = 0;i<=cmd[2]+2;i++) {
[Link](cmd[i], BYTE);
}
[Link](cs, BYTE);
}

int checkSum(int* cmd) {

Die iPod-Steuerung im Mantel 223


int sum = 0;
for(int i=2; i<=cmd[2]+2;i++) {
sum += cmd[i];
}
int checksum = 0x100 - (sum & 0xFF);
return checksum;
}

void loop() {
if ([Link]()) {
// Druckknopf geöffnet -> Pull-Up macht den Eingang HIGH
if ( [Link]() == HIGH) {
// Musik aus
sendCommand(buttonPause);
sendCommand(buttonRelease);
playStatus = 0;
}
else {
// Druckknopf geschlossen -> Pin = GND/LOW
// Musik an
sendCommand(buttonPlay);
sendCommand(buttonRelease);
playStatus = 1;
}
}

if ([Link]()) {
// Taster gedrückt = GND/LOW
if ( [Link]() == LOW) {
sendCommand(buttonVolPlus);
sendCommand(buttonRelease);
}
}

if ([Link]()) {
// Taster gedrückt = GND/LOW
if ( [Link]() == LOW) {
sendCommand(buttonVolMinus);
sendCommand(buttonRelease);
}
}

if (playStatus == 1) {
// Ist der Ipod in Betrieb, soll die LED blinken
digitalWrite(ledPin,(millis()/256) % 2);
} else {
// LED aus
digitalWrite(ledPin,LOW);
}
}

224 Kapitel 9: Wearable Computing


Tipps & Tricks
Der etwas lose Aufbau mit leitendem Draht und vielen nur verkno-
teten Kontaktstellen kann manchmal zu unerwarteten Ergebnissen
führen. Meistens kann das mit einem Voltmeter oder Durchgangs-
prüfer einfach gefunden werden. Besonders hilfreich ist es da, in
der Software das zu beobachtende Signal mittels einer LED (z.B. bei
einem normalen Arduino Pin 13 mit der eingebauten LED) wieder
auszugeben. Dann kann man das Stoffobjekt bewegen und knaut-
schen, um den Fehler hervorzurufen, und hat mittels der LED eine
direkte Beobachtungsmöglichkeit.
Bei Tastern und ähnlichen Kontakten hilft die Debounce-Biblio-
thek, zu kurze Signale von zufälligen Berührungen zu ignorieren.
Wenn eine Funktionalität wirklich nur willentlich ausgelöst wer-
den soll, hilft eine Kombination von mehreren Tastern/Sensoren
die entweder gleichzeitig oder in einer bestimmten Reihenfolge
gedrückt werden müssen, damit eine Reaktion ausgelöst wird.
Ein Taster könnte z.B. alle anderen Taster für 5 Sekunden freischal-
ten. Wobei das nicht für alle Situationen ausreichend ist, zum Bei-
spiel wenn ein größerer Gegenstand alle Taster betätigt. Da hilft
dann nur eine komplexere Sequenz von Tastendrücken und das
konsequente Abbrechen, sobald dabei eine Taste falsch oder zu
lange gedrückt wurde – ähnlich wie man das von der Tastensperre
beim Mobiltelefon kennt.

Die iPod-Steuerung im Mantel 225


KAPITEL 10 In diesem Kapitel:
• Musik steuern mit
Musik-Controller mit Arduino dem Arduino
• Das MIDI-Protokoll
• Die MidiDuino-
Bibliothek
• Ein MIDI-Zauberstab
• MIDI-Input

Musik steuern mit dem Arduino


Die zwei letzten Kapitel dieses Buches befassen sich mit elektroni-
scher Musik in ihren unterschiedlichen Ausprägungen. Die elektro-
nische Musik mit ihrer relativ kurzen Geschichte ist einer der
Pionierbereiche des 20. Jahrhunderts und hat eine lange Tradition
selbstgebauter Instrumente.
Die ersten Einsätze von Elektronik im musikalischen Bereich waren
imposante Maschinen wie das Telharmonium von Thaddeus
Cahill, das 1897 entwickelt wurde.

Abbildung 10-1
Telharmonium

Diese Mischung aus mechanischen Klangerzeugern und elektroni-


scher Steuerung, die man elektromechanische Klangerzeugung nennt,

227
lässt sich bis zum heutigen Tage verfolgen, mit faszinierenden Gerä-
ten wie z.B. den Instrumenten von Godfried-Willem Raes von der
Logos Foundation aus Belgien, der herkömmliche Instrumente
modifiziert und automatisiert, sodass sie sich elektronisch steuern
lassen.
Allgemein bekanntere elektronische Musikinstrumente sind kom-
plett elektronische Klangerzeuger, die man Synthesizer nennt.
Diese benutzen elektronische Schaltungen, um verschiedenste
Klänge zu erzeugen und zu verändern. Eins der ersten dieser elek-
tronischen Instrumente war das Theremin, 1919 vom russischen
Physikprofessor Leon Theremin erfunden. Die erste Theremin-Auf-
führung fand 1920 in St. Petersburg am Physikalisch-Technischen
Institut statt. Bekannt ist das Theremin vor allem aus der Filmmu-
sik, wo es seit den ersten Horror- und Science-Fiction-Filmen für
Soundeffekte eingesetzt wurde, unter anderem in Danny Elfmans
Soundtrack zum Film »Charlie und die Schokoladenfabrik« aus
dem Jahr 2005.
Das Theremin war das erste ganz ohne Berührung spielbare Instru-
ment: Über zwei Antennen lassen sich Lautstärke und Tonhöhe
getrennt steuern. In diesem und dem nächsten Kapitel werden wir
mit einem Arduino und ein paar Drähten ein Theremin bauen.
Ein Thereminbausatz war das erste Produkt, das Bob Moog in den
1950er Jahren vertrieb. Bob Moog wurde später bekannt als Erfin-
der und Entwickler eines der ersten weit verbreiteten Synthesizer.
Der von Bob Moog entwickelte Synthesizer war ein modularer Syn-
thesizer: Er bestand aus vielen kleinen einzelnen elektronischen
Modulen, die jeweils eine bestimmte Aufgabe erfüllten. So konnte
eins dieser Module zum Beispiel einen Ton in einer bestimmten
Höhe erzeugen, ein zweites Klangsignale aus verschiedenen Quel-
len zusammenmischen und ein drittes Steuerparameter erzeugen,
die einem bestimmten Hüllkurvenverlauf entsprachen.
Modulare Synthesizer sind heutzutage immer noch sehr beliebt und
weit verbreitet, gerade weil sie ihrem Benutzer so viel kreative und
technische Freiheit lassen. Im Vergleich zu digitalen Synthesizern,
die einen Prozessor und digitale Algorithmen verwenden, um Klänge
zu erzeugen, werden analoge Synthesizer oft als »wärmer« empfun-
den, weil die vielen Ungenauigkeiten in der elektronischen Schaltung
und den einzelnen Komponenten einen sich immer wieder leicht ver-
ändernden Klang erzeugen, der deswegen auch »menschlicher«
klingt. Es gibt mittlerweile auch viele Module für modulare Synthesi-

228 Kapitel 10: Musik-Controller mit Arduino


zer, die digital ihre Klänge erzeugen. Viele dieser Module (analoge
und digitale) lassen sich mit herkömmlichen elektronischen Kompo-
nenten in einer relativ kurzen Zeit bauen, und es gibt viele Seiten im
Internet, die Bausätze und Anleitungen anbieten. Sehr empfehlens-
wert ist Ray Wilsons Seite [Link] die
z.B. einen kompletten Synthesizer zum Selbstbauen anbietet.
Dieses Konzept von einzelnen kleinen Modulen, die man zusam-
menstecken kann, hat eine gewisse Ähnlichkeit mit dem Arduino
und seinen verschiedenen Erweiterungsmodulen, und so ist es
nicht überraschend, dass die Arduino-Plattform benutzt wird, um
analoge modulare Synthesizer zu steuern und zu ergänzen. Hier sei
z.B. auf das ModularDuino-Projekt hingewiesen, das den Arduino
als Klangerzeugermodul in einem modularen Synthesizer einsetzt.
Lange Zeit war die elektronische Musik vor allem ein Bereich für
moderne klassische Komponisten. Diese Pioniere entwickelten
durch ihre kompositorischen Ansätze und mit Einsatz von Oszilla-
toren, Radios und Bandgeräten viele der Techniken, die später auch
in herkömmlichen Synthesizern und elektronischen Musikgeräten
zum Einsatz gekommen sind. Parallel zur akademischen Musik
wurden in den Studios von Radiosendern, z.B. beim BBC Radio-
phonic Workshop, neue Klangkonzepte entwickelt und umgesetzt.
Schnell wurden Module und Geräte gebaut, die es möglich mach-
ten, musikalische Kompositionen elektronisch zu speichern, abzu-
spielen und zu modifizieren: Diese Geräte wurden Sequencer
genannt. Auf den ersten, analogen Sequencern konnte man mithilfe
einer Reihe von Potentiometern verschiedene Steuerwerte einstel-
len und in einer Sequenz wiederholen. Diese Steuerwerte konnten
z.B. Tonhöhen sein oder Lautstärken, aber auch Filtereinstellungen
und andere Klangparameter. Dadurch ließen sich relativ einfach
kurze melodische Fragmente eingeben und verschiedene rhythmi-
sche Muster einstellen, die immer wiederholt wurden: Es war nicht
mehr notwendig, Noten einzugeben, sondern man konnte kom-
plette Stücke elektronisch erstellen, und zwar so leicht wie auf
einem Klavier.
Parallel zu den Entwicklungen in der analogen Elektronik wurden
die Computer immer schneller und kleiner, und viele Komponisten
und Musiker begannen, sie einzusetzen, um Musik zu schreiben
und zu erzeugen. Das erste Musikprogramm wurde schon 1951
geschrieben, konnte allerdings nur einfache Melodien spielen.
Angesichts des Computers, auf dem dieses Programm lief, mit sei-

Musik steuern mit dem Arduino 229


nen Röhren und seinem Quecksilberspeicher, war das schon eine
beachtliche Leistung. Ähnliche Melodien können wir auch mit dem
Arduino generieren, wie es in Kapitel 11 gezeigt wird. Mit wachsen-
dem Speicher und fortschreitender Miniaturisierung war es jedoch
bald möglich, Computer zu benutzen, um komplette musikalische
Werke zu speichern und zu bearbeiten, mit sogenannten Sequen-
cerprogrammen (die im Vergleich zu analogen Sequencern digital
ihre Parameter speichern und darum viel umfangreichere Editier-
möglichkeiten boten).
Mit den größeren Speichern wurde es Computern auch möglich,
digital Musik aufzunehmen und wieder abzuspielen. Das digitale
Speichern von Klängen, das Sampling, war geboren. Diese Klanger-
zeugungsmöglichkeit veränderte in den 1980er Jahren mit Hip-Hop
das Gesicht der populären Musik. Auch auf dem Arduino ist es dank
dem WaveShield von LadyAda möglich, Klangsamples abzuspielen.

Abbildung 10-2
Arduino WaveShield

Mittlerweile sind Heimcomputer so leistungsstark, dass man auf


ihnen problemlos Dutzende, wenn nicht Hunderte von digitalen
Synthesizern laufen lassen kann. Diese Synthesizer nennt man auch
virtuelle Instrumente (virtual instruments), weil sie keine eigenstän-
digen Geräte sind. Im Endeffekt entsprechen sie aber von Aufbau
und Klangeigenschaften her eigenständigen Hardwaresynthesizern.
Es gibt mittlerweile eine ganze Reihe an Musikprogrammen, die die
Möglichkeiten des Computers, Programme auszuführen und zu

230 Kapitel 10: Musik-Controller mit Arduino


speichern, voll ausnutzen. Diese Programme bieten dem Benutzer
eine Schnittstelle, mit der er selbst seine eigenen Synthesizer und
Sequencer programmieren kann. Manche dieser Programme sind
eigentlich Softwareentwicklungsumgebungen, in denen Programme
auf herkömmliche Weise als Textdatei geschrieben und dann aus-
geführt werden (ein bisschen wie in der Arduino-Umgebung, nur
dass anstelle von Anweisungen, die die Hardware steuern, hier
Anweisungen zur Verfügung stehen, die Musiknoten spielen oder
Klangparameter verändern).
Um diese ganzen Geräte und Computer miteinander zu verbinden
(sodass ein Sequencer ohne Probleme einen beliebigen Synthesizer
ansteuern kann), wurde der MIDI-Standard im Jahre 1981 entwi-
ckelt. MIDI ist ein Kommunikationsprotokoll, das den Austausch
symbolischer musikalischer Information zwischen verschiedenen
elektronischen Instrumenten ermöglicht. »Symbolisch« heißt in
diesem Kontext, dass keine Audiodaten ausgetauscht werden, son-
dern kurze Nachrichten, die eine symbolische Bedeutung tragen.
So können von einem MIDI-Keyboard aus Noten und zusätzliche
Parameter, wie Tastenanschlagsgeschwindigkeit oder ob das Pedal
gedrückt ist, an einen Synthesizer übermittelt werden. Auch ein
Sequencer kann MIDI-Informationen speichern und abspielen und
so z.B. für Hintergrundharmonien oder komplette Lieder einge-
setzt werden. Das MIDI-Protokoll unterstützt auch die Synchroni-
sierung von unterschiedlichen Geräten, sodass mehrere Sequencer
gleichzeitig eingesetzt werden können, ohne dass sie den Takt ver-
lieren und die so erzeugte Musik wie eine Blaskapelle nach dem
Dorffest klingt. MIDI hat sich schnell durchgesetzt und ist auch
heutzutage, 25 Jahre später, immer noch die erste Wahl, um elek-
tronische Musikinstrumente zu verbinden.
Wegen der vielen Parameter, die man auf Synthesizern einstellen
kann, wurden Geräte entwickelt, die nur zur Steuerung von ande-
ren MIDI-Geräten verwendet werden und oft keine Gemein-
samkeiten mehr mit herkömmlichen Instrumenten haben. Diese
Geräte nennt man MIDI-Controller. Ein typisches Beispiel für
einen solchen MIDI-Kontroller ist ein Gerät, das dem Musiker
Drehknöpfe zur Verfügung stellt. Jeder dieser Drehknöpfe ist mit
einem bestimmten Parameter auf dem gesteuerten Synthesizer ver-
knüpft. In gewissem Sinne ist auch ein MIDI-Keyboard ein MIDI-
Controller, und so gibt es auch Controller, die eine Gitarre nach-
bauen, oder Controller, die wie ein Saxophon funktionieren (wie
der EWI-4000), nur eben keinen Klang erzeugen, sondern MIDI-
Daten. Wenn man aber das Konzept ein bisschen weiter verfolgt,

Musik steuern mit dem Arduino 231


lassen sich beliebige Sensoren zu einem MIDI-Controller umbauen,
und genau das ist einer der Bereiche, in dem der Arduino glänzend
zum Einsatz kommt.
Besonders interessant sind Geräte, die sich von dieser starren
Auftrennung in Klangerzeuger, Sequencer und Controller verab-
schieden und all diese Aspekte unter einem übergreifenden Kon-
zept kombinieren. Ein besonders interessantes und mittlerweile
weit verbreitetes Gerät ist der Monome von der Firma selben
Namens ([Link] Das ist ein Musikcontroller, der aus
64 beleuchteten Tastern besteht (es gibt auch Versionen mit 128
und 256 Tasten). Diese 64 Tasten sind in einer 8-mal-8-Matrix
angeordnet. Unter jeder Taste befindet sich eine LED, die durch-
scheint. Der Monome wird an einen Computer angeschlossen und
steuert dort die Software MAX/MSP, wofür es spezielle Patches
gibt. Das Gerät an sich sendet nur gedrückte Tasten über eine
USB-Schnittstelle und empfängt vom Computer Kommandos, um
die LEDs an- und auszuschalten. Durch diese recht schlichte
Oberfläche sind allerdings innovative und intuitive Steueroberflä-
chen möglich. Der Künstler Daedalus, der an der Entwicklung des
Monome beteiligt war, benutzt die Oberfläche, um einzelne musi-
kalische Loops (kurze, sich wiederholende Audiosamples) zu star-
ten und zu verändern.
Der Monome-Controller ist komplett quelloffen: Monome stellt
auf seiner Website die Schaltpläne und den Quellcode der Software
zur Verfügung. Dadurch ist um den Monome-Controller, der nur in
kleinen Stückzahlen (und auch als Bausatz) verkauft wird, eine
große Gemeinschaft interessierter Musiker und Programmierer ent-
standen, die das Produkt weiterentwickeln. Aus dieser Gemein-
schaft heraus wurde ein Selbstbauklon des Controllers entwickelt,
der auf Arduino und 4-mal-4-Button-Pads von Sparkfun basiert.

Abbildung 10-3
Monome-Controller

232 Kapitel 10: Musik-Controller mit Arduino


In diesem Kapitel wird das MIDI-Protokoll genauer vorgestellt, und
es wird gezeigt, wie ein Arduino benutzt werden kann, um MIDI-
Daten zu senden und zu empfangen. Damit ist es möglich, her-
kömmliche MIDI-Controller zu bauen (also Controller, die haupt-
sächlich Taster, Schieberegler und Drehknöpfe verwenden), die
genau an die Wünsche des Musikers angepasst sind (siehe
Kapitel 7). Es ist aber auch möglich, alle Sensoren, die wir bis jetzt
an den Arduino angeschlossen haben, zu benutzen, um Synthesizer
zu steuern oder Musik zu erzeugen. Letztendlich ist es auch mög-
lich, auf dem Arduino MIDI-Daten zu empfangen und weiterzuver-
arbeiten, um z.B. Klänge zu erzeugen, indem in der realen Welt
Aktoren angesteuert werden.

Das MIDI-Protokoll
Das MIDI-Protokoll ist ein asynchrones serielles Protokoll (siehe
Kapitel 5), das getrennte Kabel für die Sende- und die Empfangs-
richtung verwendet. MIDI-Geräte verfügen also meistens über eine
Eingangsbuchse (MIDI IN) und eine Ausgangsbuchse (MIDI
OUT). MIDI-Kabel verwenden einen DIN-5-Stecker, und die dazu-
gehörigen Buchsen lassen sich problemlos auf ein Steckboard ste-
cken. MIDI-Geräte bieten oft einen sogenannten THRU-Anschluss
an, der Daten, die am MIDI-IN anliegen, spiegelt. Dadurch ist es
möglich, mehrere Synthesizer hintereinander anzuschließen, um sie
von demselben Keyboard oder Sequencer aus anzusprechen. Frü-
here Computer hatten entweder von Haus aus eingebaute MIDI-
Schnittstellen (wie der Atari 1024 ST, der bis ins 21. Jahrhundert
hinein eine beliebte Computermusikplattform war) oder boten
diese an der Soundkarte an (über den Joystick-Port). Mittlerweile
ist es allerdings üblich, einen USB- oder Firewire-MIDI-Adapter zu
verwenden, um MIDI-Geräte an Heimcomputer anzuschließen.
Das MIDI-Protokoll kann man auch komplett ohne physikalische
Schnittstelle verwenden, wenn man unterschiedliche Musikpro-
gramme auf einem Rechner verwendet. Diese benutzen dann virtu-
elle MIDI-Ports, die nur intern im Computer existieren.
In diesem Kapitel werden Projekte vorgestellt, die MIDI-Daten ent-
weder senden oder empfangen. Das heißt, dass diese Projekte ohne
weitere MIDI-Hardware oder MIDI-Software nicht viele Auswir-
kungen haben werden. Falls ein Hardware-Synthesizer oder ein
Hardware-Sequencer zur Verfügung steht, lässt sich dieser über
herkömmliche MIDI-Kabel und die unten beschriebenen Schaltun-
gen direkt an den Arduino anschließen. Es ist allerdings auch mög-

Das MIDI-Protokoll 233


lich, mit dem Computer MIDI-Daten zu erzeugen und direkt über
die USB-Schnittstelle an den Arduino zu übermitteln. Dazu muss
auf dem Betriebssystem der Fluss, der über die serielle Schnittstelle
gesendet wird, als MIDI interpretiert und an den MIDI-Stack im
Computer übergeben werden. Dazu kann unter Mac OS X die Ard-
rumo-Software benutzt werden, die es frei herunterzuladen gibt
([Link] Unter Windows kann die Soft-
ware s2midi benutzt werden, die es ebenfalls frei unter [Link]
[Link]/2007/s2midi/ gibt. Für beide Plattformen können Sie
auch das Programm Serial-Midi benutzen, das Sie unter http://
[Link]/SpikenzieLabs/Serial_MIDI.html finden.

MIDI-Nachrichten
Das MIDI-Protokoll ist ein binäres Protokoll (Nachrichten werden
als numerische Werte übertragen, nicht als Zeichenketten), das auf
8-Bit-Werte aufbaut. Allerdings wird in jedem übertragenen Wert
das oberste Bit als Statusbit benutzt: Ist es gesetzt, handelt es sich
nicht um einen numerischen Wert, sondern signalisiert, dass es sich
um einen Befehl handelt und nicht um normale Daten. Dieses Sta-
tusbit vereinfacht die serielle Kommunikation sehr (siehe Kapitel 6,
um mehr über serielle Protokolle zu erfahren): Es reicht zu erken-
nen, ob das erste Bit gesetzt ist, um zu wissen, ob ein empfangenes
Byte ein Befehl oder ein numerischer Wert ist. Dadurch kann man
auch problemlos MIDI-Kabel ein- und ausstecken, ohne dass sich
Geräte neu synchronisieren müssen. Werden am Anfang unbe-
kannte Daten empfangen, reicht es, bis zum nächsten Byte mit
gesetztem Statusbit zu warten.
Bei Befehlbytes codieren die untersten 4 Bits den MIDI-Kanal. Die-
ser Kanal ist eine virtuelle Aufteilung des MIDI-Kabels in 16
getrennte Kabel. Jedes angeschlossene Gerät wird auf seinen eige-
nen Kanal konfiguriert und reagiert nur auf Nachrichten, die in den
unteren 4 Bits des Befehlbytes diesen Kanal codiert haben. Dadurch
ist es möglich, Noten nur an einen bestimmten Synthesizer zu schi-
cken, auch wenn mehrere über eine MIDI-THRU-Kette angeschlos-
sen sind (es kann auch sein, dass unterschiedliche Einheiten eines
einzelnen Synthesizers auf verschiedenen Kanälen reagieren). Oft
sind Synthesizer jedoch auf den Omnikanal eingestellt; reagiert ein
Synthesizer also auf die falschen Nachrichten oder gar nicht, lohnt
es sich nachzuprüfen, auf welchem Kanal MIDI-Nachrichten
geschickt werden und welche Kanaleinstellungen auf dem Synthesi-
zer aktiv sind.

234 Kapitel 10: Musik-Controller mit Arduino


Wenn ein Computer benutzt wird, um MIDI-Daten zu empfangen
und zu senden (heutzutage meistens über einen USB-Adapter oder,
falls der Computer über eine professionelle Soundkarte verfügt,
über die Soundkarte), ist es oft nützlich, einen sogenannten MIDI-
Sniffer zu benutzen, um solchen Problemen auf die Schliche zu
kommen. Unter Windows ist die Software MIDI-OX zu empfehlen,
die es auch erlaubt, virtuelle MIDI-Geräte zu erstellen, um verschie-
dene MIDI-Programme untereinander zu verknüpfen. MIDI-OX
kann unter [Link] heruntergeladen werden. Unter
Mac OS X ist die Software Midi Monitor zu empfehlen, die unter
[Link] heruntergeladen werden kann.
Diese Sniffer-Programme zeichnen MIDI-Kommunikation auf, deko-
dieren die einzelnen Befehle, die aufgenommen wurden, und zeigen
sie in lesbarer Form an. Besonders nützlich ist das beim Debuggen
von MIDI-Programmen, die auf dem Arduino laufen, weil in sol-
chen Fällen die normale serielle Schnittstelle nicht mehr funktio-
niert, da sie als MIDI-Schnittstelle verwendet wird und auf eine
Geschwindigkeit eingestellt ist, die nicht standardmäßig erkannt
wird.
Wegen der Kennzeichnung von Befehlbytes über das obere Status-
bit können nur numerische Werte übertragen werden, die 7 Bits
lang sind, also Werte von 0 bis 127 (deswegen kommt es in Com-
putersoftware und in Synthesizern auch oft vor, dass Parameter-
werte nur von 0 bis 127 gehen). Es gibt drei Gruppen von MIDI-
Nachrichten: normale, Echtzeit- und exklusive MIDI-Nachrichten.
Die erste Gruppe umfasst die am häufigsten gebrauchten MIDI-
Nachrichten. Nachrichten mit Befehlbyte 0x80 und 0x90 werden
benutzt, um Noteninformationen zu übertragen. Wird auf einem
MIDI-Keyboard eine Taste angeschlagen, wird eine Note On-Nach-
richt erzeugt, die die Tonhöhe der angeschlagenen Taste enthält
sowie die Geschwindigkeit, mit der diese Taste angeschlagen wurde
(falls das Keyboard über Anschlagsdynamik verfügt). Wird die
Taste wieder losgelassen, wird eine Note Off-Nachricht geschickt.
(Mittlerweile benutzen die meisten Keyboards allerdings eine Note
On-Nachricht mit einer Anschlagsgeschwindigkeit von 0).
Zwischen diesen beiden Nachrichten können beliebige weitere
Nachrichten über die MIDI-Verbindung übertragen werden. Wie
man sich leicht vorstellen kann, kann es bei intensiver Datenüber-
tragung (wenn z.B. viele Daten aus einem Sequencer gesendet wer-
den) zu Verzögerungen kommen, da die MIDI-Verbindung nur eine
begrenzte Geschwindigkeit hat. Es ist daher unter Umständen

Das MIDI-Protokoll 235


wichtig, separate MIDI-Verbindungen zu verwenden, wenn viele
Daten an mehrere Synthesizer übertragen werden sollen. Die Note
On- und Note Off-Nachrichten sind wahrscheinlich die am häufigs-
ten vorkommenden MIDI-Nachrichten.
Eine weitere MIDI-Nachricht ist die Controller Change-Nachricht,
die benutzt wird, um beliebige Parameter zu steuern. Sie wird zum
Beispiel verwendet, um die Lautstärke, die Filteröffnung und wei-
tere Syntheseparameter zu steuern. Welche Controllerwerte an wel-
che Parameter auf einem MIDI-Gerät gebunden sind, lässt sich in
den jeweiligen Handbüchern nachschlagen. Die meisten MIDI-
Controller, die nicht nur Noten senden, verwenden Controller
Change-Nachrichten, um ihre Informationen zu übermitteln. Bei
einem Blasinstrument-Controller werden z.B. der Luftdruck und
die gedrückten Ventile als Controller Change-Nachrichten übermit-
telt. Bei Controllern, die Potentiometer oder Encoder verwenden,
lässt sich meistens die Controllernummer jedes einzelnen Dreh-
knopfes einzeln zuweisen, sodass sich der Benutzer eine eigene
Kontrolloberfläche für sein gesteuertes MIDI-Gerät zurechtlegen
kann. Es können wegen der Beschränkungen des MIDI-Protokolls
nur bis zu 128 Parameter gesteuert werden. Jeder dieser Parameter
kann auf einen Wert von 0 bis 127 gesetzt werden.
Weitere MIDI-Nachrichten, die eher instrumentenspezifische Auf-
gaben übernehmen, sind die Program Change-Nachricht, mit der
verschiedene »Programme« (also Einstellungen) auf Synthesizern
aufgerufen werden, sowie die Key Pressure- und Channel Pressure-
Nachrichten, die bei Keyboards den Tastendruck übermitteln.
Diese Nachrichten werden wir in diesem Kapitel nicht verwenden.
Echtzeit-MIDI-Nachrichten sind eine spezielle Klasse von MIDI-
Nachrichten, die meistens nur ein Byte lang sind (mit gesetzten Sta-
tusbit) und hauptsächlich zur Temposynchronisation von MIDI-
Geräten eingesetzt werden. Echtzeit-MIDI-Nachrichten, die nur ein
Byte lang sind, können jede beliebige Nachricht unterbrechen und
sind meistens sehr zeitkritisch. Wenn zwei MIDI-Geräte unterein-
ander synchronisiert werden sollen, übernimmt eins dieser Geräte
die Rolle des Timing Master (also »Zeitchef«), während das andere
Gerät die Rolle des Timing Slave übernimmt. Der Timing Master
bestimmt das generelle Tempo und kann auch anhand der Start-,
Pause- und Stop-Nachrichten das Abspielen steuern. Der Timing
Master schickt regelmäßig kurze Echtzeitnachrichten (die Zeit-
Ticks) an den Timing Slave, und der Slave synchronisiert sich auf
diese regelmäßigen Nachrichten. Die MidiDuino-Library, die wir in

236 Kapitel 10: Musik-Controller mit Arduino


diesem Kapitel verwenden, unterstützt sowohl die Slave- als auch
die Master-Seite der Synchronisation. Allerdings sind für die kor-
rekte Slave-Synchronisation einige Eingriffe in das Arduino-System
notwendig, weswegen wir uns in diesem Kapitel auf die Master-
Rolle beschränken.
Systemexklusive Nachrichten schließlich sind spezielle Nachrichten,
die benutzt werden, um beliebige Daten über MIDI auszutauschen.
Binäre Daten können als Sysex-Nachrichten übermittelt werden.
Eine Sysex-Nachricht fängt mit der speziellen Nachricht 0xF0 an,
die gefolgt wird von einer beliebigen Anzahl weiterer binärer
Datenbytes (allerdings muss bei diesen Bytes das oberste Bit auf 0
gesetzt sein, weil sie ja sonst als Befehlbyte erkannt werden).
Das Erkennen von einkommenden MIDI-Nachrichten ist eine recht
komplizierte Angelegenheit, die von der MidiDuino-Library über-
nommen wird. Die Library kann alle Tricks von MIDI bearbeiten
und so alle MIDI-Nachrichten richtig erkennen.

MIDI an den Arduino anbinden


Elektrisch betrachtet, ist die serielle Schnittstelle ein Stromkreis.
Das heißt, dass Bits nicht als Spannungen übertragen werden, wie
es sonst üblicherweise vorkommt, sondern dass Stromfluss eine
»1« signalisiert und kein Strom eine »0«. Um Stromflüsse wieder
in Spannungen zu konvertieren, damit der Arduino die übertrage-
nen Bits korrekt interpretieren kann, wird ein Optokoppler einge-
setzt. Ein Optokoppler ist ein Chip, der intern eine LED und
einen Fotowiderstand enthält. Der Eingangsstrom bringt die LED
zum Leuchten, und der empfangende Fotowiderstand schaltet
einen Transistor, sodass auf der Ausgangsseite eine Spannung
geschaltet wird. So lassen sich Informationen ohne elektrische Ver-
bindung übertragen (die Übertragung geschieht optisch, daher der
Name Optokoppler). Dadurch lassen sich Grundschleifen vermei-
den, die dann vorkommen, wenn mehrere Geräte, die physikalisch
voneinander entfernt sind und deswegen oft unterschiedliche Mas-
senpotentiale haben, über ein Kabel verbunden werden. Dadurch
kommt es manchmal zu einem Brummen, wenn diese an einen Ver-
stärker angeschlossen sind, was natürlich in einem musikalischen
Kontext nicht erwünscht ist. Die Schaltung, um von einem Arduino
aus MIDI zu empfangen, ist allerdings sehr einfach und lässt sich
mit einem Optokoppler (hier hat sich der 6N138 bewährt), zwei
220-Ohm-Widerständen und einer Diode bauen.

Das MIDI-Protokoll 237


Abbildung 10-4
Schaltbild MIDI-Input

Abbildung 10-5
Schaltung MIDI-Input und
MIDI-Output

Um MIDI-Daten von einem Arduino aus zu senden, ist es nur not-


wendig, den seriellen Ausgangspin TX (Pin 2 auf dem Arduino-
Board) über einen 220-Ohm-Widerstand an Pin 5 der MIDI-Buchse
zu führen, und Pin 2 der MIDI-Buchse über einen weiteren 220-
Ohm-Widerstand an 5V zu verbinden.
Da die MIDI-Schnittstelle direkt an die serielle Schnittstelle des
Arduino angeschlossen wird, kommt es auf dem RX-Pins zu einer
»elektrischen Kollision«. Deswegen ist es notwendig, vor dem
Hochladen eines neuen Sketches den RX-Pin freizustellen, weil
sonst von der USB-Seite keine Daten empfangen werden können.
Kommt eine Timeout-Fehlermeldung beim Hochladen, bedeutet
das, dass der RX-Pin noch an den Optokoppler angeschlossen ist.

238 Kapitel 10: Musik-Controller mit Arduino


Abbildung 10-6
Schaltbild MIDI-Output

Die MidiDuino-Bibliothek
In diesem Kapitel wird die MidiDuino-Bibliothek verwendet, die
Sie unter [Link] herunterladen können.
Diese Bibliothek wurde von einem der Autoren dieses Buches
geschrieben und wird ständig weiterentwickelt. Beim Schreiben
dieses Buches wird die erste Version 0.1 der Bibliothek verwendet.
In der ZIP-Datei der Bibliothek sind verschiedene kleine Bibliothe-
ken zu finden, die alle in den Ordner hardware/libraries der Ardu-
ino-Installation kopiert werden müssen.
Die MidiDuino-Bibliothek besteht aus zwei großen Teilen. Der
erste ist der MidiUart-Teil, der sich um die serielle Schnittstelle
kümmert. Dieser Teil wird auch verwendet, um MIDI-Nachrichten
zu senden. Der zweite Teil ist der eigentliche MIDI-Stack, der ein-
kommende Nachrichten von der seriellen Schnittstelle liest und
analysiert und daraus einzelne Nachrichten erkennt und an ver-
schiedene Callback-Funktionen weiterreicht. Callback-Funktionen
sind Funktionen aus dem Sketch, die als Argument an den MIDI-
Stack übergeben und automatisch aufgerufen werden.
In diesem ersten Sketch verwenden wir den MidiUart-Teil, um in
regelmäßigen Abständen Noten über MIDI zu schicken. Statt die
serielle Schnittstelle mit [Link]() zu initialisieren, wird diese
mit dem Aufruf [Link]() initialisiert. Wenn MIDI mit den
früher erwähnten Seriell-nach-MIDI-Konvertierungsprogrammen
S2midi oder Ardrumo verwendet wird, muss als zusätzliches
Argument an [Link]() noch die serielle Geschwindigkeit
angegeben werden, ansonsten wird die standardmäßige MIDI-
Geschwindigkeit von 31.250 Bps verwendet. Dadurch, dass MIDI-
Daten binär direkt über die serielle Schnittstelle gesendet werden,
kann die Serial-Bibliothek nicht mehr verwendet werden, um

Die MidiDuino-Bibliothek 239


Daten in die serielle Konsole auszugeben. Stattdessen kann einer
der MIDI-Sniffer verwendet werden, um bestimmte Debug-
Nachrichten zum Beispiel als Noten oder Kontrollnachrichten zu
übertragen.
Wenn die USB-Schnittstelle verwendet wird, um direkt MIDI-
Daten an den Computer zu übermitteln (mithilfe von Ardrumo
oder S2Midi), muss die serielle Schnittstelle allerdings auf eine der
Standardgeschwindigkeiten umgestellt werden. Diese Geschwin-
digkeit (z.B. 9.600 Bps oder 112.500 Bps) kann man einfach als
Argument an [Link]() übergeben.
Nachdem die serielle Schnittstelle mit [Link]() initialisiert
wurde, kann sie verwendet werden, um einzelne MIDI-Nachrich-
ten zu übertragen. In diesem ersten Sketch werden Noten mit den
Funktionen [Link]() und [Link]()
gesendet. Diese Funktionen kriegen im Fall der Note On-Nachricht
als Parameter einen MIDI-Kanal, eine Notenhöhe und eine
Anschlagsgeschwindigkeit. Der Parameter MIDI-Kanal ist optio-
nal: Wenn er nicht angegeben wird, wird der Defaultwert Midi-
[Link] verwendet. Um den Default-Kanal zu ändern,
reicht ein einfaches Zuweisen an die Variable [Link]-
rentChannel.
// Einbinden der MidiDuino-Library
#include <MidiUart.h>
#include <Midi.h>
MidiClass Midi;

void setup() {
// Initialisieren der MIDI-Schnittstelle
[Link]();
// Wenn Ardrumo oder S2Midi verwendet werden, wird stattdessen
// [Link](9600);
// verwendet
}

void loop() {
// Zuerst Senden einer Note On-Nachricht
[Link](100, 100);
delay(200);
// Dann senden einer Note Off-Nachricht
[Link](100);
delay(2000);
}

Dieses Programm lässt sich leicht um Kontrollnachrichten ergän-


zen, die mit der [Link]()-Funktion gesendet werden.

240 Kapitel 10: Musik-Controller mit Arduino


Diese Funktion nimmt als Parameter einen optionalen MIDI-Kanal,
die Parameternummer und den Parameterwert. So lässt sich die
loop()-Funktion aus dem vorigen Sketch um Kontrollnachrichten
erweitern.
void loop() {
// Zuerst Senden einer Note On-Nachricht
[Link](100, 100);
[Link](5, 100);
delay(200);
// Dann Senden einer Note Off-Nachricht
[Link](100);
[Link](5, 10);
delay(2000);
}

Ein MIDI-Zauberstab
In diesem Sketch verwenden wir einen Beschleunigungssensor, um
MIDI-Daten zu erzeugen. Das Prinzip des Beschleunigungssensors
wurde schon in Kapitel 7 erläutert. In diesem Sketch verwenden wir
den Nunchuck-Kontroller einer Wii-Konsole von Nintendo, weil
das die billigste und einfachste Methode ist, an einen Beschleuni-
gungssensor zu kommen. Für einen Preis von ungefähr 20 EUR
bekommt man einen Dreiachsen-Beschleunigungssensor, einen
Joystick und zwei Taster. Der Controller versendet diese Daten
über einen digitalen synchronen seriellen Bus, den man i2c nennt.
Dieser Bus ist weit verbreitet und wird von vielen verschiedenen
Schaltungen und Chips verwendet. Die Wire-Bibliothek, die bei
Arduino mitgeliefert wird, übernimmt alle Kommunikationsaufga-
ben, sodass der Anschluss des Nunchuck an das Arduino-Board
leicht gelingt.
Um den Nunchuck zu verbinden, kann man Drähte in die einzel-
nen Pins des Anschlusskonnektors stecken und diese an den Ardu-
ino anschließen. Von vorn gesehen, ist der linke obere Pin die
Clock-Leitung, der rechte obere Pin GND, der linke untere VCC
und der rechte untere die Datenleitung. Die Wire-Bibliothek ver-
wendet die analogen Pins 4 und 5 als Kommunikationsschnittstelle,
und in diesem Sketch werden die analogen Pins 2 und 3 als Strom-
versorgungspins verwendet. GND wird an den analogen Pin 2
angeschlossen, VCC an den analogen Pin 3, Data an den analogen
Pin 4 und Clock an den analogen Pin 5. In der folgenden Abbildung
wird der Anschluss gezeigt.

Ein MIDI-Zauberstab 241


Abbildung 10-7
Nunchuck-Pinbelegung

Der Code zum Einlesen der Nunchuck-Daten ist relativ lang und
wird hier deshalb nicht komplett abgebildet. Als Erstes müssen in
der Setup-Routine sowohl der MIDI-Stack als auch die Wire-Ver-
bindung zum Nunchuck initialisiert werden. An den Nunchuck
wird dann auch gleich ein Initialisierungsbefehl geschickt.
#define pwrpin PORTC3 // analoger pin 3
#define gndpin PORTC2 // analoger pin 2

void nunchuckInit() {
// Initialisierung der Stromversorgungspins
DDRC |= _BV(pwrpin) | _BV(gndpin);
PORTC &=~ _BV(gndpin);
PORTC |= _BV(pwrpin);
delay(100);

// Initialisieren der Wire-Bibliothek und des Nunchuck


[Link]();
[Link](0x52);
[Link](0x40);
[Link](0x00);
[Link]();
}

void setup () {
[Link]();
nunchuckInit();
}

Die Nunchuck-Daten werden in der Funktion nunchuckReadData()


eingelesen und in nunchuckParseData() analysiert und decodiert.

242 Kapitel 10: Musik-Controller mit Arduino


int nunchuckReadData(byte outbuf[]) {
nunchuckSendZero();
delay (30);

[Link] (0x52, 6); // request data from nunchuck


int cnt = 0;
while ([Link] ()) {
outbuf[cnt] = nunchukDecodeByte([Link] ());
cnt++;
}

return cnt;
}

byte nunchukDecodeByte(byte x) {
x = (x ^ 0x17) + 0x17;
return x;
}

void nunchuckSendZero() {
[Link](0x52); // transmit to device 0x52
[Link](0x00); // sends one byte
[Link](); // stop transmitting
}

int joystick[2] = { 0 };
int oldJoystick[2] = { 0 };
byte joystickCC[2] = { 108, 109 };

int accel[3] = { 0 };
int oldAccel[3] = { 0 };
byte accelCC[3] = { 4, 5, 6 };

int button[2] = { 0 };
int oldButton[2] = { 0 };
byte buttonNote[2] = { 60, 62 };

void nunchuckParseData(byte outbuf[]) {


joystick[0] = outbuf[0];
joystick[1] = outbuf[1];
accel[0] = outbuf[2] << 2;
accel[1] = outbuf[3] << 2;
accel[2] = outbuf[4] << 2;

button[0] = bitRead(outbuf[5], 0);


button[1] = bitRead(outbuf[5], 1);

for (int i = 0; i < 3; i++) {


accel[i] += bitRead(outbuf[5], i + 2) * 2 + bitRead(outbuf[5],
i + 3);
}
}

Ein MIDI-Zauberstab 243


Die Ergebnisse des Auslesens werden in den Tabellen joystick[],
accel[] und button[] abgelegt, die anschließend in der Funktion nun-
chuckSendMidi() ähnlich wie beim Code im Miniaturcontroller in
MIDI-Nachrichten konvertiert werden.
void nunchuckSendMidi() {
for (int i = 0; i < 2; i++) {
if (abs(oldJoystick[i] – joystick[i]) >= 2) {
[Link](joystickCC[i], map(joystick[i], 0, 255, 0,
127));
oldJoystick[i] = joystick[i];
}
}

for (int i = 0; i < 3; i++) {


if (abs(oldAccel[i] – accel[i]) >= 7) {
int value = map(accel[i], 300, 800, 0, 127);
[Link](accelCC[i], constrain(value, 0, 127));
oldAccel[i] = accel[i];
}
}

for (int i = 0; i < 2; i++) {


if (oldButton[i] != button[i]) {
if (button[i] == 0) {
[Link](buttonNote[i], 100);
} else {
[Link](buttonNote[i]);
}
oldButton[i] = button[i];
}
}
}

Mit dieser einfachen Schaltung lässt sich also leicht ein umfassen-
der MIDI-Controller mit Joystick, Tastern und Beschleunigungs-
sensoren bauen.

MIDI-Input
In diesem Sketch wird die MidiDuino-Bibliothek benutzt, um
MIDI-Daten einzulesen. Wenn ein Notenanschlag vom Arduino
erkannt wird, wird eine LED geschaltet. Dazu müssen die Daten
der seriellen Schnittstelle eingelesen und an den eigentlichen MIDI-
Stack übergeben werden, der bis jetzt nicht verwendet wurde. Das
Erkennen der Noten wird von diesem Teil übernommen. Die
Kopplung an den Sketch erfolgt über sogenannte Callback-Funktio-
nen. Das sind Funktionen, die mit dem MIDI-Stack registriert auf-
gerufen werden, sobald eine bestimme Nachricht erkannt wurde.

244 Kapitel 10: Musik-Controller mit Arduino


In diesem Sketch werden zusätzlich zur MIDI-Schaltung, die an die
Pins TX und RX angeschlossen ist, noch zwei LEDs an Pin 10 und
12 angeschlossen. Vor dem Programmieren muss die RX-Leitung
zum MIDI-Board kurz getrennt werden, damit der Arduino den
Sketch auch empfangen kann.
Beim Empfangen von CC-Nachrichten wird die Helligkeit der zwei-
ten LED auf den empfangenen CC-Wert gesetzt. So lassen sich
durch das Anschließen von herkömmlichen MIDI-Controllern
Parameter von Arduino-Sketchen steuern, ohne dass Potentiometer
oder andere Steuerungsoberflächen angeschlossen werden müssen.
Das ist besonders in Verbindung mit Licht- oder Soundschaltungen
sehr praktisch, weil robuste kommerzielle Controller verwendet
werden können.
Das Registrieren der Callback-Funktionen geschieht über die Auf-
rufe an [Link](), [Link]()
und [Link](). Die Callback-Funktio-
nen im Sketch bekommen als Argument die binäre empfangene
MIDI-Nachricht.
// Einbinden der MidiDuino-Library
#include <MidiUart.h>
#include <Midi.h>
MidiClass Midi;

// Die erste LED ist an Pin 10 angeschlossen.


int ledPin = 13;
// Die zweite LED ist an Pin 11 angeschlossen.
int ledPin2 = 11;

void setup() {
// Initialisieren der MIDI-Schnittstelle
[Link]();
// Setzen der LED-Pins auf Ausgang
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);

// Beim Erkennen einer Note On-Nachricht wird onNoteOnCallback


// aufgerufen.
[Link](onNoteOnCallback);
// Beim Erkennen einer Note Off-Nachricht wird onNoteOffCallback
// aufgerufen.
[Link](onNoteOffCallback);
// Beim Erkennen einer Control Change-Nachricht wird
// onControlChangeCallback aufgerufen.
[Link](onControlChangeCallback);
}

void loop() {

MIDI-Input 245
// Überprüfen, ob MIDI-Daten empfangen wurden
if ([Link]()) {
// Einlesen des empfangenen MIDI-Bytes
byte c = [Link]();
// Übergeben an die MIDI-Library, damit diese die Daten
// erkennt
[Link](c);
}
}

// Wenn eine eingehende Note On-Nachricht von der MIDI-Library


// erkannt wurde, wird diese Funktion aufgerufen.
void onNoteOnCallback(byte msg[]) {
// Die Helligkeit der LED wird auf die Tonhöhe gesetzt.
analogWrite(ledPin, map(msg[1], 0, 127, 0, 255));
}

// Wenn eine eingehende Note Off-Nachricht von der MIDI-Library


// erkannt wurde, wird diese Funktion aufgerufen.
void onNoteOffCallback(byte msg[]) {
// Ausschalten der LED
digitalWrite(ledPin, LOW);
}

// Wenn eine eingehende Control Change-Nachricht von der


// MIDI-Library erkannt wurde, wird diese Funktion aufgerufen.
void onControlChangeCallback(byte msg[]) {
// Prüfen, ob es sich um CC Nummer 1 handelt
if (msg[1] == 1) {
// Helligkeit der zweiten LED auf den CC-Wert setzen
analogWrite(ledPin2, msg[2]);
}
}

Es ist also sehr einfach, mit der MidiDuino-Bibliothek MIDI-


Schaltungen auf dem Arduino zu bauen. Die MidiDuino-Biblio-
thek bietet auch eine sehr angenehme Schnittstelle für die Zeitsyn-
chronisation und das Sequencen von MIDI-Daten, sodass mit ihr
eigenständige Musikinstrumente und Musiksequencer gebaut wer-
den können.

246 Kapitel 10: Musik-Controller mit Arduino


KAPITEL 11 In diesem Kapitel:
• Töne aus dem Arduino
Musik mit Arduino • Erster Sketch: Töne mit
langsamer PWM
• Zweiter Sketch: Angenehme
Klänge mit schneller PWM
• Dritter Sketch: Steuerung von
Klängen
• Vierter Sketch: Berechnungen
in einer Interrupt-Routine
• Fünfter Sketch: Musikalische
Noten

Töne aus dem Arduino


In diesem Workshop kommt die volle Rechenkraft des Arduino
zum Einsatz, um Töne zu generieren. Es werden zuerst einfache
Klänge erzeugt, um dann später musikalische Noten zu berechnen
und so den Arduino in einen Synthesizer zu verwandeln. Als Letz-
tes wird der Arduino so programmiert, dass er automatisch Melo-
dien und Rhythmen generieren kann. Es werden zwei Aspekte der
elektronischen Musik beleuchtet: auf der einen Seite Klanger-
zeugung und Klangmodifizierung, auf der anderen algorithmische
Musik (also die Beeinflussung von Tönen, Melodien, rhythmischen
Mustern und harmonischen Reihenfolgen durch programmierte
Regeln).
Sogar ein kleines Bauteil wie der Arduino kann dazu verwendet
werden, musikalische Klänge und Geräusche zu erzeugen. Einige
Projekte sollen hier kurz vorgestellt werden, um die ganze Band-
breite der Möglichkeiten zu zeigen und die Fantasie anzuregen.

Pump up the Volume!


Die beiden Stuttgarter Künstler Daniel Dihardja und Frank Arnold
verwenden Handluftpumpen, die mithilfe von Piezo-Sensoren an
einem Arduino angebracht werden. Diese Sensoren messen den
Luftdruck, die Signale werden dann am PC in Klänge umgewandelt.
Diese interaktive Soundinstallation namens Soundbeats erforscht
ganz neue Bereiche der Klangerzeugung und soll, so die Initiatoren,
die körperliche Tätigkeit des Pumpens mit der eigentlich unkörper-
lichen Musik verbinden. Das Ergebnis ist durchaus hörenswert, wie

247
ein Video auf der Projektwebsite unter [Link]
zeigt. Dort heißt es: »Aus der Symbiose von Pumpe und Computer
entsteht eine fruchtbare Bedeutungserweiterung beider Komponen-
ten. »Pumpbeats« spielt demzufolge mit der Verbindung einer ›alten
Kunst‹ (= Musik) und den neuen Medien.«

Eine Harfe aus Licht


Eines der spektakulärsten Arduino-Projekte ist die Laserharfe von
Stephen Hobley ([Link] Ein Laser-
scanner sendet zehn Strahlen vom Boden an die Decke und sorgt
mit passendem Nebel für grüne Saiten aus Licht. Hält nun der Har-
fenspieler eine Hand in das Licht, wird das von einem Sensor
erkannt, der den daraus resultierenden Wert in ein MIDI-Signal
verwandelt; ein Synthesizer sorgt dafür, dass Sounds entstehen. In
der ersten Version der Harfe wurden noch Reflektionssensoren ein-
gesetzt, um die Position der Hand zu messen. Da sich das aber als
sehr kompliziert und unpräzise herausstellte, hat der Erfinder die
Infrarotkamera einer Wiimote so modifiziert, dass sie die Frequenz
eines grünen Lasers erkennen kann. So kann nun die Hand genauer
geortet werden, die damit auch die Tonhöhe auf einem einzelnen
Strahl moduliert.

Diver Sequencer
Der Diver Sequencer ist eine Halbkugel, auf der vier Drehregler
angebracht sind. Ein Arduino gibt nun in regelmäßigen Abständen
vier Töne nacheinander ab. Diese einzelnen Töne können durch die
Drehregler bestimmt werden, indem die Frequenz moduliert wird.
Zusammen mit der Geschwindigkeit, die ebenfalls gesteuert wer-
den kann, ergibt sich also ein kleiner Sequencer, mit dem sich
rhythmische wiederkehrende Tonfolgen erzeugen lassen. Diese
Töne sind allerdings relativ rau, sodass die blinkende Halbkugel
mit ihren Knöpfen wohl mehr Aufsehen erregen dürfte als das, was
sie produziert. Mehr über das Projekt können Sie sich unter http://
[Link]/2009/04/08/diver-sequencer-on-acid/ ansehen.

Klimpern bis zum Stubenarrest


So manche Eltern bereuten in den 1980er Jahren recht schnell, dass
sie ihrem Kind eines dieser kleinen elektronischen Klaviere gekauft
hatten, mit denen japanische Firmen den Markt überschwemmten.
Die bunten Plastikgeräte, die nervig piepsende Töne von sich

248 Kapitel 11: Musik mit Arduino


gaben, konnten für stundenlange Begeisterung und blank liegende
Nerven gleichzeitig sorgen. Wohl im Gedanken an diese Zeiten ist
Pocket Piano Shield ([Link]
[Link]) entstanden, ein Aufsatz für den Arduino, mit
dem genau solche Minisynthesizer selbst gebaut werden können.
Und möglicherweise eignet sich dieses Gerät nicht nur für die musi-
kalische Früherziehung, sondern kann Kindern auch gleichzeitig
die Welt der Elektronik und Programmierung näherbringen.

Komponenten
Die Anzahl zusätzlicher Komponenten ist bewusst klein gehalten.
Verwendet werden eine Stereoklinkenbuchse zum Anschluss eines
Kopfhörers, ein Potentiometer (10.000 Ohm logarithmisch) und
ein Widerstand (1.000 Ohm) zum Einstellen der Lautstärke, sowie
zwei 1 mikro-Farad- Folienkondensatoren zum Filtern des digitalen
Ausgangs aus dem Arduino. Für steuerbare Sketche werden zwei
weitere Potentiometer (linear, von 5.000 Ohm bis 100.000 Ohm)
und zwei Taster eingesetzt.

Warnung In diesem Workshop kann es schnell zu lauten und unkontrol-


lierten Tönen kommen, die sowohl das menschliche Gehör als
auch angeschlossene Lautsprecher oder Kopfhörer beschädi-
gen können. Schließen Sie keine hochwertigen Lautsprecher
an die Schaltung und tragen Sie gegebenenfalls Hörschutz
(oder halten Sie eine Hand auf dem Lautstärkeregler).

Schaltungsaufbau
Der Ausgangspin 9 des Arduino wird verwendet, um Klänge zu
erzeugen. Dazu sind eine Kopfhörerbuchse, ein Widerstand, ein
Potentiometer und zwei Folienkondensatoren notwendig. Der
Widerstand wird eingesetzt, um allzu hohe Lautstärken zu verhin-
dern, während das Potentiometer benutzt wird, um die Lautstärke
generell einzustellen. Das Potentiometer ist ein logarithmisches
Potentiometer, das im Bereich kleiner Widerstandswerte eine grö-
ßere Auflösung hat. Der Grund dafür ist, dass das menschliche
Gehör Lautstärke logarithmisch empfindet, wodurch es möglich
ist, sowohl leichtes Getröpfel als auch einen Düsenjäger zu hören.
Die Folienkondensatoren werden sowohl als Entkopplungskon-
densator (siehe Kasten »Elektronische Klangerzeugung«) wie auch
als Tiefpassfilter eingesetzt.

Töne aus dem Arduino 249


Abbildung 11-1
Schaltplan (ohne Steuerung)

Elektronische Klangerzeugung
Das menschliche Ohr ist eines der genauesten sind, nennt man unipolare Spannungen.) Wei-
Sinnesorgane. Es kann minimale Tonhöhenun- terhin können konstante Spannungen (die sich
terschiede erkennen, was auch die Anforde- nicht verändern) Lautsprecher beschädigen,
rungen an den Arduino deutlich erhöht. Klang weil ihre Membran sich dauernd in Bewegung
im Raum wird durch eine Veränderung des befinden muss. Um solche Beschädigungen zu
Luftdrucks erzeugt, z.B. durch die vibrierende vermeiden, werden
Membran eines Lautsprechers oder Kopfhörers. Entkopplungskondensatoren eingesetzt, die
Eine periodische Veränderung des Luftdrucks konstante Spannungen herausfiltern. Eine will-
(durch eine Klangwelle) nimmt das mensch- kommene Nebenwirkung ist, dass so ein Kon-
liche Gehirn als Tonhöhe war. Je schneller die densator auch eine sich verändernde unipolare
Luft vibriert, desto höher ist die wahrgenom- Spannung in eine bipolare umwandelt.
mene Tonhöhe.
Die Ausbreitung der Kopfhörer- oder Lautspre-
chermembran lässt sich über eine Spannung
steuern (die meistens von einen Verstärker ver-
stärkt wird, um auch große Membranen bewe-
gen zu können). Je höher die Spannung, desto
größer die Ausbreitung der Membranen. Diese
Spannungen werden als analoge Spannungen
Abbildung 11-2: Klangerzeugung
bezeichnet, weil sie eine große Menge von
Werten annehmen können, z.B. von – 5 V bis Anschaulich heißt das, dass das Audiosignal 0
+ 5 V (also –5 V, – 4,8 V, 3 V, 3,1123 V usw . . .). Volt wird, wenn es lange gleich bleibt, und
Digitale Spannungen können nur zwei Werte sonst um 0 Volt herumpendelt.
annehmen, die »An« oder »Aus« signalisieren.
Weiterhin bewegt sich die
Lautsprechermembran sowohl nach vorn als
auch nach hinten (vom Ruhezustand aus gese-
hen), sodass Audiosignale meistens als
bipolare Spannungen übermittelt werden, die
sowohl negativ als auch positiv sein können.
(Spannungen, die nur negativ oder nur positiv Abbildung 11-3: Bipolare Signale und Entkopplung

250 Kapitel 11: Musik mit Arduino


Der Arduino ist ein digitaler Mikrocontroller: Er kann keine analo-
gen Spannungen erzeugen, wie sie für die Erzeugung von Musik
notwendig sind (siehe Kasten »Elektronische Klangerzeugung«).
Die digitalen Ausgangsspannungen des Arduino (0 und 5 Volt)
müssen also in analoge Spannung konvertiert werden. Hier wird
wieder die Pulsweitenmodulation eingesetzt (Kapitel 3). Ein zweiter
Kondensator wird verwendet, der die harten Kanten des PWM-Sig-
nals filtert. Die PWM wird mit einer sehr hohen Frequenz angewen-
det (62.500 Hertz) und dann relativ hart gefiltert (die hohen
Frequenzen werden abgeschnitten). Dadurch bleibt nur noch der
Mittelwert der PWM übrig. Da die PWM so schnell ist, ist sie aller-
dings nicht von Menschen hörbar, sodass der Kondensator nur
fakultativ ist.
Testweise kann man den Tiefpassfilterkondensator aus der Schal-
tung entfernen, um die hohen Frequenzen der PWM zu hören (die
sind allerdings so hoch, dass man sie als Mensch kaum hört).
Dieser Weg ist immer noch relativ grob aufgelöst und ungenau,
sodass meistens in Synthesizern ein Digital-Analog-Wandler zum
Einsatz kommt. Ein DA-Wandler ist ein dedizierter Baustein, der
ein digitales Signal in ein analoges Signal umwandelt. Jede Sound-
karte besteht zum Beispiel aus mehreren DA- und AD-Wandlern
(um Eingangssignale aufzunehmen, z.B. von einem Mikrofon).

Erster Sketch: Töne mit langsamer PWM


In diesem ersten Sketch kommt die hauseigene Pulsweitenmodula-
tion von Arduino zum Einsatz, um Klänge zu erzeugen. Pin 9 ist der
Audioausgang, der an den Kopfhörerausgang angeschlossen ist.
#define AUDIO 9 // Definieren des Audioausgangspins
void setup() {
pinMode(AUDIO, OUTPUT); // der Audiopin ist ein Ausgangspin
}
int time = 200; // die Zeit zwischen steigender und fallender
// Flanke
void loop() // die Arduino-Hauptschleife
{
analogWrite(AUDIO, 255); // hohe Flanke auf Audioausgang
delayMicroseconds(time); // Länge der Flanke = time in
// Mikrosekunden
analogWrite(AUDIO, 0); // tiefe Flanke auf Audioausgang
delayMicroseconds(time); // Länge der Flanke = time in
// Mikrosekunden
}

Erster Sketch: Töne mit langsamer PWM 251


Als Erstes wird hier Pin 9 als Ausgang definiert. In der Hauptrou-
tine wird mit analogWrite() der Pulsweitenmodulationswert auf
dem Ausgangspin bestimmt. Durch Verändern des Wertes der
Variablen time können verschiedene Tonhöhen erzeugt werden.
Es können auch interessantere elektronische Geräusche erzeugt
werden, indem z.B. die Frequenz in einer Schleife verändert wird.
void loop() {
// in dieser Schleife wird time von 0 bis 2000 hochgezählt
{
analogWrite(AUDIO, 255); // hohe Flanke auf Audioausgang
delayMicroseconds(time); // Länge der Flanke = time in
// Mikrosekunden
analogWrite(AUDIO, 0); // tiefe Flanke auf Audioausgang
delayMicroseconds(time); // Länge der Flanke = time in
// Mikrosekunden
}
}

Man kann auch die Zeit immer zufällig wählen lassen:


void loop() {
int volume = random(0, 255); // jede Note bekommt eine zufällige
// Lautstärke
int time = random(1, 2000); // und eine zufällige Tonhöhe
// jede Note wird für 50000 Mikrosekunden gehalten (ungefähr)
for (unsigned int i = 0; i < 50000; i += time) {
analogWrite(AUDIO, volume); // hohe Flanke am Audioausgang
delayMicroseconds(time); // Länge der Flanke = time in
// Mikrosekunden
analogWrite(AUDIO, 0); // tiefe Flanke am Audioausgang
delayMicroseconds(time); // Länge der Flanke = time in
// Mikrosekunden
}
}

Zweiter Sketch: Angenehme Klänge


mit schneller PWM
Normalerweise läuft die Pulsweitenmodulation auf dem Arduino
mit 500 Hz. Das heißt, dass der höchste Ton, den der Arduino
erzeugen kann, im unteren Bereich des menschlichen Gehörs liegt.
Dadurch klingen viele der Klänge seltsam und unangenehm, weil
die Frequenz zu niedrig ist, um »glatte« analoge Spannungen zu
erzeugen. Die PWM-Frequenz des Arduino vermischt sich mit der
Frequenz, die erzeugt werden soll. Im nächsten Schritt wird die
PWM modifiziert, damit sie anstatt mit 500 mit 62.500 Hertz läuft,
was deutlich ansprechendere Klänge ermöglicht.

252 Kapitel 11: Musik mit Arduino


Um die PWM-Frequenz zu erhöhen, müssen spezielle Register des
Arduino-Prozessors geschrieben werden. Diesen Teil kann man
eigentlich getrost überspringen; wer es jedoch ganz genau wissen
will, kann in der technischen Dokumentation von Atmel auf http://
[Link]/dyn/products/product_card.asp?PN=ATmega328P
nachlesen, wie die PWM-Einheit funktioniert. Um die Frequenz
des PWM-Ausgangs auf Pin 9 und Pin 10 auf 62.500 Hz zu erhö-
hen, müssen folgende Zeilen in die setup()-Funktion eingefügt
werden.
TCCR1A = _BV(WGM10) | _BV(COM1A1);
TCCR1B = _BV(CS10) | _BV(WGM12);

Weiterhin wird nicht mehr die Funktion analogWrite() verwendet,


um den PWM-Wert zu setzen, sondern es wird gleich das Hard-
wareregister gesetzt (wie schon in Kapitel 4 bei der LED-Matrix
angewandt). Um den Code lesbar zu halten, wird eine Funktion
definiert.
void writeAudio(uint8_t val) {
OCR1A = (val);
}

Warnung Obwohl die schnelle Pulsweitenmodulation die Qualität des


Klangs erheblich verbessert, sind Steckboards, wie sie mit Ardu-
ino verwendet werden, keine gute Grundlage, um Hi-Fi-Klänge
zu erzeugen. Das Rauschen auf solchen Boards ist sehr stark.
Deutlich bessere Ergebnisse lassen sich erreichen, indem die
Schaltung auf einem kleinen Protoboard zusammengelötet
und in einem abschirmenden Metallgehäuse befestigt wird.

In diesem ersten Sketch mit schneller PWM wird nur ein einzelner
statischer Ton erzeugt. Es wird ein Zähler hochgezählt, der von 0
bis 1.024 geht. Da die PWM-Breite nur von 0 bis 255 geht, wird
dieser Wert durch 4 geteilt, bevor er mit der Funktion writeAudio()
ausgegeben wird. Dadurch wird eine Sägezahn-Wellenform er-
zeugt, weil die erzeugte analoge Spannung immer von 0 bis 5 Volt
geht und dann wieder zurück auf 0 fällt. Die Geschwindigkeit, mit
der diese Spannung hochgezählt wird, bestimmt auch die Tonhöhe.
Diese lässt sich in der Variablen inc einstellen.
int audioPin = 9; // Definition des Audio-Ausgangspins
// Funktion zum Setzen des PWM-Wertes, dazu wird das PWM-Register
// OCR1A verwendet
void writeAudio(uint8_t val) {
OCR1A = (val);
}

Zweiter Sketch: Angenehme Klänge mit schneller PWM 253


// In der Initialisierungsroutine werden der Audioausgangspin als
// Ausgang definiert und die deutlich schnellere PWM konfiguriert.
void setup() {
pinMode(audioPin, OUTPUT);
TCCR1A = _BV(WGM10) | _BV(COM1A1);
TCCR1B = _BV(CS10) | _BV(WGM12);
}
// In dieser Hauptschleife wird eine Sägezahn-Wellenform erzeugt,
// indem der PWM-Wert (also die analoge Ausgangsspannung) alle 20
// Mikrosekunden hochgezählt wird.
void loop() {
int inc = 20;
// Hochzählen der Spannung für die analoge Wellenform
for (unsigned int j = 0; j < 1024; j += inc) {
// Die PWM-Breite geht nur von 0 bis 255, also wird die
// Variable j durch 4 geteilt. Dass j bis 1.024 geht,
// ermöglicht einen größeren Raum an Tonhöhen.
writeAudio(j / 4);
// kurz warten, damit die Töne nicht zu hoch sind
delayMicroseconds(20);
}
}

Dritter Sketch: Steuerung von Klängen


In diesem Abschnitt wird der Arduino-Klangerzeuger um externe
Steuerungsmöglichkeiten ergänzt. Zum Einsatz kommen ein Tas-
ter, der an den digitalen Eingang 4 angeschlossen wird, und ein
Potentiometer, das an den analogen Eingang 0 angeschlossen wird.
Der Ton soll in diesem Sketch nur erklingen, wenn ein Taster
gedrückt wird. Der Taster wird in der Hauptroutine abgefragt, und
der Arduino erzeugt nur dann eine Wellenform, wenn der digitale
Wert am Tastereingang LOW ist. Weiterhin wird die Frequenz der
erzeugten Wellenform an gleichmäßigen Intervallen zufällig neu
gesetzt. Der Frequenzbereich (also die Höhe der zufälligen Töne)
wird durch das Potentiometer gesteuert, das an den analogen Ein-
gang 0 angeschlossen ist.
int audioPin = 9;
void writeAudio(uint8_t val) {
OCR1A = (val);
}
// Der Taster wird an den digitalen Eingang 4 angeschlossen.
int buttonPin = 4;
void setup() {
// Hier wird der Tastereingang definiert.
pinMode(buttonPin, INPUT);
// restliche Initialisierung wie üblich
pinMode(audioPin, OUTPUT);

254 Kapitel 11: Musik mit Arduino


TCCR1A = _BV(WGM10) | _BV(COM1A1);
TCCR1B = _BV(CS10) | _BV(WGM12);
}
int inc = 2; // Zähler zum Einstellen der Tonhöhe
void loop() {
// Die äußere Schleife ist dazu da, Noten im regelmäßigen
// Abständen zu ändern.
for (int i = 0; i < inc * 5; i++) {
// Erzeugen der Sägezahnwellenform, von 0 bis 1024
for (int j = 0; j < 1024; j += inc) {
// Wenn der Taster gedrückt ist, wird die Wellenform auch
// ausgegeben.
if (digitalRead(buttonPin) == LOW) {
writeAudio(j / 4);
// sonst wird der Ausgang auf stumm gestellt
} else {
writeAudio(0);
}
delayMicroseconds(20);
}
}

// Nach Ablaufen der äußeren Schleife wird hier eine neue


// Tonhöhe zufällig eingestellt. Der Bereich, aus dem die neue
// Frequenz gesetzt wird, wird durch das Potentiometer
// eingestellt.
int tieferTon = analogRead(0) / 16;
inc = random(tieferTon, tieferTon + 10);
}

Vierter Sketch: Berechnungen


in einer Interrupt-Routine
Im Gegensatz zu blinkenden oder gedimmten LEDs, bei denen es
nur grob auf zeitliche Genauigkeit ankommt, ist es bei der Klanger-
zeugung enorm wichtig, das Zeitverhalten sehr genau zu berech-
nen. Kleinste Abweichungen führen zu einem Synthesizer, der
verstimmt klingt. Weiterhin lässt sich feststellen, dass der Steue-
rungsprogrammcode eng mit dem Code zum Erzeugen der Wellen-
formen verknüpft ist, was schnell unhandlich wird. Im nächsten
Sketch wird ein weiterer technischer Trick eingeführt, um die
Berechnung der Wellenform von der Hauptschleife zu trennen.
Bis jetzt wurde die zeitliche Synchronisation der Wellenform mit-
hilfe der Funktionen delay() und delayMicroseconds() implemen-
tiert. Diese Funktionen sind allerdings nicht sehr genau, und auch
die Ausführungszeit des Programmcodes in der Hauptroutine hat
einen Einfluss auf die Tonhöhe. Um eine genaue Synchronisation

Vierter Sketch: Berechnungen in einer Interrupt-Routine 255


zu erreichen, muss eine Interrupt-Routine eingeführt werden. Das
ist eine Funktion, die vom Arduino automatisch aufgerufen wird,
wenn z.B. der Zähler der PWM-Einheit überläuft. Dadurch ist es
möglich, eine Funktion sehr regelmäßig aufzurufen. Da die PWM-
Einheit zum Erzeugen der analogen Ausgangsspannung mit 62.500
Hz läuft, ist es maximal möglich, 256 Befehle in dieser Routine aus-
zuführen. Der Programmcode muss also besonders sorgfältig
geschrieben werden.

Abbildung 11-4
Aufruf der Interrupt-Routine

In diesem Sketch wird innerhalb der Interrupt-Routine eine recht-


eckige Wellenform generiert. Dazu wird die Zählervariable phase
hochgezählt wie im vorigen Sketch. Der Zähler geht von 0 bis 65.
535. Ist der Zählerwert größer als 32.768 (also höher als die Hälfte
des möglichen Wertes), wird die Ausgangsspannung auf 255
gesetzt; ist der Zählerwert kleiner als 32.768, auf 0. Dadurch wird
eine Rechteck-Wellenform generiert, die deutlich langsamer ist als
die PWM-Rechteck-Wellenform. Die Frequenz dieser Wellenform
lässt sich über die Variable speed festlegen. Sie wird bei jedem Auf-
ruf der Interrupt-Funktion zur Variable phase hinzuaddiert. Ist
phase größer als 65.535, läuft die Variable automatisch über und
fängt wieder bei 0 an.
In der Interrupt-Routine wird als Erstes die analoge Ausgangsspan-
nung gesetzt. Dadurch hat die Dauer des folgenden Programm-
codes keinen Einfluss auf die zeitliche Genauigkeit der Routine. In
der Hauptschleife wird jetzt nur noch die Tonhöhe gesetzt, indem
der Wert des Potentiometers abgelesen und in der Variable speed
gespeichert wird. Dadurch ist eine saubere Trennung von Kontroll-
code und Audioberechnung gewährleistet.
// Definition des Ausgangspins
int audioPin = 9;
// Funktion zum Setzen der analogen Spannung
void writeAudio(uint8_t val) {
OCR1A = (val);
}

256 Kapitel 11: Musik mit Arduino


// digitaler Eingang für den Taster
int buttonPin = 4;
// Variable für die Erzeugung der Wellenform innerhalb der
// Interrupt-Routinephase ist ein Zähler, der von 0 bis 65535
// geht
uint16_t phase = 0;
// speed bestimmt, wie schnell phase hochgezählt wird.
uint16_t speed = 200;
// sample ist die Variable, in der die analoge Ausgangsspannung
// gespeichert wird.
uint8_t sample = 0;
// Das ist die Definition der Interrupt-Routine, die 625.000 Mal
// pro Sekunde aufgerufen wird (bei jedem Überlauf des PWM-
Timers).
SIGNAL(TIMER1_OVF_vect) {
// Als Erstes wird die analoge Spannung gesetzt.
writeAudio(sample);
// phase wird hochgezählt: je größer speed ist, desto schneller
phase += speed;
// Wenn phase größer als die Hälfte ist, wird die analoge
// Ausgangsspannung auf 5V gesetzt, sonst auf 0V.
// Dadurch wird eine regelmäßige Rechteck-Wellenform generiert.
if (phase >= 32768)
sample = 255;
else
sample = 0;
}
// In der Routine setup werden der PWM-Timer konfiguriert und die
// Interrupt-Routine aktiviert.
void setup() {
pinMode(audioPin, OUTPUT);
pinMode(buttonPin, INPUT);
TCCR1A = _BV(WGM10) | _BV(COM1A1);
TCCR1B = _BV(CS10) | _BV(WGM12);
// Aktivieren der Interrupt-Routine
TIMSK1 |= _BV(TOIE1);
}
void loop() {
// In der Hauptschleife wird nur noch die Tonhöhe bestimmt,
// indem die Variable speed gesetzt wird.
speed = analogRead(0) + 1;
}

Durch diese Trennung von Kontroll- und Audioberechnungscode


lassen sich jetzt deutlich kompliziertere Klänge generieren, ohne
dass der Programmcode unübersichtlich wird. Im nächsten Sketch
wird die Tonhöhe des generierten Tons durch eine zweite, langsa-
mere Wellenform kontrolliert. So eine langsame Wellenform, die
keinen Klang an sich erzeugt, sondern Parameter steuert, wird bei
Synthesizern LFO genannt, Low Frequency Oscillator, was so viel

Vierter Sketch: Berechnungen in einer Interrupt-Routine 257


heißt wie »Niedrigfrequenzoszillator«. Dadurch lassen sich z.B.
Sirenenklänge erzeugen. Hier wird nur die Hauptfunktion vorge-
stellt, setup() und Interrupt-Routine bleiben gleich.
uint16_t lfo_phase = 0;
uint16_t lfo_speed = 200;
uint8_t lfo_sample = 0;
void loop() {
lfo_speed = analogRead(0) * 5 + 1;
lfo_phase += lfo_speed;
lfo_sample = lfo_phase >> 8;
speed = lfo_sample * 5;
delay(5);
}

Der Code zum Berechnen der langsamen Wellenform (hier eine


Sägezahn-Wellenform) ist fast derselbe wie zur Berechnung der
Rechteck-Wellenform. Diese Vorgehensweise beim Berechnen der
Wellenform nennt man einen »Phasenakkumulator«. Deswegen
heißt der Zähler für die Wellenformen auch phase. Hier steuert das
Potentiometer die Geschwindigkeit der langsamen Wellenform.

Fünfter Sketch: Musikalische Noten


Bis jetzt wurden in den Sketchen nur Geräusche und Klänge
erzeugt, jedoch keine Noten. Mit der Berechnung der Interrupt-
Routine ist jedoch ein solides Fundament gegeben, um genaue
Tonhöhen zu erhalten. Jede musikalische Note in unserem Zwölf-
tonsystem entspricht einer Frequenz, und jeder dieser Frequenzen
entspricht auch ein Wert der Variablen speed. Damit diese Werte
nicht jedes Mal mit einer komplizierten Formel berechnet werden
müssen, werden die Werte von speed in einer Tabelle gespeichert.
Im nächsten Sketch wird die Tonhöhe bei jedem Druck auf den
Taster auf eine zufällige Note aus einem Moll-Arpeggio erzeugt.
Dadurch lassen sich angenehm klingende Melodien erzeugen. Es
wird nur der Programmcode für die Hauptroutine vorgestellt.
In der Tabelle freqtable werden die Werte der Variablen speed für
jede Note eingetragen. 60 Werte entsprechen fünf Oktaven. In der
Tabelle arp werden nur die vier Noten aus einem Moll-Arpeggio
festgehalten: 0 (Grundton), 3 (Mollterz), 7 (Quinte) und 10 (kleine
Septime). Wird der Taster betätigt (geht also der Wert am digitalen
Eingang von HIGH auf LOW), wird eine zufällige Note aus arp
gelesen (arp[random(4)]), und eine zufällige Oktave hinzuaddiert
(random(4) * 12). Der Wert von speed wird dann aus der Tabelle
freqtable gelesen.

258 Kapitel 11: Musik mit Arduino


// Werte der Variablen speed für 60 chromatische Noten
// (fünf Oktaven) const uint16_t freqtable[60] = {
69, 73, 77, 82, 86, 92, 97, 103, 109, 115, 122, 129, // 12
137, 145, 154, 163, 173, 183, 194, 206, 218, 231, 244, 259, // 24
274, 291, 308, 326, 346, 366, 388, 411, 435, 461, 489, 518, // 36
549, 581, 616, 652, 691, 732, 776, 822, 871, 923, 978, 1036, // 48
1097, 1163, 1232, 1305, 1383, 1465, 1552, 1644, 1742, 1845, 1955, 2071, // 60
};
// Noten in einem Moll-Arpeggio
uint8_t arp[4] = { 0, 3, 7, 10 };
// Speichern der vorigen Werts des digital Eingangs für den
// Taster; dadurch lassen sich einzelne Tasterdrücke erkennen
int oldButtonPress = HIGH;
void loop() {
int buttonPress = digitalRead(BUTTON1);
// Wurde der Taster betätigt, wird speed ein neuer Wert
// zugewiesen, der einer zufälligen Note in einem Moll-Arpeggio
// entspricht.
if (oldButtonPress == HIGH && buttonPress == LOW) {
speed = freqtable[arp[random(4)] + random(4) * 12];
}
// Speichern des jetzigen Tasterwerts, um beim nächsten
// Durchlauf ein Drücken zu erkennen
oldButtonPress = buttonPress;
}

Anhand der Frequenztabellen können jetzt auch Melodien auf dem


Arduino implementiert werden. Dazu speichert eine Tabelle die
Reihenfolge der Tonhöhen, und eine andere die Länge der Noten.
Es werden nur die Programmzeilen ab uint8_t arp geändert:
// Diese Tabelle speichert die Noten der Melodie.
uint8_t melody[8] = { 12, 15, 17, 12, 24, 27, 12, 19 };
// Diese Tabelle speichert die Länge der Noten.
uint8_t lengths[8] = { 100, 50, 100, 50, 100, 50, 100, 50 };
void loop() {
// Die Hauptroutine läuft durch die Noten und Längentabellen und
// spielt die Noten ab.
for (int i = 0; i < 8; i++) {
// Setzen der Tonhöhe der aktuell gespielten Noten
speed = freqtable[melody[i]];
// Warten für die gespeicherte Länge
delay(lengths[i] * 2);
}
}

Durch Ändern der Werte in den Tabellen lassen sich neue Melodien
schreiben. Das Konzept kann auch weitergeführt werden, um neue
Melodien auf Knopfdruck zu generieren. Besonders interessant ist,
Tonlängen unabhängig von den Tonhöhen zu generieren. Wenn
der Taster gedrückt wird, werden beide Tabellen neu gefüllt, und
eine separate Variable mit der Länge der Tabellen wird neu gesetzt.

Fünfter Sketch: Musikalische Noten 259


Frequenzen, Filter und Tiefpassfilterung
Bis jetzt wurde Klang als eine Folge von Spannun- ersichtlich. Als Faustregel gilt: Je »schärfer« die
gen in der Zeit betrachtet, wodurch man relativ Kanten, desto mehr obere Frequenzen gibt es.
viel über die Lautstärke des Signals aussagen Eine Sinuswelle (weiche Wellenform) hat keine
kann: Je größer die Ausschläge des Signals, desto Obertöne, während eine Rechteckwellenform
höher seine Lautstärke. Aber über die eigentliche viele hat. Deswegen ist auch die vom Arduino bei
Klangfarbe ließ sich relativ wenig aussagen. der Pulsweitenmodulation erzeugte Wellenform
Klänge kann man als schrill oder weich einordnen, sehr obertonlastig; sie klingt sehr »digital«.
blechern oder warm, statisch oder lebendig, und Mit sogenannten Filtern wird der Frequenzinhalt
die meisten dieser Bezeichnungen beziehen sich eines Klangs bearbeitet. Ein Tiefpassfilter schnei-
unmittelbar auf den Frequenzinhalt eines Klangs. det obere Frequenzbereiche ab, während ein
Eine andere Möglichkeit, Klanginformation zu Hochpassfilter nur höhere Frequenzbereiche
betrachten, ist das Frequenzspektrum. Jede Note durchlässt. Der Entkopplungskondensator ist in
aus einem Synthesizer besteht aus einem Grund- diesem Sinne ein Hochpassfilter, der sehr niedrige
ton, der die stärkste Frequenz in dem Ton und (konstante) Frequenzen blockiert. Filter lassen
auch die wahrgenommene Tonhöhe ist. Zusätz- sich sowohl als Programmcode implementieren
lich zu diesem Grundton gibt es eine Reihe von (das nennt man dann generell DSP-Programmie-
Obertönen, die bestimmen, wie der Ton klingt. rung, Digital Signal Processing) als auch als elek-
Der Ton einer Geige hat ein deutlich anderes Fre- tronische Schaltungen, wie man es aus analogen
quenzspektrum als der einer Oboe. Grundsätzlich Synthesizern oder Pedalen für E-Gitarren kennt.
gilt: Je mehr Obertöne, desto härter und metalli- Ein Kondensator und ein Widerstand bilden
scher klingt der Ton. schon einen elektronischen Filter, und in diesem
Diese Darstellungsweise ist auch für Geräusche Kapitel werden zwei davon eingesetzt: der
nützlich. Zum Beispiel umfasst Rauschen alle Entkopplungskondensator und der Tiefpassfilter,
möglichen Frequenzen, sodass kein einzelner Ton der die Obertöne aus dem Arduino wegfiltert.
stärker heraussticht als ein anderer.
Der Tiefpassfilter in der vorgestellten Arduino-
Zusätzlich zu diesen Obertönen ist auch der zeit- Schaltung ist sehr tief gesetzt und filtert die
liche Verlauf der Frequenzinformation sehr wich-
PWM-Rechteckwelle so stark, dass am Ende nur
tig. Eine Gitarre zum Beispiel hat einen recht har-
noch eine konstante Spannung übrig bleibt.
ten Anschlag mit vielen Obertönen, aber nach
Die hohe Geschwindigkeit der eingestellten
diesem kurzen Anschlag ist der eigentliche Klang
PWM ermöglicht es, auch mit einem digitalen
recht warm, d.h. mit weniger Obertönen.
Ausgang schnelle, »runde« Wellenformen wie
Die zeitliche Wellenform des Klangs umfasst auch z.B. Sinuswellen zu erzeugen.
den Frequenzinhalt, nur ist dieser nicht so leicht

Theremin
Der Klang des ursprünglichen Theremins (ein elektronisches
Musikinstrument, das ohne körperliche Berührung gespielt wird)
ähnelt im Vergleich mit klassischen Instrumenten am ehesten einer
Geige und klingt ähnlich wie ein Fuchsschwanz.
Gesteuert wird das Theremin mit den Händen, die zwei kapazitive
Sensoren rechts und links am Gehäuse beeinflussen. Die Form die-

260 Kapitel 11: Musik mit Arduino


ser Antennen ist so ausgeklügelt, dass sich ein nahezu linearer
Zusammenhang zwischen Tonhöhe und Abstand ergibt. Zu der
Zeit der Erfindung des Theremins 1919 waren Mikrocontroller
allerdings noch unbekannt; heute ist es uns möglich, die teilweise
fehlerhaften Sensordaten mithilfe von Software vergleichsweise
leicht zu korrigieren und so einen noch besseren Klang zu erzeugen.

Hardware
Die zwei Antennen des Theremins werden aus zwei ca. 30 bis 40 cm
langen Drähten gebogen und mit den Pins 4 und 5 verbunden.
Zusätzlich wird jeweils ein 10-Mega-Ohm-Widerstand mit der
Antenne und Pin 3 verbunden. Da 10-Mega-Ohm-Widerstände
nicht so leicht zu finden sind, können mehrere 1-Mega-Ohm
Widerstände zusammengelötet werden.

Abbildung 11-5
Theremin-Aufbau

Software
Um das Theremin hörbar zu machen, gibt es verschiedene Mög-
lichkeiten: Die Sensordaten können an den PC gesendet werden

Fünfter Sketch: Musikalische Noten 261


(Kapitel 10), wo z.B. ein Softwaresynthesizer oder Processing Töne
erklingen lässt, oder man schließt direkt einen Kopfhörer an den
Atmel an, wie bei den vorigen Beispielen beschrieben ist.
Als Erstes wird ein stabiler Nullpunkt für Lautstärke und Tonhöhe
benötigt. Da sich die Kapazität der Umwelt ständig ändert, soll sich
dieser Nullpunkt dynamisch anpassen. So ist ein ständiges Nach-
stimmen des Instruments wie beim Original nicht notwendig. Dazu
wird in den Variablen ton_null und volume_null der jeweils kleinste
jemals gemessene Wert gespeichert. Allerdings gibt es immer wie-
der Messfehler. Um diese etwas abzumildern, wird der Nullpunkt
nur um einen Bruchteil verändert, sodass einzelne Ausreißer nicht
in die Summe eingehen.
float volume_null = 0;
float ton_null = 0;
float gew_neg = 0.1;
float gew_pos = 0.0001;
void Adjust_Null(float volume_raw, float ton_raw)
{
if (volume_raw < volume_null) {
volume_null = volume_null * (1-gew_neg) + volume_raw * gew_neg;
}
if (volume_raw > volume_null) {
volume_null = volume_null * (1-gew_pos) + volume_raw * gew_pos;
}
if (ton_raw < ton_null) {
ton_null = ton_null * (1-gew_neg) + ton_raw * gew_neg; }
if (volume_raw > volume_null) {
ton_null = ton_null * (1-gew_pos) + ton_raw * gew_pos;
}
}

Mit den zwei Werten gew_neg und gew_pos kann die Geschwindig-
keit, mit der sich der Nullpunkt an geänderte Bedingungen anpasst,
verändert werden. Dabei ist aber zu beachten, dass gew_pos ziem-
lich klein sein sollte, da sich das Instrument sonst beim Spielen ver-
stimmt.
Die Werte ton_null und volume_null können nun vom Raw-Wert
abgezogen werden: Das Ergebnis ist eine Zahl, die nicht mehr von
der Umgebung abhängig ist. Damit ist aber noch nicht festgelegt,
was der höchste Wert und damit der höchste Ton oder die lauteste
Lautstärke ist. Auch hier kann der gleiche adaptive Algorithmus
verwendet werden, sodass nach dem Einschalten nur einmalig die
Hand bis ganz zum Instrument (aber ohne die Antenne zu berüh-
ren) geführt werden muss, um immer den gleichen Tonumfang zu

262 Kapitel 11: Musik mit Arduino


erhalten. Dazu müssen nur in der Funktion Adjust_Null oben und
unten vertauscht werden.
float volume_max = 0;
float ton_max = 0;
void Adjust_Max(float volume_raw, float ton_raw)
{
if (volume_raw > volume_max) {
volume_max = volume_max * (1-gew_neg) + volume_raw * gew_neg;
}
if (volume_raw < volume_max) {
volume_max = volume_max * (1-gew_pos) + volume_raw * gew_pos;
}
if (ton_raw > ton_max) {
ton_max = ton_max * (1-gew_neg) + ton_raw * gew_neg; }
if (volume_raw < volume_max) {
ton_max = ton_max * (1-gew_pos) + ton_raw * gew_pos;
}
}

Jetzt ist es ein Leichtes, direkt brauchbare Werte zu berechnen. Die


Töne sollen von 0 bis 12 (für eine Oktave) und die Lautstärke von 0
bis 100 skaliert werden.
ton = (ton_raw – ton_null)/(ton_max-ton_null)*12;
volume = (volume_raw – volume_null)/(volume_max-volume_null)*12;

Je nach Laune könnte man die Töne jetzt noch quantisieren, also
auf ganze Zahlen aufrunden, wodurch das Spielen einfacher wird,
man aber auch viel von der Ausdruckskraft des Theremins verliert,
die ja gerade in der Möglichkeit besteht, frei zu spielen.
Wir wollen für das Theremin einen schönen, weichen Sinusklang
erzeugen. Dafür verwenden wir eine Tabelle mit 256 Sinuswerten,
da das Berechnen eines Sinus viel zu lange dauern würde. Abhängig
von der Tonhöhe müssen jetzt Werte aus dieser Tabelle gelesen
und mit PWM ausgegeben werden. Dazu wird ein Zähler benutzt,
der angibt, welches der nächste Wert aus der Tabelle ist. Abhängig
davon, um wie viel dieser Zähler in jedem Durchgang erhöht wird,
entsteht eine andere Tonhöhe.
Würden hier ganze Zahlen verwendet, könnten nur der Grundton
und Vielfache davon erzeugt werden. Ein 16-Bit-Wert kann aber
auch so interpretiert werden, als ob die oberen 8 Bit die Ganzzahl
darstellen und die unteren hinter dem Komma stehen würden.
Wird jetzt z.B. jedes Mal 64 zum Zähler addiert, ändern sich die
oberen 8 Bit erst nach dem vierten Mal. Die oberen 8 Bit geben uns
also an, welcher Wert aus der Sinustabelle verwendet werden soll;
dieser Wert muss nur noch mit der gewünschten Lautstärke multi-
pliziert werden, bevor er ausgegeben wird.

Fünfter Sketch: Musikalische Noten 263


ANHANG A In diesem Kapitel:
• Arduino-Boards
Arduino-Boards und -Shields • Arduino-Shields

Arduino-Boards
Arduino Duemilanove/Diecemila
Der Arduino Duemilanove ist wohl der derzeit am meisten verkaufte
Arduino und kann als das »Standardmodell« angesehen werden. In
diesem Buch wird bei allen Workshops ein Duemilanove eingesetzt.
Er verfügt über 14 digitale Pins, von denen sechs PWM-fähig sind,
sowie sechs Analoge Eingänge. Weiterhin ist auf dem Board ein
USB-Port angebaut, der dem Duemilanove erlaubt, über eine serielle
Verbindung mit einem PC zu kommunizieren. Als Stromquelle dient
entweder der USB-Port oder ein 5-Volt-Netzteil, für das eine Buchse
angebracht ist. Der Duemilanove läuft standardmäßig mit einem
Atmega168- oder Atmega328p-Controller, der auf einem Steckso-
ckel angebracht ist. Eine ausführliche Erläuterung finden Sie unter
[Link]
Der Diecemila (italienisch für 10.000) ist der Vorgänger des Due-
milanove. Die Unterschiede dabei liegen in Details. So muss die
Stromquelle für den Duemilanove nicht mehr per Hand umge-
schaltet werden. Da der Diecemila keinerlei Vorteile bietet, emp-
fiehlt es sich nicht, ihn noch zu kaufen. Wer ein solches Board
besitzt, kann damit aber die Workshops in diesem Buch ebenso
durchführen wie mit einem Duemilanove. Mehr Informationen fin-
den Sie unter [Link]

265
Arduino Mega
Der Arduino Mega hält, was der Name verspricht: Ein Atmega1280
ist in der Lage, 54 digitale Pins zu steuern, von denen 14 PWM-
fähig sind. Er verfügt zudem über 16 analoge Inputs, vier serielle
Ports, 128 KByte Speicher und 8 KByte Arbeitsspeicher. Dieses
Monster kann eingesetzt werden, wenn die Fähigkeiten eines Due-
milanove nicht mehr ausreichen, zum Beispiel bei Installationen
mit vielen LEDs oder Displays oder wenn man mit mehr als einem
Gerät kommunizieren will. Sie sollten dabei die höhere Betriebs-
spannung von 7 bis 12 Volt beachten. Der Arduino Mega ist mit 50
Euro allerdings auch etwa doppelt so teuer wie der Duemilanove.

Arduino Bluetooth
Die besonders edle Variante des Arduino ist der Arduino Blue-
tooth. Er besitzt statt eines USB-Ports einen Bluetooth-Chip, der
mit 115.200 Bit pro Sekunde mit einer Gegenstelle kommunizieren
kann. Das ist zwar für die Entwicklung relativ egal, bietet aber
enorme Vorteile, wenn der Arduino irgendwo im Raum angebracht
werden und dennoch mit einem Rechner kommunizieren soll.
Dank dem Bluetooth-Chip ist diese Variante allerdings so teuer,
wie sie komfortabel ist. Einige Informationen zu diesem nicht sehr
weit verbreiteten Board gibt es unter [Link]
ArduinoBoardBluetooth.

Arduino Pro 5V
Die auf dem Arduino Duemilanove angebrachten Steckverbindun-
gen sind zwar praktisch, können aber auch hinderlich sein, wenn
man zum Beispiel Drähte anlöten oder den Arduino in einem
Gehäuse verbauen möchte, das möglichst dünn sein soll. Der Ardu-
ino Pro kommt in zwei Varianten (3,3 Volt und 5 Volt) daher und
ist im Prinzip ein »nacktes« Arduino-Board. Der Atmega168 ist fest
verlötet, die Pins sind nur als Kontaktstellen auf dem Board verfüg-
bar. Das macht den Arduino Pro auch um etwa ein Drittel günstiger
als den Duemilanove. Wer also professionellere Ansprüche hat und
auf Luxus verzichten kann, mag mit einem Pro gut beraten sein.
Einsteigern empfehlen wir trotzdem den Duemilanove. Mehr Infor-
mationen zum Arduino Pro finden Sie unter [Link]
Main/ArduinoBoardPro.

266 Anhang A: Arduino-Boards und -Shields


Arduino LilyPad
Das Lilypad ist speziell dafür ausgelegt, in Kleidung eingebettet zu
werden. Es ist mit etwa 5 cm Durchmesser und nur 3 mm Dicke
sehr klein und verfügt über keine Pins oder Teile, welche die umge-
bende Kleidung zerreißen könnten. Trotzdem verfügt das Board
über 14 digitale (sechsmal PWM) und sechs analoge Pins. Mit 2,7–
5,5 Volt Betriebsspannung ist es zudem geeignet, um mit kleinen
Batterien betrieben zu werden. Das ist gerade bei Kleidung immens
wichtig, weil niemand einen oder gar mehrere 9-Volt-Blöcke mit
sich herumtragen möchte. Das LilyPad ist auf der Website des MIT
Medialab genauer beschrieben, von dem es entwickelt wurde (http://
[Link]/~leah/LilyPad/).

Arduino Nano und Mini


Neben dem LilyPad gibt es weitere Boards, die für kleinere und
kleinste Anwendungen geeignet sind: Beim Arduino Nano und
dem Arduino Mini ist die Fläche des Boards minimiert: Der Nano
ist 1,85 x 4,31 cm klein, der Mini sogar nur 1,8 x 3,3 cm. Dabei ver-
fügen beide über dieselbe Anzahl digitaler Pins wie ihre großen Brü-
der und zusätzlich sogar über zwei analoge Pins mehr. Was beim
Nano fehlt, ist ein zusätzlicher Stromanschluss, sodass er über den
USB-Port betrieben werden muss. Der Mini verfügt sogar nur über
einen seriellen Anschluss: Wer ihn also mit USB betreiben möchte,
benötigt einen Adapter. Die Minivariante ist auch als Pro-Version
(mit 3,3 und 5 Volt Betriebsspannung) verfügbar, um Arduino-Pro-
jekte zu ermöglichen, die noch kleiner sind und deren Board sich
noch besser einfügt.

Weitere Boards
Die Menge der Arduino-Varianten ist riesig, wächst stetig und kann
kaum erfasst werden. Die Änderungen reichen dabei von einfachen
Layoutabweichungen und anderen Mikrocontroller-Varianten bis
hin zu Boards, die für spezielle Einsatzgebiete wie etwa die Robotik
angepasst sind.
Der Sanguino ([Link] wurde zum Beispiel entwi-
ckelt, um den RepRap anzutreiben, einen 3-D-Drucker. Ursprüng-
lich hatte man dafür einen Arduino verwendet, musste dabei aber
Kompromisse eingehen. Der Sanguino verwendet 32 digitale Pins

Arduino-Boards 267
und hat seine eigene Bauform, die etwas kompakter und in die
Länge gezogen ist.
Mit dem Roboduino ([Link]
ino) soll es leicht möglich sein, die Motoren und anderen Bauteile
von Robotern anzusteuern. Dafür verfügt das Board neben jedem
digitalen Pin noch über zwei Pins für einen weiteren Stromkreis.
Das soll vor allem das Anbringen erleichtern, da nun die anderen
Bauteile über einfache Steckverbindungen angebunden werden
können.
Weil der Arduino Duemilanove gerade für viele LEDs oder Matri-
zen nicht ausreicht, wurde der Illuminato ([Link]
com/shop/show/ILL/Illuminato) entwickelt. Er soll verhindern, dass
jeder Pin auf dem Arduino extra mit Erweiterungsbauteilen gega-
belt werden muss. Der Illuminato verfügt daher über 42 digitale
Pins. Der Arduino Fio ist mit anderen Arduino-Boards vergleich-
bar, verfügt aber neben 8 analogen und 14 digitalen Pins auch
zusätzlich über einen Xbee-Socket.
Weil sein Erfinder es leid war, sich mit den Steckverbindungen
eines Arduino herumzuärgern, schuf er den Boarduino, dessen
Bauform so entworfen ist, dass er genau auf ein Steckbrett passt.
Das macht natürlich das Entwickeln von Prototypen besonders
einfach. Mehr dazu finden Sie unter [Link]
[Link]?main_page=product_info&cPath=19&products_id=72,
wo es auch eine USB-Variante des Boards zu kaufen gibt.
Der Ardupilot wurde entwickelt, um alle wichtigen Funktionen
einer autonomen Flugdrohne wahrnehmen zu können. Dieses
spezielle Board hat deshalb Pins für Beschleunigungssensoren und
ein GPS-Modul sowie die Kontrolle von Servos. Zudem besitzt
das Board einen zweiten Stromkreis, der beim Ausfall des ersten
aktiv wird. Das verhindert das Abstürzen des Flugobjektes. Mehr
dazu finden Sie unter [Link]
705844%3ABlogPost%3A44814.
Wie in Kapitel 10 ausführlich erklärt wurde, eignet sich der Arduino
auch zur Verwendung als Midi-Controller. Über eine entsprechende
Steckverbindung kann er an Midi-Geräten angebracht werden, um
beispielsweise Ton über besondere Eingabemethoden zu steuern.
Der Miduino wurde dafür geschaffen, mit genau diesen Midi-Buch-
sen zu arbeiten. Sie können ihn unter [Link]
miduino/[Link] bestellen, wo auch die Schaltpläne und eine
genaue Dokumentation verfügbar sind.

268 Anhang A: Arduino-Boards und -Shields


Sieht der Protoduino auf den ersten Blick heillos komplex aus,
besteht er doch lediglich aus einer Leiterplatte, auf der nur die
nötigsten Leiterbahnen miteinander verbunden sind, um einen
Mikrocontroller, Stromversorgung und einen 16-MHz-Taktgeber
anzubringen. Zudem verfügt er über ein Netzwerk von Widerstän-
den für den schnellen Betrieb von LEDs. Der Protoduino ist vor
allem dann geeignet, wenn man ein eigenes Board entwerfen und
zunächst ausprobieren möchte. Dazu muss man Leiterbahnen
selbstständig auflöten, hat aber maximale Freiheit in dem, was man
tun möchte. Mehr Informationen dazu finden Sie unter [Link]
[Link]/[Link].

Arduino-Shields
Möchte man viele Sensoren oder Aktoren an den Arduino anschlie-
ßen, kann das zu komplexen Schaltungen führen, die möglicher-
weise auch nicht ganz stabil angebracht werden können. Dafür gibt
es viele verschiedene sogenannte Shields, die auf die Pins des Ardu-
ino aufgesteckt werden können. Einige gängige Shields sollen hier
kurz vorgestellt werden. Jeder Absatz enthält auch einen Link zu
weiteren Informationen über den entsprechenden Shield. Viele
davon sind leider nur als Import erhältlich, allerdings sollten Sie
auch die deutschen Websites wie [Link] oder http://
[Link] im Auge behalten. Zudem werden auch bei her-
kömmlichen Elektronik-Webshops wie [Link] oder
[Link] Shields angeboten.

Prototypen-Shields
Was der Protoduino für das Arduino-Board, ist der Arduino Proto
Shield für die passenden Aufsätze: eine Platine, auf der lediglich
die Pins des Arduino sowie zwei LEDs, der Reset-Knopf und ICSP-
Header aufgebracht sind. Er kann zum Entwickeln von weiteren
Shields verwendet werden und zum Beispiel ein Steckbrett ein-
fassen. Das Shield ist unter [Link]
beschrieben.
Ähnlich verhält sich das Breadboard-Shield, auf dem bereits ein
Steckbrett angebracht ist. Er ist deshalb nicht so flexibel wie der
Proto Shield, aber er ist ja auch nur zum schnellen Ausprobieren
und nicht zum Entwickeln gedacht ([Link]
07/11/arduino-breadboard-shield/)

Arduino-Shields 269
Arduino RepRap Shield
Das RepRap ist ein Gestell, das unter anderem als 3-D-Drucker ver-
wendet werden kann. Um die nötigen Motoren, Düsen und ande-
ren Teile anzuschließen, wurde der RepRap-Shield entwickelt. Er
bietet robuste Schraubanschlüsse für den Arduino Duemilanove
und ist deshalb auch für andere Anwendungen geeignet. Mehr
Informationen bietet das Blog des RepRap, das Sie unter [Link]
[Link]/2008/04/[Link] finden.

Propellurino
Der Propellurino steuert nicht etwa ausschließlich Propeller, wie
der Name vielleicht vermuten lässt. Vielmehr verfügt er zusätzlich
über Anschlüsse für einen VGA-Monitor, eine PS/2-Maus oder PS/
2-Tastatur, Midi und ein Mikrofon. Zudem hat er zwei DAC-Aus-
gänge, um Ton auszugeben. Bastelanleitungen und andere Infor-
mationen finden Sie auf der deutschen Website [Link]
[Link]/forum/[Link]?f=5&t=72.

Battery Shield
Möchte man den Arduino autonom betreiben, also ohne externe
Stromquelle, kann man den Battery Shield verwenden. Er repliziert
alle Pins des Arduino und hat in der Mitte eine Halterung für einen
Lithium-Ionen-Akku. Je nach Akkutyp kann das Projekt dann viele
Stunden betrieben werden, bevor es neu aufgeladen werden muss,
was über den USB-Port möglich ist. Dieser Shield ist in Deutsch-
land leider nicht erhältlich, kann aber aus den USA von liquidware.
com bezogen werden ([Link]
BP/Lithium+BackPack).

Adafruit Ethernet Shield


Diese Ethernet-Shield wurde bereits recht ausführlich in Kapitel 6
erklärt: Er bietet die Möglichkeit, ein Netzwerkkabel anzuschließen
und so den Arduino mit dem Internet oder einem Heimnetzwerk zu
verbinden. Im Handel sind mehrere Ethernet-Shields erhältlich,
zum Beispiel das von [Link]. Diese Shields sind weit verbrei-
tet, sodass man sie auch in Deutschland leicht bestellen kann. Eine
genauere Beschreibung finden Sie unter [Link]
make/eshield/.

270 Anhang A: Arduino-Boards und -Shields


Liquidware TouchShield
Auf dem TouchShield ([Link]
TouchShield+Stealth) ist ein Touchscreen mit 128 x 128 Pixeln
angebracht, dessen Eingabedaten vom Arduino verwendet werden
können. Auch der Monitor wird vom Arduino gesteuert, wobei ent-
sprechende Bibliotheken für eine einfache Ansteuerung sorgen.
Dieser Shield ist mit 140 US-Dollar teuer, was an den sehr vielfälti-
gen Möglichkeiten liegt, die er bietet.

Drahtlose Kommunikation
Neben Bluetooth, für das man am besten einen Arduino Bluetooth
verwendet, gibt es noch weitere drahtlose Übertragungsprotokolle.
WLAN ist allerdings für die meisten Zwecke übertrieben, komplex
und ein Stromfresser. Zigbee hingegen wird in vielen Projekten ein-
gesetzt, weil es einfach ist und eine gute Reichweite hat. Dieses
Protokoll wurde ursprünglich entwickelt, um Haushaltsgeräte zu
steuern und Sensordaten zu übermitteln. Der Xbee-Shield bringt
dieses Protokoll auf den Arduino und kann zum Beispiel verwen-
det werden, um Roboter oder Fluggeräte zu bedienen. Mehr Infor-
mationen darüber gibt es unter [Link]
Shields/Xbee01.
Die Radio Frequency Identification, kurz RFID, findet ihren Weg in
immer mehr Bereiche. Ein Lesegerät sendet dabei elektromagneti-
sche Frequenzen aus, die einen stromlosen Schaltkreis anregen.
Dieser emittiert dann darin gespeicherte Daten, um sich zu identifi-
zieren. Je nach Bauart können so über mehrere Meter oder wenige
Zentimeter einige Kilobytes an Informationen übermittelt werden.
Marc Boon bietet auf seiner Website einen entsprechenden Shield
an, den man auch selbst herstellen kann, wenn man möchte. Alle
Informationen dazu finden Sie unter [Link]
category2.

Musik-Shields
Mit dem Wave Shield (ebenfalls von [Link]) können Sound-
dateien abgespielt werden. Tonausgabe auf dem Arduino ist recht
kompliziert und begrenzt. Der Shield bietet Platz für eine SD-Karte,
auf der unkomprimierte Wave-Dateien (also keine MP3s und ähnli-
che Formate) gespeichert werden können. Ein Soundchip sorgt für
eine qualitativ hochwertige Ausgabe auf dem ebenfalls angebrach-

Arduino-Shields 271
ten Kopfhöreranschluss. Mehr über den Wave Shield finden Sie
unter [Link]
Eine weitere Möglichkeit, Musik zu machen, ist der SID-Chip, der
schon dem Commodore 64 8-Bit-Klänge entlockte. Er ist immer
noch sehr beliebt, weil er einen ganz eigenen Klang produziert, statt
reale Musikinstrumente nachzuahmen. Im auf der Arduino-Web-
site beschriebenen SID-Shield ([Link]
Main/SID-emulator) arbeitet ein Atmega168-Mikrocontroller, der
diesen SID-Chip emuliert und von einem Arduino gesteuert wird.
Der Arduinome ist kein Shield im eigentlichen Sinne, da er nicht für
weitere Projekte verwendbar ist. Vielmehr wird er auf den Arduino
aufgesteckt, um ein Monome zu emulieren, einen USB-Midi-Cont-
roller, der auf einer Matrix von Tasten basiert, die jeweils mit einer
LED beleuchtet werden. Der Arduinome kann so an einen PC ange-
schlossen werden, um diese Eingabedaten zu verarbeiten, oder er
erzeugt selbst weiteren Output. Das Arduinome-Projekt finden Sie
unter [Link]

Adafruit GPS Shield


Der GPS-Shield bietet die Möglichkeit, ein GPS-Modul zu montie-
ren und die ermittelten Positionsdaten auf einer SD-Karte zu spei-
chern. So lässt sich mit dem Arduino ein kompaktes Gerät
entwickeln, das den Weg einer Wanderung oder einer Fahrt durch
die Stadt speichert. Diese Daten können beispielsweise für das
Projekt OpenStreetMap ([Link] verwendet
werden, das zum Ziel hat, eine frei verfügbare Datenbank mit
Landkarten zur Verfügung zu stellen und so eine freie Alternative
zu kommerziellen Anbietern wie Google Maps zu liefern. Mehr
Informationen zu dem Shield finden Sie auf der LadyAda-Website
([Link]

MicroSD Module
Der Speicher des Arduino ist vergleichsweise klein und eignet
sich kaum dazu, über einen längeren Zeitraum Werte aufzu-
zeichnen. Glücklicherweise gibt es auch dafür eine Lösung: das
MicroSD-Modul ([Link]
=0827727742), das eine MicroSD-Karte fassen und beschreiben
kann. Die kann man dann später über den Arduino oder einen
Kartenleser auslesen.

272 Anhang A: Arduino-Boards und -Shields


DMX-shield
DMX ist ein Bussystem, mit dem in der Lichttechnik Lampen ange-
steuert werden. Es wird zum Beispiel bei Konzerten und in Disko-
theken eingesetzt, um von einem Mischpult aus die Beleuchtung
des Raumes oder der Bühne zu steuern. DMX steht für Digital Mul-
tiplex. Möchte man sein eigenes Mischpult oder andere Ansteue-
rungsmöglichkeiten (zum Beispiel über Sensoren) entwickeln, kann
man auf den DMX-shield zurückgreifen. Das Shield wird unter
anderem in Kapitel 8 beschrieben. Weitere Informationen finden
sich auf der Arduino-Website unter [Link]
ground/DMX/DMXShield.

Eingabe-Shields
Eingabesensoren wie Schieberegler oder Joysticks benötigen keine
komplexe Programmierung. Passende Shields bieten vor allem Fas-
sungen, um eine möglichst einfache Montage zu erlauben. Der
Danger Shield von Zach Hoeken ([Link] [Link]/dan-
ger-shield-v1-0) ist so einer und verfügt unter anderem über drei
Schieberegler und drei Taster. Zudem hat er allerlei andere Senso-
ren (z.B. einen Temperatur- und einen Klopfsensor) und Aktoren
(wie ein Siebensegment-Display und einen Piezo-Lautsprecher). Er
ist also quasi ein Allround-Shield, der für viele verschiedene Ardu-
ino-Projekte verwendet werden kann.
Ein anderer Shield ist der InputShield von LiquidWare ([Link]
[Link]/shop/show/INPT/InputShield). Er eignet sich zum
Beispiel dazu, einen Controller für eine Spielkonsole zu bauen, und
verfügt über einen Joystick, zwei Knöpfe, einen Vibrationsmotor
und ein serielles Interface. Damit kann man zum Beispiel eine
kleine Handheld-Konsole bauen, deren Vorbild der Game Boy von
Nintendo ist.

Motoren und Rotoren


Der Tank Shield von Liquidware ([Link]
show/TANK/TankShield) ist mehr als nur ein Shield. Er verfügt über
einen Kettenantrieb, mit dem man aus dem Arduino einen Panzer-
Roboter bauen kann. Dazu verfügt er über zwei Motorenantriebe
und eine steuerbare Achse. Dank seinem Design ist er in der Lage,
nicht nur einen Arduino, sondern auch einige weitere Shields mit
sich zu führen.

Arduino-Shields 273
Der Adafruit Motor Shield erlaubt den Anschluss mehrerer Moto-
ren. So enthält er Anschlüsse für zwei 5-Volt-Servos, vier Gleich-
strommotoren oder zwei Schrittmotoren. Mehr Informationen gibt
es unter [Link]

274 Anhang A: Arduino-Boards und -Shields


ANHANG B In diesem Kapitel:
• EEPROM-Bibliothek:
Arduino-Bibliotheken Werte langfristig speichern
• Ethernet-Bibliothek: mit dem
Internet kommunizieren
• Firmata-Bibliothek
• LiquidCrystal-Bibliothek
• Servo-Bibliothek
• Debounce-Bibliothek
• Wire-Bibliothek
• capSense-Bibliothek

Die Arduino-Umgebung bringt eine ganze Reihe nützlicher Biblio-


theken (libraries) mit, die hier kurz vorgestellt werden. Weiterhin
haben viele Benutzer von Arduino selbst Bibliotheken geschrieben
und online gestellt. Diese Libraries bieten oft eine angenehme und
einfache Programmieroberfläche für spezielle Bauteile, Sensoren
und Aktoren sowie für spezifische Arduino-Shields. Eine Liste der
verschiedenen Arduino-Bibliotheken können Sie auf der Arduino-
Website unter [Link] finden.
Eine Arduino-Bibliothek besteht aus einer Sammlung von C- und
C++-Quellcodedateien, die in einem separaten Verzeichnis gespei-
chert werden. Eine dieser Dateien ist eine sogenannte Header-
Datei, die nicht die Funktionalität und den Quellcode an sich ent-
hält, sondern die Oberfläche beschreibt, die der Benutzer der Bibli-
othek in seinem eigenen Programm aufrufen kann. Eine solche
Oberfläche nennt man oft auch API (application programming
interface).
Bibliotheken werden meistens als Archivdatei im Netz zum Her-
unterladen angeboten. Diese Datei enthält ein Verzeichnis, das wie
die Bibliothek heißt und in den Ordner hardware/libraries der Ardu-
ino-Entwicklungsumgebung kopiert wird. Anschließend muss die
Header-Datei der Bibliothek in einen Sketch eingebunden werden,
indem am Anfang der Sketch-Datei die Zeile #include <headerdatei.h>
geschrieben wird. Die Arduino-Programmierumgebung erkennt
diese Zeile, sucht nach der genannten Datei in ihrem Bibliotheks-
ordner und übersetzt die Dateien der Bibliothek zusammen mit den
restlichen Dateien des Sketches. Wenn die Arduino-Umgebung
gestartet wird, indiziert diese die verfügbaren Bibliotheken und bie-
tet sie unter SKETCH → IMPORT LIBRARIES an. Wenn dort eine Bibli-

275
othek ausgewählt wird, ergänzt die Entwicklungsumgebung den
aktuellen Sketch automatisch um die Zeile #include.
Für fortgeschrittene Benutzer wird auf der Arduino-Website unter
[Link] im Detail erklärt, wie
man eine eigene Bibliothek erstellt.

EEPROM-Bibliothek:
Werte langfristig speichern
Wie in Kapitel 6 beschrieben wird, kann der Arduino-Prozessor
Werte langfristig in seinem internen EEPROM-Speicher festhalten.
Um Werte aus dem EEPROM zu lesen und zu speichern, bietet
Arduino die EEPROM-Bibliothek. Sie muss mit der Zeile #include
<EEPROM.h> eingebunden werden.

[Link](adress)
Mit dieser Funktion kann ein Byte an der angegebenen Adresse aus
dem EEPROM-Speicher gelesen werden. Mögliche Adresswerte
gehen von 0 bis 511. Werte, die noch nie beschrieben worden sind,
sind im Arduino-Prozessor auf 255 initialisiert. Man sollte im Auge
behalten, dass die geschriebenen Werte auch nach dem Ausstecken
des Arduino erhalten bleiben, im Speicher also durchaus noch
Werte von anderen Programmen stehen können.

[Link](adress, value)
Mit dieser Funktion kann ein Bytewert an der angegebenen Adresse
in den EEPROM-Speicher geschrieben werden. Auch hier sollte
man bedenken, dass die Adresse vielleicht auch von einem anderen
Sketch verwendet wird, um Daten zu speichern. Gehen Sie beim
Schreiben also vorsichtig vor, wenn noch gespeicherte Daten von
anderen Sketchen verwendet werden sollen.
Beispiel
void setup() {
[Link](9600);
[Link](0, 15); // 15 an Adresse 0 des EEPROM-Speichers
// schreiben
byte daten = [Link](0); // Adresse 0 lesen
[Link](daten); // und an den Computer schicken
}
void loop() {
}

276 Anhang B: Arduino-Bibliotheken


Ethernet-Bibliothek:
mit dem Internet kommunizieren
Die Ethernet-Bibliothek wird zusammen mit einem Ethernet-Shield
eingesetzt. Sie implementiert zum einen eine einfache Serverfunktio-
nalität, die es einem Arduino ermöglicht, verschiedene Serverdienste
wie z.B. einen Webserver oder einen Telnet-Server anzubieten, und
zum anderen eine Clientfunktionalität, mit der der Arduino mit
anderen Servern im Internet kommunizieren kann. Die Ethernet-
Bibliothek ist deswegen in einen Server- und einen Clientteil unter-
gliedert. Bevor einer dieser beiden Bereiche verwendet werden kann,
muss die Bibliothek initialisiert werden.

[Link](mac, ip) / [Link](mac, ip, gateway) /


[Link](mac, ip, gateway, subnet)
Mit dieser Funktion werden der Ethernet-Chip auf dem Ethernet-
Shield initialisiert und die Ethernet-Adresse und die IP-Adresse des
Arduino festgelegt. Diese Funktion muss aufgerufen werden, bevor
die Server- und/oder die Client-Funktionalität der Ethernet-Library
verwendet wird. Zusätzlich können der IP-Funktion der Ethernet-
Bibliothek noch die Adresse der Default-Gateway angegeben wer-
den (also des Routers, der die Schnittstelle des lokalen Netzwerks
zum Internet ist, z.B. der Router, der vom Provider zur Verfügung
gestellt wird) sowie die Netzmaske des lokalen Netzwerks. Stan-
dardmäßig wird die Gateway-Adresse auf die IP-Adresse des Ardu-
ino gesetzt, mit einer 1 als letzter Zahl. Die Default-Netzwerkmaske
ist [Link]. Die Mac-Adresse ist eine Tabelle von sechs
Bytes, während die IP-Adresse und die Gateway-Adresse jeweils
eine Tabelle von vier Bytes sind.
Beispiel
#include <Ethernet.h>
byte mac[] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
byte ip[] = {10, 0, 0, 27};
void setup() {
[Link](mac, ip);
}
void loop() {}

Serverfunktionalität
Mit der Serverfunktionalität der Ethernet-Bibliothek kann der
Arduino einen Internetdienst anbieten. Dieser wird mit durch ein

Ethernet-Bibliothek: mit dem Internet kommunizieren 277


Serverobjekt erstellt, dem der Port mitgegeben wird, auf dem dieser
Dienst lauscht. Dieses Serverobjekt kann dann benutzt werden, um
Verbindungen anzunehmen und Daten von verbundenen Clients
zu lesen und zu schreiben.

Server(port)
Mit dieser Funktion wird ein Serverobjekt erzeugt, das auf dem
angegebenem Port lauscht. Standardwerte für port sind z.B. 23 für
einen Telnetdienst, 25 für einen Mailserver, und 80 für einen Web-
server.

[Link]()
Nachdem [Link]() aufgerufen wurde, kann ein Serverobjekt
Verbindungen annehmen.

[Link]()
Diese Funktion überprüft, ob ein Serverobjekt eine Verbindung
angenommen hat. Wenn das der Fall ist, gibt sie ein Clientobjekt
zurück, das benutzt werden kann, um mit dem Gegenpunkt der
Verbindung zu kommunizieren. Es besteht kein Unterschied zwi-
schen einem Clientobjekt, das als Folge einer Serververbindung
erzeugt wurde, und einem Clientobjekt, das erzeugt wurde, weil
der Arduino sich mit einem Server verbunden hat (siehe unten).
Wenn keine Verbindung angenommen wurde, gibt [Link]-
lable() NULL zurück.

[Link](data)
Mit dieser Funktion können Daten an alle verbundenen Gegenstel-
len des Serverobjekts geschrieben werden. data ist dabei ein Byte
oder ein Buchstabe.

[Link](value) / [Link](value, base)


Mit dieser Funktion können ähnlich wie mit [Link] (siehe
Kapitel 5) beliebige Werte formatiert an alle verbundenen Gegen-
stellen gesendet werden. value kann dabei wie bei [Link] ein
beliebiger numerischer Wert sein (allerdings keine Fließkomma-
zahl) oder ein Zeichenkette. Zusätzlich kann auch noch die Darstel-
lungsbasis angegeben werden.

278 Anhang B: Arduino-Bibliotheken


[Link](value) / [Link](value, base)
Mit dieser Funktion können ähnlich wie mit [Link] (siehe
Kapitel 5) beliebige Werte formatiert an alle verbundenen Gegen-
stellen gesendet werden. Der gesendete Wert wird von einer Zeilen-
einrückung gefolgt.
Beispiel
#include <Ethernet.h>
byte mac[] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
byte ip[] = {10, 0, 0, 27};
Server server(23);
void setup() {
[Link](mac, ip);
[Link]();
}
void loop() {
Client client = [Link]();
if (client) {
[Link]([Link]());
}
}

Clientfunktionalität
Mit der Clientfunktionalität der Ethernet-Bibliothek kann der
Arduino sich mit einem Internetdienst verbinden. Weiterhin wird
die Clientfunktionalität verwendet, wenn eine externe Gegenstelle
sich mit einem Server verbindet, der auf dem Arduino läuft. Man
kann daher die Clientfunktionalität auch als »Verbindungsfunktio-
nalität« betrachten. Eine Verbindung wird als ein Clientobjekt dar-
gestellt, das entweder von Hand erzeugt wird, um mit einem
externen Server zu kommunizieren (in diesem Fall werden Adresse
und Port des Dienstes auf diesem Server angegeben), oder beim
Aufruf von [Link]() (siehe oben).
Nachdem der Arduino sich erfolgreich mit der Gegenseite verbun-
den hat (über einen Aufruf von [Link]() oder weil das Cli-
entobjekt von einem auf dem Arduino laufenden Server erzeugt
wurde), können mit dem Clientobjekt Daten an die Gegenstelle
geschickt und von ihr empfangen werden.

Client(ip, port)
Mit dieser Funktion wird ein Clientobjekt erzeugt, das mit dem
angegebenen Dienst verbunden wird. Die IP-Adresse wird wie
gehabt als Tabelle von vier Bytes angegeben, und der Port als Inte-
ger-Wert.

Ethernet-Bibliothek: mit dem Internet kommunizieren 279


[Link]()
Diese Funktion gibt zurück, ob das benutzte Clientobjekt mit der
Gegenstelle verbunden ist (also TRUE, wenn eine laufende TCP-IP
Verbindung besteht, sonst FALSE). Diese Funktion gibt auch
TRUE zurück, wenn die Verbindung schon geschlossen wurde,
aber noch ungelesene Daten existieren.

[Link]()
Wenn diese Funktion aufgerufen wird, versucht der Ethernet-
Shield sich mit der Gegenstelle zu verbinden. Gelingt das, gibt die
Funktion TRUE zurück, kann keine Verbindung erstellt werden,
FALSE.

[Link](data)
Mit dieser Funktion können Daten an alle verbundenen Gegenstel-
len des Clientobjekts geschrieben werden. data ist dabei ein Byte
oder ein Buchstabe.

[Link](value), [Link](value, base)


Diese Funktion ähnelt [Link](), außer dass Daten nur an die
Gegenstelle der Verbindung geschickt werden.

[Link](value), [Link](value, base)


Diese Funktion ähnelt [Link](), außer dass Daten nur an
die Gegenstelle der Verbindung geschickt werden.

[Link]()
Ähnlich wie bei der seriellen Schnittstelle werden bei einer TCP-
Verbindung die empfangenen Daten auf dem Arduino gepuffert.
Mit dieser Funktion kann abgefragt werden, ob sich Daten in die-
sem Zwischenpuffer befinden, die dann später mit [Link]()
ausgelesen werden können. Diese Funktion gibt die Anzahl der vor-
handenen Bytes zurück.

[Link]()
Mit dieser Funktion kann ein einzelnes Byte aus dem Puffer ausge-
lesen werden. Mit [Link]() kann zuerst überprüft wer-
den, ob überhaupt Bytes im Puffer vorhanden sind. Sind keine
Bytes vorhanden, gibt [Link]() –1 zurück.

280 Anhang B: Arduino-Bibliotheken


[Link]()
Mit dieser Funktion kann der Puffer der Verbindung geleert werden
(es werden also alle ungelesenen Bytes gelöscht).

[Link]()
Mit dieser Funktion wird die TCP-Verbindung mit der Gegenstelle
getrennt.
Beispiel
#include <Ethernet.h>
byte mac[] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
byte ip[] = {10, 0, 0, 27};
byte server[] = {64, 233, 187, 99 }; // Google
Client client(server, 80); // Verbindung zum Google-Webserver
void setup() {
[Link](mac, ip);
[Link](9600);
[Link]();
if ([Link]()) {
[Link](»Mit google verbunden");
[Link]("GET /search?q=arduino HTTP/1.0"); // Suchkette
// verschicken
[Link]();
} else {
[Link]("Verbindung erfolglos");
}
}
void loop() {
if ([Link]()) {
char c = [Link]();
[Link](c);
}
if (![Link]()) {
[Link]("Verbindung getrennt");
[Link]();
for (;;) ; // Leere Schleife
}
}

Firmata-Bibliothek
Die in Kapitel 5 vorgestellte Firmata-Bibliothek ist ein nützliches
Werkzeug, um einen Arduino mit einem normalen Desktopcompu-
ter zu verbinden (unter anderem mit Programmen, die in Proces-
sing oder Max/MSP geschrieben sind). Mit Firmata können über
die serielle Schnittstelle viele Befehle an den Arduino gesendet und
Informationen vom Arduino empfangen werden (z.B. der Status

Firmata-Bibliothek 281
einzelner Pins, aber auch beliebige Zeichenketten und numerische
Werte). Die Bibliothek ist eine sehr große und etwas komplexe
Bibliothek, mit der die Firmata-Funktionalität in normale Sketche
mit eingebunden werden kann (im Vergleich zur »normalen«
Firmata-Firmware, die nur die Standardfunktionalität des Proto-
kolls unterstützt). Hier sei auf die ausführliche Dokumentation
des Firmata-Protokolls und der Firmata-Bibliothek im Netz ver-
wiesen, die viele nützliche Beispiele über ihre Verwendung gibt. Die
Dokumentation finden Sie unter [Link]
Interfacing/Firmata.

LiquidCrystal-Bibliothek
Mit der Bibliothek LiquidCrystal kann ein LCD-Bildschirm, der
auf einem Hitachi HD44780 oder einem seiner zahlreichen Klone
aufgebaut ist, angesprochen werden. Es gibt viele verschiedene
Varianten dieser LCD-Bildschirme, die kostengünstig bei Vertrie-
ben wie [Link] [Link] oder [Link]
bestellt werden können. Diese LCD-Bildschirme können Buchsta-
ben anzeigen und haben meistens Größen wie 2 × 16 (zwei Zeilen
mit je 16 Buchstaben), 1 × 16, 2 × 40, 4 × 16 usw. Da es viele
HD44780-kompatible Chips gibt, kann es oft zu leichten Unter-
schieden zwischen den einzelnen Displays kommen. Oft sind
gerade kleine Zeitunterschiede bei der Initialisierung oder beim
Senden von Daten wichtig, weshalb manchmal eine Anpassung der
Sketche notwendig ist. Um die genauen Zeiten herauszube-
kommen, müssen Sie im Datenblatt des Chips nachsehen, wie
lange z.B. Daten anliegen müssen oder wie lange nach bestimmten
Kommandos gewartet werden muss. Diese Zeiten kann man dann
mit delayMicroseconds() einbauen. Auch die Pinbelegung der Dis-
plays kann verschieden sein, besonders der Anschluss der Rückbe-
leuchtung variiert. Oft ist es notwendig, die Rückbeleuchtung über
einen Transistor zur Stromverstärkung anzuschließen.
Displays können in zwei verschiedenen Modi angesteuert werden:
im 4-Bit-Modus oder im 8-Bit-Modus. Beim 8-Bit-Anschluss wer-
den zwar mehr digitale Output-Pins am Arduino benutzt, die
Datenübertragung ist dafür aber deutlich schneller, sodass zum Bei-
spiel flüssigere Animationen auf dem Display dargestellt werden
können. Im 4-Bit-Modus werden vier Datenleitungen (d0 bis d3)
weniger benutzt.

282 Anhang B: Arduino-Bibliotheken


LiquidCrystal(rs, rw, enable, d4, d5, d6, d7) /
LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
Mit dieser Funktion, die eine variable Anzahl an Parametern akzep-
tiert, wird ein LiquidCrystal-Objekt erzeugt, mit dem ein Display
gesteuert werden kann. Die einzelnen Leitungen des Displays müs-
sen mit digitalen Pins am Arduino verbunden werden. Die Pinnum-
mern der einzelnen Leitungen werden an die LiquidCrystal-
Funktion übergeben. Werden d0 bis d3 angegeben, wird das Dis-
play im 8-Bit-Modus konfiguriert, ansonsten im 4-Bit-Modus. Mit
dem erzeugten Objekt kann das Display dann angesteuert werden.

[Link]()
Mit dieser Funktion werden das LCD-Display gelöscht und der
Kursor nach links oben zurückgesetzt.

[Link]()
Mit dieser Funktion wird der Kursor des LCD-Displays in die linke
obere Ecke bewegt. Ab dieser Position werden dann weitere Ausga-
ben auf dem Display angezeigt.

[Link](col, row)
Mit dieser Funktion kann der Kursor frei auf dem LCD-Display
bewegt werden. col bezeichnet dabei die Spalte und row die Zeile,
in die der Kursor bewegt werden soll. 0 ist dabei die erste Spalte
bzw. Zeile.

[Link](data)
Mit dieser Funktion kann ein einzelner Buchstabe auf dem Display
angezeigt werden.

[Link](value), [Link](value, base)


Ähnlich wie bei der Funktion [Link]() können mit Liquid-
[Link]() Zeichenketten und numerische Werte auf dem
Display angezeigt werden.
Beispiel
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); // LCD im 4-Bit-Modus
void setup() {
[Link]("HALLO WELT");
}
void loop() {}

LiquidCrystal-Bibliothek 283
Servo-Bibliothek
Mit dieser Bibliothek können ein oder zwei Servomotoren an den
Arduino angeschlossen und gesteuert werden, ohne dass anderer
Programmcode dadurch beeinflusst wird (die Steuerung läuft paral-
lel in einer Interrupt-Routine). Dazu werden die zwei PWM-Pins 9
und 10 benutzt. Wird nur ein Servo angeschlossen, kann der
andere Pin nicht als PWM-Ausgang benutzt werden (man kann die
Funktion analogWrite also nicht auf ihn anwenden). Wie in
Kapitel 6 beschrieben wurde, schließt man einen Servomotor an
GND, VCC und Pin 9 oder 10 an. Um einen Servomotor zu kon-
trollieren, muss ein Objekt des Typs Servo erzeugt werden, der
dann mit der Funktion attach vor der Benutzung konfiguriert wird.

[Link](pin), [Link](pin, min, max)


Mit dieser Funktion kann ein Servo-Objekt mit einem der beiden
Servo-Pins (9 und 10) verbunden werden. Optional kann die Puls-
breite in Millisekunden (ms) angegeben werden, die für den kleins-
ten Winkel (0 Grad am Servo) und den größten Winkel (180 Grad)
benutzt wird. Als Standardwerte werden 544 ms für den kleinsten
Winkel und 2.400 ms für den größten Winkel verwendet.

[Link](winkel)
Mit dieser Funktion kann der Servo kontrolliert werden. Auf einem
normalen Servo wird so der Winkel eingestellt (von 0 bis 180), auf
einem kontinuierlichen Servo wird die Geschwindigkeit des Servos
eingestellt. (In diesem Fall ist ein Winkel von 0 die volle Geschwin-
digkeit in die eine Richtung und 180 die volle Geschwindigkeit in
die andere Richtung, und ein ungefährer Wert von 90 die Position,
an der sich das Servo nicht bewegt.)

[Link]()
Mit dieser Funktion kann der zuletzt eingestellte Winkel ausgelesen
werden. Sie gibt einen Wert von 0 bis 180 zurück.

[Link]()
Mit dieser Funktion kann überprüft werden, ob das Servo-Objekt
schon mit einem Pin verbunden wurde. Sie gibt TRUE zurück,
wenn das Objekt schon verbunden wurde, sonst FALSE.

284 Anhang B: Arduino-Bibliotheken


[Link]()
Mit dieser Funktion kann das Servo-Objekt von seinem Pin
getrennt werden. Wurden alle Servo-Objekte von ihren Pins
getrennt, können Pin 9 und 10 wieder als normale PWM-Pins ver-
wendet werden.
Beispiel
#include <Servo.h>
Servo meinServo; // Servo-Objekt
int pos = 0; // Variable zum Speichern der Servoposition
void setup() {
[Link](9); // Der Servo ist an Pin 9 angeschlossen.
}
void loop() {
// In dieser Schleife wird der Servo komplett von links nach
// rechts bewegt.
for (pos = 0; pos < 180; pos++) {
[Link](pos);
delay(15);
}
// und wieder zurück
for (pos = 180; pos >= 1; pos—) {
[Link](pos);
delay(15);
}
}

Debounce-Bibliothek
Wie in Kapitel 3 beschrieben wurde, können bei Tastern und Schal-
tern schnell Fehler auftreten. Weil sie auf federnden Effekten basie-
ren, öffnen und schließen sie sich beim Betätigen mehrmals, am Pin
kommen also mehrere HIGH- und LOW-Signale an, was ein uner-
wünschter Effekt ist. Dieses Phänomen wird als »Prellen« oder
»Bouncing« bezeichnet, weshalb die Bibliothek, die dagegen helfen
soll, »Debounce« heißt. Sie sorgt dafür, dass der Input-Pin nach
einer Eingabe für eine bestimmte Anzahl Millisekunden gesperrt
wird, sodass alle weiteren Signale ausgesperrt werden.

Debounce(unsigned long debounceZeit byte pin)


Instanziiert ein Debounce-Objekt. Es wird eine Debounce-Zeit in
Millisekunden festgelegt und das Objekt mit einem Input-Pin ver-
bunden.

Debounce-Bibliothek 285
[Link]()
Liest den Pin neu ein und prüft, ob sich das Signal unter Berück-
sichtigung der Debounce-Zeit geändert hat. Ist das der Fall, wird
TRUE zurückgegeben, ansonsten FALSE.

[Link](unsigned long debounceZeit)


Ändert die Debounce-Zeit, die dem Objekt zugewiesen wird.

[Link]()
Liest den aktuellen Wert des mit dem Objekt verbundenen Pins ein
und berücksichtigt dabei die Debounce-Zeit.

[Link]()
Schreibt den aktuellen Debounce-Wert in den Speicher des Objekts
und auf den mit dem Objekt verbundenen Pin.
Beispiel
// schalte eine LED durch Betätigung eines Schalters an und aus
#include <Debounce.h>
#define SCHALTER 5
#define LED 13
// instanziiere ein Debounce-Objekt mit einer Debounce-Zeit von 20 ms
Debounce debouncer = Debounce( 20 , SWITCH );
void setup() {
pinMode(SWITCH,INPUT);
pinMode(LED,OUTPUT);
}
void loop() {
// update den Debouncer
[Link] ( );
// verwende den neuen Wert, um die LED damit zu schalten
digitalWrite(LED, [Link]() );
}

Wire-Bibliothek
Um mit dem Arduino über das Two-Wire-Interface bzw. das Proto-
koll I²C (inter-integrated circuit) zu kommunizieren, verwendet
man die Wire-Bibliothek. Das I²C-Protokoll ist ein sogenannter
Datenbus. Das heißt, dass auf einer Leitung mehrere Geräte ange-
schlossen werden können. Ein Hauptgerät, der Master, sendet
Daten, während die Slaves diese empfangen und darauf reagieren.
Die Wire-Bibliothek erlaubt, sowohl als Master- als auch als Slave-
Gerät an einem TWI/I²C-Bus teilzunehmen. Der Bus basiert dabei

286 Anhang B: Arduino-Bibliotheken


auf zwei Leitungen, einer Datenleitung (SDA), die auf dem analo-
gen Input-Pin 4 angeschlossen wird, sowie einer Taktleitung (SCL)
auf dem analogen Pin 5. Auf dem Arduino Mega werden die Lei-
tungen auf Pin 20 (SDA) und 21 (SCL) angeschlossen.

[Link]() /[Link](address)
Meldet den Arduino am Bus an. Wird eine Adresse (7 Bit, 0–127)
mitgegeben, geschieht diese Anmeldung als Slave, ohne Adresse als
Master.

[Link](address, quantity)
Fordert von einem Gerät Informationen an. address bezeichnet
dabei die 7-Bit-Geräteadresse, quantity die Anzahl von Bytes, die
erwartet werden.

[Link]()
Gibt die Anzahl von Bytes zurück, die auf dem Bus gelesen werden
können. Wenn der Arduino als Slave registriert ist, kann er so
Daten vom Master empfangen, andersherum wird festgestellt, wie
viele Bytes der Slave nach einer requestFrom-Anfrage gesendet hat.

[Link]()
Empfängt das nächste Byte, das auf dem Bus für das Gerät vorliegt
und gibt dieses als »Byte« zurück.

[Link](address)
Beginnt eine Übertragung als Master an die in address angegebene
Slave-Adresse.

[Link](value) / [Link](string) / [Link](data, quantity)


Speichert Daten in einer Warteschleife, die dann an eine Slave-
Adresse gesendet werden. [Link]() wird nach [Link]-
mission aufgerufen. Die Daten können dabei entweder ein Bytewert
(value), ein string oder ein Array von Bytes (data) sein, wobei im
letzten Fall zusätzlich die Anzahl von Bytes übergeben wird.

[Link]()
Beendet den Übertragungsblock, der mit beginTransmission()
gestartet und mit send() vorbereitet wurde. Mit endTransmission()
wird der gesamte Block übertragen.

Wire-Bibliothek 287
[Link](handler)
Mit dieser Funktion kann eine weitere Funktion festgelegt werden,
die aufgerufen werden soll, wenn ein Slave Daten vom Master
erhält. Dabei wird der Funktionsname übergeben, die Funktion
selbst wird im weiteren Verlauf des Sketches deklariert. Sie sollte
genau einen Int-Parameter besitzen, an den die Anzahl der übertra-
genen Bytes übergeben wird.

[Link](handler)
Diese Funktion verhält sich wie onReceive(), allerdings für den
Fall, dass der Master Daten anfordert. Die mitgegebene Funktion
hat weder einen Rückgabewert noch Parameter. Sie wird bei einem
Request aufgerufen und kann zum Beispiel die Anweisung enthal-
ten, einen Sensor auszulesen und mit write() wieder an den Master
zu senden.
Beispiel
// schließt den Arduino als Master an und sendet eine Anfrage an
// einen Slave mit Adresse 1; dann werden die Antwort gelesen und
// der Inhalt wieder an den Slave gesendet
#include <Wire.h>
void setup() {
// initialisiere die Bus-Verbindung
[Link]();
}
void loop() {
// fordere ein Byte von Gerät 1 an
[Link](1, 1);
if ([Link]()) {
byte empfangeneDaten = [Link]();
[Link](1);
[Link](empfangeneDaten);
[Link]();
}
}

capSense-Bibliothek
Mit dieser Bibliothek können auf dem Arduino einfach kapazitive
Sensoren implementiert werden. Wie in Kapitel 7 beschrieben
wurde, sind dazu nur ein Widerstand (von 100.000–50 Mio. Ohm)
und ein Stück Draht oder Aluminiumfolie notwendig. Der Wider-
stand muss zwischen zwei Pins gesteckt werden, bei dem der eine
Pin als Sendepin fungiert und der andere als Empfangspin. An den
Empfangspin muss der Draht oder die Alufolie als Antenne ange-
schlossen werden. Für einen kapazitiven Sensor wird die CapSen-

288 Anhang B: Arduino-Bibliotheken


sor-Bibliothek verwendet, um ein CapSense-Objekt zu erzeugen,
mit dem der Wert des Sensors (also die Entfernung zum menschli-
chen Körper) gemessen werden kann.
Ein Widerstand von einem Megaohm oder weniger kann eingesetzt
werden, damit der Sensor nur bei tatsächlicher Berührung aktiviert
wird; mit einem Widerstand von ungefähr 10 Megaohm wird der
Sensor bei einer Entfernung von 10–15 cm aktiviert; mit einem
Widerstand von 40 Megaohm wird der Sensor bei einer Entfernung
von 30–40 cm aktiviert. 40-Megaohm-Widerstände sind nicht so
leicht zu finden, weshalb man auch vier in Serie gelötete 10-Mega-
ohm-Widerstände einsetzen kann.

CapSense(sendePin, empfangsPin)
Mit dieser Funktion wird ein CapSense-Objekt erzeugt, mit dem
ein kapazitiver Sensor gemessen werden kann. Der Widerstand
muss zwischen Sende- und Empfangspin gesteckt werden (beides
müssen digitale Pins sein) und die Antenne an den Empfangspin
angeschlossen sein.

[Link](samples)
Mit dieser Funktion kann die Kapazität des Sensors gemessen wer-
den, in einer beliebigen Einheit. Der samples-Parameter gibt die
Zeit an, über die gemessen wird. Je länger diese Zeit und damit der
Messvorgang ist, desto genauer der gemessene Wert. Das Ergebnis
wird nicht durch die Zeitdauer geteilt, sondern es wird einfach der
rohe Messwert zurückgegeben. Die Funktion gibt -2 zurück, wenn
der gemessene Wert über CS_Timeout_millis liegt (das mit der
Funktion set_CS_Timeout_Millis eingestellt werden kann und stan-
dardmäßig 2.000 Millisekunden beträgt).

[Link](samples)
Ähnlich wie die [Link]-Funktion misst diese Funk-
tion die Kapazität des Sensors über einen gewissen Zeitrahmen.
Allerdings misst [Link] auch die Kapazität im nicht
aktivierten Zustand und zieht diese vom gemessenen Wert ab. Cap-
[Link]() sollte deswegen im nicht aktivierten Zustand
einen niedrigen Wert zurückgeben. Die automatische Kalibrierung
wird in regelmäßigen Intervallen ausgeführt, die mit der Funktion
set_CS_AutocaL_Millis eingestellt werden können. Die Autokali-
brierung wird normalerweise alle 20 Sekunden ausgeführt. Diese
Funktion gibt -2 zurück, wenn der gemessen Wert über CS_
Timeout_millis liegt.

capSense-Bibliothek 289
CapSense.set_CS_Timeout_Millis(millis)
Mit dieser Funktion wird die maximale Messzeit eingestellt.

CapSense.reset_CS_AutoCal()
Mit dieser Funktion wird sofort eine Kalibrierung der Kapazität im
nicht aktivierten Zustand ausgelöst.

CapSense.set_CS_AutoCaL_Millis(millis)
Mit dieser Funktion kann die Periode der automatischen Kalibrie-
rung eingestellt werden. Die automatische Kalibrierung kann deak-
tiviert werden, indem millis auf 0xFFFFFFFF gesetzt wird.
Beispiel
#include <CapSense.h>
CapSense cs = CapSense(4, 2); // Widerstand zwischen Pin 4 und 2
// 2 ist der Empfangspin
CapSense cs2 = CapSense(4, 3); // ein weiterer Sensor an
// Empfangspin 3
void setup() {
cs.set_CS_AutocaL_Millis(0xFFFFFFFF);
[Link](9600);
}
void loop() {
long start = millis(); // Messdauer festhalten
long wert1 = [Link](30); // ersten Sensor messen
long wert2 = [Link](30); // zweiten Sensor messen
// Messzeit und Messwerte ausgeben
[Link](millis() – start);
[Link](": ");
[Link](wert1);
[Link](", ");
[Link](wert2);
delay(10);
}

290 Anhang B: Arduino-Bibliotheken


ANHANG C In diesem Kapitel:
• Übersicht: Programmier-
Sprachreferenz sprachen
• Struktur, Werte und Funk-
tionen
• Syntax
• Programmwerte (Variablen,
Datentypen und Konstanten)
• Ausdrücke und Anweisungen
• Ausdrücke
• Kontrollstrukturen
• Funktionen
• Sketch-Struktur
• Funktionsreferenz

Übersicht: Programmiersprachen
In diesem Anhang wird die Arduino-Programmiersprache ausführ-
lich erklärt. Es werden zuerst die Syntax der Programmiersprache
(also was in der Sprache zulässig ist) und die Struktur eines Ardu-
ino-Sketches erklärt (notwendige Sketch-Funktionen, Programm-
flusskonstrukte, mathematische Operatoren). Anschließend werden
häufig benutzte Funktionen zur Steuerung der Arduino-Hardware
gezeigt. An vielen Stellen wird auf potenzielle Fehlerquellen hinge-
wiesen (Programmieren ist nicht gerade die leichteste Aufgabe). Das
soll auf keinen Fall der Abschreckung dienen, sondern eher die Feh-
lersuche erleichtern und Ihnen generell ein Gefühl für mögliche Fal-
len geben. Es kann praktisch wenig passieren, außer dass der
Arduino sich merkwürdig benimmt oder stehen bleibt. Es reichen
also bei einem Programmfehler meistens ein Reset, ein bisschen
Nachdenken und das erneute Hochladen der korrigierten Software.
Ein Arduino-Programm ist eine Folge von Programmierbefehlen,
die dem Arduino-Prozessor Anweisungen dafür geben, welche
Berechnungen er auszuführen hat. Eine Folge von Anweisungen,
die eine bestimmte Aufgabe erfüllen, nennt man Algorithmus.
Diese Anweisungen können rein mathematische Anweisungen sein
(»nimm den Wert, der an dieser Stelle im Speicher steht, addiere 3
und speichere ihn an dieser anderen Stelle«) oder auch Programm-
flussanweisungen (»wenn der Eingabewert größer als 5 ist, dann
führe diese Anweisungen aus, ansonsten führe diese anderen
Anweisungen aus«). Weiterhin gibt es eine Reihe von Strukturan-
weisungen, die es ermöglichen, bestimmte Teile eines Programms

291
flexibel zu gestalten und auch getrennt zu bearbeiten. Die Program-
mierbefehle, die diese Anweisungen beschreiben, werden vom Pro-
grammierer in einer sogenannten Programmiersprache oder
Computersprache (also nicht auf Englisch oder Deutsch) in eine
Textdatei geschrieben.
Eine Computersprache braucht eine feste Syntax, damit der Com-
puter verstehen kann, was mit dem Programm bewirkt werden soll.
Beim Hochladen eines Sketches auf den Arduino wird der Pro-
grammtext in Maschinencode übersetzt. Dieser Schritt heißt »kom-
pilieren« und wird von einem eigenen Programm namens
»Compiler« durchgeführt. Falls Arduino in diesem Schritt einen
Programmfehler antrifft (z.B. einen Tippfehler), wird der Vorgang
abgebrochen und der Fehler in der Konsole angezeigt. Der Ardu-
ino-Editor springt an die fehlerhafte Zeile im Programmcode und
markiert sie gelb. So lassen sich schnell Probleme in einem Pro-
gramm finden. Das erfolgreiche Übersetzen des Programms heißt
jedoch noch nicht, dass es auch korrekt ist, denn es können noch
viel mehr Fehler auftreten als nur Syntaxfehler.

Abbildung C-1
Programmfehler im
Arduino-Edito

Die Arduino-Programmiersprache baut auf der Programmierspra-


che C++ auf. Die Grundsyntax der Programmiersprache (welche
Wörter eine besondere Bedeutung haben und welche Sonderzei-
chen benutzt werden, um Abschnitte des Programms abzugrenzen)
ist also dieselbe wie die von C++. Falls Sie C++ schon kennen, wer-
den Sie merken, dass viele der erweiterten Konstrukte (z.B. Klas-
sen) von C++ in normalen Sketchen nicht verwendet werden.

Struktur, Werte und Funktionen


Ein Arduino-Programm kann man grob in drei Bereiche untertei-
len: Programmstruktur (der Ablauf eines Programms), Programm-
werte (Variablen und Konstanten) und Programmfunktionen (eine

292 Anhang C: Sprachreferenz


logische Einteilung von Programmfunktionalität, um diese ver-
ständlicher und wiederverwendbar zu gestalten).
Die Programmstruktur kann man als das »eigentliche« Programm
betrachten. Es umfasst Kontrollstrukturen, die es ermöglichen,
Algorithmen zu implementieren, indem der Programmfluss gesteu-
ert wird: if, if...else, switch, while usw. Es umfasst auch arithme-
tische Operationen (addieren, subtrahieren, vergleichen, logische
Operatoren), Zuweisungen (den Wert einer Variablen setzen oder
lesen) und Funktionsaufrufe.
Programmwerte kann man in Variablen und in Konstanten unter-
teilen. Konstanten sind symbolische Namen für konstante numeri-
sche Werte, die eine bestimmte festgelegte Bedeutung haben (z.B.
den logischen Wert für eine hohe Spannung an einem Eingangs-
pin). Variablen sind Ausdrücke, die einen Wert speichern können,
z.B. eine Zahl, die von einem analogen Eingang gelesen wird, oder
eine Zeichenkette. Variablen haben unterschiedliche Datentypen,
je nachdem, welche Art von Werten gespeichert werden soll.
Letztendlich werden Abschnitte von Programmstrukturen in Funk-
tionen unterteilt, um sie logisch zu trennen und wiederverwendbar
zu machen. Anstatt immer wieder denselben Programmcode zu
schreiben (unter Umständen mit nur leichten Änderungen), kann
man diesen als Funktion abkapseln und mit Funktionsaufrufen
immer wieder neu ausführen. Einem Funktionsaufruf können auch
Parameter übergeben werden, damit die Funktion flexibler wird
und so vielfältiger eingesetzt werden kann. Libraries, die bestimmte
Funktionalitäten anbieten (z.B. Schnittstellen zu diversen Sensoren
und Aktoren oder bestimmte mathematische Berechnungen) wer-
den meistens über einige bestimmte Funktionen angesprochen. Die
Zusammenfassung dieser Funktionen nennt man Library-Schnitt-
stelle (oder API, application programming interface).

Syntax
Eine Programmiersprache ist eine formale Sprache, die strikt defi-
nierten Regeln folgt, damit der Computer sie auch verstehen kann.
Anstatt Sätze zu schreiben, werden in einer Programmiersprache
Befehle an den Arduino geschrieben, die man Anweisungen nennt.
Eine Anweisung kann zum Beispiel sein: »Addiere 2 und 5, oder
setze den Ausgangspin 5 auf HIGH.«

Syntax 293
In Arduino muss jede dieser Anweisungen mit einem Semikolon
abgeschlossen werden. Vergisst man, eine Anweisung mit einem
Semikolon abzuschließen, wird Arduino einen Fehler melden. Es
kann allerdings passieren, dass der Fehler, der durch ein fehlendes
Semikolon ausgelöst wird, sehr kryptisch ist, weil der Compiler die
Programmstruktur nicht korrekt erkennen kann. Wenn Arduino
also einen »absurden« Fehler meldet, ist es sinnvoll, zuerst nach
Syntaxfehlern im Programmquellcode zu suchen.
Beispiel
int buttonPin = 2;
a = a + 3;
meineFunktion();

Mehrere Anweisungen können zu einer übergeordneten zusam-


mengefasst werden, indem sie mit geschweiften Klammern grup-
piert werden. Diese Gruppierungen nennt man Programmblock.
Jede öffnende geschweifte Klammer muss von einer passenden
schließenden geschweiften Klammer gefolgt werden. Der Arduino-
Editor ist dort eine große Hilfe: Positioniert man den Cursor hinter
einer schließenden Klammer, wird die dazugehörige öffnende
Klammer hervorgehoben. Die Programmblöcke, die durch Klam-
mern erzeugt werden, sind enorm wichtig für die Programmstruk-
tur. Fehlende oder falsch gesetzte Klammern können (wie fehlende
Semikola) zu kryptischen Programmfehlern führen (oder, noch
schlimmer, zu syntaktisch korrekten, aber fehlerhaften Program-
men). Es lohnt sich also, vorsichtig mit Klammern umzugehen und
immer sicherzustellen, dass Klammerpaare korrekt sind.
Geschweifte Klammern ({}) werden benutzt, um mehrere State-
ments zu einem Funktionskörper zusammenzufassen und einzelne
Pfade bei Programmstruktur-Konstrukten zu bilden.
Beispiel
void meineFunktion(){
statement1;
statement2;
statement3;
}
if (i > 0) {
statement1;
statement2;
} else {
statement3;
statement4;
}

294 Anhang C: Sprachreferenz


Es ist auch möglich, Textabschnitte in einem Programm so zu
markieren, dass sie vom Compiler ignoriert werden. So kann ein
Programm mit normalen Sätzen auf Deutsch oder Englisch kom-
mentiert werden, ohne dass der Compiler versucht, diese als Pro-
grammcode zu interpretieren und deswegen einen Fehler meldet.
Sieht der Compiler die Zeichenkette //, wird alles bis zum Ende
der Zeile ignoriert. Mit // kann man also kurze Kommentare, die
sich auf eine Zeile beziehen, einfügen.
Größere Blöcke von Programmcode lassen sich durch /* und */
auskommentieren. Alles, was sich zwischen diesen beiden Zeichen-
ketten befindet, wird vom Compiler ignoriert. Es können schwere
Fehler erzeugt werden, wenn solche Kommentare ungründlich ver-
schachtelt werden.
Kommentare sind natürlich in erster Linie dazu da, komplizierte
Programme für menschliche Leser zu beschreiben. So können
Algorithmen erläutert, Hinweise auf Nebenwirkungen oder Fehler-
möglichkeiten gegeben oder Anleitungen zu Anwendung und
Modifikation des Codes gegeben werden. Es gilt hier allerdings:
Kommentare sind genauso wichtig wie der Programmcode selbst
und genauso aufwendig zu warten. Schlimmer als keine Kommen-
tare sind falsche Kommentare, die nicht zum kommentierten Pro-
grammcode passen.
Es ist auch sehr praktisch, Teile des Programms auszukommentie-
ren, um verschiedene Möglichkeiten zu testen oder Programmteile
auszugrenzen, die Probleme erzeugen. Das kann besonders nützlich
sein, wenn der Compiler kryptische Fehler meldet oder ein Bug
nicht genau eingegrenzt werden kann. Mit Kommentaren können
auch Debugging-Anweisungen ein- und ausgeschaltet werden.
Beispiel
x = 5; // Dieser Kommentar geht bis zum Zeilenende.
x = x + 1; // Einzeilige Kommentare kann man so gestalten, dass sie
// über mehrere Zeilen gehen.
/* So lassen sich auch Kommentare schreiben,
die über mehrere Zeilen gehen.
Diese sind besonders nützlich für längere Erklärungen, oder um
komplette Programmteile auszukommentieren.
*/
/* Es ist wichtig, keine Kommentare zu verschachteln.
if (i > 0) {
statement1; /* denn das funktioniert nicht und führt zu
Programmfehlern */

Syntax 295
statement2; // Einzeilige Kommentare kann man allerdings
// schachteln.
}
*/

Um Programmcode leserlich zu halten (ihn zu schreiben, ist


immer viel einfacher, als ihn nachträglich zu verstehen und zu
modifizieren), ist es sehr wichtig, gewisse Schreibregeln einzuhal-
ten. So wird Code, der in geschweiften Klammern gruppiert ist,
eingerückt, damit man schon beim Überfliegen der Datei sehen
kann, wie das Programm strukturiert ist. Der Arduino-Editor hilft
einem dabei, indem der Cursor automatisch an die richtige Stelle
gesetzt wird, wenn eine neue Zeile eingefügt wird. Wird jedoch
durch späteres Editieren die Programmstruktur verändert, kann es
leicht vorkommen, dass die Einrückungen nicht mehr korrekt
sind. Der komplette Programmcode kann zurechtgerückt werden,
indem die Funktion TOOLS → AUTOFORMAT ausgeführt wird
(alternativ auch Apfel-T auf Mac OS X und Steuerung-T auf Linux
und Windows).
Neben den Syntaxsymbolen werden in der Arduino-Programmier-
sprache numerische Werte (also Zahlen) und Wörter verwendet.
Ein Teil der möglichen Wörter ist als Teil der Programmiersprache
definiert (z.B. int, if, else, return, break usw., aber auch
Operatoren wie +, -, <<, && und &). Diese Wörter und Zeichen
nennt man »reserviert«, denn sie haben eine von der Programmier-
sprache definierte Bedeutung. Weitere Wörter können vom Pro-
grammierer als Variablen (siehe Abschnitt über Variablen) und
Funktionen (siehe Abschnitt über Funktionen) definiert werden.
Diese frei definierbaren Wörter müssen mit einem Buchstaben
anfangen (Spezialbuchstaben wie ä oder ü sind nicht erlaubt,
außer in Zeichenketten) und dürfen nur Buchstaben, Zahlen und
das _-Zeichen enthalten. Groß- und Kleinschreibung ist in Ardu-
ino-Programmen wichtig. Im folgenden Beispiel werden einige
mögliche Variablennamen gezeigt.
Beispiel
byte meineVariable; // Das Trennen von Teilwörtern in einem Namen
// mit Großbuchstaben ist eine weit verbreitete
// Programmierkonvention, die man "CamelCase" nennt.
const byte MeineZweiteVariable; // Eine weitere Konvention ist ein
// Großbuchstabe als erster Buchstabe bei Konstanten
// (siehe Konstanten).

296 Anhang C: Sprachreferenz


Programmwerte (Variablen,
Datentypen und Konstanten)
Die meisten Arduino-Programme gehen mit Daten um, die in dem
internen Speicher des Arduino abgelegt oder von den Eingangspins
abgelesen werden. Diese Daten werden im Programm in Variablen
gespeichert, damit man als Programmierer systematisch auf den
Speicher zugreifen kann.
Eine Variable hat einen Namen, einen Datentyp und einen Wert.
Der Name ist eine beliebige Zeichenkette, die keine Sonderzeichen
oder Leerzeichen enthalten darf, die mit einem Buchstaben anfan-
gen muss und die nicht zu den reservierten Wörtern der Arduino-
Programmsprache gehören darf.

Datentypen
Weiterhin hat eine Variable einen Datentyp. Der interne Speicher
des Arduino besteht aus einer langen Tabelle von 8-Bit-Werten;
eine Variable kann allerdings noch viel mehr Arten von Daten ent-
halten. Datentypen kann man in zwei Gruppen unterteilen: nume-
rische und zusammengesetzte Datentypen.
Numerische Datentypen werden benutzt, um Zahlen oder Boole-
sche logische Werte abzubilden. Sie unterscheiden sich grundsätz-
lich durch den Zahlenbereich, den sie abbilden können. Hier muss
man zwischen ganzzahligen numerischen Typen unterscheiden, die
nur ganze Zahlen darstellen können, und Fließpunktkommazah-
len, die Kommazahlen darstellen können. Die Datentypen float und
double werden benutzt, um Fließkommazahlen zu speichern. Der
Arduino basiert auf einem 8-Bit-Prozessor, sodass Kommazahlen
nur mit viel Mehraufwand eingesetzt werden können. Falls schnelle
Berechnungen notwendig sind (oder ein kürzerer Programmcode)
ist es besser, ganze Zahlen einzusetzen.
Zusammengesetzte Datentypen lassen sich in Tabellen und Daten-
strukturen unterteilen. Datenstrukturen sind ein fortgeschrittenes
Thema und werden in diesem Buch nicht behandelt. Datentabel-
len sind Listen von vielen Werten eines Datentyps, auf die inde-
xiert zugegriffen werden kann. Diese Werte werden hintereinander
im Speicher abgelegt. Einen speziellen zusammengesetzten Daten-
typ bilden Zeichenketten, die als Tabelle von char-Werten im Spei-
cher abgebildet werden. Der letzte Wert in einer Zeichenkette ist
immer 0.

Programmwerte (Variablen, Datentypen und Konstanten) 297


Im Folgenden sehen Sie die meistbenutzten Datentypen in Ardu-
ino-Programmen.

Tabelle C-1 Datentyp Beschreibung Beispiel


Datentypen
boolean Ein boolean hat entweder den Wert true oder boolean a = true;
den Wert false. Dieser Datentyp wird benutzt,
um Binärlogikwerte zu speichern.
char Speichert einen Buchstaben in einem Byte Spei- char c = 'a';
cher.
byte Speichert einen numerischen Wert von 0 bis 255 byte b = 35;
in einem Byte Speicher.
signed Speichert einen numerischen Wert von –128 bis unsigned byte b = 35;
byte 127 in einem Byte Speicher.
int Speichert einen numerischen Wert von –32.768 int i = -9892;
bis 32.767 in 2 Bytes Speicher.
unsigned Speichert einen numerischen Wert von 0 bis 65. unsigned int i = 9723;
int 535 in 2 Bytes Speicher.
long Speichert einen numerischen Wert von – 2.147. long l = 98237498L;
483.648 bis [Link] in 4 Bytes Speicher.
unsigned Speichert einen numerischen Wert von 0 bis 4. unsigned long l =
long 294.967.295 in 4 Bytes Speicher. 834759824L;
float Speichert eine Fließkommazahl von mittlerer float f = 4.34;
Auflösung in 4 Bytes Speicher.
double Auf dem Arduino ist double äquivalent zu double d = 4.34;
float.
string Speichert eine Zeichenkette als 8-Bit-Tabelle mit char str[] = "arduino";
abschließender 0.
array Speichert eine Tabelle von Variablen. Die Größe int meineWerte[] = {1,
wird angegeben. 2, 3, 4, 5};
void Wird nur bei Funktionsdeklarationen verwendet
und gibt an, dass die Funktion keinen Rückgabe-
wert hat.

Numerische Datentypen und binäre Darstellung


Wie man anhand der Tabelle sehen kann, gibt es eine Vielzahl
numerischer Datentypen in der Arduino-Programmiersprache.
Diese unterscheiden sich durch ihre Größe und den numerischen
Bereich, den sie abdecken. In diesem Abschnitt wird ein bisschen
tiefer gehend erklärt, wie Zahlen auf dem Arduino-Chip abgelegt
werden, da es sehr wichtig ist, das zu verstehen, um Fehler zu ver-
meiden und den richtigen Datentyp auszuwählen.
In einem Prozessor werden sämtliche Werte als Folgen von Bits
abgespeichert. Ein Bit ist die grundlegende Speichereinheit und kann

298 Anhang C: Sprachreferenz


als Wert entweder 0 oder 1 annehmen. Da man mit einem einzelnen
Bit noch nicht viel rechnen kann, werden sie in Bytes zusammenge-
fasst, wobei ein Byte 8 Bits umfasst. Dabei wird das sogenannte
Binärsystem benutzt, das ähnlich wie unser Dezimalsystem funktio-
niert. Wenn wir 13 schreiben, heißt das soviel wie 1 * 10 + 3, jede
Stelle nach links bedeutet also zehn Mal so viel wie die auf der rech-
ten Seite. Im Binärsystem ist jede Stelle nach links nur zweimal wich-
tiger, weil eine Stelle eben nur zwei Werte darstellen kann. In der
folgenden Tabelle sehen Sie ein paar Zahlen in Binärdarstellung auf-
gelistet. Mehr über das Binärsystem findet man zum Beispiel in der
Wikipedia unter [Link]
Wenn ein numerischer Wert als Folge von Bits interpretiert wird,
redet man von einer Bitmaske. Für den Arduino-Prozessor gibt es
keinen Unterschied zwischen einer normalen Zahl und einer Bit-
maske, diese Unterscheidung ist also nur für den Programmierer
von Relevanz. Bitmasken sind bei der Programmierung von einge-
betteten Prozessoren, wie der Arduino-Prozessor einer ist, oft von
Relevanz. So lassen sich in einer Bitmaske digitale Werte (also 0
oder 1) sehr speichereffizient speichern (siehe Kapitel 4 über LED-
Matrix). Anstatt ein Byte zu verwenden, um einen digitalen Wert zu
speichern, kann ein Byte als Bitmaske interpretiert gleich acht digi-
tale Werte speichern (siehe Abschnitt über logische Operationen).
Mit einer Bitmaske lassen sich auch mehrere Pins auf einmal schal-
ten, was in bestimmten Anwendungen (siehe Kapitel 4, LED-Matrix
und Kapitel 10 über Musik) aus Geschwindigkeitsgründen wichtig
sein kann. Da Zahlen generell als Bitmasken gespeichert werden,
lassen sich bestimmte mathematische Operationen mit Bitmasken
sehr effizient berechnen (siehe Abschnitt »Logische Operationen«).

Dezimaldarstellung Hexadezimaldarstellung Binärdarstellung Tabelle C-2


0 0x0 0 Binärdarstellung
1 0x1 1
2 0x2 10
10 0xa 1010
15 0xf 1111
255 0xff 11111111
260 0x104 1 00000100
60000 0xea60 11101010 01100000
-128 (8 bit) -0x80 10000000
-127 (8 bit) -0x7f 10000001
-128 (16 bit) -0x80 11111111 10000000
-127 (16 bit) -0x7f 11111111 10000001

Programmwerte (Variablen, Datentypen und Konstanten) 299


Zahlen von 0 bis 255 lassen sich in einem Byte speichern, größere
Zahlen werden in mehreren Bytes gespeichert. Intern arbeitet der
Prozessor auf einem Arduino-Board mit 8 Bit, d.h. er kann intern
8-Bit-Werte addieren, subtrahieren und multiplizieren. Werden
größere numerische Werte benutzt, werden diese in mehrere 8-Bit-
Werte zerlegt und nach der Bearbeitung im Prozessor wieder
zusammengefügt. Wenn viele Daten sehr schnell bearbeitet werden
müssen (z.B. bei bestimmten Sensoren), ist es also wichtig, die pas-
sende Größe für numerische Werte zu benutzen.
Negative Zahlen werden in der sogenannten Zweierkomplement-
Darstellung gespeichert. Dazu wird das größte Bit benutzt, um zu
speichern, ob die Zahl positiv oder negativ ist. Ist das größte Bit
gesetzt, wird die Zahl in den unteren Bits auf den kleinsten nega-
tivsten Wert addiert (bei 8 Bit z. B. –128). Die Datentypen, die
negative und positive Zahlen erlauben, werden »signierte« (englisch
signed) Datentypen genannt, im Unterschied zu den »unsignierten«
(unsigned) Datentypen, die nur positive Werte speichern können.
Dadurch, dass der größte und der kleinste Wert einer Variable
beschränkt sind, kann es dazu kommen, dass eine Variable über-
läuft bzw. unterläuft. Wird z.B. zum 8-Bit-Wert 255 eine 2 addiert,
kommt als Ergebnis nicht 261 heraus, sondern 1, weil die Variable
übergelaufen ist. Das ist eine häufige Quelle von Fehlern, weshalb
es notwendig ist, bei der Wahl von numerischen Datentypen immer
sehr vorsichtig vorzugehen. Besonders kritisch und kompliziert
wird es, wenn signierte und unsignierte Datentypen in mathemati-
schen Operationen vermischt werden. In solchen Operationen ist
es sehr schwer nachzuvollziehen, wo und wie ein Überlauf passie-
ren kann. Wann immer mit unsignierten und signierten Datenty-
pen gerechnet wird, lohnt es sich also, die unsignierten Datentypen
in signierte Datentypen umzuwandeln und erst dann zu rechnen.
Beispiel
unsigned char x = 0; // unsignierter Datentyp, 0-255
char y = 0; // signierter Datentyp, -128 – 127
char x2 = x; // umwandeln von x in einen signierten Datentyp
// x muss kleiner als 128 sein!
char ergebnis = y + x;

In der Arduino-Programmiersprache können Zahlen in verschiede-


nen Darstellungen angegeben werden. So ist es natürlich möglich,
Zahlen in der üblichen Dezimaldarstellung zu schreiben. Ganz ähn-
lich können Kommazahlen (als Datentyp float) in der Dezimaldar-
stellung angegeben werden. Als Komma wird das Punktzeichen
verwendet, wie es in englischsprachigen Ländern üblich ist.

300 Anhang C: Sprachreferenz


Weiterhin können Zahlen aber auch in der Hexadezimaldarstellung
angegeben werden, in der sie mit 0x beginnen. Bei der Hexadezi-
maldarstellung werden die Ziffern 0–9 und die Buchstaben a-f
benutzt. a ist dabei äquivalent zu 10 in der Dezimaldarstellung, b
zu 11, c zu 12 usw. Eine Ziffernstelle in Hexidezimaldarstellung
geht also von 0 bis 15, nicht von 0 bis 10 wie in Dezimaldarstel-
lung. Das Praktische an der Hexadezimaldarstellung ist, dass eine
Ziffer genau 4 Bit im Speicher belegt, ein Byte also als zwei Ziffern
angegeben werden kann. Dadurch lässt sich beim ersten Blick auf
die Zahl sehen, wie viel Speicher sie benötigt. Deswegen werden
häufig Adresswerte und Zahlenwerte in technischen Artikeln und
Datenblättern in Hexadezimaldarstellung angegeben.
In der Arduino-Programmiersprache (aber nicht im normalen C++)
lassen sich Zahlenwerte auch direkt in Binärdarstellung angeben.
Das ist besonders praktisch bei der Ansteuerung bestimmter Senso-
ren und Aktoren, bei denen einzelne Bits eine bestimmte Bedeu-
tung haben. Zahlen in Binärdarstellung werden mit 0b am Anfang
angegeben.
Beispiel
unsigned char a = 128; // Dezimaldarstellung
float f = 3.14; // Kommadarstellung
unsigned char x = 0x80; // Hexadezimaldarstellung
unsigned char b = 0b10101010; // Binärdarstellung

Fließkommazahlen
Fließkommazahlen werden benutzt, um Zahlen darzustellen, die
ein Komma (das ja durch einen Punkt dargestellt wird) haben.
Allerdings sind diese Zahlen nicht genau, sondern nähern diesen
Wert soweit möglich. Der darstellbare Zahlenbereich geht von –3.
4028253E+38 bis 3.4028235E+38. Dadurch, dass diese Zahlen
nicht genau sind, kann es vorkommen, dass z.B. 6.0 geteilt durch 3.
0 nicht gleich 2.0 ist. Der Prozessor auf einem Arduino-Board kann
nicht mit Fließkommazahlen umgehen, sodass eine zusätzliche
Library benutzt wird, die diese Berechnung auf 8-Bit-Zahlen abbil-
det. Dadurch sind Fließkommaberechnungen sehr langsam, und
bei zeitkritischen Berechnungen ist es oft notwendig, sie auf ganze
Zahlen umzuwandeln.

Buchstaben (char)
Buchstaben werden in der Arduino-Programmiersprache als nume-
rische Werte gespeichert. Ein Buchstabe ist ein Byte groß und kann

Programmwerte (Variablen, Datentypen und Konstanten) 301


Werte von 0 bis 255 annehmen. Um zuzuordnen, welcher Buch-
stabe welchen numerischen Wert hat, wird die ASCII-Tabelle
benutzt. Diese enthält die numerischen Werte für viele übliche
Buchstaben (auch viele der deutschen Spezialzeichen sowie Sonder-
zeichen wie Zeilenumbruch oder Leerzeichen). Damit in Program-
men aber nicht immer Zahlen als Buchstaben angegeben werden,
können einfache Anführungszeichen verwendet werden. Den Buch-
staben a kann man also als 'a' notieren. Es ist sehr wichtig, zwi-
schen einfachen Anführungszeichen, die zum Kennzeichnen von
einzelnen Buchstaben benutzt werden, und doppelten Anführungs-
zeichen, die zum Kennzeichnen von Zeichenketten verwendet wer-
den (siehe Abschnitt »Variablen« in diesem Anhang), zu
unterscheiden.

Tabellen (Arrays)
Tabellen speichern Listen von Werten desselben Datentyps.
Anhand eines numerischen Index kann dann auf einen Wert aus
einer Liste zugegriffen werden. Es gibt mehrere Arten, Arrays zu
erzeugen.
Beispiel
int meineTabelle[6];
int meineWerte[] = {4, 5, 6, 7, 8, 9, 10};
int meineNummern[5] = { 4, 5, 6, 7, 8}

In der ersten Zeile in diesem Beispiel wird eine Tabelle mit dem
Datentyp int erzeugt, die sechs Werte speichern kann. Im Speicher
werden also zwölf Bytes benutzt (weil ein int-Wert zwei Bytes
belegt), um diese sechs Werte zu speichern. Diese sechs Werte wer-
den automatisch auf 0 initialisiert.
In der zweiten Zeile wird die Größe des Array nicht explizit defi-
niert, sondern implizit durch die folgenden (sieben) Initialisie-
rungswerte gesetzt.
Im der dritten Zeile werden die Größe des Array definiert und Initi-
alisierungswerte übergeben. Stimmt die Größe der Initialisierungs-
werte nicht mit der Größe des Array überein, wird vom Compiler
ein Fehler gemeldet.
Diese Tabellen werden im Arbeitsspeicher des Arduino-Prozessors
gehalten, der relativ klein ist (2 oder 4 KByte auf einem Arduino
Duemilanove, je nach Herstellungszeitpunkt). Der Arduino-Editor
wird allerdings keinen Fehler signalisieren, wenn eine Tabelle zu
groß für den Arbeitsspeicher ist. Es ist also wichtig, sich darüber im

302 Anhang C: Sprachreferenz


Klaren zu sein, wie viel Speicher größere Tabellen belegen, und ob
so viel noch vorhanden ist.
Der Zugriff auf einzelne Tabellenwerte erfolgt über einen soge-
nannten Indexwert. Dieser gibt an, an welcher Stelle innerhalb der
Tabelle ein Wert geschrieben oder ausgelesen werden soll.
Beispiel
meineTabelle[0]; // Lesezugriff auf den ersten Wert aus
// meineTabelle
meineTabelle[6]; // Lesezugriff auf den letzten Wert aus
// meineTabelle
meineTabelle[0] = 1; // Schreibzugriff auf den ersten Wert aus
// meineTabelle

Indexe für Tabellen fangen bei 0 an und gehen bis zur Größe der
Tabelle minus eins. Deswegen wird in Programmen generell von 0
aus gezählt, nicht von 1 aus (das ist besonders bei Schleifen wich-
tig, siehe Abschnitt Kontrollstrukturen). Bei einer Tabelle der
Größe 6 geht der Indexwert also von 0 bis 5. Es ist sehr wichtig
sicherzustellen, dass der Indexwert innerhalb der zugelassenen
Größe liegt. Der Arduino-Prozessor wird das beim Ausführen des
Tabellenzugriffes nicht überprüfen und wird irgendwo im Speicher
lesen (was nicht so schlimm ist, aber zu komischen Ergebnissen
führt) oder schreiben (was deutlich schlimmer ist und zu sehr
schwer nachvollziehbaren Fehlern führt, z.B. dass das Arduino-
Board spontan neu startet oder in Funktionen springt, die gar nicht
angegeben worden sind). Bei Tabellenzugriffen ist also äußerste
Vorsicht geboten.
Es ist oft nützlich, eine Tabelle mit einer for-Schleife zu durchlau-
fen (siehe Abschnitt Kontrollstrukturen). Dazu wird eine Variable
hochgezählt, die jeden möglichen Index-Wert für die Tabelle
annimmt.
Beispiel
for (int i = 0; i < 5; i++) { // i nimmt alle Werte von 0 bis 5 an
meineTabelle[i] = i; // Zugriff auf das i-te Element aus
// meineTabelle
}

Eine fortgeschrittene Nutzung von Tabellen ist die Möglichkeit,


mehrdimensionale Tabellen zu erzeugen. Auf eine mehrdimensio-
nale Tabelle wird anhand von zwei oder mehr Indexwerten zuge-
griffen. Damit hat man die Möglichkeit, z.B. zweidimensionale
Tabellen zum Speichern von Grafiken für eine LED-Matrix zu erzeu-
gen. Zum Erzeugen einer mehrdimensionalen Tabelle werden meh-

Programmwerte (Variablen, Datentypen und Konstanten) 303


rere Größen in eckigen Klammern angegeben. Zum Initialisieren
mehrdimensionaler Tabellen werden geschachtelte Initialisierungs-
werte in geschweiften Klammern angegeben. Der Speicheraufwand
einer mehrdimensionalen Tabelle ist desto größer, je mehr Dimensi-
onen verwendet werden. So belegt eine 5-mal-5-Tabelle genauso viel
Speicher wie eine eindimensionale Tabelle mit 25 Werten.
Beispiel
int meine2DTabelle[5][5]; // Diese Tabelle speichert 5 x 5 = 25
// Werte.
int nochEineTabelle[3][2] = { // Diese Tabelle wird auch
// initialisiert.
{ 0, 1 }, // Hier ist es wichtig zu beachten, dass die Tabelle
// dreimal
{ 2, 3 }, // zwei Werte speichert, nicht zweimal drei Werte.
{ 4, 5 }
};

Hier ist es auch wichtig, die Grenzen der einzelnen Größen zu


beachten. Beim Zugriff muss sich der erste Indexwert innerhalb des
für die erste Tabelle festgelegten Rahmens befinden, der zweite
innerhalb des Rahmens der zweiten Tabelle usw..
Beispiel
int meine2DTabelle[5][5]; // Diese Tabelle speichert 5 x 5 = 25
// Werte.
meine2DTabelle[0][0] = 1; // Zugriff auf verschiedene Elemente
// innerhalb
meine2DTabelle[0][1] = 2; // der zweidimensionalen Tabelle
meine2DTabelle[3][3] = 3;

Ähnlich wie bei einer eindimensionalen Tabelle kann man eine


mehrdimensionale Tabelle mit mehreren geschachtelten for-Schlei-
fen durchlaufen.
Beispiel
// for-schleife zum Durchlaufen der ersten Dimension
for (int y = 0; y < 5; y++) {
// for-schleife zum Durchlaufen der zweiten Dimension
for (int x = 0; x < 5; x++) {
meine2DTabelle[y][x] = x; // Zugriff auf die zweidimensionale
// Tabelle
}
}

Zeichenketten
Zeichenketten sind einfach Tabellen von char-Werten. Zusätzlich
muss allerdings noch die Länge der Zeichenkette angegeben wer-

304 Anhang C: Sprachreferenz


den. Dazu wird an das Ende der Tabelle eine 0 angehängt, die sig-
nalisiert, dass damit die Zeichenkette zu Ende ist. Um zur
Initialisierung von Zeichenketten nicht immer explizit diese 0 ange-
ben zu müssen, gibt es die Möglichkeit, die Zeichenkette in dop-
pelte Anführungszeichen zu setzen. Dadurch wird automatisch eine
Zeichentabelle angelegt und die schließende 0 eingefügt.
Es ist sehr wichtig, diese 0 anzugeben. Fehlt sie, werden die meisten
Funktionen, die mit Zeichenketten arbeiten, das Ende der Zeichen-
kette nicht erkennen und weiter im Speicher lesen oder schreiben,
mit den problematischen Folgen, die schon erläutert wurden. Wer-
den statt doppelter Anführungszeichen (") einfache Anführungszei-
chen (') benutzt, wird auch eine Tabelle für die Zeichenkette
erzeugt, allerdings ohne schließende 0.
Beispiel
char meinString[8]; // leere Zeichenkette der Größe 8
// explizite Initialisierung der Zeichenkette mit schließender 0
// Die Null wird als '\0' (Buchstabenwert 0) angegeben.
char meinString2[8] = { 'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0' };
// explizite Initialisierung der Zeichenkette, die 0 ist implizit
char meinString3[8] = { 'a', 'r', 'd', 'u', 'i', 'n', 'o' };
// Initialisierung mit doppelten Anführungszeichen
char meinString4[] = "arduino";
// Initialisierung mit expliziter Größe
char meinString5[8] = "arduino";

Wegen der schließenden 0 sind für die Zeichenkette arduino also


acht Buchstaben notwendig. Es ist auch möglich, direkt eine mit
doppelten Anführungszeichen gekennzeichnete Zeichenkette inner-
halb eines Programms zu benutzen, ohne eine eigene Variable dafür
einzurichten. Es wird allerdings immer noch der notwendige Spei-
cherplatz für diese Variable benutzt. Wenn also viele Zeichenketten
in einem Programm verwendet werden, ist es unter Umständen
auch nötig, ein Auge auf den Speicherplatzverbrauch zu werfen.
Oft muss man in Anwendungen, die viel mit Zeichenketten arbei-
ten (z.B. Anwendungen, die ein Display verwenden), eine Tabelle
von Zeichenketten anlegen. Dazu wird eine sogenannte Zeigerta-
belle verwendet. Zeiger sind ein fortgeschrittenes Konstrukt der
Arduino-Programmiersprache, das hier nur verwendet, aber nicht
weiter erläutert wird. Ein Zeiger »zeigt« auf einen Speicherbereich,
in dem andere Daten gespeichert werden. Für unseren Gebrauch
lassen sich Zeiger so benutzen wie Tabellen. Man kann also grob
sagen, dass die untere Zeigertabelle weitere Tabellen speichert, die
wiederum unsere Zeichenketten enthalten.

Programmwerte (Variablen, Datentypen und Konstanten) 305


Beispiel
char *meineKetten[] = {
"meine erste Kette",
"meine zweite Kette",
"meine dritte Kette"
};
[Link](meineKetten[0]);
[Link](meineKetten[1]);

So wie Tabellen können auch Strings durchlaufen werden. Aller-


dings ist die Länge der Zeichenkette nicht bekannt, und die schlie-
ßende 0 muss erkannt werden.
Beispiel
char meinString[] = "arduino";
for (int i = 0; meinString[i] != 0; i++) {
sendCharacter(meinString[i]);
}

Variablen
Mit Variablen lassen sich Speicherbereiche mit symbolischen
Namen verbinden. Das erleichtert erheblich die Programmierung,
weil sich so mit einem informativen Namen Werte auslesen und
speichern lassen. Zum Beispiel kann die Variable sensorWert
benutzt werden, um den zuletzt ausgelesenen Statuswert eines Sen-
sors zu speichern.
Jede Variable ist mit einem Datentyp verbunden. So kann beim
Kompilieren des Programms berechnet werden, welcher Bereich im
Speicher belegt ist und wie mit den dort gespeicherten Werten
gerechnet werden muss. Dadurch können Tabellenzugriffe und
Zeichenkettenzugriffe berechnet werden.
Variablen sind eines der wichtigsten Konzepte beim Programmie-
ren, und sie sind in quasi jedem Programm mehrfach anzutreffen.
Die Wahl der benutzten Variablen (also der Namen für Speicherbe-
reiche) ist äußerst wichtig für die Strukturierung eines Programms.
Namen dienen auch zur menschlichen Verständlichkeit eines Pro-
gramms. So sollte eine Variable namens zaehler nicht benutzt wer-
den, um eine Zeichenkette zu speichern, da das verwirrend sein
kann, wenn man ein Programm nach einiger Zeit wieder modifizie-
ren und dazu verstehen will.
Beispiel
char meinString[] = "hallo"; // Die Variable meinString speichert
// einen String.
int meineZahl = 5; // Die Variable meineZahl speichert eine Zahl

306 Anhang C: Sprachreferenz


// vom Datentyp int.
int meineTabelle = 5; // Der Name meineTabelle ist schlecht
// gewählt, da meineTabelle eine Zahl
// speichert.

Um die Arbeit mit Variablen zu erleichtern, benutzt die Arduino-


Programmiersprache das Konzept der Variablensichtbarkeit. Nicht
an allen Orten im Programm sind alle Variablen erreichbar. Als
Faustregel gilt, dass innerhalb von geschweiften Klammern defi-
nierte Variablen nur in diesem Bereich auch sichtbar sind (man
nennt sie lokale Variablen). Die äußerste Ebene des Programms ist
die globale Ebene, in der sogenannte globale Variablen (und Funk-
tionen) definiert werden können. Diese globalen Variablen sind im
gesamten Programm sichtbar und können deshalb benutzt werden,
um Informationen zu speichern, die zentral für das Programm sind.
Weiterhin kann eine Variable nicht benutzt werden, bevor sie
deklariert wird.
Geschweifte Klammern können geschachtelt werden (besonders
mit Kontrollstrukturen, siehe den entsprechenden Abschnitt). Vari-
ablen sind somit auch geschachtelt, und es gilt immer die zuletzt
definierte Version einer Variablen. Hier ist auch Vorsicht geboten,
weil so mehrere Variablen mit demselben Namen (aber in anderen
Speicherbereichen) definiert werden und dann im Programm-
Quellcode verwirrend sein können (und zu Fehlern führen).
Beispiel
int globaleZahl = 5; // globaleZahl ist eine globale Variable und
// von überall aus zugreifbar.
void setup() {
int lokaleZahl = 5; // lokaleZahl ist nur innerhalb der
// setup-Funktion erreichbar.
for (int i = 0; i < 10; i++) {
int lokalereZahl = 8; // i und lokalereZahl sind nur
// innerhalb der for-Schleife
// erreichbar.
int lokaleZahl = 10; // Innerhalb der for-schleife
// wurde auch eine neue
// Variable namens lokaleZahl
// definiert. Innerhalb der
// Schleife hat lokaleZahl den
// Wert 10.
lokaleZahl = 18; // Hier wird die Variable
// lokaleZahl überschrieben, die
// innerhalb der for-Schleife
// definiert wurde.
}
// Hier hat lokaleZahl wieder den Wert 5.
}

Programmwerte (Variablen, Datentypen und Konstanten) 307


Eine weitere Faustregel ist, dass Variablen immer im kleinstmögli-
chen Bereich definiert sein sollten. Werden Variablen außerhalb
geschweifter Klammern nicht benutzt, ist es sinnvoll, sie in diesem
Bereich auch zur definieren.
Oft werden globale Variablen als Konfigurationsvariablen benutzt.
Diese setzen dann z.B. die Pinbelegung für das Arduino-Programm
fest oder ermöglichen es, schnell bestimmte Zeitintervalle zu
definieren. Es ist oft nützlich, diese globalen Konfigurationsvariab-
len unmittelbar am Anfang des Programms zu schreiben, damit sie
alle an einem Ort gruppiert erscheinen. Späterer Benutzer des Pro-
gramms können dann schnell bestimmte Konfigurationswerte ein-
stellen, ohne im kompletten Programm nach ihnen suchen zu
müssen.

Konstanten
Konstanten sind eine besondere Art von Variablen, die nicht verän-
dert werden können. Konstanten belegen meistens auch keinen
Speicherplatz (außer Tabellen und Zeichenketten) und werden oft
benutzt, um bestimmten festen Werten symbolische Namen zuzu-
ordnen (zum Beispiel die Nummer eines Pins, der eine bestimmte
Funktion erfüllt, die Nummer eines bestimmten Kommandos auf
einem externen Sensor oder ein Konfigurationsparameter der Soft-
ware). Eine Konstante wird mit dem Wort const deklariert. Bei
Schreibzugriffen auf diese Variable meldet die Arduino-Software
einen Programmierfehler.
Beispiel
const int ledPin = 5; // ledPin kann nicht verändert werden und
// hat den Wert 5.

Allgemein ist es sehr praktisch, häufig benutzte explizite Werte


(zum Beispiel eine Pinnummer, die häufig verwendet wird, oder die
Dauer für einen sleep()-Aufruf) als Konstanten zu deklarieren.
Damit sind diese Konfigurationswerte später leicht zu ändern, weil
sie nur an der Definitionsstelle der Konstante geändert werden
müssen, nicht an jeder Einsatzstelle. Weiterhin wird mit der Defini-
tion der Konstante jeder Programmierer, der das Programm zu
einem späteren Zeitpunkt verwendet, darauf hingewiesen, dass ein
bestimmter Konfigurationswert benutzt wird, und welche Bedeu-
tung dieser Wert hat (wenn der Name der Konstante gut gewählt
wurde).

308 Anhang C: Sprachreferenz


Beispiel
const int ledPin = 5;
digitalWrite(ledPin, HIGH); // Diese Schreibweise ist leichter zu
// verstehen ...
digitalWrite(5, HIGH); // ... als diese Schreibweise.

Ausdrücke und Anweisungen


In der Arduino-Programmiersprache wird zwischen zwei Arten von
Programmierbefehlen unterschieden. Auf der einen Seite gibt es
Ausdrücke, die einen bestimmten Wert berechnen, den Rückgabe-
wert. Diese Art von Programmierbefehlen ist mit einer Funktions-
definition in der Mathematik zu vergleichen: Aus bestimmten
Werten (Konstanten oder Variablen) wird ein neuer Wert berech-
net, zum Beispiel werden mit dem Programmierbefehl a + b die
Variablen a und b addiert. Ausdrücke lassen sich in beliebiger
Weise kombinieren und schachteln, mit ähnlichen Regeln wie in
der Mathematik. Es ist oft wichtig, runde Klammern (( und )) zu
benutzen, um die Reihenfolge der Ausdrücke korrekt zu berechnen.
Da jeder Ausdruck einen Wert berechnet, hat jeder Ausdruck auch
einen entsprechenden Datentyp, den man Rückgabetyp nennt. Die-
ser hängt sowohl vom Ausdruck als auch von den im Ausdruck
benutzten Datenwerten ab. Im nächsten Abschnitt werden die ver-
schiedenen Ausdrücke der Arduino-Programmiersprache erläutert.
Eine spezielle Art von Ausdrücken sind Funktionsaufrufe, die in
dem Abschnitt über Funktionen erklärt werden.
Auf der anderen Seite gibt es sogenannte Anweisungen, die im
Unterschied zu Ausdrücken keine Werte berechnen, sondern orga-
nisatorische Rollen übernehmen und den Status des Prozessors
beeinflussen (einen Wert zu berechnen, verändert erst einmal
nichts, dazu muss er zunächst gespeichert werden). Sie bestimmen
auch die Struktur des Programms, also welche Funktionen es gibt
und welche Variablen definiert werden. Sie bestimmen auch, wel-
cher Weg durch das Programm letztendlich benutzt wird (welche
Anweisungen ausgeführt werden). Diesen Weg und seine Steue-
rung nennt man den Programmkontrollfluss.
Ausdrücke sind auch Anweisungen, allerdings bewirken Ausdrücke
(außer den Zuweisungsausdrücken, siehe den Abschnitt über Aus-
drücke) nichts: Die Werte, die sie berechnen, werden nirgendwo
gespeichert, und meistens werden allein stehende Ausdrücke vom
Compiler ignoriert.

Ausdrücke und Anweisungen 309


Eine Art von Anweisungen wurde schon erläutert, die Variablende-
klaration. Eine weitere Kategorie von Anweisungen sind Kontroll-
strukturen und Funktionsdefinitionen, die in in ihren entsprechen-
den Abschnitten erläutert werden.

Ausdrücke
Die einfachste Art Ausdruck in der Arduino-Programmiersprache
haben wir schon oft gesehen. Es ist ein einfacher expliziter Wert,
z.B. eine Zahl oder die Angabe einer Zeichenkette. Dieser Aus-
druck hat den Typ des expliziten Werts, und der Wert ist natürlich
die angegebene Zahl. Bei Zeichenketten ist der Wert die Adresse
der Speicherkette, dieses Detail ist allerdings in den meisten Ardu-
ino-Programmen nicht von Bedeutung.
Beispiel
5; // Zahlenausdruck mit Wert 5
"arduino"; // Der Wert dieses Ausdrucks ist die Adresse der
// Zeichenkette.
// Beide Ausdrücke werden vom Compiler ignoriert.

Variablenzuweisung
Ein weiterer Ausdruck ist die Variablenzuweisung, die das Gleich-
heitszeichen (=) als Symbol verwendet. Auf der linken Seite des =
steht die Variable, der ein Wert zugewiesen werden soll, und auf
der rechten Seite steht der Ausdruck, der berechnet und anschlie-
ßend gespeichert werden soll.
Eigentlich ist die Variablenzuweisung eine Anweisung, sie hat
jedoch den zugewiesenen Wert als Rückgabewert und den Typ der
zugewiesenen Variable als Rückgabetyp (das ist wichtig bei der
automatischen Datentypkonvertierung, die weiter unten erklärt
wird). Dadurch ist es möglich, mehrere Variablenzuweisungen zu
schachteln und Variablenzuweisungen innerhalb von weiteren Aus-
drücken zu verwenden. Hier ist aber wieder Vorsicht geboten, weil
deswegen die Zuweisungsreihenfolge von Variablen nicht unbe-
dingt klar ersichtlich ist. Es ist deswegen ratsam, Zuweisungen bes-
ser als getrennte Anweisungen in das Programm zu schreiben.
Beispiel
int i = 0; // Die Variable i wird mit 0 initialisiert
// (kein Ausdruck).
int j = 2; // Die Variable j with mit 2 initialisiert.
i = 5; // Der Variable i wird der Wert 5 zugewiesen.

310 Anhang C: Sprachreferenz


j = i = 6; // Der Variable i wird der Wert 6 zugewiesen,
// dann wird der Variable j der Wert 6 zugewiesen.
j = (i = 5) * 2; // Der Variable i wird der Wert 5 zugewiesen,
// der Variable j wird der Wert 10 zugewiesen.
i = 5; // Es ist allerdings ratsamer, die vorige Zeile
// in zwei getrennte
j = i * 2; // Zuweisungen zu schreiben. Der erzeugte
// Maschinencode ist in beiden Fällen identisch.

Ein häufiger Fehler beim Lernen der Arduino-Programmiersprache


(und von C und C++) ist das Verwechseln der Variablenzuweisung
= und der Vergleichsoperation == (siehe Abschnitt Vergleichsopera-
tionen). Im ersten Fall wird ein Wert gespeichert, und der Rückga-
bewert des Ausdrucks ist dieser Wert. Im zweiten Fall werden zwei
Werte verglichen (es wird kein Wert gespeichert), und der Rückga-
bewert des Ausdrucks ist ein Boolescher Wert true oder false. Es
kommt ziemlich häufig vor, dass = statt == verwendet wird, und der
Compiler meldet auch keinen Fehler. Im Programm ist ein solcher
Fehler auch schwer zu erkennen, weil = und == ähnlich aussehen.
Ein Weg, um das zu umgehen, ist, bei Vergleichsoperationen mit
literalen Werten den literalen Wert auf die linke Seite zu schreiben.
Wird dann = mit == verwechselt, meldet der Compiler einen Fehler,
weil in einem literalen Wert nichts gespeichert werden kann.
Beispiel
if (i = 2) { // Hier wird nicht i mit 2 verglichen, sondern i wird
// 2 zugewiesen.
}
if (2 == i) { // Mit dieser Schreibweise lassen sich solche
// Verwechslungen oft vermeiden.
}

Operationen
Der Großteil der Ausdrücke in der Arduino-Programmiersprache
sind Operationen, die aus einem oder mehreren Argumenten einen
neuen Wert berechnen. Es gibt mehrere Arten von Operationen,
die innerhalb von Ausdrücken benutzt werden können. Eine Ope-
ration nimmt einen oder mehrere Werte und berechnet daraus
einen neuen Ergebniswert. Je nach Operationsart und Typ der Ein-
gabewerte werden Werte mit unterschiedlichen Datentypen
berechnet.
Wir stellen Ihnen jetzt zuerst die verschiedenen Operationen im
Überblick vor und erklären sie im weiteren Abschnitt dann detail-
liert.

Ausdrücke 311
Arithmetische Operationen berechnen aus Zahlenwerten einen
neuen Zahlenwert: Es sind die bekannten Operationen wie Addie-
ren, Subtrahieren, Multiplizieren und Teilen. Logische Operatio-
nen berechnen aus Bitmasken neue Bitmasken (Bitmasken sind
binär dargestellte Zahlen), es sind die Operationen »und« (&),
»oder« (|), »exklusiv oder« (^), »Negieren« (~) und »Shiften« (<<
und >>). Boolesche Operationen berechnen aus den Booleschen
Werten »wahr« und »falsch« neue Boolesche Ergebniswerte, die
Operationen »und« (&&), »oder« (||) und »Negieren« (!). Diese sind
sehr einfach mit den logischen Operationen zu verwechseln, sind
aber ganz anders definiert (die Unterschiede werden weiter unten
im Abschnitt über logische Operationen erläutert).
Viele Operationen arbeiten mit Booleschen Werten (also mit
»wahr« oder »falsch«). Diese Werte müssen natürlich auch im Spei-
cher des Arduino-Prozessors gespeichert werden, entweder als Bit
in einem größeren numerischen Wert oder als eigener Wert (z.B.
wenn dieser Boolesche Wert in einer Variable gespeichert wird).
Deswegen gibt es Konvertierungsregeln, die einen Booleschen Wert
in einen numerischen Wert (oder Bitwert) konvertieren und anders
herum. Falsch wird generell als 0 kodiert (also als numerischer
Wert 0 oder als Bitwert 0). Wahr sind dementsprechend alle Werte,
die nicht 0 sind (also der Bitwert 1 und jeder mögliche numerische
Wert ungleich 0). Diese Unterscheidung mag ein bisschen übertrie-
ben klingen, ist aber sehr wichtig, besonders wenn Vergleichsope-
rationen und logische Operationen verwendet werden.

Datentypkonvertierung
Diese Konvertierung von numerischen Werten zu Booleschen Wer-
ten ist eigentlich nur ein kleiner Einblick in ein größeres Thema: die
Datentypkonvertierung. Generell ist es möglich, Operationen auf
unterschiedliche Datentypen anzuwenden, um zum Beispiel eine
long-Zahl zu einer short-Zahl zu addieren oder um eine signed-Zahl
mit einer unsigned-Zahl zu vergleichen. Es gibt zwei Arten von
Datentypkonvertierungen: implizite und explizite. Implizite Daten-
typkonvertierungen werden automatisch ohne spezielle Markie-
rung vom Programmierer vom Compiler eingefügt, wenn z.B.
unterschiedliche Datentypen im selben Ausdruck vorkommen.
Explizite Datentypkonvertierungen werden vom Programmierer
eingefügt. Es ist nur selten notwendig, explizite Datentypkonvertie-
rungen einzuführen, aber besonders auf einem Mikrocontroller wie
dem Arduino-Prozessor, der über eine begrenzte Menge an Spei-
cher verfügt und intern mit 8 Bit rechnet, ist es in fortgeschrittenen

312 Anhang C: Sprachreferenz


Fällen notwendig, genau zu kontrollieren, welche Datentypen ein-
gesetzt werden.
Die einfachste Art von implizierter Konvertierung geschieht bei der
Zuweisung einer Variable. Hier kann es zwei Möglichkeiten geben.
Im unproblematischen Fall umfasst der Zieldatentyp den Quellda-
tentyp. Im problematischen Fall ist der Zieldatentyp kleiner als der
Quelldatentyp (z.B. wenn ein unsigned-Wert in einen signed-Wert
konvertiert wird, oder wenn ein int-Datentyp in einen byte-Daten-
typ konvertiert wird). In diesem Fall wird der Wert trunkiert, je
nachdem, welche Konvertierung vorgenommen wird. Belegt der
Zieldatentyp weniger Platz im Speicher, wird einfach der obere Teil
des Wertes verworfen, was zu interessanten Ergebnissen führen
kann, wie im folgenden Beispiel gezeigt wird. Wird eine signierte
Konvertierung vorgenommen, wird der alte Wert jetzt signiert
interpretiert, was unter Umständen zu einer kompletten Umkeh-
rung des Wertes führen kann (siehe das Beispiel). Es ist bei Konver-
tierungen also kritisch zu überprüfen, dass keine fehlerhaften
Konvertierungen passieren.
Beispiel
byte b = 5;
int i;
i = b; // Der byte-Wert von b wird in einen int-Wert konvertiert.
i = 260;
b = i; // Der int-Wert von i wird in einen byte-Wert konvertiert.
// Da int zwei Byte belegt, wird das oberste Byte einfach
// verworfen. b hat jetzt den Wert 4.
unsigned byte b2 = 160;
signed byte b3 = b2; // Hier wird 160 als signierte Zahl
// interpretiert.
// Der Wert von b3 ist -96.
b2 = -80; // Hier wird -80 als unsignierte Zahl interpretiert.
// Der Wert von b2 ist 176.
int i2 = 60 * 100; // Der Wert von i2 ist 6000.
int i3 = 60 * 1000; // Der Wert von i3 ist -5536 (!).

Werden unterschiedliche Datentypen im selben Ausdruck verwen-


det, konvertiert der Compiler sie automatisch in den »größten«
Datentyp, der alle benutzten Argumente und das Ergebnis der Ope-
ration beinhalten kann. Wird eine byte-Zahl zu einer weiteren byte-
Zahl addiert, ist das Ergebnis eine int-Zahl, weil das Ergebnis unter
Umständen (z.B. 250 + 8) nicht mehr in das eine Speicherbyte einer
byte-Zahl passen würde. Wird eine byte-Zahl zu einer int-Zahl
addiert, ist das Ergebnis eine long-Zahl, weil wie im vorigen Bei-
spiel das Ergebnis nicht mehr in die zwei Speicherbytes einer int-
Zahl passen würde.

Ausdrücke 313
Besonders knifflig wird die Thematik, wenn signed-Werte und unsi-
gned-Werte im selben Ausdruck verwendet werden. Dadurch wird
der Ausdruck zu einem signierten Ausdruck, und es kann bei der
Zuweisung des Ergebnisses oder beim Vergleich mit unsignierten
Werten schnell zu unerwarteten Ergebnissen kommen. Solche Feh-
ler sind besonders schwer herauszufinden, weil sie beim Lesen des
Programms nicht sofort ersichtlich sind. Falls also bei Rechen-
ausdrücken oder Vergleichen (insbesondere in Schleifen) unerwar-
tete Werte auftreten, ist es manchmal notwendig, die Ausdrücke
ganz genau unter die Lupe zu nehmen, und zur Not explizite
Datentypkonvertierungen zu verwenden.
Einer der häufigsten Fehler ist der Vergleich von signed- und unsig-
ned-Zahlen, der immer wahr oder immer falsch ist und zum Bei-
spiel zu nie endenden Schleifen führen kann. Solche simplen Fehler
werden häufig vom Compiler erkannt, aber nur als Warning
gekennzeichnet, sodass man sie in der Arduino-Umgebung, wenn
die verbose-Kompilation nicht angeschaltet ist, nicht zu sehen
bekommt.
Explizite Datentypkonvertierungen werden vom Programmierer
eingefügt. Hier wird vor dem zu konvertierenden Ausdruck in
Klammern der Zieldatentyp angegeben. Es gelten die gleichen
Regeln und Warnungen wie für implizite Datentypkonvertierungen.
Beispiel
short s = 2;
int i = (int)s; // explizite Konvertierungen von short nach int

Präzedenzregeln
Bei Ausdrücken gibt es in der Arduino-Programmiersprache festge-
legte Präzedenzregeln (in welcher Reihenfolge Ausdrücke berechnet
werden). Generell gelten die üblichen arithmetischen Regeln (Mul-
tiplikation und Division vor Addition und Subtraktion), ansonsten
wird der Ausdruck von links nach rechts ausgewertet. Das ist bei
längeren Ausdrücken schwer nachzuvollziehen, insbesondere wenn
Operationen verwendet werden, die programmiersprachenspezi-
fisch sind. Es ist möglich, die Auswertungsreihenfolge explizit zu
beschreiben, indem man runde Klammern benutzt. Ausdrücke
innerhalb von Klammern werden als Erstes berechnet und ihr
Ergebnis im übergeordneten Ausdruck eingesetzt. Runde Klam-
mern können beliebig geschachtelt werden.

314 Anhang C: Sprachreferenz


Auch hier ist es manchmal angebracht, der Lesbarkeit halber den
Ausdruck in mehrere einzelne Ausdrücke aufzutrennen, die in
lokale Variablen gespeichert werden. Oft hat das keinen Einfluss
auf die Geschwindigkeit eines Programms.
Beispiel
int i = 5 + 2 * 6 – 8 / 2; // Der Wert von i ist 13.
int i2 = ((5 + 2) * 6 – 8) / 2; // Der Wert von i2 ist 17.
// Hier wird der Ausdruck von i2 in mehrere einzelne lokale
// Variablen aufgetrennt.
int tmp1 = 5 + 2;
int tmp2 = tmp1 * 6 – 8;
int i3 = tmp2 / 2; // Der Wert von i3 ist 17.

Arithmetische Operationen
Die arithmetischen Operationen in der Arduino-Programmierspra-
chen sind die üblichen mathematischen Operationen: Addition,
Subtraktion, Multiplikation und Division.
Eine spezielle arithmetische Operation ist die Modulo-Operation,
die den Restwert einer ganzzahligen Division berechnet. Die
Modulo-Operation ist auf Fließkommazahlen nicht definiert. Die
Modulo-Operation wird häufig benutzt, um einen Wert innerhalb
eines bestimmten Bereichs zu halten (z.B. innerhalb der Größe
einer Tabelle). Die Modulo-Operation mit einem Teiler, der eine
Zweierpotenz ist (also 2, 4, 8, 16, 32 usw.), lässt sich auf einem
Computer besonders effizient ausführen. Es ist also aus Geschwin-
digkeitsgründen wichtig, bei häufig benutzten Tabellen, auf die
mithilfe der Modulo-Operation zugegriffen wird, eine Zweierpo-
tenz als Größe zu wählen.
Beispiel
byte b = 5 % 3; // Der Wert von b ist 2, weil 2 der Restwert von 5
// geteilt durch 3 ist.
byte b2 = 65 % 20; // Der Wert von b2 ist 5, weil 5 der Restwert
// von 65 geteilt durch 20 ist.
int tabelle[64]; // eine Tabelle mit 64 Werten
int index = 40;
tabelle[index % 64] = 5; // So ist gewährleistet, dass der
// Indexwert immer innerhalb der Tabelle
// ist.
tabelle[index % 64]; // Diese Operation ist um ein Vielfaches
// schneller als:
tabelle[index % 63];

Wird die Divisionsoperation auf ganzzahlige Wert angewendet, ist


das Ergebnis auch eine ganzzahlige Zahl, es wird also die ganzzah-

Ausdrücke 315
lige Division angewendet. Soll eine Fließkommazahl berechnet
werden, muss mindestens eins der Divisionsargumente eine Fließ-
kommazahl sein (also vom Datentyp float oder double). Das lässt
sich entweder durch explizite Datentypkonvertierung erreichen,
oder indem literale Werte mit einem Komma (geschrieben als
Punkt) angegeben werden (zur Not mit ».0«).
Beispiel
byte b = 5 / 2; // Der Wert von b ist 2.
float f = 5 / 2; // Der Wert von f ist 2.0.
float f2 = 5.0 / 2.0; // Der Wert von f2 ist 2.5.

In der folgenden Tabelle werden alle arithmetischen Operationen


zur Referenz aufgelistet.

Tabelle C-3 Zeichen Name Erklärung


Arithmetische Operationen
+ Addition addiert zwei Zahlen
- Subtraktion subtrahiert zwei Zahlen
* Multiplikation multipliziert zwei Zahlen
/ Division teilt zwei Zahlen (wenn beide Argumente ganzzahlig sind, ist die
Division ganzzahlig)
% Modulo Berechnet den Restwert der ganzzahligen Division von zwei Zahlen

Logische Operationen
Logische Operationen rechnen mit Bitwerten, also mit 0 und 1. Da
sich aber einzelne Bitwerte nicht direkt auf dem Arduino-Prozessor
speichern lassen, arbeiten die logischen Operationen mit den ein-
zelnen Bits der normalen numerischen Datenwerte (also mit der
Bitmaskendarstellung, siehe Abschnitt Datentypen). Die logische
Operation wird auf jedes einzelne Bit des numerischen Wertes
getrennt angewendet.
Das logische UND (&) und das logische ODER (|) ähneln den Boo-
leschen Operatoren UND (&&) und ODER (||), und beide Operato-
ren sind leicht zu verwechseln. Die logischen Operationen arbeiten
jedoch auf numerische Werte und beeinflussen jedes einzelne Bit
dieser Werte, während die Booleschen Operatoren mit Booleschen
Werten arbeiten (0 ist falsch, alles andere ist wahr). Dazu werden
numerische Argumente erst in Boolesche Werte konvertiert (siehe
oben im Abschnitt »Datentypkonvertierung« in diesem Anhang).
Viele der logischen Operatoren werden benutzt, um einzelne Bits
auf 0 oder auf 1 zu setzen. Deswegen bietet die Arduino-Program-
mierumgebung ein Funktion, um eine Bitmaske zu erzeugen, in der

316 Anhang C: Sprachreferenz


ein einziges Bit gesetzt ist. Diese Funktion heißt bit(bitNummer).
Hier muss beachtet werden, dass bitNummer bei 0 anfängt, also
bit(0) verwendet wird, um eine Bitmaske zu erzeugen, in der das
unterste (also das letzte) Bit auf 1 gesetzt ist.
Beispiel
byte a = bit(4); // a wird auf 00010000 gesetzt.
a = bit(0); // a wird auf 00000001 gesetzt.

In der folgenden Tabelle sind alle logische Operationen zur Refe-


renz aufgelistet.

Zeichen Name Erklärung Tabelle C-4


Logische Operationen
& Und logisches UND, Maskierung
(1 & 1 = 1, sonst 0)
| Oder logisches ODER
(0 | 0 = 0, sonst 1)
^ Exklusiv-Oder exklusives ODER (gibt 1 zurück, wenn genau eins der
Argumente 1 ist)
~ Bitweise negieren invertiert jedes Bit (aus 1 wird 0, aus 0 wird 1)
<< Shift nach links bewegt alle Bits um eine Stelle nach links und füllt mit 0 auf
>> Shift nach rechts bewegt alle Bits um eine Stelle nach rechts und füllt mit dem
Sign-Bit nach, wenn notwendig, sonst mit 0

& : Logisches UND (Maskierung)


Die &-Operation ist der logische UND-Operator. Er gibt 1 zurück,
wenn seine beiden Argumente auch 1 sind. Seine Funktionsweise
lässt sich am leichtesten mit der folgenden Tabelle erläutern. Das
&-Zeichen muss immer mit Leerzeichen abgetrennt werden, da es
in der Arduino-Programmiersprache eine fortgeschrittene (und
ganz andere) Bedeutung hat, wenn es direkt an einem Wort hängt .

a b a&b Tabelle C-5


Logische UND-Operation
0 0 0 & 0 = 0
0 1 0 & 1 = 0
1 0 1 & 0 = 0
1 1 1 & 1 = 1

In den folgenden Beispielen wird der logische UND-Operator auf


numerische Datenwerte angewendet (die obige Funktionstabelle
wird auf jedes einzelne Bit der Datenwerte angewendet).

Ausdrücke 317
Beispiel
byte a = 5; // a ist 00000101 in Binärdarstellung.
byte b = 3; // b ist 00000011 in Binärdarstellung.
byte c = a & b; // c ist a & b = 00000101 & 00000011 = 00000001 = 1.
a = 0xFE; // a ist 11111110 in Binärdarstellung.
c = a & b; // c ist a & b = 11111110 & 00000011 = 00000010 = 2.

Üblicherweise wird der Maskierungsoperator verwendet, um ein-


zelne Bits aus einem Wert zu extrahieren oder zu testen. So kann
man das letzte Bit aus einem Wert (oder einem Eingangsport des
Arduino) extrahieren, indem man ihn mit 1 maskiert. Das letzte Bit
in einem Wert kennzeichnet, ob der Wert gerade oder ungerade ist,
so lässt sich also mit dem Maskierungsoperator bestimmen, ob eine
Zahl gerade oder ungerade ist, ohne sie durch 2 teilen zu müssen.
Beispiel
byte a = 5;
if (a & 1) {
// a ist ungerade, da das letzte Bit gesetzt ist.
} else {
// a ist gerade, da das letzte Bit nicht gesetzt ist.
}

Ähnlich lassen sich z.B. die vier unteren Bits oder die vier oberen
Bits aus einem Wert extrahieren (das ist manchmal notwendig,
wenn z.B. ein Sensor zwei 4-Bit-Werte in einem Byte zurückgibt).
Um die Werte auch richtig zu bearbeiten, wird oft noch der Shift-
Operator (siehe Abschnitt über Shift-Operator) eingesetzt, um die
extrahierten Bits an die unterste Stelle zu bewegen.
Beispiel
byte a = 0xfe;
byte untereBits = (a & 0xF); // extrahiert die 4 unteren Bits, da
// 0xF = 00001111
byte obereBits = (a & 0xF0) >> 4; // extrahiert die 4 oberen Bits,
// da 0xF0 = 11110000

Mit dem Maskierungsoperator ist es auch möglich, bestimmte Bits


auf 0 zu setzen. Im folgenden Beispiel wird gewährleistet, dass das
oberste Bit der Variable value auf 0 gesetzt wird.
Beispiel
value = value & 0x7F; // Das oberste Bit von value ist immer 0, da
// 0x7F = 01111111.

Oft werden auch Masken als Konstanten definiert (siehe Abschnitt


über Konstanten), um den Programmtext besser lesbar zu machen.
Die obigen Beispiele lassen sich auch wie folgt schreiben:

318 Anhang C: Sprachreferenz


Beispiel
const byte UntereBitsMaske = 0x0F;
const byte ObereBitsMaske = 0xF0;
byte a = 0xfe;
byte untereBits = (a & UntereBitsMaske);
byte obereBits = (a & ObereBitsMaske) >> 4;
const byte ValueByteMaske = 0x7F; // Diese Maske wird auf alle
// Values angewendet.
value = value & ValueByteMaske;

|: Logisches ODER
Das | ist der logische ODER-Operator. Er gibt 1 zurück, wenn min-
destens eins seiner Argumente auch 1 ist. Seine Funktionsweise
lässt sich am besten mit der folgenden Tabelle erläutern.

a b a|b Tabelle C-6


Logische ODER-Operation
0 0 0 | 0 = 0
0 1 0 | 1 = 1
1 0 1 | 0 = 1
1 1 1 & 1 = 1

In den folgenden Beispielen wird der logische ODER-Operator auf


numerische Datenwerte angewendet (die obige Funktionstabelle
wird auf jedes einzelne Bit der Datenwerte angewendet).
Beispiel
byte a = 5; // a ist 00000101 in Binärdarstellung.
byte b = 3; // b ist 00000011 in Binärdarstellung.
byte c = a | b; // c ist a | b = 00000101 | 00000011 = 00000111 = 7.
a = 0x8E; // a ist 10001110 in Binärdarstellung.
c = a | b; // c ist a | b = 10001110 | 00000011 = 10001111 = 0x8F.

Üblicherweise wird der ODER-Operator verwendet, um einzelne


Bits in einem Wert auf 1 zu setzen. Hier lässt sich die Funktion
bit(bitNummer) einsetzen, um gezielt einzelne Bits auf 1 zu setzen.
Beispiel
value = value | 1; // Das unterste Bit in value wird auf 1
// gesetzt.
byte a = bit(0) | bit(2) | bit(4); // a wird auf 00010101 gesetzt.

^: Exklusives ODER
Das ^ ist der exklusive ODER-Operator. Er gibt 1 zurück, wenn
genau eins seiner Argumente auch 1 ist. Seine Funktionsweise lässt
sich am besten mit der folgenden Tabelle erläutern .

Ausdrücke 319
Tabelle C-7 a b a^b
Exklusive ODER-Operation
0 0 0 ^ 0 = 0
0 1 0 ^ 1 = 1
1 0 1 ^ 0 = 1
1 1 1 ^ 1 = 0

In den folgenden Beispielen wird der exklusive ODER-Operator auf


numerische Datenwerte angewendet (die obige Funktionstabelle
wird auf jedes einzelne Bit der Datenwerte angewendet).
Beispiel
byte a = 5; // a ist 00000101 in Binärdarstellung.
byte b = 3; // b ist 00000011 in Binärdarstellung.
byte c = a ^ b; // c ist a ^ b = 00000101 ^ 00000011 = 00000010 = 2.
a = 0x8E; // a ist 10001110 in Binärdarstellung.
c = a ^ b; // c ist a ^ b = 10001110 ^ 00000011 = 10000001 = 0x81.

Üblicherweise wird der exklusive ODER-Operator verwendet, um


einzelne Bits umzukehren, ohne andere Bits zu beeinflussen. Das ist
besonders praktisch, um zum Beispiel eine bestimmte LED bei
jedem Durchlaufen einer Funktion blinken zu lassen (beim ersten
Durchlauf anschalten, beim nächsten Durchlauf ausschalten, dann
wieder anschalten usw.), wenn der Wert dieser LED zusammen mit
den Werten anderer LEDs in einer Variable gespeichert wird (wie
bei unserer LED-Matrix, siehe ).
Beispiel
byte ledZeile = 0; // ledZeile speichert den Wert von 8 LEDs
void toggleLed() {
ledZeile = ledZeile ^ 1; // die unterste LED in ledZeile wird
// invertiert
}

~: Logische Negierung
Die Tilde ~ ist der logische Negierungsoperator, der ein einzelnes
Argument annimmt (das auf eine rechte Seite geschrieben wird). Er
gibt 1 zurück, wenn er auf 0 angewendet wird, und 0, wenn er auf 1
angewendet wird, wie der folgenden Tabelle zu entnehmen ist.

Tabelle C-8 a ~a
Logische Negierung
0 ~0 = 1
1 ~1 = 0

In den folgenden Beispielen wird die logische Negierung auf nume-


rische Datenwerte angewendet (die obige Funktionstabelle wird auf
jedes einzelne Bit der Datenwerte angewendet).

320 Anhang C: Sprachreferenz


Beispiel
byte a = 5; // a ist 00000101 in Binärdarstellung.
byte c = ~a; // c ist ~a = ~00000101 = 11111010 = 0xFA.
a = 0x8E; // a ist 10001110 in Binärdarstellung.
c = ~a; // c ist ~a = ~10001110 = 01110001 = 0x71.

Üblicherweise wird der Negierungsoperator verwendet, um jedes


Bit in einem Wert umzukehren.

<<: Shift nach links


Die <<-Operation verschiebt die Bits in einem Wert um eine
bestimmte Anzahl von Stellen nach links. (Auf Englisch heißt ver-
schieben »to shift«, diese Operation wird auch auf Deutsch übli-
cherweise »shiften« genannt.) Die dadurch »entstehenden« Stellen
werden mit Nullen gefüllt. Bits, die nicht mehr in den Datentyp
hineinpassen, verschwinden.
Beispiel
byte a = 5; // a ist 00000101 in Binärdarstellung.
byte b = a << 2; // b ist 00010100 in Binärdarstellung,
// der Wert von a wurde um 2 Stellen nach links
// verschoben.
byte c = 0x7F; // c ist 01111111.
byte d = c << 3; // d ist 11111000.

In Kombination mit der |-Operation lassen sich so beliebige Bit-


masken erstellen. Eine eigene Implementierung der bit(bitNum-
mer)-Funktion (die allerdings nur für byte-Bitmasken funktioniert)
könnte in etwa so aussehen wie im folgenden Beispiel (um mehr zu
Funktionsdefinition zu erfahren, siehe den Abschnitt Funktionen).
Beispiel
byte meinBv(uint8_t bitNummer) {
return (1 << bitNummer);
}

Da auf einem Computer Zahlen in Binärdarstellung gespeichert


werden, ist die Shift-nach-links-Operation eine effiziente Art,
Werte mit einer Zweierpotenz zu multiplizieren. Einen Wert um
eine Stelle nach links zu verschieben, entspricht einer Multiplika-
tion mit der Zahl 2. Einen Wert um zwei Stellen nach links zu ver-
schieben, entspricht einer Multiplikation mit der Zahl 4 usw.
Deswegen lassen sich Multiplikationen mit Zweierpotenzen oft
schneller ausführen als allgemeine Multiplikationen.
Beispiel
byte a = 5;
byte b = a << 2; // b ist gleich 5 * 4 = 20.

Ausdrücke 321
>>: Shift nach rechts
Die >>-Operation verschiebt die Bits in einem Wert um eine
bestimmte Anzahl von Stellen nach rechts. Im Unterschied zur
Shift-nach-links-Operation werden allerdings die »entstehenden«
Stellen nicht immer mit Nullen gefüllt. Wegen der Zweierkomple-
ment-Darstellung (siehe Abschnitt über Datentypen) ist bei negati-
ven Zahlen das oberste Bit auf 1 gesetzt. Um das Vorzeichen eines
Wertes beim Shiften nach rechts zu erhalten, wird dementspre-
chend bei negativen Zahlen mit Einsen aufgefüllt. Deswegen ist
Vorsicht beim Shiften nach rechts geboten, weil unerwartete Werte
herauskommen können.
Um zu vermeiden, dass mit dem obersten Bit bei negativen Zahlen
aufgefüllt wird, kann der Wert vor dem Shiften mit einer expliziten
Datentypkonvertierung zuerst in einen unsigned-Wert konvertiert
werden.
Beispiel
byte a = 5; // a ist 00000101 in Binärdarstellung.
byte b = a >> 2; // b ist 00000001 in Binärdarstellung,
// der Wert von a wurde um zwei Stellen nach
// rechts verschoben. Da a keine signed Nummer
// ist, wird hier mit 0 aufgefüllt.

signed byte c = -16; // c ist 11110000 in Binärdarstellung.


signed byte d = c >> 3; // d ist 11111110 in Binärdarstellung.
signed byte e = (unsigned)c >> 3; // d ist 00011110 in
// Binärdarstellung.

Ähnlich wie die >>-Operation entspricht die Shift-nach-rechts-


Operation einer ganzzahligen Division durch eine Zweierpotenz.
Beispiel
byte a = 100;
byte b = a >> 2; // b ist gleich 100 / 4 = 25.

Mit dem >>-Operator und dem logischen UND (&) lassen sich ein-
zelne Bits aus einem Wert extrahieren und in einem anderen spei-
chern.
Beispiel
byte b = (a >> 2) & 1; // Das dritte Bit von a wird in b
// gespeichert.

Vergleichsoperationen
Vergleichsoperationen sind eine der am häufigsten eingesetzten
Arten von Operationen, insbesondere kombiniert mit dem Einsatz

322 Anhang C: Sprachreferenz


von Kontrollstrukturen (siehe Abschnitt von Kontrollstrukturen).
Mit Vergleichsoperationen lassen sich zwei Werte vergleichen. Der
Rückgabetyp von Vergleichsoperationen ist ein Boolescher Wert,
der sich auch als numerischer Wert einsetzen lässt (wahr ist 1,
falsch ist 0).
Der ==-Operator vergleicht, ob zwei Werte gleich sind. Dieser Ope-
rator sollte nicht mit dem Zuweisungsausdruck (=) verwechselt wer-
den. Der !=-Operator ist das genaue Gegenteil des ==-Operators und
gibt immer »wahr« zurück, wenn zwei Werte unterschiedlich sind.
Beispiel
byte a = 255;
byte b = 101;
signed byte c;
a == 255; // ist wahr
a != 255; // ist falsch
a == b; // ist falsch
a != b; // ist wahr
byte d = a == b; // d hat jetzt den Wert 0.
c == 128; // ist immer falsch, egal welchen Wert c hat,
// da der Datentyp von c 128 nicht umfasst
c != 128; // ist immer wahr
a = b; // Das ist eine Zuweisung und kein Vergleich!
char x = 'a';
x == 'a'; // ist wahr

Zeichenketten lassen sich allerdings nicht so einfach vergleichen,


weil der »eigentliche« Wert einer Zeichenkette ihre Adresse im
Speicher ist, nicht die Zeichenketten als solche. Auch Tabellen las-
sen sich nicht mit Vergleichsoperationen vergleichen.
Beispiel
char meineKette[] = "foobar";
meineKette == "foobar"; // ist falsch
int meineTabelle[] = { 1, 2, 3};
int meineTabelle2[] = { 1, 2, 3};
meineTabelle != meineTabelle2; // ist wahr

Ähnlich wie ihre verwandten Operatoren in der Mathematik ver-


gleichen die Operatoren > (größer als), < (kleiner als), >= (größer als
oder gleich) und <= (kleiner als oder gleich) numerische Werte.
Hier sei wieder auf die vom Compiler ausgeführte implizite Typ-
konvertierung und die möglichen Werte der einzelnen Datentypen
hingewiesen.
Beispiel
byte a = 5;
a < 10; // ist wahr
a > 2; // ist wahr

Ausdrücke 323
a > 5; // ist falsch
a >= 5; // ist wahr
a < 300; // ist für jeden Wert von a wahr

In der folgenden Tabelle sind alle Vergleichsoperationen zur Refe-


renz aufgelistet.

Tabelle C-9 Zeichen Name


Vergleichsoperationen
== gleich
!= nicht gleich
< kleiner
<= kleiner oder gleich
> größer
>= größer oder gleich

Boolesche Operationen
Boolesche Operationen ähneln sehr ihren äquivalenten logischen
Operationen. Allerdings arbeiten Boolesche Operationen mit den
Wahrheitswerten »wahr« und »falsch«, nicht mit Bits. Mit Boole-
schen Operationen lassen sich verschiedene Boolesche Ausdrücke
(z.B. Vergleichsoperationen) miteinander verknüpfen.
Das Boolesche UND && (im Unterschied zum logischen UND &)
gibt »wahr« zurück, wenn seine beiden Argumente wahr sind. Das
Boolesche ODER || (im Unterschied zum logischen ODER |) gibt
»wahr« zurück, wenn mindestens eines seiner Argumente wahr ist.
Die Boolesche Negierung ! (im Unterschied zur logischen Negie-
rung ~) gibt »wahr« zurück, wenn ihr Argument falsch ist, und
»falsch«, wenn ihr Argument wahr ist.
Da mit Booleschen Operatoren oft kompliziertere Vergleichsopera-
tionen verknüpft werden, ist es meist ratsam, runde Klammern ein-
zusetzen, um die Auswertungsreihenfolge explizit zu formulieren –
sonst kann es unter Umständen zu fehlerhaften Ausdrücken kom-
men (insbesondere wenn mehrere &&- und ||-Operatoren verknüpft
werden). Wie man leicht sehen kann, können Boolesche Ausdrücke
ähnlich kompliziert werden wie arithmetische Ausdrücke. Auch
hier ist es oft hilfreich (und meistens nicht langsamer), Zwischenva-
riablen einzuführen, um die Ausdrücke zu vereinfachen.
Beispiel
byte a = 5;
byte b = 10;
(a < 10) && (a > 4); // ist wahr

324 Anhang C: Sprachreferenz


(a > 6) && (b == 10); // ist falsch
(a < b) || (b > 10); // ist wahr
!(a == 5); // ist falsch
!((a < b) || !(b > 10)); // ist falsch

Ein wichtiger Unterschied zu logischen Operatoren ist, wie Boole-


sche Operatoren ihre Argumente auswerten. »Auswerten« heißt in
diesem Fall, dass geprüft wird, ob der Wert des Ausdrucks auch
tatsächlich berechnet wird. Das ist insbesondere bei Zuweisungen
und Funktionsaufrufen wichtig, da diese Nebenwirkungen haben.
Wird ein Ausdruck wie z.B. »2 + 5« oder »a / b« ausgewertet,
ändert sich eigentlich gar nichts, außer dass der Arduino-Prozessor
ein bisschen Rechenzeit verbraucht hat. Wird allerdings ein Aus-
druck wie »a = 5« ausgewertet, wurde a ein neuer Wert zugewiesen.
Bei logischen Operatoren werden beide Argumente immer ausge-
wertet. Bei Booleschen Operatoren werden allerdings nur so viele
Argumente ausgewertet wie nötig. Ist das erste Argument eines
Booleschen UND (&&) falsch, braucht das zweite Argument gar
nicht erst ausgewertet zu werden, weil das Ergebnis auf jedem Fall
falsch sein wird. Ähnlich verhält es sich, wenn das erste Argument
eines Booleschen ODER (||) wahr ist, denn dann ist das Ergebnis
des Ausdrucks auf jeden Fall wahr.
Beispiel
(a == 1) & (b = 5); // In diesem Fall wird b immer auf 5 gesetzt.
(a == 1) && (b = )5; // b wird nur dann auf 5 gesetzt, wenn a == 1.

Diese unterschiedlichen Auswertungsstrategien können zu fehler-


haften Programmen führen, wenn sie nicht beachtet werden. Sie
lassen sich jedoch auch einsetzen, um bestimmte Kontrollvorgänge
knapper zu formulieren, wie im folgenden Abschnitt über Kontroll-
strukturen gezeigt wird. In der folgenden Tabelle sind die Boole-
schen Operationen zur Referenz aufgelistet.

Zeichen Name Beschreibung Tabelle C-10


Boolesche Operationen
&& und wahr, wenn beide Argumente wahr sind
|| oder wahr, wenn mindestens eins der Argumente wahr ist
! negieren wahr, wenn das Argument falsch ist, falsch, wenn das Argument
wahr ist

Zusammengesetzte Operationen
Es kommt häufig vor, dass mit einer Variablen gerechnet und das
Ergebnis anschließend wieder in dieser Variablen gespeichert wird.
Um das Schreiben solcher Vorgänge zu vereinfachen, gibt es eine

Ausdrücke 325
Reihe zusammengesetzter Operationen, die eine Zuweisungsopera-
tion mit einer arithmetischen oder logischen Operation verknüpfen.
Zwei spezielle zusammengesetzte Operation sind die Inkrementie-
rungsoperation, die 1 zu einer Variablen hinzuaddiert, und die
Dekrementierungsoperation, die 1 von einer Variablen subtrahiert.
Beide werden oft in Schleifen eingesetzt, um einen Wertebereich zu
durchlaufen. Bei diesen beiden Operationen gibt es zwei mögliche
Schreibweisen. Man kann den Operator vor die zu inkrementie-
rende (oder dekrementierende) Variable schreiben – in diesem Fall
spricht man von Prä-Inkrementierung bzw. Prä-Dekrementierung.
Wenn man ihn hinter die Variable schreibt, spricht man von Post-
Inkrementierung bzw. Post-Dekrementierung. Der Unterschied
zwischen beiden Schreibweisen ist der Rückgabewert des Aus-
drucks. Im Fall der Prä-Operationen wird zuerst die Variable modi-
fiziert; der Rückgabewert des Ausdrucks ist der Wert der Variablen
nach der Inkrementierung oder Dekrementierung. Im Fall der Post-
Operationen wird die Variable erst nach der Auswertung der Vari-
ablen inkrementiert oder dekrementiert, d.h. der Wert des Aus-
drucks ist der Wert der Variablen vor der Modifikation. In den
meisten Fällen werden Post-Operationen verwendet.
Inkrementierung und Dekrementierung werden oft bei while-
Schleifen eingesetzt, die im folgenden Abschnitt erläutert werden.
Beispiel
byte a = 5;
byte b = a++;
// b hat jetzt den Wert 5, a hat den Wert 6.
b = ++a;
// b hat jetzt den Wert 7, a hat auch den Wert 7.

In der folgenden Tabelle sind die zusammengesetzten Operationen


zur Referenz aufgelistet und jeweils mit einem entsprechenden aus-
geschriebenen Ausdruck dokumentiert.

Tabelle C-11 Zeichen Name Ausdruck Äquivalenter Ausdruck


Zusammengesetzte Operationen
++ inkrementieren a++ a = a + 1
-- dekrementieren a-- a = a – 1
+= addieren und zuweisen a += 4 a = a + 4
-= subtrahieren und zuweisen a -= 4 a = a – 4
*= multiplizieren und zuweisen a *= 4 a = a * 4
%= teilen und zuweisen a *= 4 a = a % 4
&= und und zuweisen a *= 4 a = a & 4

326 Anhang C: Sprachreferenz


Zeichen Name Ausdruck Äquivalenter Ausdruck
|= oder und zuweisen a *= 4 a = a | 4
<<= Shift nach links und zuweisen a *= 4 a = a << 4
>>= Shift nach rechts und zuweisen a *= 4 a = a >> 4

Kontrollstrukturen
Bis jetzt wurden Datentypen, Variablen und Ausdrücke vorgestellt.
Mit diesen Konstrukten lassen sich Werte berechnen, es fehlt aber
noch eines der grundlegenden Fundamente der Programmierung:
Kontrollstrukturen. Ohne Kontrollstrukturen ist es kaum möglich,
auf unterschiedliche Daten (aus externen Sensoren, dem Daten-
speicher oder der seriellen Schnittstelle) zu reagieren.
Kontrollstrukturen steuern den Programmfluss, also in welcher
Reihenfolge der Arduino-Prozessor das Programm abarbeitet. Ein
Algorithmus (also eine Folge von Anweisungen, die eine bestimmte
Aufgabe ausführen) lässt sich oft auf unterschiedliche Arten imple-
mentieren (also als Programm niederschreiben). Viele der Kontroll-
strukturen der Programmiersprache lassen sich durch andere
ersetzen. Die Auswahl der benutzten Kontrollstrukturen wird
durch mehrere Parameter beeinflusst: Effizienz (wie schnell kann
der Arduino-Prozessor diese Anweisungen ausführen), Lesbarkeit
(je nach Aufgabe sind bestimmte Kontrollstrukturen besser geeig-
net, und einen Algorithmus zu beschreiben) und Programmierstil
(jeder Programmierer hat seine eigenen Vorlieben). Bestimmte
Strukturen lassen sich auch leichter debuggen, falls Fehler auftre-
ten, manche anderen lassen sich später leichter modifizieren.
In diesem Abschnitt stellen wir die unterschiedlichen Kontroll-
strukturen der Arduino-Programmiersprache vor und gehen auf
ihre jeweiligen Einsatzbereiche, Vor- und Nachteile ein.

if
Die if-Kontrollstruktur ist die einfachste Kontrollstruktur in der
Arduino-Programmiersprache und auch eine der am häufigsten
benutzten. Mit ihr lässt sich ein Programmblock ausführen, wenn
eine bestimmte Bedingung zutrifft. Diese Bedingung ist ein Boole-
scher Ausdruck (also ein Ausdruck, der als Boolescher Wert inter-
pretiert wird). Meistens ist dieser Ausdruck ein Vergleichsoperator,
wie in den folgenden Beispielen. Die Syntax der if-Kontrollstruktur
ist folgende:

Kontrollstrukturen 327
if (Boolescher Ausdruck) {
// Dieser Block wird nur dann ausgeführt, wenn der Boolesche
// Ausdruck wahr ist.
}

Beispiel
if (a == 5) {
// Dieser Funktionsaufruf wird nur ausgeführt, wenn die Variable
// a den Wert 5 hat.
[Link]("a ist 5");
}
if ((a < 5) || (b > 10)) {
// Dieser Funktionsaufruf wird nur ausgeführt,
// wenn a kleiner als 5 ist oder wenn b größer als 10 ist.
[Link](»a ist kleiner als 5 oder b ist größer als 10.");
}

Es lassen sich natürlich beliebige Ausdrücke innerhalb der runden


Klammern nach dem if benutzen. Dabei werden die in Abschnitt
»Datentypkonvertierung« in diesem Anhang vorgestellten Konver-
tierungsregeln verwendet. So ist es also möglich, z.B. ein bestimm-
tes Bit zu testen und nur dann ein Block auszuführen, wenn dieses
Bit gesetzt ist.
Beispiel
if (a & bit(3)) {
[Link]("Das vierte Bit von a ist gesetzt.");
}
if (ledMatrix[3] & bit(4)) {
// Die LED wird angeschaltet, wenn das fünfte Bit von
// ledMatrix[3] gesetzt ist.
digitalWrite(ledPin, HIGH);
}

if … else
Die if ... else-Kontrollstruktur ist eine Erweiterung der if-Kon-
trollstruktur. Mit ihr es möglich, die Alternative zu beschreiben,
falls die Bedingung falsch ist, ohne gleich eine zweite if-Struktur
benutzen zu müssen. Die einfache Syntax der if ... else-Kontroll-
struktur ist folgende:
if (Boolescher Ausdruck) {
// Dieser Block wird nur dann ausgeführt, wenn der Boolesche
// Ausdruck wahr ist.
} else {
// Dieser Block wird nur dann ausgeführt, wenn der Boolesche
// Ausdruck falsch ist.
}

328 Anhang C: Sprachreferenz


Wenn der Boolesche Ausdruck wahr ist, wird der erste Block aus-
geführt. Diesen Block nennt man auch den if-Zweig. Ist der Boole-
sche Ausdruck allerdings falsch, wird der erste Block übersprungen
und der zweite Block, der nach dem else definiert wird, ausgeführt.
Diesen zweiten Block nennt man auch den else-Zweig.
Es ist auch möglich, die geschweiften Klammern wegzulassen,
wenn ein Block nur aus einer einzigen Anweisung besteht. Das
bringt allerdings keine Vorteile (das Programm wird dadurch nicht
kleiner), aber eine ganze Reihe von Problemen mit sich. Erstens
wird dadurch der Programmtext schwerer zu lesen, weil nicht mehr
klar ersichtlich ist, wo der if-Zweig aufhört und wo der else-Zweig
anfängt. Wird später einer der Zweige mit weiteren Anweisungen
ergänzt, müssen die geschweiften Klammern hinzugefügt werden.
Besonders haarig wird es, wenn mehrere if ... else-Ausdrücke
geschachtelt werden. Spätestens in diesem Fall ist es notwendig,
geschweifte Klammern einzuführen, weil sonst nicht mehr nach-
vollziehbar ist, welches else zu welchem if gehört.
So lassen sich die vorigen Beispiele wie folgt ergänzen.
Beispiel
if (a & bit(3)) {
[Link]("Das vierte Bit von a ist gesetzt.");
} else {
[Link]("Das vierte Bit von a ist nicht gesetzt.");
}
if (ledMatrix[3] & bit(4)) {
// Die LED wird angeschaltet, wenn das fünfte Bit von
// ledMatrix[3] gesetzt ist.
digitalWrite(ledPin, HIGH);
} else {
// Sonst wird die LED ausgeschaltet.
digitalWrite(ledPin, LOW);
}

Die if ... else-Kontrollstruktur erlaubt auch die Verknüpfung von


mehreren if-Kontrollstrukturen in eine große Kontrollstruktur,
indem mehrere Bedingungen verknüpft werden. Die verschiedenen
Bedingungen werden der Reihe nach ausgewertet, bis eine den
Wert »wahr« zurückgibt. In dem Fall wird der dazugehörige Pro-
grammblock ausgeführt und schließlich das Programm nach dem
Ende der if ... else-Kontrollstruktur weiter ausgeführt. Trifft
keine der Bedingungen zu, wird der else-Teil der Kontrollstruktur
(falls vorhanden) ausgeführt.

Kontrollstrukturen 329
Beispiel
if (a > 10000) {
[Link]("a ist groß.");
} else if (a > 500) {
[Link]("a ist mittelgroß.");
} else if (a > 10) {
[Link]("a ist klein.");
} else {
[Link]("a ist sehr klein.");
}

An diesem Beispiel kann man sehen, dass die Reihenfolge der


Bedingungen unter Umständen relevant sein kann. Folgende
Schreibweise wäre z.B. falsch, weil sie für alle Werte von a, die grö-
ßer als 10 sind, »a ist klein.« anzeigen würde. Selbst bei ver-
hältnismäßig einfachen Kontrollstrukturen ist es also leicht, Fehler
zu machen. Die meisten Programmfehler rühren von fehlerhaften
Kontrollstrukturanweisungen her.
Beispiel
if (a > 10) {
[Link]("a ist klein.");
} else if (a > 500) {
[Link]("a ist mittelgroß.");
} else if (a > 10000) {
[Link]("a ist groß.");
} else {
[Link]("a ist sehr klein.");
}

Komplexe bzw. sehr lange if ... else-Strukturen lassen sich oft


mit der switch-Kontrollstruktur einfacher beschreiben.
Es ist natürlich möglich, mehrere if und if ... else zu schachteln.
Dazu ist es wichtig, den Programmtext sauber einzurücken (beim
Schreiben oder mit Apfel-T bzw. Steuerung-T), damit dieser gut
lesbar bleibt.
Beispiel
if (a > 10) {
if (b > 10) {
[Link]("a und b sind größer als 10.");
} else {
[Link]("a ist größer als 10, b aber nicht.");
}
} else {
if (b > 10) {
[Link]("a ist kleiner oder gleich 10, aber b ist größer
als 10.");
} else {
[Link]("a und b sind kleiner oder gleich 10.");
}

330 Anhang C: Sprachreferenz


Besondere Vorsicht ist beim Einsatz von Booleschen Operatoren in
if ... else-Ausdrücken geboten. Der else-Zweig wird nur ausge-
führt, wenn der komplette Boolesche Ausdruck falsch ist, was zu
nicht unbedingt sofort ersichtlichen Fallunterscheidungen führt
(besonders bei langen Booleschen Ausdrücken.)
Beispiel
if ((a > 10) && (b > 10)) {
[Link]("a und b sind größer als 10.");
} else {
[Link]("a ist kleiner oder gleich 10, oder b ist kleiner
oder gleich 10.");
[Link]("Es kann aber sein, dass a größer ist als 10.");
[Link]("Es kann auch sein, dass b größer ist als 10.");
}

switch ... case


Die switch ... case-Kontrollstruktur kann man als spezialisierte if
... else-Kontrollstruktur betrachten. Ein Ausdruck wird mit einer
Reihe von Werten verglichen, und falls er mit einem dieser Werte
gleich ist, wird ein bestimmter Programmblock ausgeführt. Ist der
Ausdruck mit keinem der angegebenen Werten gleich, wird ein
Default-Programmblock (falls vorhanden) ausgeführt. Die Syntax
der switch ... case-Kontrollstruktur ist folgende:
switch (Ausdruck) {
case Wert1:
programmBlock1;
break;
case Wert2:
programmBlock2;
break;
case Wert3:
programmBlock3;
break;
default:
defaultProgrammBlock;
break;
}

Die break-Anweisung bewirkt einen Sprung ans Ende der switch ...
case-Kontrollstruktur. Falls die break-Anweisung fehlt, wird der
nächste Programmblock in der Struktur ausgeführt, was in speziel-
len Fällen praktisch sein kann (man sagt, dass das Programm in den
nächsten switch ... case-Block »fällt«). Meistens ist das aber eher
eine Fehlerquelle, weshalb es wichtig ist, sicherzustellen, dass die
break-Anweisung am Ende der einzelnen Programmblöcke auch
wirklich vorhanden ist.

Kontrollstrukturen 331
Es ist sinnvoll, immer einen default-Block zu definieren, der unde-
finierte Fälle abfängt und zur Not einen Fehler anzeigt oder das
Programm neu initialisiert. Damit lassen sich beim Entwickeln Feh-
ler abfangen.
Programmblöcke sind einfache Listen von Anweisungen, die mit
einem Semikolon getrennt werden. Es ist auch möglich, nach einer
case-Anweisung lokale Variablen zu definieren, indem der Pro-
grammblock mit geschweiften Klammern abgeschlossen wird.
switch (Ausdruck) {
case Wert1: {
int lokaleVariable;
programmBlock1;
}
break;
case Wert2:
programmBlock2;
break;

switch ... case-Kontrollstrukturen lassen sich natürlich auch


schachteln. Auch dabei ist es wichtig, den Programmtext sauber
einzurücken, da er sonst sehr schwer zu lesen sein kann.
Eine switch ... case-Kontrollstruktur benutzt den üblichen ==-Ver-
gleichsoperator. Deswegen ist es nicht möglich, Zeichenketten mit
einer switch ... case-Struktur zu unterscheiden.
Beispiel
char zeichenKetten[] = "arduino";
// Falsch! Zeichenketten und Tabellen lassen sich nicht mit switch
// ... case bearbeiten.
switch (zeichenKette) {
case "foobar":
break;
case "arduino":
break;
}

Ein häufiger Einsatzbereich von switch ... case-Kontrollstrukturen


ist die Fallunterscheidung zwischen unterschiedlichen Modi eines
Programms (z.B. ob das Programm sich gerade im Konfigurations-
modus oder im Betriebsmodus befindet). Dazu wird eine Statusva-
riable deklariert, die eine bestimmte Anzahl von vordefinierten
Werten annehmen kann. Diese Werte werden oft als Konstanten
deklariert, damit der Programmquelltext besser zu lesen ist. Im fol-
genden Beispiel wird vorausgesetzt, dass zwei LEDs und ein Taster
am Arduino angeschlossen sind. blinkErsteLed(), blinkZwei-
teLed() und buttonPressed() sind Funktionen, die nicht gezeigt,
sondern nur als Beispiele benutzt werden.

332 Anhang C: Sprachreferenz


Beispiel
const int BetriebsModus = 0;
const int KonfigurationsModus = 1;
int programmStatus = BetriebsModus;
void loop () {
switch (programmStatus) {
case BetriebsModus:
// Im Betriebsmodus wird die erste LED geblinkt.
blinkErsteLed();
if (buttonPressed()) {
// Wurde der Taster gedrückt, wird in den
// Konfigurationsmodus gewechselt.
programmStatus = KonfigurationsModus;
}
break;
case KonfigurationsModus:
// Im Konfigurationsmodus wird die zweite LED geblinkt.
blinkZweiteLed();
if (buttonPressed()) {
// Wurde der Taster gedrückt, wird in den
// Betriebsmodus gewechselt.
programmStatus = BetriebsModus;
}
break;
default:
// Falls die programmStatus-Variable durch einen Fehler
// einen unbekannten Wert annimmt, wird diese auf den
// Betriebsmodus zurückgesetzt.
programmStatus = BetriebsModus;
break;
}
}

Die switch ... case-Kontrollstruktur lässt sich auch einsetzen, um


unterschiedliche Kommandos zu erkennen, die z.B. als Bytes über
die serielle Schnittstelle vom Computer aus an den Arduino gesen-
det werden (siehe Abschnitt serielle Schnittstelle). Im folgenden
Beispiel werden drei Kommandos erkannt, die ebenfalls die hier
nicht gezeigten Funktionen blinkLed(), motorAn() und motorAus()
aufrufen.
Beispiel
const int BlinkLedCommand = 10;
const int MotorAnCommand = 11;
const int MotorAusCommand = 12;
void loop() {
if ([Link]()) {
switch ([Link]()) {
case BlinkLedCommand:
blinkLed();
break;

Kontrollstrukturen 333
case MotorAnCommand:
motorAn();
break;
case MotorAusCommand:
motorAus();
break;
default:
// unbekanntes Kommando ignorieren
break;
}
}
}

for
Die for-Kontrollstruktur wird eingesetzt, um einen Programm-
block mehrmals in einer Schleife auszuführen. Oft wird diese
Struktur gemeinsam mit einem Schleifenzähler eingesetzt, um den
Programmblock eine bestimmte Anzahl von Malen zu wiederho-
len oder eine Tabelle oder Zeichenkette zu durchlaufen (siehe
Abschnitt über Tabellen und Zeichenketten). Die Syntax der for-
Kontrollstruktur sieht so aus:
for (Initialisierung; Schleifenbedingung; Schleifenanweisung) {
// Schleifencode
}

Zu Beginn der Schleife wird die Initialisierungsanweisung ausge-


führt. Mit dieser Anweisung kann z.B. die Schleifenvariable initiali-
siert werden. Bei jedem Durchlauf wird der Programmcode
innerhalb des Schleifenblocks ausgeführt. Nach jedem Schleifen-
durchlauf wird die Schleifenanweisung ausgeführt (die oft dazu ver-
wendet wird, den Schleifenzähler zu inkrementieren). Letztendlich
wird die Schleifenbedingung ausgewertet. Ist der Rückgabewert der
Schleifenbedingung »wahr«, wird die Schleife erneut durchlaufen.
Ist er »falsch«, wird die Schleife abgebrochen, und das Programm
wird nach dem Ende der for-Kontrollstruktur weiter ausgeführt.
Im folgenden Beispiel wird die LED 10 Mal ein- und wieder
ausgeschaltet.
Beispiel
int i; // i wird als Schleifenvariable verwendet.
for (i = 0; i < 10; i++) {
digitalWrite(ledPin, HIGH); // LED wird angeschaltet.
delay(200); // kurz warten
digitalWrite(ledPin, LOW); // LED wird ausgeschaltet.
delay(200);
}

334 Anhang C: Sprachreferenz


In diesem Beispiel wird zu Beginn der Schleife die Variable i mit 0
initialisiert. Anschließend wird die LED einmal ein- und ausge-
schaltet. Dann wird i inkrementiert (wegen der Schleifenanweisung
i++). Im nächsten Schritt wird der Ausdruck i < 10 ausgewertet, und
falls i noch klein genug ist, wird die Schleife weiter ausgeführt.
Selbst in einfachen Schleifen kann es zu Problemen kommen. Es
ist besonders wichtig, beim Einsatz von Schleifenvariablen zu
überprüfen, ob diese Schleifenvariable den gewünschten Bereich
durchläuft (insbesondere, wenn diese Schleifenvariable als Index
in einer Tabelle verwendet wird, weil sonst auf den falschen Spei-
cher zugegriffen werden könnte). Wäre der Schleifenkopf wie folgt
geschrieben, würde die Schleife entweder nicht genug oder zu oft
ausgeführt.
Beispiel
// Die Schleife wird nur 9 Mal ausgeführt.
for (i = 1; i < 10; i++) {
}
// Die Schleife wird 11 Mal ausgeführt.
for (i = 0; i <= 10; i++) {
}

Diese Art von Fehlern, die insbesondere bei komplizierteren Schlei-


fen auftritt, wird so häufig gemacht, dass sie ihren eigenen Namen
verdient hat: Man nennt sie »off by one«-Fehler, weil die Schleifen-
variable meistens um genau 1 neben dem beabsichtigten Wert liegt.
Hier kommen auch die ganzen Vorsichtsanweisungen zum Tragen,
die bei den verschiedenen Vergleichsoperatoren vorgestellt wurden.
Folgende Schleife zum Beispiel wird nie enden (der Schleifenblock
wird also immer wieder bis in alle Unendlichkeit wiederholt):
Beispiel
int i;
for (i = 0; i < 40000; i++) {
// i ist ein int, ist also immer kleiner als 40000.
// Die Bedingung ist also immer erfüllt, und die Schleife bricht
// nie ab.
}

Die for-Kontrollstruktur ist sehr flexibel. So lassen sich in der


Arduino-Programmiersprache auch direkt Variablen innerhalb der
Initialisierungs-Anweisung definieren. Diese Variablen sind nur
innerhalb des Schleifenblocks sichtbar. Somit lässt sich immer wie-
der derselbe Name für eine Schleifenvariable verwenden, ohne dass
es zu Konflikten oder Mehrfachbenutzungen kommt.

Kontrollstrukturen 335
Beispiel
for (int i = 1; i < 10; i++) {
// Die Variable i ist nur innerhalb des Schleifenblocks sichtbar.
analogWrite(ledPin, i * 25);
}

Es ist auch möglich, mehrere Anweisungen in der Initialisierung


oder den Schleifenanweisungen auszuführen. Dazu werden die
Anweisungen mit dem sogenannten sequenziellen Operator , ver-
knüpft. So können z.B. mehrere Schleifenvariablen initialisiert und
inkrementiert werden (es ist allerdings nicht möglich, mehrere
Schleifenvariablen mit unterschiedlichen Typen zu deklarieren).
Beispiel
for (int i = 1, j = 2; i < 5; i++, j += 2) {
// i und j durchlaufen die Werte
// i = 1, j = 2
// i = 2, j = 4
// i = 3, j = 6
// i = 4, j = 8
}

Es ist durchaus möglich, mehrere for-Kontrollstrukturen zu


schachteln. So lassen sich z.B. mehrdimensionale Tabellen durch-
laufen. Hier ist wichtig, die Schleifenvariablen nicht zu verwech-
seln.
Beispiel
int ledMatrix[10][10];
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 10; y++) {
// Jeder Wert der ledMatrix wird auf 1 gesetzt.
ledMatrix[x][y] = 1;
}
}

Innerhalb des Schleifenblocks kann der Programmfluss der Schleife


auch beeinflusst werden. Die break-Anweisung wird benutzt, um
aus der Schleife auszusteigen. Das Programm wird anschließend
nach dem Ende der for-Schleife weitergeführt. Dadurch lassen sich
im Schleifenblock weitere Terminierungsbedingungen überprüfen.
Der Programmfluss innerhalb der Schleife kann auch durch die
continue-Anweisung beeinflusst werden. Die continue-Anweisung
bewirkt, dass ans Ende des Programmblocks innerhalb der Schleife
gesprungen wird. Es werden also direkt nach der continue-Anwei-
sung die Schleifenanweisung ausgeführt (meistens wird dann der
Schleifenzähler inkrementiert), die Schleifenbedingung ausgewertet
und, falls diese wahr ist, der nächste Schleifendurchlauf ausgeführt.

336 Anhang C: Sprachreferenz


Will man zum Beispiel die fünfte Zeile der Matrix überspringen,
würde sich folgende Schleife anbieten:
Beispiel
int ledMatrix[10][10];
for (int x = 0; x < 10; x++) {
// fünfte Zeile wird übersprungen
if (x == 4)
continue;
for (int y = 0; y < 10; y++) {
// Jeder Wert der ledMatrix wird auf 1 gesetzt.
ledMatrix[x][y] = 1;
}
}

Bei geschachtelten Kontrollstrukturen beziehen sich break und con-


tinue jeweils auf die zuletzt definierte Kontrollstruktur (break und
continue lassen sich auch bei den switch ... case-, while- und do ...
while-Kontrollstrukturen einsetzen).
Ein spezielle Schreibweise der for-Kontrollstruktur findet man in
Arduino-Programmen oft, wenn ein Endpunkt erreicht wurde und
das Programm sozusagen beendet werden soll. Da es dem Arduino
nicht möglich ist, sich selbst auszuschalten, wird eine unendliche
Schleife ausgeführt. Dazu genügt eine for-Schleife ohne Abbruch-
bedingung.
Beispiel
for (;;) {
// unendliche Schleife
}

while
Die while-Kontrollstruktur ist eine weitere Kontrollstruktur, mit
der sich Schleifen implementieren lassen. Im Vergleich zur for-
Kontrollstruktur, die eher darauf ausgelegt ist, Schleifen mit Zäh-
lervariablen zu beschreiben, führt eine while-Schleife den Schleifen-
block so lange aus, wie die Schleifenbedingung wahr ist. Die
Schleifenbedingung wird vor dem ersten Durchlauf der Schleife
ausgewertet. Ist sie dort schon falsch, wird die Schleife gar nicht
ausgeführt. So lässt sich z.B. eine Schleife ausführen, bis ein Sensor
einen bestimmten Wert meldet oder ein Taster betätigt wird. Die
Syntax der while-Kontrollstruktur ist folgende:
while (schleifenBedingung) {
// Schleifenblock
}

Kontrollstrukturen 337
Im folgenden Beispiel wird die LED solange an- und ausgeschaltet,
bis ein Taster gedrückt wird.
Beispiel
while (!tasterGedrueckt()) {
blinkLed();
}

Wie bei der for-Schleife kann die break-Anweisung benutzt wer-


den, um aus der Schleife herauszugelangen. Die continue-Anwei-
sung führt einen neuen Schleifendurchlauf aus (falls die Bedingung
wahr ist).

do … while
Die do ... while-Kontrollstruktur ist eng verwandt mit der while-
Kontrollstruktur. Bei dieser Kontrollstruktur wird die Schleifenbe-
dingung allerdings erst nach dem Schleifenblock ausgewertet,
sodass die Schleife mindestens einmal ausgeführt wird. Die Syntax
der do ... while-Kontrollstruktur ist folgende:
do {
// Schleifenblock
} while (schleifenBedingung);

Funktionen
Mit den bis jetzt erklärten Konstrukten lassen sich schon alle
möglichen Programme schreiben. Allerdings kommt es relativ oft
vor, dass bestimmte Programmabschnitte immer wieder ausge-
führt werden sollen, nur mit leicht unterschiedlichen Werten oder
Programmanweisungen. Diese immer wieder verwendeten Pro-
grammblöcke kann man als getrennte Funktionen schreiben, die
aufgerufen werden können (das nennt man Funktionsaufruf, und
viele der bisherigen Programmbeispiele haben schon solche Funk-
tionsaufrufe enthalten), das heißt, sie werden von einer anderen
Stelle im Programm aus angesprungen und ausgeführt.
Beim Funktionsaufruf kann man einer Funktion eine Anzahl von
Werten übergeben, die man Parameter nennt. Mit Parametern lässt
sich das Verhalten der Funktion steuern. Man kann zum Beispiel
Berechnungen mit unterschiedlichen Werten ausführen oder
bestimmte Teile der Funktion deaktivieren. Nachdem eine Funk-
tion ausgeführt wurde, springt sie wieder zur Stelle zurück, an der
sie aufgerufen wurde, und gibt gegebenenfalls einen Wert zurück
(den Rückgabewert).

338 Anhang C: Sprachreferenz


Dieses Auftrennen von Programmcode ist eins der wichtigsten Kon-
strukte in Programmiersprachen allgemein. Auf der einen Seite
wird dadurch der Programmtext kürzer, weil oft verwendete
Abschnitte nur einmal geschrieben werden müssen. So lassen sich
auch viele Fehler vermeiden, weil nur noch eine Stelle korrigiert
werden muss, wenn ein Problem auftritt. Den Prozess des Extrahie-
rens bestimmter Programmteile und ihre Definition in eigenen
Funktionen nennt man »Refaktorieren«. Besonders nach einer län-
geren Programmierphase ist es oft ganz nützlich, sich das Pro-
gramm in Ruhe anzugucken und Stellen zu identifizieren, die sich
angenehmer als getrennte Funktionen definieren lassen würden.
Als Faustregel gilt: Kommt ein Stück Programmcode mehr als zwei
Mal vor, wird daraus eine Funktion definiert. Auch sehr lange
Funktionen (z.B. mehr als einen Bildschirm lang) sollte man in klei-
nere Funktionen auftrennen, die jeweils bestimmte Aufgaben erle-
digen. Dadurch wird das Programm viel klarer zu lesen.
Auch das erzeugte Programm, das auf dem Arduino gespeichert
wird, wird dadurch kleiner. Da jede Funktion auch einen eigenen
Namen hat, wird das Programm auch einfacher zu verstehen. Der
Programmname erklärt sofort (wenn er gut gewählt wurde), was
die Funktion bewirkt. Es ist auch bei sehr kleinen Funktionen (die
z.B. nur einen bestimmten Wert, der oft verwendet wird, einer wei-
teren Funktion übergeben) sinnvoll, eine eigene Funktion zu defi-
nieren, weil der Compiler diese effizienter bearbeiten kann.
Funktionen erhöhen auch die Wiederverwendbarkeit von Pro-
grammcode. Oft werden in einem Programm Funktionen benutzt,
die auch im Kontext eines anderen Programms sinnvoll sind. Man
kann also Funktionen von einem Programm zum anderen wieder-
verwenden. Viele sinnvolle Funktionen sind schon in der Arduino-
Programmiersprache enthalten: Das sind auf der einen Seite die ein-
gebauten Funktionen der Arduino-Umgebung, die in den Work-
shops ab Kapitel 3 vorgestellt und beschrieben werden, auf der
anderen Seite die Funktionen, die in zusätzlichen Libraries enthal-
ten sind und eine bestimmte Funktionalität implementieren (z.B.
die Kommunikation mit einem Sensor).
Funktionen sind auch der beste Weg, um Programme oder Pro-
grammteile mit anderen Leuten auszutauschen. Es ist nicht mehr
notwendig, ein Stück Programmcode genau zu erklären, sondern es
reicht, die generelle Funktionsweise einer Funktion zu beschreiben
sowie ihre Argumente und ihren Rückgabewert. Damit weiß jeder
Programmierer Bescheid, wie die Funktion einzusetzen ist. Auch

Funktionen 339
zur eigenen Referenz ist es sinnvoll, einen kurzen Kommentar vor
die Funktion zu schreiben, der die Argumente und den Rückgabe-
wert beschreibt. In diesem Kommentar sollte man auch mögliche
Nebenwirkungen der Funktion auflisten (z.B. dass sie einen
bestimmten Pin in der Richtung ändert).

Funktionsaufruf
Das Aufrufen einer Funktion ist ein Ausdruck (und keine Anwei-
sung), d.h. er hat einen Wert, der in weiteren Ausdrücken eingesetzt
werden kann. Es ist allerdings auch möglich, den Rückgabewert
einer Funktion zu ignorieren (das sollte man allerdings mit Vorsicht
tun, oft wird der Rückgabewert benutzt, um z.B. Fehler zu signali-
sieren). Die Syntax eines Funktionsaufrufs sieht so aus:
funktionsName(argumente);

Die Argumente sind eine Folge von Werten, die an die Funktion
übergeben wird. Sie werden mit einem einfachen Komma getrennt.
Es ist wichtig, die richtige Anzahl von Argumenten zu geben, da der
Compiler sonst einen Fehler meldet (bestimmte Funktionen können
eine variable Anzahl von Argumenten bearbeiten, was zum Beispiel
im Anhang Libraries deutlich wird. Es ist auch wichtig, dass die ein-
zelnen Argumente den passenden Datentyp haben. Dazu werden
die gleichen Konvertierungsregeln benutzt, die in Abschnitt »Daten-
typkonvertierung« vorgestellt wurden. Genauso werden bei der wei-
teren Bearbeitung des Rückgabewerts (z.B. Speichern in einer
Variablen) dieselben Konvertierungsregeln angewandt. Im Folgen-
den werden einige Funktionsaufrufe vorgestellt.
Beispiel
machNichts(); // ruft die Funktion machNichts auf, die keine
// Argumente braucht
byte knopfWert = knopfGedrueckt(); // Der Rückgabewert von
// knopfGedrueckt wird in
// knopfWert gespeichert.
int x = analogRead(sensorEinsPin) + 2 * analogRead(sensorZweiPin);
do {
machWas(); // führt die Funktion machWas aus, solange der Knopf
// nicht gedrückt wurde
} while (!knopfGedrueckt())

Funktionsdefinition
Das Hinschreiben einer Funktion (mit Namen, Parametern und
Programmrumpf) nennt man Funktionsdeklaration oder Funk-
tionsdefinition. Eine Funktionsdeklaration ähnelt stark einer Vari-

340 Anhang C: Sprachreferenz


ablendeklaration. Es ist allerdings nicht möglich, Funktionen
innerhalb von beliebigen Programmblöcken zu deklarieren (im
Gegensatz zur Deklaration von lokalen Variablen). Funktionen las-
sen sich nur auf der obersten Ebene des Programmtextes definie-
ren. Im Unterschied zu Variablendefinitionen können allerdings
Funktionen aufgerufen werden, bevor sie definiert werden.
Die Syntax einer Funktionsdeklaration ist folgende:
returntyp funktionsName(argumentenListe) {
programmRumpf;
}

Ähnlich wie eine Variable besitzt eine Funktion einen Datentyp,


den man Rückgabetyp nennt. Dieser Typ beschreibt den Datentyp
der Rückgabewerte der Funktion. Der Rückgabetyp einer Funktion
umfasst alle numerischen Datentypen, die im Abschnitt Datenty-
pen vorgestellt wurden. Es ist jedoch nicht möglich, eine Tabelle
oder eine Zeichenkette aus einer Funktion zurückzugeben; das
funktioniert nur mit Pointern, die ein fortgeschrittenes Konstrukt
der Arduino-Programmiersprache sind und keinen Platz in diesem
Buch gefunden haben. Es kommt noch ein weiterer spezieller Rück-
gabetyp hinzu: der void-Datentyp. void ist eigentlich kein Daten-
typ, sondern kennzeichnet, dass eine Funktion keinen Wert
zurückgibt.
Funktionsnamen folgen denselben Regeln wie Variablennamen: Sie
müssen mit einem Buchstaben anfangen, dürfen Buchstaben, Zah-
len und Unterstriche (_) enthalten, und sie dürfen nicht mit schon
definierten Namen kollidieren (also mit reservierten Wörtern der
Programmiersprache und mit schon definierten Funktionsnamen
und Variablennamen).
In der Argumentenliste, die in runden Klammern nach dem Funkti-
onsnamen geschrieben wird, werden die Argumente definiert, die
die Funktion annimmt (und bearbeitet). Argumente ähneln stark
den lokalen Variablen, die beim Funktionsaufruf initialisiert wer-
den und innerhalb des Funktionsrumpfes definiert sind (man kann
nicht auf Argumente außerhalb der Funktion zugreifen, sondern sie
nur beim Funktionsaufruf initialisieren). In der Argumentenliste
werden Argumente wie Variablen mit einem Namen und einem
Datentyp definiert. Mehrere Argumentdefinitionen werden durch
Kommata voneinander getrennt. Es ist auch möglich, eine Funk-
tion ohne Argumente zu definieren. Dazu wird eine leere Argumen-
tenliste verwendet (die runden Klammern sind aber nach wie vor
notwendig). Bei einem Funktionsaufruf wird der erste übergebene

Funktionen 341
Parameterwert in das erste Argument kopiert, der zweite Parame-
terwert in das zweite Argument usw.
Es ist auch möglich, Tabellen und Zeichenketten als Argumente zu
übergeben. Dazu wird der Tabellentyp in eckigen Klammern ange-
geben. Unten sehen Sie verschiedene Argumentenlisten als Bei-
spiele. Oft ist es bei Tabellen notwendig, der Funktion auch noch
die Tabellengröße zu übergeben (bei Zeichenketten kann die Funk-
tion die abschließende Null erkennen), es sei denn, alle Tabellen,
die der Funktion als Argumente übergeben werden, haben dieselbe
Größe.
Funktionsargumente werden als Werte übergeben (diese Eigen-
schaft nennt man in der Programmierwelt »call-by-value«). Wird
also an einer Stelle eine Variable als Argument übergeben und
dieses Argument innerhalb der Funktion modifiziert, wird die
ursprüngliche Variable nicht modifiziert. Stattdessen wird beim
Aufruf der Funktion eine lokale Kopie der Variablen erzeugt und
im Funktionsrumpf verwendet. Das ist ein bisschen gewöhnungs-
bedürftig (und nicht unbedingt leicht zu verstehen), erhöht aber die
Wiederverwendbarkeit von Funktionen und verhindert auch viele
Programmfehler.
Funktionen können deswegen nur den globalen Status eines Pro-
gramms (globale Variablen) verändern (und natürlich den Zustand
des Arduino-Prozessors). Weitere Veränderungen müssen vom Pro-
grammierer explizit angegeben werden, indem zum Beispiel der
Rückgabewert der Funktion gespeichert wird. Nach dem Zurück-
kehren aus einer Funktion werden alle lokalen Variablen (und alle
Argumente) gelöscht und sind nicht mehr zugänglich. Es ist also
nicht möglich, einen lokalen Wert als Speicherplatz zu verwenden,
der von Funktionsaufruf zu Funktionsaufruf bestehen bleibt. Dazu
muss eine globale Variable verwendet werden.
Beispiel
int zaehlHochFalsch() {
// Diese Funktion gibt immer 1 zurück, weil bei jedem
// Aufruf a neu initialisiert wird.
int a = 0;
a++;
return a;
}
int a = 0;
int zaehleHochRichtig() {
// Diese Funktion gibt bei jedem Aufruf einen hochgezählten
// Wert zurück (also 1, 2, 3 usw.). Nach 32767 wird der
// Wert -32768, weil die Variable a übergelaufen ist.

342 Anhang C: Sprachreferenz


a++;
return a;
}

Es ist allerdings besser, die Anzahl von globalen Variablen, die


innerhalb einer Funktion verwendet werden, zu begrenzen.
Dadurch wird nämlich nicht die Wiederverwendbarkeit der Funk-
tion eingeschränkt: Auf der einen Seite hängt die Funktion dann
von mehreren globalen Variablen ab, weshalb es nicht mehr mög-
lich ist, sie ohne Weiteres in ein neues Programm einzusetzen. Auf
der anderen Seite steigt durch globale Variablen auch die Anzahl
von Nebenwirkungen der Funktion, d.h. der Programmierer, der
die Funktion aufruft, muss jetzt immer berücksichtigen, dass
dadurch mehrere globale Variablen verändert werden können.
Werden globale Variablen benutzt, sollte man sich also überlegen,
ob diese durch weitere Argumente oder durch einen Rückgabewert
ersetzt werden können.
Vorsicht ist allerdings bei Tabellen und Zeichenketten geboten.
Diese können innerhalb der Funktion doch modifiziert werden,
weil sie beim Aufruf der Funktion nicht kopiert werden; stattdessen
wird der Funktion ein Zeiger auf die Tabelle oder die Zeichenkette
übergeben (das nennt man in der Programmierwelt »call-by-refe-
rence«). Es erhöht die Geschwindigkeit der Funktion, weil keine
Daten kopiert werden, kann aber zu Programmfehlern führen,
wenn Tabellen unabsichtlich modifiziert werden. Auf der anderen
Seite kann genau diese Eigenschaft benutzt werden, um Tabellen zu
modifizieren. Zum Beispiel werden viele der Funktionen im Work-
shop zur LED-Matrix in Kapitel 4 verwendet, um die gespeicherte
Tabelle der Matrix zu modifizieren.
In seltenen Fällen ist es notwendig, mehrere Werte aus einer Funk-
tion zurückzugeben. Dazu kann man einzelne Argumente als »call-
by-reference« übergeben (wird im Funktionsrumpf einem Argu-
ment ein Wert zugewiesen, wird auch in die ursprüngliche Variable
geschrieben). Dazu wird der Referenz-Operator & benutzt. Dieser
muss direkt vor den Argumentnamen in der Argumentenliste
geschrieben werden (ohne Leerzeichen zwischen & und Variablen-
namen). Diese Schreibweise ist nur in sehr seltenen Fällen notwen-
dig und sollte sparsam eingesetzt werden.
Beispiel
int machWas(int a) { // a ist ein call-by-value-Argument.
a = a + 10; // Nur die lokale Kopie von a wird verändert.
return a;
}

Funktionen 343
int machWasMitReferenz(int &a) { // a ist jetzt ein call-by-
reference-Argument.
a = a + 10; // Auch die ursprüngliche wird verändert.
}
int foo = 0;
machWas(foo);
// foo ist immer noch 0.
foo = machWas(foo);
// foo ist jetzt 10.
machWasMitReferenz(foo);
// foo ist jetzt 20.
foo = machWas(foo);
// foo ist jetzt 30 (wird aber zweimal zugewiesen).

Der Funktionsrumpf einer Funktion beinhaltet alle Programmier-


anweisungen der Funktion. Diese werden in geschweiften Klam-
mern hinter dem Funktionsnamen und der Argumentenliste
angegeben. Bei einem Funktionsaufruf werden die Anweisungen
wie ein normales Stück Programmcode ausgeführt. Erreicht der
Prozessor die letzte Zeile des Funktionsrumpfes (und damit die
schließende geschweifte Klammer), und hat die Funktion keinen
Rückgabewert (wurde also mit dem Datentyp void definiert), wird
aus der Funktion zurückgekehrt. Das Programm wird nach dem
ursprünglichen Funktionsaufruf weiter ausgeführt.
Die return-Anweisung wird verwendet, um aus einer Funktion
zurückzukehren. Diese Anweisung lässt sich also einsetzen, um an
beliebigen Stellen innerhalb des Funktionsrumpfes (und nicht nur
am Ende der Funktion) aus der Funktion auszubrechen. Gibt die
Funktion einen Wert zurück (hat also nicht den Datentyp void),
geschieht das mit dem Wort return und dem Wert oder Namen
der Variable, die zurückgegeben werden soll.
Innerhalb eines Funktionsrumpfes ist es möglich, lokale Variablen
zu definieren, wie in jedem Programmblock, der durch geschweifte
Klammern abgeschlossen ist. In einer Funktion kann man natürlich
auch weitere Funktionen aufrufen.
Beispiel
// Dies ist eine sehr einfache Funktion, die nichts macht und auch
// keinen Wert zurückgibt. Sie dient nur als Beispiel und hat
// keinen praktischen Nutzen.
void machNichts() {
}
// Diese Funktion macht auch gar nichts, gibt allerdings den Wert
// 5 (vom Datentyp int) zurück. Sie dient auch nur als Beispiel
// und hat keinen praktischen Nutzen.
int fuenf() {
return 5;

344 Anhang C: Sprachreferenz


}
// Diese Funktion schaltet die LED aus, die an ledPin hängt. Diese
// Funktion ist an sich auch nicht sehr nützlich. Allerdings wird
// beim Ersetzen der ledAus()-Funktion deutlich, was der
// Programmcode bewirkt.
void ledAus() {
digitalWrite(ledPin, LOW);
}
// Diese Funktion addiert 5 zum Argument x hinzu und gibt diesen
// Wert zurück.
int addierFuenf(int x) {
return x + 5;
}
// Diese Funktion schaltet die LED an, wenn a größer ist als 10.
int ledAn(int a) {
if (a > 10) {
digitalWrite(ledPin, HIGH);
} else {
return;
}
}
// Diese Funktion addiert 10 zu x hinzu, wenn x positiv ist, sonst
// gibt sie 0 zurück. x wird hier nur innerhalb der Funktion
// modifiziert.
int addierZehnPositiv(int x) {
if (x > 0) {
x = x + 10;
return x;
} else {
return 0;
}
}

Bei einem Funktionsaufruf wird der Funktionsrumpf einer Funk-


tion immer ausgeführt. Es ist also oft sinnvoll, den Rückgabewert
einer Funktion zu speichern, anstatt immer wieder die Funktion
mit denselben Argumenten aufzurufen. Dabei sollte natürlich
berücksichtigt werden, welche Nebenwirkungen eine Funktion hat
(z.B. ob sie bestimmte Werte auf die serielle Schnittstelle schreibt).
Generell ist es aber möglich, Ausdrücke deutlich effizienter zu
gestalten, wie Sie bei den Beispielen sehen können.
Beispiel
// Anstatt des Ausdrucks
int x = square(y) + square(y); // y-Quadrat wird zweimal berechnet
// ist das hier effizienter:
int y2 = square(y); // y-Quadrat wird nur einmal berechnet
int x = y2 + y2;

Rückgabewerte werden auf zwei unterschiedliche Arten benutzt.


Im ersten Fall wird die Funktion hauptsächlich benutzt, um einen

Funktionen 345
Wert zu berechnen. Das Ergebnis dieser Berechnung wird als Rück-
gabewert an die aufrufende Programmstelle zurückgegeben. Der
Rückgabewert wird aber auch oft benutzt, um den Status der Aus-
führung einer Funktion zurückzugeben (um zum Beispiel zu signa-
lisieren, dass ein Fehler bestimmte andere Ereignisse eingetreten
sind). Für einen einfachen Rückgabestatus »erfolgreich« bzw.
»nicht erfolgreich« reicht ein boolean-Rückgabetyp. Dadurch kann
man auch gleich den Funktionswert in einer Kontrollstruktur ein-
setzen, wie im folgenden Beispiel gezeigt wird. Hier können Sie
außerdem sehen, wie man eine Funktion flexibler gestaltet, indem
man ihr einen zusätzliches Argument übergibt.
Beispiel
boolean istKnopfEinsGedrueckt() {
if (digitalRead(knopfEinsPin) == HIGH) {
return true;
} else {
return false;
}
}
// Diese Funktion kann man auch flexibler schreiben, indem man ihr
// die Nummer des Pins übergibt, an dem ein Knopf angeschlossen ist.
boolean istKnopfGedrueckt(int knopfPin) {
if (digitalRead(knopfPin) == HIGH) {
return true;
} else {
return false;
}
}

Es ist aber auch möglich, einen numerischen Wert als Rückgabetyp


zu verwenden, um unterschiedliche Statuswerte zu signalisieren. So
ist es z.B. möglich, verschiedene Fehlerquellen zu signalisieren. Es
ist sinnvoll, diese unterschiedlichen Statuswerte als Konstanten zu
deklarieren, um das Programm besser lesbar zu machen. Diese
Rückgabewerte lassen sich am besten mit einer switch ... case-
Kontrollstruktur bearbeiten. Es ist oft auch praktisch, Fehlerwerte
als negative Werte zu definieren und Erfolge als positive Werte,
weil man so mit einem einfachen arithmetischen Vergleich bestim-
men kann, ob ein Fehler aufgetreten ist.
Beispiel
const int KeinKnopfGedruecktFehler = -1;
const int NurKnopfEinsGedruecktFehler = -2;
const int NurKnopfZweiGedruecktFehler = -3;
const int BeideKnoepfeGedruecktErfolg = 1;
byte sindBeideKnoepfeGedrueckt() {

346 Anhang C: Sprachreferenz


if (!istKnopfGedrueckt(knopfEinsPin) &&
!istKnopfGedrueckt(knopfZweiPin)) {
return KeinKnopfGedruecktFehler;
} else if (istKnopfGedrueckt(knopfEinsPin)) {
return NurKnopfEinsGedruecktFehler;
} else if (istKnopfGedrueckt(knopfZweiPin)) {
return NurKnopfZweiGedruecktFehler;
} else {
return BeideKnoepfeGedruecktErfolg;
}
}
// Die folgenden Zeilen zeigen einen möglichen Aufruf von
// sindBeideKnoepfeGedrueckt.
int retWert = sindBeideKnoepfeGedrueckt();
if (retWert < 0) {
// Der Rückgabewert ist negativ, also ist ein Fehler
// aufgetreten, der jetzt gemeldet wird.
switch (retWert) {
case KeinKnopfGedruecktFehler:
[Link]("Es ist kein Knopf gedrueckt worden.");
break;
case NurKnopfEinsGedrueckt:
[Link]("Es ist nur Knopf eins gedrueckt worden.");
break;
case NurKnopfZweiGedrueckt:
[Link]("Es ist nur Knopf zwei gedrueckt worden.");
break;
}
} else {
// Der Rückgabewert ist positiv, es wurden also beide Knöpfe
// gedrückt.
[Link]("Es sind beide Knoepfe gedrueckt worden.");
}

Es ist möglich, aus einer Funktion heraus dieselbe Funktion noch-


mal aufzurufen. Man kann auch eine zweite Funktion aufrufen, die
wiederum die erste aufruft. Diese Programmiertechnik nennt man
rekursive Funktionsaufrufe. Sie ist allerdings mit großer Vorsicht zu
genießen und bei den meisten Arduino-Programmen nicht notwen-
dig. Durch jeden Funktionsaufruf werden neue temporäre Variab-
len angelegt und ein bisschen Speicher belegt. Dadurch kann es
schnell zu einem Überlauf des Speichers kommen.

Sketch-Struktur
Ein Arduino-Programm wird Sketch genannt. Ein Sketch wird im
Arduino-Editor geschrieben und als Ordner gespeichert, der alle
Daten und Programmdateien enthält, die für das Ausführen not-
wendig sind. Die Programmdateien haben die Endung .pde.

Sketch-Struktur 347
In der Hautpdatei des Sketches müssen zwei Funktionen auf jeden
Fall implementiert werden: setup() und loop().
Die Funktion setup() wird beim Programmstart aufgerufen (also
wenn das Arduino-Board eingeschaltet oder Reset gedrückt wird).
In dieser Funktion werden Variablen initialisiert, Pinmodi gesetzt
sowie benutzte Libraries und zusätzliche Hardware initialisiert.
setup() wird nur einmal ausgeführt.
Beispiel
int buttonPin = 2;
int meinZaehler;
void setup()
{
meinZaehler = 0;
pinMode(buttonPin, INPUT);
[Link](9600);
}

Zwischen die geschweiften Klammern werden nun alle Befehle


geschrieben, die vor dem Start des Hauptprogramms zum Einrich-
ten des Arduino benötigt werden. Dazu gehört die Festlegung ein-
zelner Pins als Ein- oder Ausgang. In diesem Beispiel hier sind das
die Zeile pinMode(buttonPin, INPUT), die Initialisierung zusätzlicher
Libraries (hier die Initialisierung der seriellen Schnittstelle auf 9.600
Baud) und das Initialisieren von Variablen (hier das Initialisieren
von meinZaehler auf 0).
Die Setup-Routine wird nur ein einziges Mal ausgeführt, wenn das
Board neu an eine Stromquelle (oder per USB an den Rechner)
angeschlossen oder neuer Code hochgeladen wird.

Loop
Die Funktion loop() wird auch als Hauptfunktion bezeichnet. Von
hier aus werden andere Bestandteile des Programms aufgerufen und
Befehle abgearbeitet. Wie der Name schon verrät, läuft loop() in
einer Schleife, das heißt sie beginnt immer wieder von vorn, sobald
sie durchlaufen wurde. In dieser Funktion wird meistens die
gesamte Funktionalität des Sketches implementiert. Einzige Aus-
nahme ist die Funktionalität, die über Interrupt-Routinen imple-
mentiert wird. Interrupts sind allerdings ein fortgeschrittenes
Konstrukt von Arduino und werden meistens in Libraries gekapselt.
Beispiel
void loop()
{
if (meinZaehler > 100) {

348 Anhang C: Sprachreferenz


serialWrite("ueberLauf");
meinZaehler = 0;
} else {
meinZaehler++;
}
if (digitalRead(buttonPin == LOW)) {
serialWrite('H');
} else {
serialWrite('L');
}
delay(1000);
}

Mehrere Dateien in einem Sketch


Meistens wird ein Arduino-Programm in einer Datei gespeichert,
die auch den Namen des Sketches trägt (mit der Endung .pde). Bei
komplizierteren Programmen wird diese Datei allerdings ziemlich
lang, und es ist oft schwer, einzelne Funktionen oder Variablen-
deklarationen wiederzufinden. Deswegen ist es möglich, im Ardu-
ino-Editor mehrere Dateien anzulegen, die vor dem Kompilieren zu
einer großen Datei zusammengefügt werden. So können in einem
größeren Programm unterschiedliche Bereiche in getrennte Dateien
geschrieben werden (z.B. eine Datei für alle LED-Funktionen, eine
für die serielle Kommunikation und eine für die Kommunikation
mit einem Sensor). Dazu muss für jede neue Datei ein neuer Tab
angelegt werden, indem der Knopf mit dem Pfeilsymbol auf der
rechten Seite gedrückt wird (nicht der Knopf mit dem Pfeilsymbol
in der Hauptleiste, der verwendet wird, um einen Sketch auf das
Arduino-Board hochzuladen). Danach erscheint ein Menü, mit
dem die einzelnen Tabs (sprich Dateien) verwaltet werden können.
Zum Anlegen einer neuen Datei muss NEW TAB ausgewählt wer-
den. Der Arduino-Editor fragt nach einem Namen für den Tab und
speichert die so erzeugte Datei im Verzeichnis des Arduino-Pro-
gramms.
Beim Kompilieren des Arduino-Programms werden alle Tabs zu
einer großen Datei zusammengefügt und anschließend übersetzt.
Das kann zu Problemen führen, wenn in einer Datei globale Variab-
len benutzt werden, die in einer anderen Datei definiert wurden
(die Reihenfolge der Variablendefinition ist nämlich wichtig, siehe
Abschnitt Variablen), weil die Reihenfolge des Zusammenfügens
sich nicht steuern lässt. Es ist deswegen sinnvoll, globale Variablen
so zu definieren, dass sie nur in einer Datei verwendet werden, und
als Schnittstelle zwischen den einzelnen Dateien Funktionen zu
definieren. Das gilt auch für Programmabschnitte, die in loop()

Sketch-Struktur 349
und setup() verwendet werden. Eine Strukturierung, die sich als
sinnvoll erwiesen hat, ist, in jeder Datei passende Funktionen loop-
Dateiname() und setupDateiname() zu definieren, die dann in den
eigentlichen loop()- und setup()-Funktionen aufgerufen werden.
Zugriff auf globale Konfigurationswerte wird in sogenannte Getter
und Setter gekapselt. Eine Getter-Funktion liefert nur den Wert
einer Variablen zurück, während eine Setter-Funktion den Wert
einer Variablen setzt. Im folgenden Beispiel werden der Zugriff auf
die globale Variable ZeitInterval gekapselt und eine zweite Datei
[Link] benutzt.
Beispiel
// Dies ist die Hauptdatei des Sketches.
int zeitInterval = 10; // globale Konfigurationsvariable
int getZeitInterval() { // Getter-Funktion zum Lesen von
// zeitInterval
return zeitInterval;
}
void setZeitInterval(int wert) { // Setter-Funktion zum Schreiben
// von zeitInterval
zeitInterval = wert;
}
void setup() {
setupZeit(); // Aufruf der setup-Funktion in der Datei [Link]
}
void loop() {
loopZeit(); // Aufruf der loop-Funktion in der Datei [Link]
}
// Dies ist die Datei [Link] des Sketches.
void setupZeit() {
setZeitInterval(20); // Setzen von zeitInterval auf 20 in der
// Initialisierungsphase
}
void loopZeit() {
delay(getZeitInterval()); // Hauptroutine der Datei [Link] mit
// Lesen der zeitInterval-
// Konfigurationsvariable
}

Funktionsreferenz
In diesem Abschnitt werden die in der Arduino-Programmierspra-
che vordefinierten Funktionen vorgestellt. Sie decken eine breite
Menge von unterschiedlichen Bereichen ab, von der Kommunika-
tion mit der elektronischen Außenwelt (digitale und analoge Ein-
und Ausgabe) über Zeitfunktionen (Zeitmessen und Warten) und
mathematische Funktionen bis hin zur Kommunikation mit dem
Computer über die serielle Schnittstelle (bzw. die USB-Schnittstelle).

350 Anhang C: Sprachreferenz


Digitale Ein- und Ausgabe
Die Funktionen für digitale und analoge Ein- und Ausgabe ermögli-
chen die Kommunikation des Arduino mit der Außenwelt, indem
Werte von Pins eingelesen und auf diese Pins geschrieben werden
können.

pinMode(pin, mode)
Diese Funktion initialisiert die »Richtung« eines digitalen Pins. pin
ist die Nummer des Pins, wie sie auf dem Arduino-Board geschrie-
ben steht. Jeder Pin, auch die als »analog« markierten, kann als
digitaler Eingangs- und Ausgangspin initialisiert werden. .mode
definiert die Richtung und kann entweder INPUT sein, um den Pin
als Eingangspin zu initialisieren, oder OUTPUT, um den Pin als Aus-
gangspin zu initialisieren.
Beispiel
pinMode(13, OUTPUT); // initialisiert Pin 12 als Ausgangspin
pinMode(9, INPUT); // initialisiert Pin 9 als Eingangspin

digitalWrite(pin, value)
Diese Funktion setzt die Spannung eines als Ausgangspin definier-
ten digitalen Pins oder aktiviert die Pull-up-Funktionalität für Pull-
up-Widerstände eines als Eingangspin definierten digitalen Pins.
Wird der Wert des digitalen Ausgangspins auf HIGH gesetzt, legt
der Arduino-Prozessor eine Spannung von 5 Volt (bzw 3,3 auf
Boards mit 3,3-Volt-Versorgungsspannung) an den Pin an. Wird
der Wert auf LOW gesetzt, legt der Arduino-Prozessor eine Span-
nung von 0 Volt an.
Ist der Pin als Eingangspin definiert, wird beim Schreiben eines
HIGH-Wertes der interne Pull-up-Widerstand des Arduino akti-
viert, und der Pin wird auf die Versorgungsspannung »hochgezo-
gen«. Wird auf den Eingangspin der Wert LOW geschrieben, wird
der Pull-up-Widerstand deaktiviert.
Beispiel
pinMode(13, OUTPUT); // initialisiert Pin 12 als Ausgangspin
digitalWrite(13, HIGH); // Jetzt liegen 5V an Pin 13 an.
digitalWrite(13, LOW); // Jetzt liegen 0V an Pin 13 an.
pinMode(9, INPUT); // initialisiert Pin 9 als Eingangspin
digitalWrite(0, HIGH); // Der Pull-up-Widerstand auf Pin 9 ist aktiviert.
digitalWrite(0, LOW); // Der Pull-up-Widerstand auf Pin 9 ist deaktiviert.

Funktionsreferenz 351
int digitalRead(pin)
Mit dieser Funktion lassen sich digitale Werte (HIGH oder LOW)
auslesen, die an einem digitalen Eingangspin anliegen. Der Pin
muss vorher als digitaler Eingangspin festgelegt worden sein. Liegt
keine definierte Spannung am Eingangspin an (z.B. wenn nichts
angeschlossen wurde), kann digitalRead einen zufälligen Wert
zurückgeben.
Beispiel
pinMode(9, INPUT); // initialisiert Pin 9 als Eingangspin
int val = digitalRead(9);

Analoge Ein- und Ausgabe


Auf dem Arduino-Prozessor gibt es eine Reihe von Pins, die sich als
analoge Eingänge konfigurieren lassen (auf dem Arduino Duemila-
nove sind es die Pins 14 bis 19). Im Unterschied zu digitalen Ein-
gängen können diese den kompletten Spannungsbereich (und nicht
nur 0 und 5V) auslesen. Dazu wird intern auf dem Arduino-Prozes-
sor ein sogenannter AD-Wandler eingesetzt, der analoge Werte in
digitale konvertiert. Dieser AD-Wandler hat eine Auflösung von 10
Bit, d.h. Eingangsspannung 0 bis zur Referenzspannung (meistens
5V, siehe aber analogReference) werden zum numerischen Bereich
0 bis 1.023 konvertiert, es ist also möglich, mit einer Genauigkeit
von 5 / 1.024 = 4.9mV Spannungen zu messen. Hier sei angemerkt,
dass diese Eingänge oft sehr empfindlich für Rauschen sind, die
Genauigkeit entspricht also nur in den seltensten Fällen der the-
oretisch möglichen. Analoge Pins lassen sich auch problemlos als
digitale Ein- und Ausgangspins einsetzen. Das umgekehrte Vorge-
hen ist leider nicht möglich.

int analogRead(pin)
Mit analogRead wird die Spannung, die an einem analogen Ein-
gangspin anliegt, ausgelesen. Der Rückgabewert geht von 0 (0V)
bis 1.023 (Referenzspannung). Das Einlesen analoger Werte dauert
deutlich länger als das Einlesen digitaler Werte, was unter Umstän-
den berücksichtigt werden muss.
Wie bei digitalRead werden bei einem Pin, an dem keine definierte
Spannung anliegt, einigermaßen zufällige Werte zurückgegeben (je
nachdem, wie nah der Benutzer am Arduino ist, wie hoch die Luft-
feuchtigkeit ist und ob mit einem Gummihuhn über der Schaltung
gewedelt wird).

352 Anhang C: Sprachreferenz


Beispiel
pinMode(9, INPUT); // Initialisiert Pin 9 als Eingangspin
int val = digitalRead(9);

analogWrite(pin, value)
Obwohl die analogWrite-Funktion in der analogen Kategorie aufge-
listet wird, wird sie konkret benutzt, um den Arbeitszyklus eines
PWM-Pins festzulegen. Wie in Kapitel 3 beschrieben, wird bei
PWM-Pins (auf dem Arduino Duemilanove sind das die Pins 3, 5,
6, 9, 10 und 11) periodisch zwischen HIGH und LOW alterniert.
Mit analogWrite lässt sich die Länge der HIGH-Periode einstellen
(aber nicht die Periodendauer).

analogReference(type)
Mit analogReference lässt sich die Referenzspannung, die der AD-
Wandler benutzt, umstellen. Dies ist eine fortgeschrittene Funktion
und sollte mit großer Vorsicht eingesetzt werden, weil man damit
den Arduino-Prozessor beschädigen kann. Die Referenzspannung
bestimmt, welche Spannung den Wert 1.023 beim Aufruf von ana-
logRead() bekommt. Ist die Referenzspannung 5 Volt, wird 0 Volt
als 0 gelesen, 5 als 1.023, und 2,5 als 512. Ist die Referenzspannung
allerdings 1 Volt, wird 0 Volt als 0 gelesen, 1 als 1.023, und 0,5 als
512. Wird eine höhere Spannung als die Referenzspannung an einen
analogen Eingang angelegt, besteht die Möglichkeit, den Arduino-
Prozessor zu beschädigen. Es ist also große Vorsicht geboten, wenn
die Referenzspannung verändert wird, was bei bestimmten Sensoren
zur Erhöhung der Genauigkeit notwendig ist. Die Referenzspan-
nung kann nicht höher als die Versorgungsspannung liegen (in den
meisten Fällen 5 Volt, auf einigen Arduino-Clones allerdings 3,3).
Weiterhin ist es sehr sinnvoll, Referenzspannungen an den AREF-
Pin über einen 5.000-Ohm-Widerstand anzuschließen, um den
Arduino-Prozessor zu schützen. Dadurch wird ein zu großer Strom-
fluss verhindert, falls die aktuellen Referenzspannungseinstellun-
gen nicht kompatibel zum Aufbau der Schaltung sind.
Es gibt drei mögliche Einstellungen für die Referenzspannung, die
mit dem type-Argument gesetzt werden. Die normale Einstellung
(wenn als Argument DEFAULT übergeben wird), die für die meisten
Fälle ausreichen sollte, ist das Verwenden von AVCC (also der
analogen Betriebsspannung, die 5 Volt beträgt) als Referenzspan-
nung. Der AREF-Pin muss frei sein und wird intern mit AVCC
beschrieben.

Funktionsreferenz 353
Die zweite Möglichkeit ist das Anschließen einer internen Span-
nung von 1,1 Volt als Referenzspannung. Dazu muss type als
INTERNAL gesetzt werden.
Die dritte Möglichkeit ist das Konfigurieren der Referenzspannung
über den AREF-Pin, indem type als EXTERNAL gesetzt wird. Dazu
wird die Spannung an AREF angelegt (am besten über einen 5.000-
Ohm-Widerstand, um Fehler zu vermeiden). Diese Spannung wird
dann als Referenzspannung benutzt.

Fortgeschrittene Ein- und Ausgabe


Bei komplizierten Aufbauten müssen oft viele Werte über einen syn-
chronen seriellen Bus ausgegeben werden. Das klingt ziemlich kom-
pliziert, ist aber eigentlich sehr einfach. Z.B. sind die Shift-Register,
die wir in Kapitel 10 (Musik-Controller) eingesetzt haben, so ange-
schlossen. Über solche Busse werden längere digitale Werte über-
tragen (z.B. 16 Bits), aber nur zwei oder drei digitale Ausgangspins
benutzt.
Anders als bei einer asynchronen seriellen Schnittstelle, wie wir sie
in Kapitel 5 gesehen haben, wird bei einer synchronen Schnittstelle
ein expliziter Takt mitgegeben: Nach jedem übermittelten Bit (das
auf eine Datenleitung gesetzt wird) wird ein sogenanntes Clock-Sig-
nal gepulst, um zu signalisieren, das gerade ein Bit anliegt. Das Pul-
sen des Clock-Signals muss eine gewisse Länge haben, damit der
empfangende Chip genügend Zeit hat, den Wert einzulesen, kann
aber sonst in einem beliebigen Tempo gesetzt werden. Die Clock-
Leitung und die Datenleitung sind die einzigen notwendigen Lei-
tungen, um Daten zu übermitteln. Oft wird aber noch eine dritte
Leitung verwendet, um die Kommunikation zu starten (bzw. zu
beenden). Bei einem Shift-Register wird zum Beispiel die Enable-
Leitung verwendet, um die übermittelten Daten dann letztendlich
auch zu aktivieren. Der komplette Kommunikationsablauf sieht
also wie folgt aus: Kommunikation starten (wenn notwendig), ers-
tes Datenbit anlegen, Clock-Signal pulsen, zweites Bit anlegen,
Clock-Signal pulsen usw. Zum Abschluss muss ggf. noch die Kom-
munikation beendet werden.

shiftOut(dataPin, clockPin, bitOrder, value)


Diese Funktion vereinfacht das Übermitteln von Daten über eine
synchrone serielle Schnittstelle. Übergeben werden dataPin, die
Nummer des digitalen Ausgangspins, der für Datenübermittlung

354 Anhang C: Sprachreferenz


verwendet wird, clockPin, die Nummer des digitalen Ausgangspins,
der für die Clock-Leitung verwendet wird, bitOrder, die Rei-
henfolge, in der die Bits übermittelt werden sollen, und value, der
numerische byte-Wert (also 8 Bits lang), der übermittelt werden soll.
Die Bitreihenfolge (bitOrder) kann zwei unterschiedliche Werte
annehmen: LSBFIRST und MSBFIRST. LSBFIRST ist die Abkürzung für
»least significant bit first«, und heißt, dass das niedrigste Bit aus
value zuerst übertragen wird. So wird zum Beispiel Byte 19, also
00010011 in Binärdarstellung, wie folgt übertragen: 1, 1, 0, 0, 1, 0,
0, 0. MSBFIRST ist die Abkürzung für »most significant bit first«, und
Byte 19 würde als 0, 0, 0, 1, 0, 0, 1, 1 übertragen. Je nach empfan-
genden Chip ist die eine oder die andere Darstellung erforderlich.
Beispiel
int clkPin = 9;
int dataPin = 10;
pinMode(clkPin, OUTPUT);
pinMode(dataPin, OUTPUT);
shiftOut(dataPin, clkPin, MSBFIRST, 19); // übertragen von 19 auf
// der synchronen
// seriellen
Schnittstelle
// auf Pins 9 und 10

unsigned long pulseIn(pin, value) /


unsigned long pulseIn(pin, value, timeout)
Manchmal werden Sensorwerte (z.B. beim Beschleunigungssensor
ADXL, siehe ) als Pulse übertragen. Je länger der Puls, desto höher
ist der übertragene Wert. Es bedarf also einer Funktion, mit der
sich diese Pulslänge messen lässt. Diese Funktion lässt sich z.B. mit
den unten beschriebenen Zeitfunktionen definieren, ist dann aller-
dings nicht sehr genau (weil die Zeitfunktionen der Arduino-Umge-
bung nur als grobe Hilfen zur Verfügung stehen). Deswegen wird
für solche Zwecke die Funktion pulseIn verwendet.
pulseIn gibt die Länge eines Pulses auf dem digitalen Eingangspin
pin zurück. Dabei gibt value an, welchen Wert der Puls haben will.
Wird als value HIGH übergeben, wartet die Funktion, bis der Ein-
gangspegel am Pin auf HIGH geht, und misst die Zeit, bis der Ein-
gangspegel wieder auf LOW geht. Die gemessene Zeit wird in
Mikrosekunden zurückgegeben. Wird LOW als value übergeben,
wartet die Funktion darauf, dass der Eingangspegel auf LOW geht,
und misst die Zeit, bis er wieder zu HIGH zurückkehrt. Wird nach
einer bestimmten Timeout-Zeit kein Pegel erkannt (als Standard-
wert wird eine Sekunde benutzt, es ist allerdings möglich, den

Funktionsreferenz 355
Timeout als drittes Argument zu übergeben), gibt die Funktion 0
zurück. Die Zeitmessungen dieser Funktionen können von 10
Mikrosekunden bis ungefähr 3 Minuten gehen, werden allerdings
ungenauer, je länger der Puls ist.
Beispiel
pinMode(9, INPUT); // initialisiert Pin 9 als Eingangspin
int pulsLaenge = pulseIn(9, HIGH); // misst einen positiven Puls
// auf Pin 9
pulsLaenge = pulseIn(9, HIGH, 400);// misst einen positiven Puls
// auf Pin 9, gibt 0 zurück, falls
// innerhalb von 400 Mikrosekunden
// kein Puls erkannt wurde

Zeitfunktionen
Es ist oft notwendig, Zeiten zu messen und auch bestimmte Zeiten
zu warten, um Programme zu implementieren. Diese Zeiten lassen
sich in zwei größere Ebenen einteilen: »menschliche Zeit«, also
Zeitintervalle, die für Menschen bemerkbar sind. Diese reichen von
ein paar Millisekunden (wenn z.B. LEDs blinken sollen) bis zu
mehreren Sekunden oder gar Minuten (wie z.B. beim Brainma-
chine-Workshop in ). Auf der anderen Seite gibt es die »Compu-
terzeit«, die deutlich schneller ist. Sie wird z.B. benötigt, um auf
bestimmte Sensoren oder Chips zu warten, um ein Kommunikati-
onsprotokoll genau zu implementieren, um Lichter zu dimmen (sie
also so schnell flackern zu lassen, dass der Mensch es nicht
bemerkt).
Deswegen sind die zwei Zeitfunktionen (eine Funktion zum
Messen von Zeit und eine Funktion zum Warten) immer in zwei
Versionen vorhanden: eine für Millisekunden und eine für Mikro-
sekunden (es gibt 1.000 Millisekunden in einer Sekunde und 1.000
Mikrosekunden pro Millisekunde). Der Arduino-Prozessor läuft
mit 16 MHz, d.h. er kann bis zu 16 Millionen Instruktionen pro
Sekunde ausführen. Das setzt auch die unterste Grenze für die Auf-
lösung gemessener Zeitwerte fest. Jeder Zyklus ist genau 0,0625
Mikrosekunden lang, es ist also nicht möglich, mit dem Arduino
sehr genaue Werte in Mikrosekunden überhaupt zu messen. Wei-
terhin entstehen durch den Aufruf der Funktion und unterschiedli-
che andere Nebenwirkungen (wie z.B. periodische Interrupts, die
in Arduino verwendet werden) Verzögerungen, die sich nicht vor-
aussagen lassen. Dadurch ist die Genauigkeit dieser Zeitfunktionen
mit Vorsicht zu genießen.

356 Anhang C: Sprachreferenz


unsigned long millis()
Diese Funktion gibt die Anzahl von Millisekunden zurück, die seit
dem Anschalten des Arduino abgelaufen sind. Der Zähler wird bei
jedem Neuprogrammieren, Neuanschließen und Resetten des
Arduino-Boards neu initialisiert. Nach ungefähr 50 Tagen läuft die
Variable unsigned long über und beginnt wieder bei 0 (das ist ein
ähnliches Problem wie beim Y2K-Bug). Das folgende Programm
gibt die abgelaufene Zeit in Millisekunden auf der seriellen Schnitt-
stelle aus.
Beispiel
unsigned long time;
void setup() {
[Link](9600);
}
void loop() {
time = millis(); // Auslesen der abgelaufenen Millisekunden
// seit Programmanfang
[Link](time); // Ausgeben auf der seriellen Konsole
elay(1000); // eine Sekunde warten
}

unsigned long micros()


Diese Funktion ist das Mikrosekunden-Pendant zur Funktion mil-
lis(). Sie gibt die abgelaufene Anzahl an Mikrosekunden seit Pro-
grammanfang zurück und läuft schon nach ungefähr 70 Minuten
über. Durch den Aufrufmehraufwand gibt diese Funktion auf
einem Arduino-Board immer ein Vielfaches von 4 Mikrosekunden
zurück (wenn das Arduino-Board mit 16 MHz läuft; 8-MHz-Ardu-
ino-Boards wie z.B. das LilyPad liefern Vielfache von 8 Mikrose-
kunden zurück).

delay(ms)
Diese Funktion hält das Ausführen des Programms für die angege-
bene Zeit ms (Millisekunden) an. In Wirklichkeit läuft der Prozes-
sor weiter (es werden z.B. auch Interrupt-Funktionen weiter
aufgerufen) und führt nur Anweisungen aus, die nichts bewirken.
Die serielle Schnittstelle läuft deswegen problemlos weiter und
empfangene Bytes werden weiter im Puffer gespeichert. Auch mit
PWM gepulste Pins (siehe ) laufen während eines delay-Aufrufs
weiter. Allerdings ist es in dieser Zeit auch nicht möglich, z.B. wei-
tere Werte aus einem Sensor oder von Tastern auszulesen. Deswe-
gen ist es bei längeren Pausen (von mehr als nur ein paar

Funktionsreferenz 357
Millisekunden) besser, auf die Funktionen micros() und millis()
auszuweichen, um bestimmte zeitabhängige Verhalten zu imple-
mentieren.
Da Interrupts weiterlaufen, während delay() ausgeführt wird, ist
die zeitliche Genauigkeit der Funktion nicht sehr hoch. Sie sollte
nicht eingesetzt werden, um zeitkritische Verhalten zu implemen-
tieren. Auch in diesem Fall ist es besser, die Funktion millis() zu
benutzen oder die Interrupts zu deaktivieren.
In dem folgenden einfachen Beispiel wird eine LED zum Blinken
gebracht.
Beispiel
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT); // Der LED-Pin wird als Ausgang
// initialisiert.
}
void loop() {
digitalWrite(ledPin, HIGH); // LED anschalten
delay(1000); // 1000 Millisekunden warten (also eine
// Sekunde)
digitalWrite(ledPin, LOW); // LED ausschalten
delay(1000); // eine weitere Sekunde warten
}

Das folgende Beispiel zeigt, wie man das Blinken der LED ohne
delay() implementieren kann. Dazu wird in jedem loop()-Aufruf
die Zeit gemessen, die verlaufen ist, und entsprechend die LED an-
und ausgeschaltet. Das Beispiel scheint relativ uninteressant zu
sein, aber im Vergleich zum vorigen Programmbeispiel lassen sich
jetzt z.B. problemlos Taster abfragen. Würde man delay() mit Tas-
tenabfragen kombinieren, würden viele verloren gehen, weil der
Prozessor in dieser Zeit damit beschäftigt wäre, delay() auszufüh-
ren.
Beispiel
int ledPin = 13;
int ledValue = LOW; // der aktuelle Wert der LED
long ledSchaltZeit = 0; // die Zeit, zu der die LED zuletzt
// geschaltet wurde
long intervall = 1000; // die Länge des Intervalls zwischen jedem
// Schalten
void setup() {
pinMode(ledPin, OUTPUT); // Der LED Pin-wird als Ausgang
// initialisiert.
}
void loop() {
// zeit speichert die Dauer seit dem letzten Schalten.

358 Anhang C: Sprachreferenz


unsigned long zeit = millis() – ledSchaltZeit;
// überprüfen, ob genügend Zeit seit dem letzten Schalten
// abgelaufen ist
if (zeit > intervall) {
// es ist genügend Zeit abgelaufen, jetzt muss die LED
// geschaltet werden
if (ledValue == LOW) {
ledValue = HIGH;
} else {
ledValue = LOW;
}
digitalWrite(ledPin, ledValue);
// jetzt wird die aktuelle Zeit als Schaltzeit gespeichert
ledSchaltZeit = millis();
}
// Hier können jetzt Sensoren und Taster abgefragt und andere
// Aufgaben ausgeführt werden.
}

delayMicroseconds(us)
delayMicroseconds() ist das Mikrosekunden-Pendant zur delay()-
Funktion. Auch hier gibt es wichtige Unterschiede. Im Unterschied
zur delay()-Funktion ist delayMicroseconds() zwischen ungefähr 3
Mikrosekunden und 16.383 Mikrosekunden sehr genau. Um diese
Genauigkeit zu erreichen, werden allerdings die Interrupts deakti-
viert, d.h. es werden keine Daten auf der seriellen Schnittstelle
empfangen, und Zeiten, die von millis() und micros() zurückge-
geben werden, werden nicht hochgezählt. delayMicroseconds()
sollte man deswegen nur für sehr kurze Pausen benutzen, delay()
dagegen für längere. Wegen der Art, wie delayMicroseconds()
geschrieben wurde (um diese Genauigkeit einzuhalten), führt
delayMicroseconds(0) zu einer deutlich längeren Pause von unge-
fähr 1.020 Mikrosekunden.

Mathematische und trigonometrische Funktionen


Viele häufig verwendete mathematische Funktionen werden auch
von der Arduino-Programmiersprache zur Verfügung gestellt. Sie
decken Bereiche ab von der einfachen Berechnung (Minimum,
Maximum) bis hin zu komplexeren trigonometrischen Funktionen
wie Sinus und Kosinus.

min(x, y)
Diese Funktion gibt die kleinere der beiden Zahlen x und y zurück.
Sie kann auf alle numerischen Datentypen angewandt werden. Aus

Funktionsreferenz 359
nicht ganz intuitiven Gründen wird min oft benutzt, um die obere
Grenze einer Variable zu setzen. Aus Implementationsgründen
sollte man vermeiden, weitere Ausdrücke in die Parameter von min
zu schreiben, da die Gefahr besteht, sie mehrmals auszuführen.
Deswegen sollte man unbedingt darauf achten, reine Zahlen und
Variablen als Argumente an min (und an max) zu übergeben.
Beispiel
int x = 13;
x = min(x, 12); // x wird nie größer als 12 sein.
min(x++, 20); // Diese Schreibweise ist falsch, x++ könnte
// mehrmals ausgeführt werden.
x++;
min(x, 20); // Dies ist die richtige Schreibweise.

max(x, y)
Diese Funktion gibt die größere der beiden Zahlen x und y zurück.
Wie min kann auch max auf alle numerischen Datentypen ange-
wandt werden. Auch nicht ganz intuitiv ist die Anwendung von max
zum Setzen der unteren Grenze einer Variablen. Zum Einschränken
einer Variablen nach oben und unten sollte man allerdings auf die
schwer lesbare Kombination von min und max verzichten und statt-
dessen die Funktion constrain einsetzen. Auch hier sollten nur
Variablen und Zahlen als Argumente übergeben werden.
Beispiel
int x = 13;
x = max(x, 5); // x wird nie kleiner als 5 sein.
// Folgendes ist schwer zu lesen.
int y = 80;
y = max(min(y, 100), 20); // y wird immer zwischen 20 und 100
sein.

abs(x)
Diese Funktion gibt den Absolutwert einer Zahl zurück (also x,
wenn x positiv ist, und –x, wenn x negativ ist) und kann auf alle
numerischen Datentypen angewandt werden. Auch an abs dürfen
nur Variablen und numerische Zahlenwerte übergeben werden,
keine beliebigen Ausdrücke.
Beispiel
int x = 13;
int y = abs(x); // y ist 13.
x = -13;
y = abs(x); // y ist 13.

360 Anhang C: Sprachreferenz


constrain(x, a, b)
Anstatt eine Kombination aus min und max zu verwenden, um einen
Wert nach oben und unten zu beschränken, lässt sich die Funktion
constrain einsetzen. Sie gibt x zurück, wenn x größer oder gleich a
und kleiner oder gleich b ist. Ist x kleiner als a, wird a zurückgege-
ben. Ist x größer als b, wird b zurückgegeben.
Beispiel
int x = 13;
x = constrain(x, 10, 20); // x ist immer zwischen 10 und 20.

map(value, fromLow, fromHigh, toLow, toHigh)


Soll ein Wert in einem bestimmten numerischen Bereich in einen
anderen numerischen Bereich konvertiert werden (also nicht nur
beschränkt werden), ist die map-Funktion zu benutzen. Die Zahl
value, die sich im Bereich fromLow bis fromHigh befindet, wird in
den Bereich toLow bis toHigh abgebildet. So kann z.B. ein Wert in
dem Bereich 0 bis 100 konvertiert werden, damit er im Bereich von
50 bis 60 liegt. Dann wird z.B. 0 zu 50, 50 zu 55, 100 zu 60. So lässt
sich auch der Wertebereich invertieren, indem man zum Beispiel
eine Zahl von 0 bis 100 auf den Bereich 100 bis 0 konvertiert. Wei-
terhin kann die map-Funktion auch Bereiche mit negativen Zahlen
bearbeiten, sodass man z.B. den Bereich 20 bis 40 auf den Bereich –
20 bis 80 legen kann (20 wird zu –20, 30 wird zu 30, 40 wird zu
80).
Die map-Funktion beschränkt Eingangswerte nicht auf den angege-
benen Bereich, weil es oft auch nützlich ist, Ausreißer zu berück-
sichtigen. Die Funktion arbeitet mit ganzzahligen Werten, auch
wenn je nach Eingabe mathematisch eine Fließkommazahl erzeugt
werden müsste.
Beispiel
int val = analogRead(0); // analoger Sensorwert, von 0 bis 1023
int y = map(val, 0, 1023, 0, 255); // jetzt von 0 bis 255
analogWrite(9, y); // und als PWM-Wert für Pin 9 eingesetzt
// für mathematisch interessierte Leser ist hier die Definition
// der Funktion:
long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x – in_min) * (out_max – out_min) / (in_max – in_min) + out_min;
}

sq(x)
Diese Funktion gibt das Quadrat einer Zahl zurück.

Funktionsreferenz 361
pow(base, exponent)
Diese Funktion gibt die Potenz der Zahl base zurück. Der Grad der
Potenz wird im Argument exponent übergeben. Die Argumente der
pow-Funktion sind Fließkommazahlen, sodass auch Bruchwerte als
Potenzen eingesetzt werden können (z.B. um Wurzeln oder expo-
nentielle Werte zu berechnen). Allerdings ist deswegen die Funk-
tion relativ langsam und sollte sparsam (oder mithilfe von Lookup-
Tabellen, siehe Kapitel 4, »LED-Matrix«) eingesetzt werden. Alle
weiteren Funktionen (insbesondere die trigonometrischen) in die-
sem Abschnitt arbeiten mit Fließkommazahlen und komplizierten
Algorithmen und sind deswegen sehr langsam.

sqrt(x)
Diese Funktion gibt die quadratische Wurzel einer Fließkomma-
zahl zurück.

sin(rad)
Diese Funktion gibt den Sinus eines Winkels rad, der in Radian
angegeben ist, zurück.

cos(rad)
Diese Funktion gibt den Kosinus eines Winkels rad, der in Radian
angegeben ist, zurück.

tan(x)
Diese Funktion gibt den Tangens eines Winkels rad, der in Radian
angegeben ist, zurück.

Zufallszahlen
Es ist möglich, auf dem Arduino-Prozessor Zufallszahlen zu erzeu-
gen. Allerdings sind diese nicht »echte« Zufallszahlen, sondern
werden algorithmisch generiert. Ein sogenannter PRNG (pseudo-
random number generator, pseudozufälliger Zahlengenerator) rech-
net immer wieder neue Zahlen aus, die in keiner ersichtlichen
logischen Reihenfolge zueinander stehen. Wird dieser PRNG mit
demselben Wert initialisiert (das Initialisieren nennt man auf eng-
lisch seeding, also »Samen pflanzen«, den Initialisierungswert seed,
also »Samen«), generiert er auch dieselbe Folge an Zufallszahlen.
Das kann ein Vor- oder ein Nachteil sein. Auf der einen Seite kön-
nen immer wieder gleiche Zufallszahlen nach einer gewissen Zeit

362 Anhang C: Sprachreferenz


ihren Reiz verlieren, auf der anderen Seite ist es so möglich, einen
bestimmten Ablauf zu wiederholen, falls z.B. ein Fehler oder eine
besonders interessante Folge gefunden wurde. Um jedes Mal eine
neue Folge zu generieren, kann man den PRNG mit einer »richti-
gen« Zufallszahl initialisieren (z.B. dem Ergebnis von analogRead
auf einem nicht angeschlossenen Pin). Echte Zufallszahlen sind
aber nicht gleich verteilt, während die erzeugten Zufallszahlen eini-
germaßen gleich verteilt und deshalb besser einzusetzen sind.

randomSeed(seed)
Mit dieser Funktion wird der PRNG initialisiert.

long random(max) / long random(min, max)


Diese Funktion liefert einen zufälligen Wert als Ergebnis. Dieser
Wert befindet sich zwischen 0 (bzw. min, wenn min als Argument
angegeben wurde) und der oberen Schranke max.
Beispiel
randomSeed(analogRead(0)); // initialisiert den PRNG auf einen
// wirklich zufälligen Wert, weil 0
// nicht angeschlossen ist
int val = random(300); // liefert einen zufälligen Wert zwischen 0
// und 300
int val2 = random(10, 20); // liefert einen zufälligen Wert
// zwischen 10 und 20

Serielle Kommunikation
Mit den folgenden Funktionen lässt sich die serielle Schnittstelle
des Arduino-Prozessors konfigurieren und benutzen (siehe ). Diese
serielle Schnittstelle ist über einen weiteren Chip an die USB-
Schnittstelle angebunden und kann so einfach an jedem Computer
angebracht werden. Die Funktionen in diesem Abschnitt können
verwendet werden, um sowohl Daten vom Arduino-Prozessor an
den Computer zu schicken als auch Daten vom Computer aus an
den Arduino-Prozessor zu übermitteln.

[Link](speed)
Bevor die serielle Schnittstelle verwendet werden kann, um Daten
zwischen Computer und Arduino-Prozessor auszutauschen, muss
erst die Geschwindigkeit der Übertragung eingestellt werden. Diese
Geschwindigkeitseinstellung (und weitere Initialisierungen der seri-
ellen Schnittstelle und der dazugehörigen Speicherdaten) werden

Funktionsreferenz 363
durch die Funktion [Link]() implementiert. Als Argument
wird ihr die gewünschte Geschwindigkeit der Schnittstelle in Bits
pro Sekunde (oder auch Baud) mitgegeben. Aus technischen und
historischen Gründen sind allerdings nicht alle Geschwindigkeiten
möglich, sondern nur folgende (die vielleicht noch aus Modemzei-
ten bekannt sind): 300, 1.200, 2.400, 4.800, 9.600, 14.400, 19.200,
28.800, 38.400, 57.600 oder 115.200 Bits pro Sekunde. Es ist wich-
tig, dass auf der empfangenden Seite (auf dem Computer) und im
Sketch die gleichen Geschwindigkeiten eingestellt sind.
Es ist nicht möglich, die serielle Schnittstelle vor der Initialisierung
zu benutzen. Deswegen ist in den meisten Sketches, die die serielle
Schnittstelle verwenden, ein Aufruf an die Funktion [Link]()
als erste Anweisung in der Funktion setup zu sehen. Ein weiterer
wichtiger Punkt ist, dass nach dem Initialisieren der seriellen
Schnittstelle die Benutzung der ersten zwei digitalen Pins nicht
mehr möglich ist, weil diese Pins die eigentliche serielle Schnitt-
stelle bilden (ein Pin für den Datenempfang und einer für den
Datenversand).

int [Link]()
Der Arduino-Prozessor empfängt Daten, die vom Computer aus
über die serielle Schnittstelle geschickt wurden, automatisch in
einer getrennten Interrupt-Routine. Diese Routine speichert die
empfangenen Daten in einem kleinen Puffer, damit der Sketch, der
auf dem Arduino-Prozessor läuft, nicht dauernd unterbrochen
wird. Die Funktion [Link]() prüft, ob Daten in diesem
Zwischenpuffer empfangen wurden, und gibt zurück, wie viele
Bytes an Daten vorhanden sind. Es ist wichtig, regelmäßig Daten
aus diesem Puffer mithilfe der Funktion [Link]() auszulesen
oder ihn mit [Link]() zu leeren, damit er nicht überläuft (er
kann maximal 128 Bytes zwischenspeichern).

int [Link]()
Diese Funktion liest das nächste Byte aus dem Empfangspuffer und
gibt es zurück. Dadurch wird wieder ein Byte in diesem Puffer frei.
Falls keine Daten empfangen wurden, gibt die Funktion –1 zurück.
Beispiel
void setup() {
[Link](9600); // Initialisieren der seriellen
// Schnittstelle auf 9600 Baud
}

364 Anhang C: Sprachreferenz


void loop() {
// überprüfen, ob Daten über die serielle Schnittstelle
// empfangen wurden
if ([Link]() > 0) {
// es wurden Daten empfangen
byte b = [Link](); // Auslesen des ersten
// Bytes und Ausgabe auf der
seriellen Schnittstelle
[Link]("Empfangen: ");
[Link](b, DEC);
}
}

[Link]()
Mit dieser Funktion lässt sich der komplette Empfangspuffer leeren
(z.B. beim Neuinitialisieren des Programms). Diese Funktion ist
auch nützlich, wenn z.B. ein Überlauf des Empfangspuffers erkannt
wurde und die enthaltenen Daten nicht mehr gebraucht werden.

[Link](data) / [Link](data)
Mit diesen zwei Funktionen können beliebige ganzzahlige Werte
und Zeichenketten auf der seriellen Schnittstelle ausgegeben wer-
den. Die Funktion [Link]() fügt eine Leerzeile an das Ende
der Ausgabe ein.
Wird [Link] ohne zweites Argument verwendet, wird das
erste Argument in Dezimaldarstellung ausgegeben. Es ist allerdings
möglich, die Darstellung als zweites Argument an [Link]()
zu übergeben, um so z.B. eine Zahl in Hexadezimaldarstellung aus-
zugeben. Es ist so möglich, mit DEC eine Zahl in Dezimaldarstellung
auszugeben, mit HEX in Hexadezimaldarstellung, mit OCT in Oktal-
darstellung, mit BIN in Binärdarstellung und mit BYTE als ASCII-Zei-
chen.
Es ist nicht möglich, Fließkommazahlen auf der seriellen Schnitt-
stelle auszugeben; sie werden in ganzzahlige Zahlen konvertiert. Es
ist allerdings möglich, diese Fließkommazahlen vor dem Ausgeben
noch mit 10 oder 100 zu multiplizieren, um so zumindest ein paar
Nachkommaziffern anzeigen zu können.
Beispiel
void setup() {
[Link](9600); // Initialisieren der seriellen
// Schnittstelle auf 9600 Baud
}
void loop() {
// gibt die Zahlen von 0 bis 9 auf der seriellen Schnittstelle aus

Funktionsreferenz 365
for (int x = 0; x < 10; x++) {
[Link]("Normal: ");
[Link](x);
[Link]("DEC: ");
[Link](x, DEC);
[Link]("OCT: ");
[Link](x, OCT);
[Link]("HEX: ");
[Link](x, HEX);
[Link]("BIN: ");
[Link](x, BIN);
}
}

366 Anhang C: Sprachreferenz


ANHANG D
Händlerliste

In der folgenden Tabelle finden Sie einige Lieferanten, die Arduino-


boards führen.

Händler Internet
bausteln [Link]

Geist Electronic-Versand GmbH [Link]


Hans-Sachs-Strasse 19
78054 VS-Schwenningen
Telefon 0049 (0)7720 / 36673
Fax 0049 (0)7720 / 36905
SEGOR-electronics GmbH [Link]
Kaiserin-Augusta-Allee 94
10589 Berlin

TinkerSoup [Link]

Watterott electronic [Link]


Winkelstr. 12a
37327 Hausen

367
Index

Symbole Arduino XVI


AIR-Projekt 9
# (Raute) 138
Aktoren 4, 20
// (Kommentarzeichen) 295
Analoger Pin 20
<<-Operation 321
Arbeitsspeicher 27
==-Operator 323
Arduino-Programm 292
>>-Operation 322
Betriebsleuchte 19
~ (Tilde) 320
Bezugsquellen 21
~ (Tildenoperator) 116
Bibliotheken 275
Board 267
Numerisch Bootloader 19
3-D-Drucker 267 C++ 5
Duemilanove 5
A Editor 292
EEPROM 165
Abisolierzange 63 E-Mails versenden 137
Abstandssensor 178 Entwicklungsboard 3
Acknowledged 154 Entwicklungsumgebung 3, 22
Adafruit Ethernet Shield 270 Ethernet-Shield 155
Adafruit GPS Shield 272 GND (Ground) 20
Adafruit Motor Shield 274 Hobley, Stephen 248
ADXL320 176 I/O-Pin 20
ADXL330 176 Installation unter Linux 22
AIR-Projekt 9 Java 5
Aktoren 187 Kommunikation mit PC 137
Alphawellen 121 Labyrinth 14
Ampere 36 LilyPad 8
analoge Codierung 41 Markenrecht XVI
Analoge Ein- und Ausgabe 352 Mega 266
Anode 85 Minuspol 20
Api Musik 12, 247
Application Programming Interface 94 Philosophie 7
Application Programming Interface Programmfunktionen 292
API 94 Programmstruktur 292
Ardrumo 234 Programmwerte 292
Ardugotchi 119

| 369
Prototypen 7 B
Proxy 137
BakerTweet 15
Pulsweitenmodulation 251
Banzi, Massimo 2
Reset-Schalter 19
Basis
Sensoren 20
Transistor 105
serielle Kommunikation 131
Battery Shield 270
serielle Konsole 132
Bausteln-Projekt 21
Shield 269
Bauteile
Sounderzeugung 12
Bedrahtete 44
Spiele 12
Oberflächenbauteile 44
Stromanschluss 19
parallel schalten 39
Syntax 291
passive Komponente 44
Übertragungsleuchte 19
surface mounted devices (SMD) 44
USB-Chip 18
Benutzerschnittstelle 33
USB-Port 18
Beschleunigungssensor 241
Varianten 267
Beschleunigungssensoren 176
visuelle Effekte 9
Betawellen 121
Webserver 157
Bibliothek 275
Wii Balance-Board 14
Biegungssensor 186
Arduino Bluetooth 266
Bilderrahmen 17
Arduino Duemilanove 18, 265
bipolare Spannung 250
Arduino Lilypad 267
Bitübertragungsschicht 153
Arduino Mega 266
Blinkenlights 12
Arduino Mini 267
Blinkenlights-Projekt 109
Arduino Nano 267
Boarduino 268
Arduino Pro 5V 266
Boolesche Operation 324
Arduino Proto Shield 269
Bootloader 62
Arduino RepRap Shield 270
Botanicalls 161
Arduino, Giovanni 2
Bouncing
Arduinoboy 14
Prellen 95
Arduino-Entwicklungsumgebung
Boxsack 11
Codefenster 27
Brain Machine 122
Konsole 27
Brainmachine 65
Sketch 26
BrainPong 185
Sketchbook 28
Brainwave 128
Skizzenbuch 28
Breadboard-Shield 269
Symbolleiste 26
Brewboard 15
Syntax Highlighting 28
BrewTroller 15
Arduinome 272
Buchse 58
Arduino-Shield 269
Buchsenleisten 60
ArduPilot 268
Buchstaben 301
Argumentenliste 341
Byte 130
arithmetische Operation 315
Arnold, Frank 247
Array 91 C
Arrays 302 Cadmiumsulfid 175
Atari 12 Cahill, Thaddeus 227
Atmega168 18 Callback-Funktion 244
Atmega328 18 capSense-Bibliothek 288
Ausdruck 309, 310 Channel Pressure-Nachricht 236
Chip 41

370 | Index
Codierung E
analoge 41
EAGLE 46
digitale 41
Echtzeit-MIDI-Nachricht 236
Controller Change-Nachricht 236
EEPROM 165, 276
Creative Commons 3
Lebensdauer 170
Cuartielles, David 2
Schreibzyklen 169
Eingabepin 87
D Eingabesensoren 273
Dance Dance Revolution 34 Eingabe-Shields 273
Datenblätter 44 Elektret-Kondensatormikrofone 183
Datenblattsammlungen 45 Elektretmikrofone 183
Datentyp 86 elektrische Regel 43
Variablen 86 elektrischer Leiter 43
Datentypen 297 elektrischer Strom 36
Numerische 298 Elektroenzephalografie 185
Datentypkonvertierung 312 Elektrolytkondensator 53
Debounce-Bibliothek 94, 285 elektromechanische Klangerzeugung 227
Dehnungsmessstreifen 186 Elektron 36
Dekrementierungsoperation 326 Elektronische Klangerzeugung 250
Deltawellen 121 elektronisches Klavier 248
Desktopcomputer 33 Elko 53
Die binäre Brücke 11 Entkopplungskondensator 250, 260
Diecemila 265 Entlöten 71
Differenzdrucksensor 185 Entlötlitze 71
Digiripper 9 Entlötpumpe 72
Digital-Analog-Wandler 251 Entwicklungsumgebung
digitale Codierung 41 Processing 2
Digitale Ein- und Ausgabe 351 Epoxidharz 43
digitale Kommunikation 129 E-Reihen 50
Dihardja, Daniel 247 Erschütterungssensor 194
Dimmen 107 Ethernet 277
Diode 55 exklusiver ODER-Operator 319
Anode 55 EyeToy 34
Kathode 55
diskrete Spannungswerte 41 F
Display
Fehlerquellen 77
Siebensegment 111
Feldeffekttransistor 105
Diver Sequencer 248
Fernbedienung 173
DMX 273
Feuchtigkeitssensor 182
DMX-shield 273
Filtern 260
do ... while-Kontrollstruktur 338
Fingerabdruckssensoren 184
Dorsum Arduino 2
Firmata 144, 281
DPDT (Double Pole, Double Throw) 49
Bibliothek 281
DPST (Double Pole, Single Throw) 49
Schnittstelle 281
Drehknopf 102
Flash 4
Helligkeit 102
Flexsensoren 53
Drehregler 172
Fließkommazahlen 301
Dreiachsen-Beschleunigungssensor 241
Flugdrohne 173, 177
Drei-Wege-Handshake 154
Fluidforms 11
Drucksensoren 53
Flusskontrolle 151
Dynamisches Mikrofon 183

Index | 371
for-Kontrollstruktur 334 Hirnwellenfrequenz 127
Fototransistor 175 HMC6352 182
Fotowiderstand 53 Hochpräzisionswiderstände 50
Fotowiderstand (LDR) 175 Holm, Eric 13
Fotozelle 53 Honeywell 182
[Link] XVI HTTP 155
Frequenzen 260 Hygrometer 182
Frequenztabelle 259 Hypertext Transport Protocol (HTTP) 155
Funktion 92, 338, 342
Argumente 92 I
Funktionsargumente 342
i2c 241
Funktionsaufruf 338
IC 61
Funktionsdefinition 340
if ... else-Kontrollstruktur 328
Funktionsdeklaration 340
if-Kontrollstruktur 327
Igoe, Tom 3
G Illuminato 268
Gadget 16 IMAP 155
Galliumarsenid 105 In-Circuit Serial Programming
Gammawellen 121 ICSP 19
Gasdrucksensor 185 Infrarotsensoren 181
gEDA 46 Inkrementierungsoperation 326
Gehirnmaschine 122 Input 32
Gehirnwellenmaschine 16 Input-Output
Geschweifte Klammern ({}) 294 IO 88
Glasfaser 43 [Link] XVII
Gleichspannung 56 Integer
Gleichstrommotor 188 Zahl 86
Glühbirnen vs. LED 106 integrated circuit 41
GND Interaction Design 2
Ground 85 Interaction Design Institute Ivrea (IDII) 2
Gobetwino 137 Interactive Telecommunications Program 3
Gotcha 14 Internet Protocol (IP) 153
GPS-Shield 272 Interrupt-Routine 255
Grundton 263 IO
Gyroskop 178 Pin 88
IP-Adresse 154
H iPhone 33
iterieren 91
Halbleiter 40
Halbleitermaterial 54
Hall, Edwin 180 J
Hall-Sensor 180 Joystick 173, 273
Handluftpumpen 247
Hauptfunktion 84 K
loop() 84
Kabel 58
Hayward, David 107
Kapazitiver Pad 173
Heißluftpistole 72
kapazitiver Sensor 179
Helligkeitsstufen 102
Kathode 85
Hexadezimaldarstellung 301
Katze 17
HIGH-Spannung 41

372 | Index
Key Pressure-Nachricht 236 libraries 275
KiCad 46 Lichtschranke 176
Kingbright TA20 110 Lichtsensor 146
Klangstufen 10 Lichtwechsel 93
Kleidung 8 Lichtwecker 107
Kohleschichtwiderstände 50 Light Intensity 175
Kollision 148 Lilie, Anita 16
Kommentare 295 Linux 22
Kommunikation LiquidCrystal 282
Protokoll 129 Liquidware 273
Kompass 182 Liquidware TouchShield 271
Kompilieren 95 Lochrasterplatine 43, 65
Kondensator 53 Logarithmustabelle 100
Farad 53 Logische Negierung 320
Filter 54 Logische Operation 316
Konstanten 308 Löten 64
Kontrollstruktur 327 Sicherheit 72
Kraftsensor 185 Lötkolben 67
Krokodilklemmen 59 Lötpunkte 70
Künstler 8 Lötspitze 67
Kupferleiterbahn 43 Lötvorgang 69
Kupferlitze 59 Lötzinn 68
Flussmittel 68
L ROHS-Regelung 68
Low Frequency Oscillator (LFO) 257
L293 189
LOW-Spannung 41
Ladyada XVII
LSBFIRST 355
Lampe
Luftfeuchtigkeit 182
Farbverläufe 100
Luftverschmutzung 9
Lampen 106
Laptop 130
RS232-Schnittstelle 130 M
Laserharfe 248 Mac OS X 22
Laserspiele 13 Make Magazine XVI
Laufschrift 109 March Frame Projec 16
Lautsprechermembran 250 Maskierung 317
LCD-Bildschirm 282 Masse 85
LDR (Fotowiderstand) 53, 162, 175 mathematische Funktion 359
LED 109, 187 Matrix 109
Anode 85 Flackern 115
Auge 98 MAX/MSP 11
Diode 84 Max/MSP 4
Kathode 85 [Link] XVII
Lichtfarbe 85 Mellis, David 2
light emitting diodes 84 Melodien 259
Matrix 110 MEMS 176
Leistung 39 Messung
Leuchtdioden 106 analoger Eingang 102
Leuchtstofflampen vs. LED 106 Metalldetektor 180
Leyh, Arvid 122 Metalloxid-Halbleiter-Feldeffekttransistor
LFO 257 Mosfet 105

Index | 373
Metallschichtwiderstände 50 Nintendo Gameboy 14
MicroSD Module 272 Note Off 236
MIDI 231 Note On 236
Temposynchronisation 236 NPN-Transisto 105
Timing Master 236 Nullpunkt 262
Timing Slave 236 Nunchuck 173, 241
Midi 143
Midi Monitor 235 O
MidiDuino 239
Obertöne 260
Bibliothek 239
Objekt 95
MIDI-Gerät 231
ODER-Operator 319
MIDI-Nachrichten 235
Ohmsches Gesetz 37
MIDI-Protokoll 231, 233
Open Heart Kit 65
MIDI-Sniffer 235
Open Source 5
Miduino 268
Open Systems Interconnection Model 129
Mika Satomi 186
OpenEEG 185
Mikrocontroller 32
Operationen 311
Mikrofon 106
Optokoppler 237
Mikrofone 183
OSI-Modell 129
Milk Lamp 107
Oszilloskop 81
MIT Media Lab 2
Output 32
Mittelwert 101
Modulo 93
Modulo-Operation 315 P
Moll-Arpeggio 258 Pad 173
Mollterz 258 Paintball 13
Monome 232 Parameter 338
Moog, Bob 228 Parker, Alastair 13
Morup, Mikael 137 Perner-Wilson, Hannah 186
Motion-Capturing 186 Physical Computing 31
Motor-Driver 189 Grundlagen 35
Motoren 188 Rechnen 42
MSBFIRST 355 Sensoren 171
Multimeter 78 Piezoeffekt 184
Spannungen messen 80 Piezoelektrisches Mikrofon 184
Ströme messen 81 Pin
Widerstandswerte messen 80 Festlegung 84
Multitouch-Oberfläche 33 Setup-Routine 84
Musik-Shield 271 Pinzette 64
Platine 43
N Pocket Piano Shield 249
Nam June Paik 9 Pong 12
Natal 34 POP3 155
Negative Zahlen 300 Potentiometer 102, 172
Negierungsoperator 320 Powerball 13
Nervenzellen Präzedenzregeln 314
Spannungsimpulse 121 Prellen 94
Niedrigfrequenzoszillator 258 Bouncing 95
PRNG (pseudorandom number generator) 362
Nintendo 177

374 | Index
Processing 2, 142 S
Drehknopf 145
s2midi 234
Program Change-Nachricht 236
Sanguino 267
Programmblock 294
Schaltbild
Programmiersprache 84
Verbindungen 46
Programmrumpf 340
Schalter 48, 87
Programmstruktur 293
Ball Switches 48
Propellurino 270
Taster 49
Protoduino 269
Schaltkreis 36, 61
pseudozufälliger Zahlengenerator 362
elektrischer 35
Pulswellenmodulation
Schaltung 43
PWM 97
analoge 40
Zähler 98
digitale 40
Punkten 42
Schaltungen
PWM
Fehlersuche 73
Pulsweitenmodulation 97
Temperatursensortransistorverstärkungsschal-
tung 74
Q Schieberegler 273
Quadrokopter 178 Fader 52
Quecksilberspeicher 230 Schleife
Quinte 258 for() 91
loop() 91
R Schleifendurchlauf 91
Schrittmotor 189
R.E.M. 142 Schutzbrille 122
Radio Frequency Identification, (RFID) 271 Seitenschneider 63
Raes, Godfried-Willem 228 Semikolon 294
Rails 65 Sensor
Rapid Prototyping XI resistiver 39, 53
Rauschen 260 Sensoren 171
Raute (#) 138 Septime 258
Reed-Relais 180 Sequencer 229
Relais 54 Serielle Kommunikation 363
RepRap 267 Servo
reservierte Zeichen 296 Bibliothek 284
resistive Sensoren 172 Servo (siehe Servomotor) 139
Resistiver Pad 173 Servomotor 138, 188
resistiver Touchscreen 174 Servomotoren 284
Resistor Capacitator (RC) 180 shiften 321
Restwert 315 Shift-Register 62
RFID 271 SID-Chip 272
RGB-LED 106 Siebensegment 111
Ribbon Controller 173 Signal
Roaming Drone 175 digitales 86
Roboduino 268 elektrisches 35
Roboter 12 Silizium 54
Rotor 189 Sketch 347
Rückgabetyp 309 Funktionsreferenz 350
Rückgabewert 309 Kompiliervorgang 26

Index | 375
loop() 348 Thetawellen 121
.pde 349 Tiefpassfilter 106, 249, 260
Stop-Symbol 27 Tilde (~) 320
Struktur 347 Tildenoperator (~) 116
Sleeptracker 16 [Link] XVI
SMTP 155 Tischzange 69
SN754410NE 189 dritte Hand 69
Sniffer 155 Tomczak, Sebastian 9
Solenoid 190 Tonhöhe 127
Sonar 181 Touchpad 173
Sonic Body 11 Touchscreen 174
Soundchip 271 TouchShield 271
Spannung 35, 41, 86 Transistor 54
U 86 Basis 105
Volt 35 Emitter 105
Spannungsregler 56 Kollektor 105
Spannungsteiler 38 NPN 105
Spannungswert 50 PNP 105
SparkFun 176 Transistoren 105
SPDT (Single Pole, Double Throw) 49 Treiberbaustein 61
Spielekonsolen 12 TSL230R-LF 175
Spielzeugroboter 12 Tweetie 160
Spitzzange 64 Tweets 160
SPST (Single Pole, Single Throw) 49 Twhirl 160
Stahlwolle 68 Twitter 160
Steckbrett 43, 57
Stecker 58 U
Steckernetzteil 56
UDP 154
Stereoklinkenbuchse 249
Ultraschallsensor 17
Strom 36
Umgang mit Strom
Studentenkneipe
Fehlerstromsicherung 40
Arduino 2
Sicherheitsregeln 40
switch ... case-Kontrollstruktur 331
Umwandlung aus Energie
Synthesizer
Wärme 36
modularer 228
UND-Operator 317
Systeme
unipolare Spannung 250
mikroelektrisch-mechanische 176

T V
Vakuumröhren 105
T.V.-be-Gone 65
Val, Olaf 9
Tabellen 302
Variable 297, 306
Tamagotchi 118
Variablenzuweisung 310
Tank Shield 273
Vergleichsoperation 323
Taos 175
VGA 9
Taster 48, 87
virtual instrument 230
TCP 154
virtuelles Instrument 230
Telharmonium 227
void 92
Temperatursensor 182
Vorwiderstand 86
Theremin 228, 260
Vorzeichenmarker 98
Thermistoren 53
VVVV 4

376 | Index
W Wireshark 155
Wiznet W1500 156
Wärmeleitpaste 106
WLAN-Modul 154
Watt 39
Wave Shield 271
Wearable Computing XVII X
LilyPad 8 x0xbox 65
Webduino 160 Xbee-Shield 271
Webserver 138, 157
Wellenform 258 Z
Sägezahn 258
Tonhöhen 258 Zahl
while-Kontrollstruktur 337 Integer 86
Widerstand 36, 50, 86 Zahlen 300
Drehpotentiometer 52 Zählvariable 91
Farbcode 50 Zapfanlage 15
lichtempfindlicher 53 Zeichenketten 304
Ohm 36 Zeitfunktion 356
R 86 Zeitschaltuhr 32
Schieberegler 52 Zigbee 271
Variabler 52 Zilius, Jonas XVIII
Wii 34 Zufallszahlen 362
Wiimote 173 Zusammengesetzte Operation 325
Windows 22 Zylinderspule 190
Wire-Bibliothek 286

Index | 377
Über die Autoren
Manuel Odendahl ist Selbstständiger und stellt unter dem Namen
»Ruin & Wesen« Opensource-MIDI-Kontroller her.
Julian Finn ist Informatikstudent kurz vor dem Diplom und arbei-
tet bei der Gameforge AG in Karlsruhe, sowie als freier Autor. Er
hat die Texte für mehrere Computerspiele verfasst und beschäftigt
sich ansonsten mit den Randbereichen von Technik, Kunst und
Gesellschaft. Dazu gehört die Arbeit an Medienkunstinstallationen
genauso wie Text- und Diskussionsbeiträge zu digitaler Kultur,
freiem Wissen und Netzpolitik.
Alex Wenger wollte schon als Kind wissen wie die Welt im Inneren
funktioniert und kein elektrisches Gerät war vor Ihm sicher. Nach
dem Physik- und Dipl. Ing. Informationstechnikstudium entwickelt
er hauptberuflich Software und Elektronik für Display-Anwendun-
gen. Zu den weiteren Beschäftigungen gehört die Arbeit als
Medienkünstler und Dozent.
Yunjun Lee ist in Südkorea geboren und arbeitet momentan als
Gastkünstler am Karlsruher Zentrum für Kunst- und Medientech-
nologie (ZKM). Yunjun Lee entwickelt vielseitige Medienkunstpro-
jekte, bei denen er seine Fähigkeiten als Maler, Bildhauer und
Musiker mit technischen Mitteln erweitert.
Jonas Zilius studiert Architektur an der Universität Karlsruhe.
Neben seiner Tätigkeit als freier Grafiker für Print- und Web-
Medien ist seine Leidenschaft die Photographie. Er ist studentischer
Mitarbeiter in der zentralen Fotowerkstatt der Fakultät Architektur.
Arbeiten aus den Bereichen Veranstaltungen/Konzerte, Sport, Port-
rait und Produkte zählen zu seinen Referenzen. Ein Reise-Bildband
über Tirana/Albanien ist in Arbeit.

Kolophon
Das Coverlayout dieses Buchs hat Michael Oreal gestaltet. Als
Textschrift verwenden wir die Linotype Birka, die Überschriften-
schrift ist die Adobe Myriad Condensed und die Nichtproportio-
nalschrift für Codes ist LucasFont's TheSansMono Condensed.

Common questions

Auf Basis von KI

Eingebettete Computer in alltäglichen Geräten sind Mikrocontroller, die über physikalische Schnittstellen mit der Umgebung und Benutzern kommunizieren. Diese Schnittstellen, wie z.B. Sensoren und Aktoren, unterscheiden sich stark von den traditionellen Ein- und Ausgabegeräten wie Tastatur und Monitor. Herkömmliche Computer führen Programme aus und sind für allgemeine Aufgaben konzipiert. Eingebettete Systeme hingegen sind auf spezifische Aufgaben spezialisiert und in Geräte integriert, um deren Funktionalitäten zu verbessern, etwa in Kaffeemaschinen und Kühlschränken .

Physical Computing erweitert die kreative Reichweite von Künstlern und Designern, da sie interaktive Installationen und intelligente Geräte schaffen können, die auf den Betrachter reagieren. Sensoren und Aktoren ermöglichen dynamische Kunstwerke, die sich basierend auf Umweltbedingungen oder Benutzerinteraktionen verändern. Beispielsweise können Lichtinstallationen entwickelt werden, die auf Bewegungen oder Geräusche reagieren, oder Geräte, die auf Social Media-Interaktionen abstimmen. Dadurch verschwimmen die Grenzen zwischen digitaler und physischer Kunst .

Das Löten einer Schaltung auf eine Platine bietet mehrere Vorteile gegenüber der Verwendung eines Steckbretts. Eine gelötete Schaltung ist stabiler und robuster, was wichtig ist, wenn sie in Gehäuse eingebaut oder in Kunstinstallationen verwendet werden soll. Gelötete Verbindungen sind weniger anfällig dafür, sich zu lösen, was bei Steckbrettern oft ein Problem ist, insbesondere wenn sie bewegt werden. Zudem kann die Schaltung auf einer Platine ästhetischer und platzsparender sein .

MIDI-Daten auf einem Arduino werden über serielle Schnittstellen verarbeitet. Mit der MidiDuino-Bibliothek können Arduinos MIDI-Daten empfangen, auswerten und über Aktoren Klänge erzeugen oder Gerätschaften steuern. Dies bietet die Möglichkeit, traditionelle MIDI-Controller zu simulieren und an die spezifischen Bedürfnisse von Musikern anzupassen. Zudem erlaubt es das Erstellen eigenständiger Musikinstrumente oder Sequencer, die mit kommerziellen Geräten interagieren können .

Ethernet-Shields erlauben einem Arduino, sowohl als Server als auch als Client zu fungieren, und ermöglichen damit die Kommunikation über lokale Netzwerke und das Internet. Ein Arduino kann so beispielsweise Webserver-Funktionalitäten bereitstellen oder Daten an externe Server senden. Damit sind etwa Projekte wie das Übermitteln von Sensordaten an eine Webseite oder das Ansteuern von Arduino-Geräten über das Internet möglich .

Globale Variablen in der Arduino-Programmierung sind nützlich, da sie innerhalb des gesamten Programms zugänglich sind, ohne dass sie explizit durch Funktionsargumente weitergereicht werden müssen. Jedoch erhöht ihr Einsatz die Gefahr von ungewollten Nebenwirkungen, da jede Funktion ihre Werte ändern kann. Daher sollten sie, wo möglich, durch lokale Variablen ersetzt werden, um den Code weniger fehleranfällig zu machen. In Ausnahmefällen können sie gezielt für call-by-reference übergebene Argumente verwendet werden, um Tabellen effizient zu modifizieren .

Das Verständnis der elektrischen Eigenschaften neuer Bauteile ist wichtig, um sicherzustellen, dass sie innerhalb ihrer spezifizierten Grenzen betrieben werden. Beispielsweise sind minimale und maximale Strom- und Spannungswerte kritisch, um Schäden zu vermeiden und die ordnungsgemäße Funktion der Schaltung zu gewährleisten. Bei der Einführung neuer Bauteile ist oft das Studium ihrer Datenblätter erforderlich, um die Bedingungen korrekt einzustellen und somit eine gesicherte Funktionalität in der Schaltung zu gewährleisten .

Mit Physical Computing kann eine Lampe über einen Mikrocontroller gesteuert werden, wodurch komplexe Schaltprogramme möglich werden. Dadurch kann, z.B., das Licht nach einem bestimmten Muster blinken, nur für eine gewissen Zeit leuchten, oder sich an- und ausschalten, sofern bestimmte Bedingungen erfüllt sind, wie die Anwesenheit von Personen. Solche Steuerungsmöglichkeiten sind mit bloßen mechanischen Schaltungen nicht möglich .

Kontrollstrukturen wie Schleifen und Bedingungen sind entscheidend für die Verarbeitung von Eingaben und das Umsetzen in Steuerungsbefehle in Physical Computing Projekten. Schleifen erlauben das kontinuierliche Lesen von Sensoren und das Anpassen von Aktoren in Echtzeit. Zum Beispiel kann eine Schleife in einem Arduino-Programm verwendet werden, um Sensorwerte kontinuierlich zu überwachen und entsprechend LEDs zu steuern. Bedingungen ermöglichen Entscheidungen basierend auf den Sensordaten, wie das Ein- oder Ausschalten von Geräten .

Der Einsatz von Platinen verbessert die Entwicklung und Nutzung komplexer Schaltungen erheblich, indem sie eine stabile und dauerhafte Grundstruktur bieten, die der Schaltung Solidität und Eleganz verleiht. Im Gegensatz zu Steckbrettern, die Kabelverbindungen instabil machen können, erlauben Platinen das feste Anbringen von Bauteilen durch Löten, was die Schaltungen robuster und langlebiger macht . Platinen erlauben auch das Design von komplexen Schaltungen durch die Verwendung von Kupferleiterbahnen, die eine feste Verknüpfung der Komponenten ermöglichen . Dies macht es einfacher, Schaltungen zu erweitern und Anpassungen vorzunehmen, ohne dass die Stabilität oder Ordnung der Schaltung leidet . Dennoch sollte das Design und die Anordnung der Bauteile im Voraus gut durchdacht sein, um Platzmangel und Kurzschlüsse zu vermeiden .

Das könnte Ihnen auch gefallen