Einstieg Mikrocontroller mit dem Arduino     

2 Digitale Eingänge   


Elektronik-Labor   Projekte   AVR 





1.4.22: Einstieg Mikrocontroller mit Arduino
29.4.22: Einstieg Arduino 1, Portausgaben
6.5.22: Einstieg Arduino 2, Digitale Eingänge
13.5.22: Einstieg Arduino 3, Analoge Messungen
20.5.22: Einstieg Arduino 4, Programmschleifen
28.5.22: Einstieg Arduino 5, Übungen
10.6.22: Einstieg Arduino 6, Sesoren
21.6.22: Einstieg Arduino 7, Ampelsteuerung
24.6.22: Einstieg Arduino 8, Zufall und Spiele

Lade das Programm EingangD2 (Input1.ino) und starte es. In der Setup-Funktion wird zuerst mit Serial.begin(9600) die serielle Schnittstelle eingerichtet, damit Informationen auf den Bildschirm deines Computers übertragen werden können. Dann wird mit pinMode(2, INPUT) der Anschluss D2 als Eingang geschaltet. Die andere Richtung (OUTPUT) kanntest du ja schon.

//Digitaler Eingang D2
void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);

}

void loop() {
  int eingang = digitalRead(2);
  Serial.println(eingang);
  delay(100);     

In der Loop-Funktion wird der Zustand des Eingangs gelesen und in die Variable „eingang“ geschrieben. Variablen kennt man ja aus der Mathematik. Die heißen x, y, z oder ganz anders. Hier kann man sich einen Namen selbst ausdenken. Aber wichtig ist, dass man sagt, welche Art von Zahlen sie enthalten kann. „int“ steht für Integer, das bedeutet Ganzzahlen wie 0,1,2,3 usw.,  im Gegensatz zu gebrochenen Zahlen wie 3,1415. In diesem Fall können nur die Zahlen 0 (für aus) und 1 (für an) vom Eingang D2 gelesen werden.
 
Die Zeile „int eingang = digitalRead(2);“ überträgt also den Eingangszustand von D2 in die Variable „eingang“. Und mit „Serial.println(eingang);“ wird der Inhalt der Variablen an den PC übertragen. Danach folgt noch eine kleine Wartezeit, damit die Zahlen nicht zu schnell erscheinen. 

Starte nun mit Werkzeuge/Serieller Monitor das Ausgabefenster.


Wichtig ist außerdem, dass du die richtige Übertragungsgeschwindigkeit von 9600 Baud einstellst. Das ist die Geschwindigkeit der seriellen Übertragung, die du auch in deinem Programm eingestellt hast. In diesem Fall bedeutet sie, dass 9600 Bits pro Sekunde übertragen werden.


Fertig, jetzt kommen laufend Nullen oder Einsen, die den Zustand des Ports D2 zeigen. 1 bedeutet, dass eine hohe Spannung anliegt, 0 bedeutet, dass eine niedrige oder keine Spannung anliegt.

Schließe ein Kabel oder einen Draht an D2. Wenn du deine Hand nur in die Nähe hältst, können manchmal wechselnde Zustände beobachtet werden. Stecke das andere Ende an GND, dann werden nur noch Nullen gelesen. Stecke es an 5V oder an RXD, dann kommen Einsen. Im einen Fall beträgt die Spannung am Eingang 0 V, im andern Fall +5 V.

Vereinfache nun das Programm. Die Einstellung als Eingang kann gelöscht werden, weil nach einem Neustart alle digitalen Ports grundsätzlich als Eingänge geschaltet sind. Und du kannst den Umweg über eine Variable weglassen und den Lesebefehl direkt in die die Ausgabezeile schreiben. Achte bei den Änderungen auf die richtige Anzahl und Position der Klammern und auf das Semikolon am Ende jeder Zeile. Wenn da ein Fehler passiert, gibt der C-Compiler eine Fehlermeldung aus. Füge zusätzlich eine Print-Zeile mit dem Text „D2 = “ ein. Weil da einmal Serial.print (ohne ln) steht und einmal Serial.println (mit ln), stehen beide Ausgaben auf dem Bildschirm in einer Zeile. „ln“ steht für Line und bedeutet „neue Zeile“.

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print("D2 = ");
 
Serial.println(digitalRead(2));
  delay(100);    

So muss der Quelltext am Ende aussehen. Diesmal gibt es kein fertiges Programm zum Laden, sondern du musst versuchen selbst alles richtig zu ändern. Das Ergebnis sieht dann im seriellen Monitor so aus:


Aufgabe: Erweitere das Programm so, dass zwei Eingänge abgefragt werden und in einer Zeile dargestellt werden, zum Beispiel so: D2 = 1, D3 = 0

Und jetzt kommt ein Versuch, der nicht gut funktioniert. Baue einen Tastschalter zwischen D2 und 5V. Wenn man draufdrückt, wird die Spannung am Eingang 5 V sein. Der serielle Monitor zeigt das Ergebnis 1. Und wenn man wieder loslässt?


Der Versuch zeigt: Einschalten wird erkannt, aber das Ausschaltern wird manchmal erst mit langer Verzögerung gemeldet, manchmal gar nicht, und manchmal wechselt die Anzeige von allein hin und her. Das ist alles sehr unzuverlässig, und ein Informatiker mag so etwas überhaupt nicht. Es liegt daran, dass der Schalter den Eingang zwar auf +5 V hoch zieht, aber nichts ihn wieder auf 0 V herunter zieht. Diese Aufgabe kann ein Widerstand übernehmen, der zusätzlich zwischen D2 und GND eingebaut wird.


Jetzt funktioniert es richtig: Mit dem Loslassen erscheint sofort der Zustand 0. Man kann es auch anders herum bauen. Der Widerstand führt dann nach 5V und der Schalter nach GND.

So ist die Funktion des Schalters umgekehrt. Im geschlossenen Zustand erscheinen Nullen, weil der Schalter den Eingang mit GND verbindet. Im geöffneten Zustand zieht der Widerstand die Spannung hoch auf +5 V, sodass Einsen erscheinen. In dieser Funktion nennt man den Widerstand auch einen Pullup-Widerstand, weil der die Spannung hoch zieht (engl. pull up).

Im Mikrocontroller gibt es eingebaute Pullup-Widerstände, die man für jeden Port einzeln zuschalten kann ( pinMode(2, INPUT_PULLUP); ). Nun funktioniert das Programm genauso, aber man kann den äußeren Widerstand weglassen.

//Digitaler Eingang D2
void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
}

