Materialien zum Ausdrucken für die Schüler:
senseBox:edu Station 1 - Ansteuern einer LED (erweitert)
senseBox:edu Station 2 - Auslesen digitaler Signale
senseBox:edu Station 3 - Auswerten analoger Signale (modifiziert)
senseBox:edu Station 4 - Distanzmessung
Lösungen Station 2
Aufgabe 2 - Abfragen des Tasters und Ausgeben des Zustands im seriellen Monitor:
// Abfragen des Tasters an Port 2 // Ausgabe des Wertes (0 oder 1) im seriellen Monitor void setup() { Serial.begin(9600); Serial.println("Eingabetaster auswerten"); pinMode(2, INPUT); } void loop() { boolean TestVariable = 0; TestVariable = digitalRead(2); Serial.print("Schalterzustand = "); // Kein Zeilenumbruch! Serial.println(TestVariable); delay(500); // Abfrage alle 500 ms } |
Aufgabe 3 - Eine LED mit dem Taster einschalten
// Abfragen des Tasters an Port 2 und LED an Port 13 steuern // Ausgabe des Wertes (0 oder 1) im seriellen Monitor void setup() { Serial.begin(9600); Serial.println("Eingabetaster auswerten"); pinMode(2, INPUT); pinMode(13, OUTPUT); } void loop() { boolean TestVariable = 0; TestVariable = digitalRead(2); Serial.print("Schalterzustand = "); // Kein Zeilenumbruch! Serial.println(TestVariable); digitalWrite(13, TestVariable); // LED an- oder ausschalten delay(500); // Abfrage alle 500 ms } |
Aufgabe 3 wurde modifiziert: Eine LED mit dem Taster einschalten und ausschalten
Der Schalter ist nun ein "Toggle" - ziemlich aufwändig!
// Abfragen des Tasters an Port 2 und LED an Port 13 steuern // Der Taster ist diesmal ein "Toggle" // -> 1 x Drücken = AN // Noch 1 x Drücken = AUS // Noch 1 x Drücken = AN usw. // Globale Variablen werden unbedingt benötigt, um den aktuellen und früheren // Zustand des Tasters sowie den Zustand der LED zu speichern: boolean varToggle = 0; // Zustand der LED -> AN oder AUS? boolean varTastenwert = 0; // Aktueller Zustand des Tasters boolean varTastenwertAlt = 0; // Zustand des Tasters beim vorigen Durchlauf void setup() { Serial.begin(9600); Serial.println("Eingabetaster toggeln"); pinMode(2, INPUT); pinMode(13, OUTPUT); } void loop() { // Aktuellen Wert des Tasters einlesen: varTastenwert = digitalRead(2); if (varTastenwert != varTastenwertAlt) // Nur wenn sich mit dem Zustand des Tasters etwas geändert hat: { if ((varTastenwert == 1) && (varTastenwertAlt == 0)) // Der Toggle muss nun negiert werden // AN wird AUS bzw. HIGH wird LOW und umgekehrt varToggle = !varToggle; varTastenwertAlt = varTastenwert; // Speichern für den nächsten Durchlauf } digitalWrite(13, varToggle); // LED an- oder ausschalten // Das Delay ermöglicht eine elegante Tasten-Entprellung! delay(100); // Reaktion auf Schalter alle 100 ms } |
Lösungen Station 3
Lösung Aufgabe 1 - Anzeigen der LDR-Helligkeits-Messung:
void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("Anzeige analoger Messwerte"); } void loop() { // put your main code here, to run repeatedly: Serial.println( analogRead(A0)); delay(1000); } |
Vorübung Aufgabe 2 - intelligente Straßenbeleuchtung
Wir testen erst einmal, ob die LED blinkt (also richtig angeschlossen ist):
void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("Anzeige analoger Messwerte"); pinMode(13, OUTPUT); } void loop() { // put your main code here, to run repeatedly: Serial.println( analogRead(A0)); delay(1000); digitalWrite(13, HIGH); // Schalte die LED an delay(1000); digitalWrite(13, LOW); // Schalte die LED aus } |
Lösung Aufgabe 2 - intelligente Straßenbeleuchtung
Aufgabe 2 wurde modifiziert:
Baue jetzt eine intelligente Straßenbeleuchtung! Wenn es dunkel wird, dann soll die LED eingeschaltet werden und leuchten. Wenn es hell wird, dann soll die LED ausgeschaltet werden.
void setup() { // Wenn es dunkel wird, dann geht die LED an - sonst aus |
Lösung Aufgabe 3 - Helligkeitsanzeige
Aufgabe 3 wurde modifiziert: Je nach Helligkeit sollen 1, 2 oder 3 LEDs gleichzeitig leuchten.
void setup() { // ROT = PIN11, GELB = PIN12, GRÜN = PIN13 |
Das Ganze etwas schöner - mit Symbolischen Konstanten:
#define PINROT 11 |
Lösungen Station 4
Lösung Aufgabe 1 - Entfernungen mit dem Infrarot-Distanzmesser bestimmen
void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("--- Start Serial Monitor ---"); Serial.print("Abstandsmessung"); } void loop() { Serial.print("Abstand = "); Serial.println(4800/(analogRead(A0)-20)); //Serial.println(analogRead(A0)); delay(1000); } |
Lösung Aufgabe 2 - Entfernungen mit dem Ultraschall-Sensor messen und anzeigen
Wir programmieren nun etwas eleganter, indem wir die Ports und die Impulslänge als Konstanten definieren. Dadurch wird das Programm erheblich besser lesbar.
Die Variable varImpulslaufzeit definieren wir als Globale Variable. Das wäre in dieser Aufgabe nicht unbedingt erforderlich...
// Ultraschall-Abstandsmessung #define SENDERPORT 7 #define EMPFAENGERPORT 9 #define PULSLAENGE 10 int varImpulslaufzeit = 0; void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("--- Start Serial Monitor ---"); Serial.print("Abstandsmessung Ultraschall"); pinMode(SENDERPORT, OUTPUT); pinMode(EMPFAENGERPORT, INPUT); } void loop() { // Senden des Ultraschall-Impulses digitalWrite(SENDERPORT, HIGH); delayMicroseconds(PULSLAENGE); digitalWrite(SENDERPORT, LOW); varImpulslaufzeit = pulseIn(EMPFAENGERPORT, HIGH); Serial.print("Der Abstand ist etwa "); Serial.println(varImpulslaufzeit/58); Serial.println(" cm"); delay(100); } |
Lösung Aufgabe 3 - Fahrzeuge mit Ultraschall zählen
Zuerst wollen wir einfach unseren Variable varFahrzeuganzahl jede Sekunde um 1 erhöhen und auf dem Seriellen Monitor ausgeben. Man sollte nicht zu viel auf einmal programmieren, ohne Zwischenschritte zu testen und zu "monitoren":
// Verkehrszählung mit Ultraschall #define SENDERPORT 7 #define EMPFAENGERPORT 9 #define PULSLAENGE 10 int varImpulslaufzeit = 0; int varFahrzeuganzahl = 0; void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("--- Start Serial Monitor ---"); Serial.println("Verkehrszaehlung mit Ultraschall"); pinMode(SENDERPORT, OUTPUT); pinMode(EMPFAENGERPORT, INPUT); } void loop() { // Senden des Ultraschall-Impulses digitalWrite(SENDERPORT, HIGH); delayMicroseconds(PULSLAENGE); digitalWrite(SENDERPORT, LOW); varImpulslaufzeit = pulseIn(EMPFAENGERPORT, HIGH); varFahrzeuganzahl++; Serial.print("Fahrzeuganzahl = "); Serial.println(varFahrzeuganzahl); //Serial.print("Der Abstand ist etwa "); //Serial.println(varImpulslaufzeit/58); //Serial.println(" cm"); delay(1000); } |
Lösung (vollständig) Aufgabe 3 - Fahrzeuge mit Ultraschall zählen
Ich habe es mir nun aber relativ einfach gemacht...
Falls ein Fahrzeug direkt vor dem Ultraschallsensor stehen bleibt, so wird alle 300 ms weiter gezählt. Die korrekte Zählung funktioniert also nur, wenn das Fahrzeug eine gewisse Geschwindigkeit einhält:
// Verkehrszählung mit Ultraschall #define SENDERPORT 7 #define EMPFAENGERPORT 9 #define PULSLAENGE 10 int varImpulslaufzeit = 0; int varFahrzeuganzahl = 0; void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("--- Start Serial Monitor ---"); Serial.println("Verkehrszaehlung mit Ultraschall"); pinMode(SENDERPORT, OUTPUT); pinMode(EMPFAENGERPORT, INPUT); } void loop() { // Senden des Ultraschall-Impulses digitalWrite(SENDERPORT, HIGH); delayMicroseconds(PULSLAENGE); digitalWrite(SENDERPORT, LOW); varImpulslaufzeit = pulseIn(EMPFAENGERPORT, HIGH); // Fahrzeuge nur im Abstand zwischen 10 und 40 cm messen // Klamnmerung beachten! if (((varImpulslaufzeit/58)>10) && ((varImpulslaufzeit/58)<40)) { varFahrzeuganzahl++; } Serial.print("Entfernung = "); Serial.print(varImpulslaufzeit/58); Serial.print("Fahrzeuganzahl = "); Serial.println(varFahrzeuganzahl); delay(300); } |
Im Tipp zur Aufgabe 3 steht, dass man zusätzlich prüfen muss, ob eine definierte Maximaldifferenz gemessen wurde. Dann wäre das bereits gezählte Fahrzeug zwischenzeitlich auf jeden Fall schon wieder "verschwunden". Dazu habe ich jetzt keine Lust mehr - gähn...
Okay - neuer Morgen - neue Energie!
Hier nun eine Programmvariante, die eine Variable varToggle verwendet, um festzustellen, ob dasselbe Fahrzeug immer noch vor dem Sensor "rumliegt".
Siehe auch oben: Aufgabe 3 modifiziert: Eine LED mit dem Taster einschalten und ausschalten
Wir nehmen mal an, dass am Anfang des Programms kein Fahrzeug vor dem Sender ist:
(varToggle == 0).
Sobald ein Fahrzeug vor dem Sensor steht, wird varToggle = 1 gesetzt.
Im nächsten Loop wird varFahrzeuganzahl dann nicht erhöht, wenn ein Fahrzeug vor dem Sensor steht und varToggle == 1 ist (Fahrzeug war schon im letzten Loop da).Steht kein Fahrzeug mehr vor dem Sensor, so wird wieder varToggle = 0 gesetzt.
Die neuen Zeilen sind gelb hinterlegt:
// Verkehrszählung mit Ultraschall #define SENDERPORT 7 #define EMPFAENGERPORT 9 #define PULSLAENGE 10 int varImpulslaufzeit = 0; int varFahrzeuganzahl = 0; boolean varToggle = 0; // Kein Fahrzeug vor dem Sensor void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("--- Start Serial Monitor ---"); Serial.println("Verkehrszaehlung mit Ultraschall"); pinMode(SENDERPORT, OUTPUT); pinMode(EMPFAENGERPORT, INPUT); } void loop() { // Senden des Ultraschall-Impulses digitalWrite(SENDERPORT, HIGH); delayMicroseconds(PULSLAENGE); digitalWrite(SENDERPORT, LOW); varImpulslaufzeit = pulseIn(EMPFAENGERPORT, HIGH); // Fahrzeuge nur im Abstand zwischen 10 und 40 cm messen // Klamnmerung beachten! if (((varImpulslaufzeit/58)>10) && ((varImpulslaufzeit/58)<40)) { // Vorher war kein Fahrzeug da if (varToggle == 0) { varFahrzeuganzahl++; varToggle = 1; } } else { varToggle = 0; } Serial.print("Entfernung = "); Serial.print(varImpulslaufzeit/58); Serial.print(" Fahrzeuganzahl = "); Serial.println(varFahrzeuganzahl); delay(100); } |
Station 09 - Nutzung des Summers (um ein Lied auszugeben)
Ich habe das etwas vereinfacht - die Tonlängen sind daher nicht ganz exakt.
Notenwert und Notenlänge werden wieder in Arrays gespeichert.
Neu ist die Verwendung einer Funktion mit Parametern:
void PlayTone(int varNote, int varTonlaenge)
Die Töne entstehen durch das periodische HIGH- und LOW-Setzen des SPEAKERPORT 5:
_|‾|_|‾|_|‾|_|‾|_ -> natürlich mit zeitlicher Steuerung (siehe define h 4064 usw.)
Weil es sonst dauer-nervt, habe ich die Lied-Abspielfunktion nicht in den Loop gelegt!
// Ein Lied mit dem Summer abspielen digitalWrite(SPEAKERPORT, HIGH); |
.