Bastelprojekt 1:
Hallo Welt – das Blinken einer LED

In den meisten Büchern zum Erlernen einer Programmiersprache wird zu Anfang ein sogenanntes Hallo-Welt-Programm‌ präsentiert. Es soll einen Einblick in die Syntax der Programmiersprache bieten, indem es etwas recht Simples tut, und zwar nur den Text Hallo Welt auf dem Bildschirm ausgibt. Auf diese Weise kann ein Programmierer einen zeitsparenden Eindruck von der Programmiersprache und seiner Syntax gewinnen.

»Hallo Welt« wird geblinkt

Wie sieht ein Hallo-Welt-Programm bei dem Arduino aus? Der Arduino hat ja in seinem Urzustand kein Display, also kein Anzeigegerät, um sich dir mitzuteilen. Was also tun? Wenn eine Kommunikation nicht in schriftlicher Form möglich ist, dann vielleicht mittels optischer oder akustischer Signale. Wir entscheiden uns für die optische Variante, denn einen Signalgeber wie eine Leuchtdiode, auch LED genannt, können wir ohne allzu große Probleme an einen der digitalen Ausgänge klemmen und er erregt bestimmt Aufmerksamkeit. Ich war jedenfalls sehr beeindruckt, als es bei mir auf Anhieb funktioniert hat. Schauen wir uns zuerst die Bauteilliste an.

Was wir brauchen

Für dieses Bastelprojekt wird nicht viel benötigt und im Grunde genommen könnten wir auch ohne zusätzliche Bauteile auskommen, denn auf dem Arduino-Board befindet sich eine LED‌ mit der Bezeichnung L. Dennoch möchte ich dieses Bastelprojekt mit ein paar Komponenten anreichern, die auch in weiteren Projekten Verwendung finden.

Tabelle 1: Bauteilliste

Bauteil

Bild

LED rot 1x

[Bild]

Widerstand 220Ω 1x

[Bild]

Bevor wir jedoch einen Blick auf das Arduino-Programm – oder auch Sketch genannt – werfen, sehen wir uns den Schaltplan‌ an. Ein Schaltplan ist übrigens eine grafische Darstellung einer elektronischen Schaltung, manche nennen das auch Schaltbild.

Der Schaltplan‌

Unsere Schaltung weist lediglich eine LED mit passendem Widerstand auf.

Die Anode der LED (das längere Beinchen) wird über den Widerstand mit 220Ω an Pin 13 verbunden und das andere Ende, bei dem es sich um die Kathode handelt (das kürzere Beinchen), mit der Masse (GND) des Arduino-Boards. Beim folgenden Schaltungsaufbau verwende ich erstmalig die Kombination aus Arduino-Board und Breadboard, die ich bereits in den Einführungskapiteln erwähnt habe (Kapitel 2). In späteren Bastelprojekten werde ich das Arduino Discoveryboard einsetzen, aber du kannst selbstverständlich alle Bastelprojekte auch auf einem ganz normalen Breadboard realisieren.

[Bild]

Abb. 1: Der Schaltplan

Der Schaltungsaufbau

Der Schaltungsaufbau auf einem Breadboard ist leicht nachvollziehbar und übersichtlich. Nachfolgend ist der Arduino Uno mit dem Breadboard zu sehen. Beide sind über Steckbrücken verbunden. An dem Breadboard habe ich die LED und den Widerstand platziert.

[Bild]

Abb. 2: Der Schaltungsaufbau auf einem kleinen Arduino-Combi-Board

Was ist bei der LED-Polung zu beachten?

[Bild]

Achte auf die korrekte Polung der LED‌, denn andernfalls können wir lediglich eine dunkle LED bewundern. Man läuft zwar mit einer falsch gepolten LED nicht Gefahr, etwas zu beschädigen, doch es sollte schon richtig gemacht werden.

Der Arduino-Sketch

Der Programmcode für unseren ersten Sketch bewirkt, dass er eine über einen Widerstand angeschlossene LED im Sekundentakt blinken lässt. Das Programm dafür sieht folgendermaßen aus:

int ledPin = 13;   // Variable mit Pin 13 deklarieren + initialisieren

void setup() {
  pinMode(ledPin, OUTPUT); // Digitaler Pin 13 als Ausgang
}

void loop() {
  digitalWrite(ledPin, HIGH);   // LED auf High-Pegel (5V)
  delay(1000);                  // Eine Sekunde warten (1000ms)
  digitalWrite(ledPin, LOW);    // LED auf LOW-Pegel (0V)
  delay(1000);                  // Eine Sekunde warten (1000ms)
}

Ich empfehle dringend, den Code selbst abzutippen. Aus meiner Sicht hat das einen hohen Lerneffekt. So lernst du beispielsweise, immer ein Semikolon am Ende einer Befehlszeile zu setzen. Du bekommst ein besseres Gefühl für die Feinheiten der Programmierung, wenn du selbst die Codezeilen eingibst. Das gilt besonders für den Code in den ersten Bastelprojekten. Bei späteren Projekten wird der Code manchmal so umfangreich, dass eine Eingabe per Hand zu aufwändig wäre.

Der im Buch verwendete Code steht hier zum Download zur Verfügung:

[Bild]

https://erik-bartmann.de/?Downloads___Arduino

Der grundlegende Aufbau eines Arduino-Sketches

[Bild]

Jeder Arduino-Sketch hat den gleichen Aufbau. In der folgenden Abbildung 3 wird dieser Aufbau klar:

[Bild]

Abb. 3: Die grundlegende Struktur eines Sketches

Das ganze Programm ist – nach dem Start des Sketches – in drei Blöcke unterteilt, die du oben erkennen kannst. Die einzelnen Blöcke haben eine klar definierte Aufgabe in einem Sketch.

Grüner Block: Die Deklarierung und Initialisierung

In diesem ersten Block werden beispielsweise – falls notwendig – externe Bibliotheken über die #include-Anweisung eingebunden. Wie das funktioniert, wirst du in späteren Bastelprojekten erfahren. Des Weiteren ist hier der geeignete Platz zur Deklaration globaler Variablen, die innerhalb des kompletten Sketches sichtbar sind und verwendet werden können. Bei der Deklaration‌ wird festgelegt, welchem Datentyp die Variable zugeordnet sein soll. Bei der Initialisierung‌ hingegen wird die Variable mit einem Wert versehen.

Blauer Block: Die setup-Funktion

In der setup-Funktion werden meistens die einzelnen Pins des Mikrocontrollers programmiert. Es wird also festgelegt, welche der Pins als Ein- und Ausgänge arbeiten sollen. An manchen werden womöglich Sensoren wie Taster oder temperaturempfindliche Widerstände angeschlossen, die Signale von außen an einen entsprechenden Eingang leiten. Andere wiederum leiten Signale an Ausgänge weiter, um zum Beispiel einen Motor oder eine Leuchtdiode anzusteuern.