void loop() {
  Serial.print("D2 = ");
 
Serial.println(digitalRead(2));
  delay(100);    

Wie der Mikrocontroller einen Eingangszustand lesen kann, hast du jetzt gesehen. Aber einfach nur Anzeigen ist auf die Dauer langweilig. Man kann mit dieser Information viel mehr anfangen. Mit einer If-Abfrage kann man Entscheidungen treffen und so direkt auf einen Tastendruck reagieren.

Die If-Abfrage lautet: if (digitalRead(2)==0). Wenn das Ergebnis der Portabfrage gleich 0 ist, dann soll das ausgeführt werden, was in den geschweiften Klammern danach steht. Beachte, dass zwei Gleichheitszeichen geschrieben werden müssen, wenn es um einen Vergleich geht. Und was soll dann passieren? Die Zeile tone(9, 440, 500); bewirkt, dass dann ein Ton von 440 Hz am Pin 9 ausgegeben werden soll, und zwar eine halbe Sekunde (500 ms) lang. Schließe da den Piezo-Lautsprecher an.  Also haben wir eine Türklingel programmiert!

//Klingel
void setup() {
  pinMode(2, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(2)==0)
  {
    tone(9, 440, 500);
  }   

Deine Aufgaben:

 

Download: Arduino2.zip

Zurück: ArduinoKurs1.htm

Ergänzungen: Die Morsetaste


//Morsetaste
void setup() {
  pinMode(2, INPUT_PULLUP);
}
void loop() {
  if (digitalRead(2)==0)
  {
    tone(9, 440, 5);
  }    
}

Hier wurde die Wartezeit auf 5 ms festgelegt (20 ms geht auch). Ein Teilnehmer hat sich gewundert, dass die Taste so präzise und ohne Kontaktprellen funktioniert. Das liegt an der Tonlänge von 5 ms. Die Taste wird also nur alle 5 ms einmal abgefragt, was wie eine Entprellung wirkt.

Bei diesem Versuch waren einige Teilnehmer sehr schnell erfolgreich, nur bei mir wollte es nicht funktionieren. Dann habe ich bemerkt, dass mein Arduino heiß geworden war. Ich habe dann das USB-Kabel getrennt und mit einer zweiten Platine weiter gearbeitet. Inzwischen ist klar geworden, was passiert war: Beim Anstecken des Piezo-Schallwandlers hatte ich ein lautes Knacken gehört. Die Piezoscheibe war offensichtlich aufgeladen, was durch Temperaturänderungen passieren kann. Der Entladestrom hat einen Latchup ausgelöst, wobei ein parasitärer Thyristor am Portanschluss zündet und viel Strom von VCC nach GND fließen lässt. Erst durch die Unterbrechung der Stromversorgung wird dieser Zustand gelöscht. Ich wusste zwar, dass sowas passieren kann, hatte aber noch nie erlebt, dass es mir selbst passiert.

Zur Sicherheit hätte ich die Anschlüsse einmal zusammenhalten sollen, oder ich hätte den Piezo bei abgezogenem USB-Kabel anschließen können. Am Ende hat sich aber glücklicherweise gezeigt, dass der Arduino keinen dauerhaften Schaden genommen hat. Er funktioniert wieder wie vorher.

Hier eine Lösung zum Flurlicht:



Dieses Flurlicht ist eine Luxusversion. Kurz bevor das Licht ausgeht, kommt ein Warnton. Wer dann gerade 24 rohe Eier durch den Flur trägt, hat gerade noch Zeit den Schalter zu finden, damit er nicht im Dunkeln stolpert.


//Flurlicht

void setup() {
  pinMode(2, INPUT_PULLUP);
  pinMode(6, OUTPUT);
}

void loop() {
  if (digitalRead(2)==0)
  {
    digitalWrite(6,1);  //Licht an
    delay (5000);       //5 s
    tone(9, 440, 100);  //Warnton
    delay (1000);       //1 s
    digitalWrite(6,0);  //Licht aus
  }    
}



Elektronik-Labor   Projekte   AVR