Ein Rücklicht fürs Fahrrad
AFB I–IITim baut für sein Fahrrad ein Rücklicht mit einem Arduino Uno. Normalerweise soll die rote LED blitzen; solange der Taster am Lenker gedrückt ist, soll sie dauerhaft leuchten. Die Schaltung und der Sketch sehen so aus:
const int LED = 9; const int TASTER = 2; void setup() { pinMode(LED, OUTPUT); pinMode(TASTER, INPUT_PULLUP); } void loop() { if (digitalRead(TASTER) == LOW) { // Dauerlicht digitalWrite(LED, HIGH); } else { // Blinklicht digitalWrite(LED, HIGH); delay(100); digitalWrite(LED, LOW); delay(400); } }
INPUT_PULLUP nicht.- Nennen Sie die Pins, die der Sketch als Ausgang bzw. als Eingang benutzt, wie oft
setup()undloop()jeweils ausgeführt werden und den Speicher, in dem das übersetzte Programm auf dem Board liegt. - Berechnen Sie für das Blinklicht die Periodendauer \(T\), die Frequenz \(f\) und die Anzahl der Blitze in einer Minute.
- Erläutern Sie, warum der Sketch einen gedrückten Taster an
LOWerkennt und warum die LED nach dem Drücken manchmal erst mit Verzögerung dauerhaft leuchtet.
Hinweise
Hinweis zu Aufgabe a)
pinMode-Aufrufe. Welcher Speicher des Mikrocontrollers behält das Programm auch ohne Strom?Hinweis zu Aufgabe b)
Hinweis zu Aufgabe c)
digitalRead in loop() überhaupt aufgerufen?Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
Ausgang: Pin 9 (LED). Eingang: Pin 2 (Taster, mit internem Pull-up-Widerstand).
setup() läuft einmal nach dem Einschalten bzw. Reset, loop() danach immer wieder, solange Strom anliegt.
Das Programm wird auf dem PC übersetzt und beim Hochladen in den Flash-Speicher (32 KB beim ATmega328P) geschrieben; dort bleibt es auch ohne Strom erhalten.
Erwartungshorizont zu Aufgabe b)
\(T = t_{an} + t_{aus} = 100\,\text{ms} + 400\,\text{ms} = 500\,\text{ms} = 0{,}5\,\text{s}\)
\(f = \frac{1}{T} = \frac{1}{0{,}5\,\text{s}} = 2\,\text{Hz}\)
\(N = f \cdot t = 2\,\tfrac{1}{\text{s}} \cdot 60\,\text{s} = 120\)
Die LED blitzt zweimal pro Sekunde, also 120-mal in einer Minute.
Erwartungshorizont zu Aufgabe c)
Mit INPUT_PULLUP ist Pin 2 intern über einen Widerstand mit 5 V verbunden: Offener Taster ergibt HIGH. Drückt Tim, verbindet der Taster den Pin direkt mit GND, der Pin liest LOW. Deshalb bedeutet hier „gedrückt = LOW“.
Der Taster wird nur einmal am Anfang jedes loop()-Durchlaufs abgefragt. Läuft gerade der Blinkzweig, wartet der Mikrocontroller in delay(100) und delay(400) und reagiert währenddessen nicht. Drückt Tim z. B. kurz nach dem Aufblitzen, leuchtet die LED erst nach dem Ende der Pause dauerhaft — im ungünstigsten Fall rund 0,5 s später (eine ganze Periode). Beispiel aus einem Test: Drücken ab 1,2 s, Dauerlicht erst ab 1,5 s. Ein sehr kurzer Druck mitten in der Pause wird sogar ganz übersehen.
Gießen im Schulgarten
AFB II–IIIDie Schulgarten-AG möchte ihre Tomatenpflanzen im Gewächshaus automatisch gießen. Aylin schließt an einen Arduino einen Feuchtesensor an (Pin 4 meldet HIGH, wenn die Erde trocken ist) sowie über ein Relais eine kleine Pumpe an Pin 7. Die Pumpe fördert 25 ml Wasser pro Sekunde.
const int SENSOR = 4; // Feuchtesensor: HIGH = Erde trocken const int PUMPE = 7; // Relais der Pumpe void setup() { pinMode(SENSOR, INPUT); pinMode(PUMPE, OUTPUT); } void loop() { if (digitalRead(SENSOR) == HIGH) { digitalWrite(PUMPE, HIGH); delay(3000); digitalWrite(PUMPE, LOW); delay(60000); // Wasser einsickern lassen } }
Lehrer Herr Brandt wünscht sich zusätzlich einen Taster an Pin 2 für „Gießen von Hand“ (2 Sekunden Pumpe) und eine LED an Pin 12, die leuchtet, solange die Erde als trocken gemeldet wird. Außerdem fragt er, was passiert, wenn der Sensor einmal defekt ist und dauerhaft „trocken“ meldet.
- Stellen Sie den Ablauf von
loop()in Aylins Sketch als Struktogramm dar. - Erweitern Sie den Sketch um den Taster und die LED nach Herrn Brandts Wunsch.
- Diskutieren Sie, ob
delay(60000)für diese Anlage geeignet ist. Gehen Sie dabei auf den Handbetrieb und auf einen defekten Sensor ein.
Hinweise
Hinweis zu Aufgabe a)
if einen Block mit Dreieck und den Spalten „ja“ und „nein“. Ein else fehlt im Sketch — was steht dann in der „nein“-Spalte?Hinweis zu Aufgabe b)
pinMode in setup(); beim Taster bietet sich INPUT_PULLUP an (gedrückt = LOW). Die LED braucht auch einen Zweig, in dem sie wieder ausgeht.Hinweis zu Aufgabe c)
delay tun? Berechnen Sie für den defekten Sensor, wie viele Gießvorgänge in eine Stunde passen und wie viel Wasser das ist.Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
loop() beginnt dann sofort von vorn.Bewertet werden: Endloswiederholung als äußerer Block, Verzweigung mit Bedingung, vier Anweisungen in der richtigen Reihenfolge im „ja“-Zweig, leerer „nein“-Zweig.
Erwartungshorizont zu Aufgabe b)
const int SENSOR = 4; // HIGH = Erde trocken const int PUMPE = 7; const int TASTER = 2; // gedrueckt = LOW const int LED = 12; // leuchtet bei trockener Erde void setup() { pinMode(SENSOR, INPUT); pinMode(PUMPE, OUTPUT); pinMode(TASTER, INPUT_PULLUP); pinMode(LED, OUTPUT); } void loop() { if (digitalRead(SENSOR) == HIGH) { digitalWrite(LED, HIGH); digitalWrite(PUMPE, HIGH); delay(3000); digitalWrite(PUMPE, LOW); delay(60000); } else { digitalWrite(LED, LOW); } if (digitalRead(TASTER) == LOW) { // Handbetrieb digitalWrite(PUMPE, HIGH); delay(2000); digitalWrite(PUMPE, LOW); } }
Bewertet werden: pinMode für beide neuen Pins, LED an im trockenen und aus im feuchten Fall (else), Tasterabfrage mit LOW, Pumpe 2 s an und wieder aus. Ebenfalls richtig: die Tasterabfrage vor die Sensorabfrage setzen.
Erwartungshorizont zu Aufgabe c)
Pro: Die Pause ist fachlich sinnvoll — das Wasser braucht Zeit zum Einsickern, sonst würde gegossen, bis der Sensor reagiert, und der Topf liefe über. Der Code bleibt kurz und für Anfänger gut lesbar.
Contra: Während delay tut der Mikrocontroller nichts anderes. Ein Tastendruck in den 63 Sekunden eines Gießvorgangs wird nicht bemerkt; der Handbetrieb wirkt „kaputt“. Bei einem defekten Sensor wiederholt sich der Ablauf ungebremst: \(3600\,\text{s} : 63\,\text{s} \approx 57\) Gießvorgänge pro Stunde, also \(57 \cdot 3\,\text{s} \cdot 25\,\tfrac{\text{ml}}{\text{s}} = 4275\,\text{ml} \approx 4{,}3\,\text{l}\) Wasser pro Stunde.
Ergebnis: Die Pause selbst ist nötig, aber ein einziger langer delay macht die Anlage träge und bietet keinen Schutz. Sinnvoll wären eine Obergrenze für Gießvorgänge (Zähler) und eine Wartezeit ohne Blockieren, z. B. mit millis(), die den Taster weiter abfragt. Eine vollständige Antwort wägt mindestens ein Pro- und zwei Contra-Argumente (mit Rechnung) ab und kommt zu einem begründeten Ergebnis.