Oranger Block 3: Die loop-Funktion

Die loop-Funktion bildet eine Endlosschleife. In ihr ist die Logik untergebracht, beispielsweise werden kontinuierlich Sensoren abgefragt oder Motoren angesteuert. Beide Funktionen, also die setup- und die loop-Funktion, bilden zusammen einen Ausführungsblock, der im Code durch die geschweiften Klammerpaare {} gekennzeichnet wird. Sie dienen als Begrenzungselemente, damit erkennbar ist, wo die Funktionsdefinition beginnt und wo sie aufhört.

Die beiden Funktionen setup und loop müssen genau so heißen, denn beim Start des Sketches wird nach ihnen gesucht, weil sie als Einstiegspunkte dienen, um einen definierten Start zu gewährleisten. Woher sollte der Compiler wissen, welche Funktion nur einmal ausgeführt werden soll und welche kontinuierlich in einer Endlosschleife? Diese Namen sind also unerlässlich für jeden Sketch. Ihnen wird jeweils noch das Schlüsselwort void vorangestellt. Es zeigt an, dass die Funktion voraussichtlich keine Informationen an die Funktion zurückgibt, von der sie aufgerufen wurde.

Den Code verstehen

Zu Beginn deklarieren und initialisieren wir eine globale Variable namens ledPin, ihr weisen wir den Wert 13 zu. Mit dem Befehl int (int = Integer) bestimmen wir, dass es ein ganzzahliger Datentyp ist. Somit ist sie in allen Funktionen sichtbar und es kann darauf zugegriffen werden. Die Initialisierung ist gleichbedeutend mit einer Wertzuweisung‌ über den Zuweisungsoperator‌ =.‌ Die Deklaration und Initialisierung erfolgt hier in einer einzigen Zeile.

[Bild]

Die setup-Funktion wird einmalig zu Beginn des Sketch-Starts aufgerufen und der digitale Pin 13 als Ausgang programmiert. Sehen wir uns dazu noch einmal den Befehl pinMode‌ an.

[Bild]

Er nimmt zwei numerische Argumente auf, wobei der erste für den zu konfigurierenden Pin steht und der zweite bestimmt, ob sich der Pin wie ein Eingang oder Ausgang verhalten soll. Wir wollen ja eine LED anschließen, und deswegen benötigen wir einen Pin, der als Ausgang arbeitet. Die Datenflussrichtung des zweiten Argumentes wird über eine vordefinierte Konstante festgelegt. Hinter OUTPUT verbirgt sich der Wert 1.

Ebenso verhält es sich mit dem Befehl digitalWrite, der ebenfalls zwei Argumente entgegennimmt.

[Bild]

Hier haben wir ebenfalls eine Konstante mit dem Namen HIGH‌, die als Argument bewirken soll, dass ein HIGH-Pegel an Pin 13 anliegt. Dahinter verbirgt sich der numerische Wert 1. In der folgenden Tabelle findest du die entsprechenden Werte:

Tabelle 2: Konstanten und ihre Werte

Konstante

Wert

Erklärung

INPUT‌

0

Konstante für den Befehl pinMode (programmiert Pin als Eingang)

OUTPUT‌

1

Konstante für den Befehl pinMode (programmiert Pin als Ausgang)

LOW‌

0

Konstante für den Befehl digitalWrite (setzt Pin auf LOW-Level)

HIGH‌

1

Konstante für den Befehl digitalWrite (setzt Pin auf HIGH-Level)

Der Befehl delay‌ im Sketch ist für die Zeitverzögerung‌ zuständig. Er unterbricht die Sketch-Ausführung für einen entsprechenden Zeitraum, wobei der übergebene Wert diese Zeitdauer in Millisekunden (ms) angibt.

[Bild]

Der Wert 1000 besagt, dass genau 1000ms, also eine Sekunde, gewartet wird, bis es schließlich weitergeht.

Die einzelnen Arbeitsschritte der Endlosschleife, die durch den void loop-Befehl ausgelöst wurde, sind:

  1. LED an Pin 13 anschalten,

  2. Warte 1 Sekunde,

  3. LED an Pin 13 ausschalten,

  4. Warte 1 Sekunde,

  5. Geh wieder zu Punkt 1.

Der zeitliche Verlauf visualisiert

Es ist zwar schwierig zu erkennen, doch beim genaueren Hinschauen können wir sehen, dass die Onboard-LED‌ zur selben Zeit leuchtet wie die extern angeschlossene LED. Die LEDs sollten direkt nach der erfolgreichen Übertragung zum Board zu blinken beginnen. Ein Oszillogramm‌ zeigt den zeitlichen Verlauf des Impulses am digitalen Ausgang etwas genauer an, wobei ich den Pegel direkt am Ausgang ohne den Widerstand aufgenommen habe. Er wechselt kontinuierlich zwischen 0V und 5V, was hier mit L (LOW) und H (HIGH) gekennzeichnet ist.

[Bild]

Abb. 4: Der Verlauf des Pegels am digitalen Ausgang Pin 13

Achtung!

[Bild]

Im Internet kursieren Schaltskizzen, bei denen eine Leuchtdiode direkt zwischen Masse und Pin 13 gesteckt wurde. Da die beiden Steckbuchsen auf der Seite der digitalen Pins direkt nebeneinander liegen, könnte man dort sehr einfach eine LED einstecken. Ich warne ausdrücklich vor dieser Variante, da die LED ohne Widerstand betrieben wird. Dabei mache ich mir weniger Sorgen um die LED als um den Mikrocontroller. Ich habe einmal die Stärke des Stromes gemessen: Er beträgt ganze 60mA. Dieser Wert liegt 50% über dem Maximum des erlaubten Stromflusses und ist damit definitiv zu hoch. Der maximal zulässige Strom für einen einzelnen digitalen Pin des Mikrocontrollers beträgt 40mA.

Troubleshooting

Fehler schleichen sich schnell ein, auch wenn du glaubst, dich genau an meine Texte und Abbildungen zu halten. Aus eigener Erfahrung weiß ich, dass die Suche nach Fehlern in einem Programm oder einer Schaltung oft das Zeitaufwendigste überhaupt ist. Deshalb gebe ich dir auch immer in jedem Bastelprojekt Hinweise auf mögliche Fehlerquellen. Sollte dein Bastelprojekt also zunächst nicht das tun, was du von ihm erwartest, dann geh die Punkte durch, die ich an dieser Stelle immer aufliste.

Falls die LED‌‌ nicht leuchtet, kann es mehrere Gründe dafür geben.

Eine mögliche Verpolung?

Erinnere dich noch einmal an die beiden unterschiedlichen Anschlüsse einer LED mit der Anode‌ und Kathode‌.

[Bild]

Defekte LED?

Die LED ist vielleicht defekt und durch Überspannung aus vergangenen Bastelprojekten durchgebrannt. Teste sie mit einem Widerstand an einer 5V-Spannungsquelle.

Verkabelung fehlerhaft?

Kontrolliere noch einmal die Steckleistenbuchsen, die mit der LED und dem Widerstand verbunden sind. Sind es wirklich GND und Pin 13?

Sketch fehlerhaft?

Überprüfe noch einmal den Sketch, den du in den Editor der IDE eingegeben hast. Hast du möglicherweise eine Zeile vergessen oder falsch geschrieben und ist der Sketch wirklich korrekt übertragen worden? Hast du die geschweiften Klammerpaare zu Beginn und Ende der setup- und loop-Funktion gesetzt? Hast du auch immer das Semikolon am Ende einer Befehlszeile gesetzt? Das ist übrigens der häufigste Einsteigerfehler.

Wenn die auf dem Board befindliche LED blinkt, sollte die eingesteckte LED ebenfalls blinken, da dann der Sketch korrekt arbeitet.

Grundlagen zur Berechnung des Widerstandes

[Bild]

Ich habe in unserem Blink-Bastelprojekt einfach einen Widerstand von 220Ω verwendet, der für solche Schaltungen vollkommen ausreichend ist. Dennoch kommt sicherlich die Frage auf, warum das so ist und was dabei beachtet werden sollte. Die folgende Schaltung zeigt uns eine Leuchtdiode mit einem Widerstand, die an eine Spannungsquelle angeschlossen wurde.

[Bild]

Abb. 5: Eine LED mit Widerstand

Zusätzlich habe ich noch ein paar Pfeile für Spannungswerte sowie den Gesamtstrom eingezeichnet. Um den Wert eines Widerstandes zu ermitteln, greifen wir auf das sogenannte Ohmsche Gesetz‌ zurück. Das Ohmsche Gesetz beschreibt die Zusammenhänge zwischen Spannung, Strom und dem Widerstand. Legen wir an einem Bauteil eine Spannung U an, dann verändert sich der hindurchfließende Strom I proportional zur Spannung. Der Quotient zwischen den beiden Größen, also Spannung und Strom, ist konstant und definiert den elektrischen Widerstand‌ R. Wir können folgende Formel aufschreiben:

[Bild]

Bringe ich die Formelbuchstaben jetzt in die richtige Reihenfolge, so ergibt sich zum Bestimmen des elektrischen Widerstandes die folgende kurze Formel:

[Bild]

Doch ein wichtiger Aspekt scheint noch nicht angesprochen zu sein. Was ist überhaupt ein Widerstand? Die Elektronen, die sich durch einen Leiter bewegen, haben es mehr oder weniger leicht, ihn zu durchqueren und müssen sich gegen einen bestimmten vorherrschenden Widerstand zur Wehr setzen. Es gibt unterschiedliche Kategorien, die Aufschluss über die Leitfähigkeit eines Stoffes geben.

  • Isolatoren‌ (sehr hoher Widerstand, zum Beispiel Keramik)

  • Schlechte Leiter (hoher Widerstand, zum Beispiel Glas)

  • Gute Leiter (geringer Widerstand, zum Beispiel Kupfer)

  • Sehr gute Leiter (Supraleitung bei sehr niedrigen Temperaturen, bei der der elektrische Widerstand auf 0 sinkt)

  • Halbleiter‌ (Widerstand kann gesteuert werden, zum Beispiel Silizium‌ oder Germanium‌‌)

Damit habe ich schon zwei entscheidende elektrische Größen ins Spiel gebracht, die in einem gewissen Zusammenhang zueinander stehen: den Widerstand R und die Leitfähigkeit G. Je höher der Widerstand, desto geringer der Leitwert‌ und je geringer der Widerstand, desto höher der Leitwert. Folgender Zusammenhang besteht:

[Bild]

Der Widerstand ist der Kehrwert des Leitwertes. Ein erhöhter Widerstand ist mit einem Engpass vergleichbar, den die Elektronen überwinden müssen. Es bedeutet, dass der Stromfluss gebremst und im Endeffekt geringer wird. Stell dir vor, du läufst über eine ebene Fläche. Das Gehen bereitet dir keine großen Schwierigkeiten. Jetzt versuch, bei gleichem Kraftaufwand durch hohen Sand zu gehen. Das ist recht mühsam. Du gibst Energie in Form von Wärme ab und deine Geschwindigkeit sinkt. Ähnlichen Schwierigkeiten sehen sich die Elektronen gegenüber, wenn sie statt durch Kupfer plötzlich zum Beispiel durch Glas müssen.

Dieser zu überwindende Widerstand hat natürlich Auswirkungen. Aufgrund der verstärkten Reibung der Elektronen, beispielsweise an der Außenwand oder untereinander, entsteht Reibungsenergie‌ in Form von Wärme, die der Widerstand nach außen abgibt.

In den meisten elektronischen Schaltungen werden spezielle Bauteile verwendet, die den Stromfluss künstlich verringern, wobei der Widerstandswert R in Ohm (Ω‌)‌ angegeben wird. Es handelt sich dabei um extra angefertigte Widerstände (zum Beispiel Kohleschicht- oder Metallschichtwiderstände) mit unterschiedlichen Werten, die mit einer Farbcodierung versehen werden, die auf ihren jeweiligen Widerstandswert schließen lässt. Wir kommen gleich näher darauf zu sprechen.

[Bild]

Abb. 6: Ein Widerstand, der den Elektronenfluss bremst

Wenn du dir Abbildung 6 mit dem Elektronenfluss ansiehst, dann könnte man zu dem Schluss kommen, dass die Elektronen auf der linken Seite eine höhere Geschwindigkeit haben als die auf der rechten Seite. Doch dem ist nicht so. Der Strom in einem geschlossenen Kreis ist immer gleich! Er wird natürlich durch den hier gezeigten Widerstand entscheidend beeinflusst, doch im Endeffekt ist der Stromfluss vor und hinter einem Widerstand immer gleich. An jeder Stelle passiert pro Zeiteinheit immer dieselbe Anzahl von Elektronen den Leiter beziehungsweise den Widerstand.

Kommen wir zurück zu unserer Schaltung, um den Widerstand zu berechnen. Wir müssen uns überlegen, wie die Werte von Spannung und Strom ermittelt werden. Das ist nicht weiter schwer. An Widerstand und LED (zwischen den Punkten A und C in Abbildung 5) liegen +5V an, denn das ist die Betriebsspannung des Arduino und sie liegt am Ausgang des jeweiligen digitalen Pins an, wenn er mit einem HIGH-Pegel angesteuert wird. An der LED, also zwischen den Punkten B und C fallen in der Regel 2V ab, was aber an der LED und deren Farbe liegt. Die Spannung am Widerstand zwischen den Punkten A und B ist demnach die Differenz von 5V und 2V, ergibt also 3V

Nun fehlt uns noch der Strom, der durch den Widerstand fließt. Wenn wir Bauteile hintereinander in einem einzigen Strompfad schalten, sprechen wir von einer Reihenschaltung, was hier offensichtlich der Fall ist. In einer Reihenschaltung‌ ist der Strom durch alle Bauteile gleich. Ein Blick in das Datenblatt des Arduino teilt uns mit, dass der maximale Strom, den ein digitaler Pin liefern kann und darf, 40mA beträgt. Dieser Wert darf nicht überschritten werden, weil der Mikrocontroller ansonsten Schaden nimmt. Aus diesem Grund begrenzen wir den Strom mit dem eingezeichneten Widerstand Rv. Nun sollte man in der Elektronik nicht unbedingt am Limit arbeiten, sondern immer etwas unterhalb des angegebenen Grenzwertes. Zur Berechnung des Widerstandes werde ich deswegen zwei unterschiedliche Stromwerte von 5mA und 10mA zur Verdeutlichung verwenden, wobei Werte zwischen 5mA und 30mA für eine LED ausreichend sind. Sehen wir uns die entsprechenden Berechnungen und die daraus resultierenden Ergebnisse einmal an:

[Bild]

und

[Bild]

Für einen passenden Widerstandswert können wir uns also Werte im Bereich zwischen 300Ω und 600Ω aussuchen. Der Ausgang des jeweiligen Arduino-Pins wird nur moderat belastet. Ein Wert von 330Ω ist für unsere Belange vollkommen ausreichend. Widerstände werden übrigens nicht in allen nur erdenklichen Größen hergestellt, sondern in unterschiedlichen E-Reihen mit bestimmten Abstufungen angeboten. Zudem sollte auf die maximale Verlustleistung‌ geachtet werden, wobei ein Wert von ¼ Watt ok ist. Passende Sortimente sind im Handel erhältlich.

Auf der folgenden Abbildung sehen wir einen Widerstand und erkennen die unterschiedlichen Farbringe. Diese Farbringe stellen eine Farbcodierung dar.

[Bild]

Was haben sie zu bedeuten und wie ist der Code zu entziffern? Sehen wir uns das anhand der folgenden Grafik genauer an:

[Bild]

Ein Widerstand besitzt in der Regel vier Farbringe. Man hat sich für diese Form der Beschriftung entschieden, da für den Aufdruck von Zahlenwerten einfach zu wenig Platz vorhanden ist. Um die Farbringe zu dekodieren, muss der Widerstand so positioniert werden, dass die drei Ringe, die am dichtesten beieinander liegen, sich auf der linken Seite befinden. Mit welchem Widerstandswert haben wir es denn hier zu tun?

1. Ring

2. Ring

3. Ring

4. Ring

Widerstandswert

Gelb: Wert 4

Violett: Wert 7

Rot: Wert 100

Gold: +/- 5%

4,7KΩ

Wenn wir uns die ermittelten Werte hintereinander aufschreiben, ist das Ergebnis leicht abzulesen: 4700 entsprechen 4,7KΩ. Der Toleranzwert gibt Aufschluss über die Güte: Je kleiner er ist, desto genauer hält sich der Widerstandswert an seine Vorgaben. Wie bin ich aber zu diesen Werten gekommen? Ganz einfach! In der folgenden Tabelle finden wir die unterschiedlichen Farben mit den entsprechenden Werten zur Berechnung eines Widerstandswertes:

Tabelle 3: Farbcodierung der Widerstände

Farbe

1. Ring

2. Ring

3. Ring

4. Ring

[Bild] Schwarz

x

0

100 = 1

[Bild] Braun

1

1

101 = 10

+/- 1%

[Bild] Rot

2

2

102 = 100

+/- 2%

[Bild] Orange

3

3

103 = 1.000

[Bild] Gelb

4

4

104 = 10.000

[Bild]Grün

5

5

105 = 100.000

+/- 5%

[Bild] Blau

6

6

106 = 1.000.000

+/- 0,25%

[Bild] Violett

7

7

107 = 10.000.000

+/- 0,1%

[Bild] Grau

8

8

108 = 100.000.000

+/- 0,05%

[Bild] Weiß

9

9

109 = 1.000.000.000

[Bild] Gold

-

-

10-1 = 0,1

+/- 5%

[Bild] Silber

-

-

10-2 = 0,01

+/- 10%

Die Schaltzeichen, also die Symbole, die in den Schaltplänen verwendet werden, sehen wie folgt aus, wobei sich Unterschiede zwischen der deutschen DIN- und der amerikanischen ANSI-Norm ergeben:

[Bild]

Abb. 7: Die Schaltzeichen eines Widerstandes

Auf das Ohm-Zeichen (Ω) wird bei der Darstellung in der Regel verzichtet, wobei bei Werten, die kleiner als 1Kilo-Ohm (1000Ohm) sind, lediglich die nackte Zahl genannt wird und bei Werten ab 1KΩ ein K für Kilo bzw. ab 1MΩ ein M für Mega angehängt wird. Hier ein paar Beispiele:

Tabelle 4: Ein paar markante Widerstandswerte

Wert

Kennzeichnung

220Ω

220

1000Ω

1K

4700Ω

4,7K oder 4K7

2,2MΩ

2,2M

Die maximale Verlustleistung der Widerstände, die wir für unsere Arduino-Projekte benötigen, beträgt 1/4-Watt. Es handelt sich in allen Fällen um Kohleschichtwiderstände. Sie sind auch billiger als die Kollegen aus der Metallfilmabteilung. Widerstände gibt es in allen möglichen Größen und Farben und je größer beziehungsweise dicker sie sind, desto größer ist auch die Verlustleistung.

So, das war dein erstes Projekt, das du mit dem Arduino gemacht hast! Du hast eine LED und einen passenden Widerstand an das Arduino-Board angeschlossen und hast über den Sketch die LED in einem von dir bestimmten Rhythmus blinken lassen. Wenn du die LED erfolgreich zum Blinken gebracht hast, kannst du bereits stolz auf dich sein! Wenn du es dir zutraust, dann wage dich auch noch an folgendes Thema heran. Das Thema PWM wird dir immer wieder in deiner Bastlerkarriere begegnen. Wenn du es jetzt nicht auf Anhieb verstehst, beschäftige dich später erneut mit diesem Thema.

Die PWM-Ansteuerung

[Bild]

Kommen wir zur Ansteuerung einer LED über PWM. Was das ist, habe ich kurz in Kapitel 1 erwähnt. Nun ist es an der Zeit, es in die Tat umzusetzen. Wir wollen eine LED über eine analoge Ansteuerung langsam aufblenden und sie beim Erreichen des Maximalwertes schlagartig verlöschen lassen, bevor das Spiel von vorne beginnt. Dabei handelt es sich quasi um ein sanftes Blinken im Gegensatz zum abrupten Blinken in der vorherigen Schaltung. Die Ansteuerung erfolgt dabei über die digitalen Pins, die eine Tilde vor der Nummerierung besitzen. Das sind die Pins D3, D5, D6, D9, D10 und D11. Für unser Beispiel habe ich Pin 3 verwendet. Der Sketch-Code sieht folgendermaßen aus:

int ledPin = 3;   // Variable mit Pin 3 deklarieren + initialisieren
int pwmValue = 0; // Variable für PWM deklarieren + initialisieren

void setup() { /* Kein Code erforderlich */ }

void loop() {
  analogWrite(ledPin, pwmValue++); // LED mit PWM-Wert ansteuern
  delay(10);                       // Kurze Pause
  if(pwmValue > 255) pwmValue = 0; // Wenn PWM-Wert > 255 -> 
                                   // auf 0 setzen
}

Den Code verstehen

Zu Beginn deklarieren und initialisieren wir zwei globale Variablen, die die Namen ledPin und pwmValue aufweisen und vom ganzzahligen Datentyp int (int = Integer) sind. Sehen wir uns den Befehl analogWrite genauer an.

[Bild]

Er nimmt zwei Argumente auf, wobei das erste den Pin bestimmt und das zweite den PWM-Wert, der sich im Bereich von 0 bis 255 bewegen darf. Über

pwmValue++

wird die Variable pwmValue nach der Verwendung über die beiden nachfolgenden Pluszeichen um den Wert 1 erhöht. Dieser Vorgang wird in der Programmierung Inkrementieren genannt. Konventionell würde man das gleiche Verhalten mit der folgenden zusätzlichen Codezeile erreichen:

pwmValue = pwmValue + 1;

Würden wir das Inkrementieren der Variablen pwmValue ohne nachfolgende Überwachung in der loop-Endlosschleife laufen lassen, wäre irgendwann ein unzulässiger Wert größer 255 erreicht. Um das zu verhindern, erfolgt über die if-Anweisung eine Abfrage auf Werte größer 255. Wird diese Bewertung positiv beantwortet, erfolgt die Ausführung des nachfolgenden Befehls:

pwmValue = 0;

Darüber erfolgt eine Rücksetzung auf den Anfangswert 0, was zur Folge hat, dass die LED beim nächsten Aufruf des analogWrite-Befehls erlischt. Ändern wir doch den Code derart ab, dass die LED nicht schlagartig erlischt, sondern langsam abblendet.

Wichtig!

[Bild]

Für die PWM-Ansteuerung eines digitalen Pins mit dem analogWrite-Befehl ist keine vorherige Programmierung über den pinMode-Befehl erforderlich, um diesen als Ausgang festzulegen. Wir sehen, dass die setup-Funktion keinen derartigen Befehl enthält und komplett frei von Code ist.

Weitere Informationen zu PWM sind unter der folgenden Adresse zu finden:

[Bild]

  • http://www.arduino.cc/en/Tutorial/PWM

  • https://www.arduino.cc/en/Reference/AnalogWrite

Gut zu wissen

Wir haben gesehen, wie man mit ein paar Codezeilen eine LED blinken lässt. Es geht jedoch noch ein wenig kürzer:

int ledPin = 13;  // Variable mit Pin 13 deklarieren + initialisieren

void setup() {
  pinMode(ledPin, OUTPUT); // Digitaler Pin 13 als Ausgang
}

void loop() {
  digitalWrite(ledPin, !digitalRead(ledPin)); // Toggeln der LED
  delay(1000);   // Eine Sekunde warten
}

Die entscheidende Zeile lautet:

digitalWrite(ledPin, !digitalRead(ledPin));

Wir nutzen an dieser Stelle zwei neue Konstrukte. Da ist zum einen der Befehl zum Ermitteln des Status eines digitalen Pins über digitalRead.

[Bild]

Außerdem nutzen wir den sogenannten NOT-Operator‌ mithilfe des Ausrufezeichen‌s (!‌), der dazu verwendet wird, ein Ergebnis in das Gegenteil zu verkehren. In der Programmiersprache C/C++ existiert kein eigener Datentyp für logische Werte wie wahr oder falsch und deshalb wird ein Wert vom Datentyp int verwendet. Wir haben in der Tabelle 2 über die Konstanten gesehen, dass ein LOW-Pegel den Wert 0 und ein HIGH-Pegel den Wert 1 besitzt. Über den NOT-Operator wird zwischen beiden hin- und hergewechselt, was auch Togge‌ln genannt wird. Hinweise zu booleschen Operatoren sind unter dem folgenden Link zu finden:

[Bild]

https://www.arduino.cc/en/Reference/Boolean

Wenn du weiter in die Thematik der Widerstände eintauchen möchtest, dann rate ich dir einen Blick in mein Buch Elektronik verstehen durch spannende Experimente – Analog- und Digitaltechnik, ISBN 978-3-946496-23-6. Dort werden unter anderem Reihenschaltungen, Parallelschaltungen und Gemischtschaltungen von Widerständen angesprochen und detailliert erklärt.

Was haben wir gelernt?

Du hast die korrekte Deklaration und die korrekte Initialisierung einer globalen Variable kennen gelernt.

Workshop zur blinkenden LED

Ich möchte dir am Ende dieses Projektes die Aufgabe stellen, den Sketch so abzuändern, dass du die Zeit, in der die LED leuchtet beziehungsweise aus ist, in zwei Variablen auslagerst. Darüber kann der sogenannte Tastgrad‌ eingestellt werden. Er beschreibt das Verhältnis von Impulsdauer‌ und Periodendauer‌. Das Ergebnis wird meist in Prozent angegeben. Auf dem folgenden Impulsdiagramm siehst du die unterschiedlichen Zeiten für t bzw. T:

[Bild]

Abb. 8: Der Verlauf des Pegels am digitalen Ausgang Pin 13 bei einem Tastgrad von 25%

t = Impulsdauer

T = Periodendauer

Die Formel zur Berechnung des Tastgrades lautet:

[Bild]

Programmiere den Sketch so, dass die LED 0,5s leuchtet und 1,5s dunkel ist. Der Tastgrad würde sich wie folgt berechnen:

[Bild]

Das entspricht also einem Tastgrad von 0,25 und im Hinblick auf die gesamte Periodendauer leuchtet die LED also zu 25%.

Bastelprojekt 2:
Arduino-Low-Level-Programmierung

Der Arduino Uno besitzt als Herzstück einen Mikrocontroller, der die zentrale Recheneinheit auf dem Board ist. Neben der Spannungsversorgung sind zur Kommunikation mit der Außenwelt natürlich weitere Anschlüsse vorhanden. Da gibt es die analogen und digitalen Ein- beziehungsweise Ausgänge – wir haben das schon in Kapitel 1 gesehen –, die abgefragt und auf die Einfluss genommen werden kann. Da ein Mikrocontroller auf unterster Ebene digital arbeitet, werden die Informationen als HIGH- bzw. LOW-Pegel gespeichert und verarbeitet. Diese finden in bestimmten Speicherbereichen ihr Zuhause, die man Register nennt. In diesem Bastelprojekt werden wir die ganze Sache auf unterster Ebene beleuchten, was zwar knifflig anmutet, doch zum Verständnis der Grundlagen sicherlich hilfreich ist. Aber keine Bange, ich erkläre es Schritt für Schritt.

Was um Himmels Willen ist denn ein Register‌? Wenn es um die Programmierung eines Mikrocontrollers geht, dann besitzt er zur internen Verwaltung und Speicherung von Werten bestimmte Speicherstellen. Die meisten davon haben einen Schreib- und Lesezugriff, was bedeutet, man kann dort etwas ablegen und auch wieder auslesen. Andere können lediglich ausgelesen werden und stellen somit nur einen Lesezugriff zur Verfügung. Derartige Speicherbereiche werden Register genannt. Wenn wir gleich die sogenannten Ports kennenlernen, dann handelt es sich um Register

Die Zugänge des Mikrocontrollers

Um mit einem Mikrocontroller in Verbindung zu treten, muss es eine Möglichkeit geben, Signale zu senden und zu empfangen. Aus diesem Grund sind bestimmte Zugänge geschaffen worden, die Ports genannt werden. Port‌ kommt aus dem Lateinischen von porta, was Tür beziehungsweise Zugang bedeutet. Auf dem Arduino-Board befinden sich mehrere nebeneinanderliegende Pins, die teilweise zu Funktionsgruppen zusammengefasst wurden. Sie werden Ports genannt und haben eine Datenbreite von acht Bits. Auf der folgenden Abbildung 1 sehen wir einige dieser Ports:

[Bild]

Abb. 1: Die Ports des Arduino Uno

Die farbig markierten Ports sind mit den folgenden Pins verbunden:

Da jeder der drei genannten Ports individuell programmiert werden kann, sind zusätzliche Register erforderlich, die für die Konfigurationen notwendig sind. Der kleine Buchstabe x wird später durch den benötigten Port ersetzt. Die Ports haben ebenfalls eine Datenbreite von acht Bits und lauten wie folgt:

[Bild]

http://www.arduino.cc/en/Reference/PortManipulation

Die Programmierung eines Ports

Sehen wir uns die Sache einmal im Detail an, wobei ich nochmal erwähne, dass diese Art des Arbeitens schon in Richtung Fortgeschrittenenprogrammierung geht, doch zum tieferen Verständnis trägt dieses Wissen allemal bei. Werfen wir doch einmal einen Blick auf Port B mit den digitalen Pins 8 bis 13.

[Bild]

Abb. 2: Port B

An den Buchsen, die auch Header genannt werden, sind nicht alle Pins einem Port zugeordnet. Wir erkennen das hier an den kleinen diagonalen Kreuzen. Auf der Seite der Header befinden sich Beschriftungen, die Hinweis auf die Funktion geben, was in meinen Augen eine sehr nützliche und hilfreiche Sache ist. Die vier Anschlüsse von links gesehen können nicht für unsere Vorhaben verwendet werden, da sie dem I²C-Bus, der Spannungsversorgung und der Masse zugeordnet sind. Damit wir auf die digitalen Pins 8 bis 13 zugreifen können, müssen entsprechende Register vorbereitet werden. Doch zuvor sollten wir uns im Klaren darüber sein, welche Pins als Ein- und welche als Ausgänge arbeiten sollen. Wir machen es uns einfach und legen Folgendes fest:

Ich habe anfangs schon die Register erwähnt, die zur Konfiguration und zur Ansteuerung der Ports verwendet werden. Auf der folgenden Abbildung 3 sehen wir zwei Register mit acht Bit Datenbreite, die diese Funktion übernehmen, wobei wir später in diesem Projekt noch die Bekanntschaft mit einem weiteren Register machen:

[Bild]

Abb. 3: Die Register DDRx und PORTx

Sie haben die Bezeichnung DDRx und PORTx. Fangen wir mit DDRx an, das für die Datenflussrichtung verantwortlich ist, wobei das x für den jeweiligen Port steht. In unserem Fall also DDRB. Wir wissen, dass Eingänge mit dem Wert 0 und Ausgänge mit dem Wert 1 konfiguriert werden.

[Bild]

Abb. 4: Die Konfiguration von Port B

Die Pfeile geben die Datenflussrichtung an und wir müssen die Programmierung, wie im nachfolgenden Sketch zu sehen, in die Entwicklungsumgebung eingeben. Ich möchte noch einmal darauf hinweisen, was ich im letzten Bastelprojekt 1 bereits ausführlich dargestellt habe: Die setup-Funktion wird einmalig zum Sketch-Start ausgeführt und die loop-Funktion kontinuierlich in einer Endlosschleife:

void setup() {
  DDRB  = 0b11111000; // Pin 8, 9, 10 als INPUT. Pin 11, 12, 13 als OUTPUT
  PORTB = 0b00111000; // Pin 11, 12, 13 auf HIGH-Pegel setzen
}

void loop() {/* leer */}

In diesem Beispiel befindet sich nur in der setup-Funktion der Quellcode, denn wir benötigen lediglich eine einmalige Ausführung und deswegen ist die loop-Funktion leer. Die Zuweisung eines Wertes an das jeweilige Register kann im Binärformat erfolgen, was die Sache in meinen Augen sehr vereinfacht, denn auf diese Weise ist sofort ersichtlich, wie die einzelnen Pins des Ports arbeiten. Durch das Vorangestellte 0b erreichen wir die Interpretation des nachfolgenden Wertes als Binärzahl:

DDRB = 0b11111000; // Entspricht dem Dezimalwert 248

Was wir brauchen

Für dieses Bastelprojekt benötigen wir folgende Bauteile:

Tabelle 1: Bauteilliste

Bauteil

Bild

LED grün 6x

[Bild]

Widerstand 330Ω 6x

[Bild]

Widerstand 10KΩ 3x

[Bild]

Mikrotaster 3x

[Bild]

Der Schaltplan zur Ansteuerung der LEDs sieht wie folgt aus:

[Bild]

Abb. 5: Der Schaltplan mit 6 LEDs

Der Versuchsaufbau auf einem Arduino Discoveryboard könnte wie folgt aussehen:

[Bild]

Abb. 6: Der Versuchsaufbau mit sechs Leuchtdioden auf dem Arduino Discoveryboard

Auf diese Weise kann mit unterschiedlichen Werten in der Ansteuerung gespielt werden und das Ergebnis ist sofort ersichtlich. Es gilt zu beachten, dass lediglich die Pins 11, 12 und 13 als Ausgänge konfiguriert wurden. Der Aufbau zeigt jedoch sechs Leuchtdioden an den Pins 8 bis 13. Was muss geändert werden, damit alle sechs Leuchtdioden angesteuert werden können? Die Antwort ist sicherlich einfach. Doch halt! Was ist überhaupt eine Leuchtdiode und was ist bei der Ansteuerung zu beachten? Eine Leuchtdiode‌ – auch kurz LED (Light Emitting Diode) genannt – ist ein Halbleiterbauelement, das Licht einer bestimmten Wellenlänge abgibt und abhängig vom verwendeten Halbleitermaterial ist. Wie der Name Diode schon vermuten lässt, ist beim Betrieb auf die Stromrichtung zu achten, denn nur in Durchlassrichtung sendet die LED Licht aus. Bei entgegengesetzter Polung geht die LED nicht kaputt, sie bleibt aber einfach dunkel. Es ist unbedingt darauf zu achten, dass eine LED immer mit einem richtig dimensionierten Vorwiderstand betrieben wird. Andernfalls leuchtet sie einmal in einer beeindruckenden Helligkeit auf und dann nie wieder. Wie du den Wert des Vorwiderstands bestimmst, hast du schon im Bastelprojekt 1 gelernt. Ein Wert von 330Ω ist da ein guter Wert. Genau wie bei einer Diode gibt es bei der Leuchtdiode zwei Kontakte, von denen einer die Anode und der andere die Kathode ist. Das Schaltzeichen sieht ähnlich aus und hat zusätzlich zwei Pfeile, die das ausstrahlende Licht andeuten:

[Bild]

Abb. 7: Die Schaltzeichen einer Leuchtdiode‌

Kommen wir zurück zu unserer ursprünglichen Konfiguration, wo die Pins 8, 9 und 10 als Eingänge konfiguriert sind. Wie testen wir das Verhalten? Dazu muss ich ein wenig ausholen. In der Digitaltechnik gibt es nichts Schlimmeres als einen Schaltkreis, der als Eingang definiert ist und an dem nichts angeschlossen wurde. Wie ist das zu verstehen? Sehen wir uns die folgenden Schaltungen etwas genauer an:

[Bild]

Abb. 8: Ein offener Eingang

Ist der Taster geschlossen, liegen +5V am Eingangs-Pin an und öffnen wir den Taster, sollten man meinen, dass nun 0V dort anliegen. Das stimmt jedoch nicht, denn über den offenen Eingang, dem kein definierter Pegel zugewiesen wurde, können Störsignale einfließen. Es reicht schon aus, wenn mit dem Finger der Eingangs-Pin berührt wird, um einen sich ständig wechselnden Pegel zu erreichen. Aus diesem Grund verwenden wir die folgende Schaltung mit einem sogenannten Pulldown-Widerstand.

[Bild]

Abb. 9: Ein offener Eingang mit Pulldown-Widerstand

Ist der Taster geschlossen, ändert sich zur vorherigen Situation nichts und die +5V liegen am Eingangs-Pin an beziehungsweise fallen über dem Pulldown-Widerstand von 10KΩ nach Masse ab. Wird der Taster losgelassen, wird über den Widerstand das Massepotential an den Eingang geleitet, so dass dort ein LOW-Pegel von 0V anliegt. Wir haben also in beiden Tastersituationen ein definiertes Signal am Eingangs-Pin vorherrschen. Für das nun folgende Bastelprojekt wird wieder das Arduino Discoveryboard genutzt, das über fest verdrahtete Pulldown-Widerstände verfügt. Der Schaltplan für das kommende Bastelprojekt sieht wie folgt aus:

[Bild]

Abb. 10: Der Schaltplan mit drei LEDs und drei Tastern

Sehen wir uns den entsprechenden Versuchsaufbau mit den zusätzlichen drei Tastern an:

[Bild]

Abb. 11: Der Versuchsaufbau mit zusätzlichen Tastern

Natürlich müssen wir die Programmierung anpassen:

void setup() {
  DDRB  = 0b11111000; // Pin 8, 9, 10 als INPUT. Pin 11, 12, 13 als OUTPUT
  PORTB = 0b00111000; // Pin 11, 12, 13 auf HIGH-Pegel setzen
  Serial.begin(9600); // Serielle Schnittstelle mit 9600 Baud vorbereiten
}

void loop() {
  // Binäre Ausgabe von Register PINB über
  // die serielle Schnittstelle
  Serial.println(PINB, BIN);
  delay(1000); // Pause von 1 Sekunde
}

Bevor wir den Code besprechen, müssen wir noch ein weiteres Register besprechen. Es nennt sich PINx, wobei das x wieder für den entsprechenden Port steht:

[Bild]

Abb. 12: Das Register PINx

Bei dem Register PINB (Input Pin Address) handelt es sich quasi um ein Statusregister, das den Zustand des Ports widerspiegelt. Es kann nur lesend darauf zugegriffen werden. Wir verwenden es, um den Status aller Pins auf dem sogenannten Serial Monitor anzuzeigen. In der setup-Funktion wird die serielle Schnittstelle mit ihrer Übertragungsrate von 9600 Baud initialisiert. Die spätere Ausgabe erfolgt innerhalb der loop-Funktion über println (Print Linefeed) mit dem zusätzlichen Parameter BIN, der eine binäre Ausgabe des Wertes erzwingt.

Der sogenannte Serial Monitor wird über ein Symbol in der Entwicklungsumgebung geöffnet, das ich rot umrandet habe:

[Bild]

Abb. 13: Das Öffnen des Serial Monitors

Nach einem Mausklick darauf öffnet sich der Monitor:

[Bild]

Abb. 14: Das Fenster des Serial Monitors

Die drei niedrigsten Bits auf der rechten Seite im Serial Monitor spiegeln den Status der drei Taster wider. Welche Taster oder welchen Taster habe ich wohl gedrückt, um die hier gezeigten Bitkombinationen zu erreichen?

Was ist beim Input-Register PINx zu beachten?

[Bild]

Hinsichtlich des Input-Registers PINx werden alle Statusinformationen des jeweiligen Ports auf einmal gelesen.

Register und C++-Befehle

Zur Programmierung und Ansteuerung der verschiedenen Pins ist diese Art der Programmierung vielleicht etwas umständlich und deswegen stehen verschiedene Befehle in der Programmiersprache C++ zur Verfügung, die uns die Sache etwas vereinfachen. Wir kommen im Detail im nächsten Bastelprojekt 3 darauf zu sprechen, aber ich möchte dennoch den direkten Zusammenhang an dieser Stelle verdeutlichen:

Tabelle 2: Register und ihre Entsprechungen

Register

C++-Befehl

Beispiel

DDRB

pinMode

pinMode(13, OUTPUT);

PORTB

digitalWrite

digitalWrite(10, HIGH);

PINB

digitalRead

digitalRead(8);

Hier noch einige Informationen zu den verwendeten Befehlen:

pinMode

Der Befehl pinMode programmiert die Datenflussrichtung eines digitalen Pins, wobei zwei Parameter notwendig sind. Der erste gibt den gewünschten Pin an und der zweite die Richtung, wobei OUTPUT für Ausgang und INPUT für Eingang steht.

digitalWrite

Der Befehl digitalWrite beeinflusst den Zustand eines digitalen Pins, wobei zwei Parameter notwendig sind. Der erste gibt den gewünschten Pin an und der zweite den Pegel, wobei HIGH 5V und LOW 0V entspricht.

digitalRead

Der Befehl digitalRead liest den Zustand eines digitalen Pins, wobei das Ergebnis entweder HIGH oder LOW sein kann.

Was ist beim Input-Register PINx zu beachten?

[Bild]

Hinsichtlich der beiden Pins RX und TX der seriellen Schnittstelle, die in ihren Datenflussrichtungen nicht verändert werden sollten und sich auf Port D befinden, gibt es eine sicherere Methode. Das nachfolgende Beispiel programmiert Pin 2 bis 7 als Ausgänge und verändert Pin 0 und 1 nicht: DDRD |= 0b11111100;

Warum ist das so? Wir verwenden eine binäre Oder-Verknüpfung des binären Wertes mit dem gezeigten Register. An den kritischen Stellen Pin 0 und 1 erfolgt eine Oder-Verknüpfung mit dem Wert 0, was bedeutet, dass diese beiden Bits unverändert bleiben. Nähere Informationen zur Manipulation von Bits sind unter der folgenden Adresse zu finden:

[Bild]

http://playground.arduino.cc/Code/BitMath

Für Detailinformationen zum Pin-Mapping ist die folgende Adresse sicherlich hilfreich:

[Bild]

http://www.arduino.cc/en/Reference/Atmega168Hardware

Der Pullup-Widerstand

Wir haben gesehen, dass ein offener Eingang an einem digitalen Pin zu Problemen führen kann und deswegen eine externe Beschaltung zum Beispiel über einen Pulldown-Widerstand erforderlich ist. Nun gibt es aber auch eine Schaltung, bei der ein sogenannter Pullup-Widerstand‌ eingesetzt wird. Es handelt sich dabei um einen ganz normalen Widerstand, der jedoch im Gegensatz zum Pulldown, der an Masse liegt, jetzt mit 5V der Versorgungsspannung verbunden ist. Bei einem offenen Eingang würden demnach 5V am betreffenden Pin anliegen. Sehen wir uns dazu die folgende Schaltung an:

[Bild]

Abb. 15: Ein offener Eingang mit Pullup-Widerstand

Worauf ich hinaus möchte, ist die Tatsache, dass der Mikrocontroller intern über eingebaute Pullup-Widerstände verfügt, die bei Bedarf aktiviert werden können. Wie funktioniert das? Wir müssen dazu zwei Schritte durchführen, die eigentlich widersprüchlich sind:

Warum habe ich widersprüchlich gesagt? Nun, wenn ein Pin als Eingang programmiert wird, dann erwartet man doch, dass von außen ein Pegel anliegt, der sich auch ändern kann. Wenn wir jetzt aber im zweiten Schritt diesen Pin mit dem Wert HIGH versehen und so tun, als wäre der Pin als Ausgang programmiert, wird der interne Pullup-Widerstand aktiviert. Sehen wir uns dazu den entsprechenden Sketch an, der die Register DDB und PORTB verwendet:

void setup() {
  DDRB  = 0b00000000; // Alle Pins als INPUT
  PORTB = 0b00000111; // Pullup für Pin 8, 9 und 10 aktiviert
  Serial.begin(9600); // Serielle Schnittstelle mit 9600 Baud vorbereiten
}

void loop() {
  Serial.println(PINB, BIN);
  delay(500); // Pause von 500 Millisekunden
}

Wenn wir jetzt lediglich drei Mikrotaster ohne Widerstände an die digitalen Eingänge 8, 9 und 10 anschließen, dann funktioniert unsere Schaltung perfekt, denn die internen Pullup-Widerstände sorgen für einen sauberen und störungsfreien Pegel. Natürlich können für dieses Bastelprojekt die auf dem Arduino Discoveryboard vorhandenen Taster nicht verwendet werden, da sie über einen fest verdrahteten Pulldown-Widerstand verfügen. Das ist aber kein Problem, denn es befindet sich auf dem Arduino Discoveryboard ein kleines Breadboard, auf dem die kleinen Mikrotaster sehr gut eingesteckt werden können.

[Bild]

Abb. 16: Eine Schaltung mit drei Tastern

Wenn wir jetzt den Serial Monitor öffnen, werden wir feststellen, dass bei nicht gedrückten Tastern die jeweiligen Bits auf HIGH-Pegel liegen, was ja auch zu erwarten war. Drücken wir jetzt einen der Taster, ändert sich der betreffende Pegel des Bits von HIGH- auf LOW-Pegel. Natürlich kann man die internen Pullup-Widerstände auch mit einem konventionellen Arduino-Befehl aktivieren oder deaktivieren.

Troubleshooting

Was haben wir gelernt?

Bastelprojekt 3:
Einen Taster sicher abfragen

Warum werden in der Elektronik überhaupt Taster benötigt? Eine einfache Frage, die gar nicht so einfach zu beantworten ist, wie es auf den ersten Blick scheint. Klar, Taster werden dafür verwendet, um von außen Informationen an eine Schaltung zu leiten. Wird ein Taster gedrückt, sollen bestimmte Aktionen erfolgen, die in der Programmierung definiert wurden. Taster bilden also eine Schnittstelle zwischen Mensch und Mikrocontroller. Damit ein Tastendruck genau das bewirkt, was beabsichtigt ist, müssen wir grundlegende Dinge klären: Wann und wie oft wurde ein Taster gedrückt? In diesem Bastelprojekt wenden wir uns der Thematik zu, wann ein Taster gedrückt wurde und dass dieser Impuls auch nur dann weitergeleitet wird, wenn man den Taster schließt. In einem späteren Bastelprojekt – »Der störrische Taster« (Bastelprojekt 5) – geht es darum, wie oft ein Kontakt geschlossen wird, wenn der Taster einmal gedrückt wurde. Das sollte normalerweise auch nur einmal der Fall sein, was aber nicht immer stimmt. Wenn es also darum geht, einen Taster abzufragen, so wie es in der Überschrift steht, geht es darum zu ermitteln, wann dieser gedrückt wurde.