Arduino Patterns
Patterns sind wiederkehrende Muster, die in vielen Projekten auf die eine oder andere Weise nützlich sein können. Die Beispielsketche sind wie immer minimal, damit die Grundfunkionalität einfach sichtbar wird.
Kantenfindung (Edge Detection)
Bei der Kantenfindung werden nur dann Werte ausgegeben, wenn sich die Eingabe im Vergleich zum letzten Mal geändert hat.
int lesePin = 0; int gelesenerWert = 0; int gelesenerWertAlt = gelesenerWert; void setup() { Serial.begin(9600); } void loop() { gelesenerWert = analogRead(lesePin); if (gelesenerWert != gelesenerWertAlt){ Serial.println(gelesenerWert); } gelesenerWertAlt = gelesenerWert; }
Das funktioniert auch mit Drucktastern:
int buttonPin = 4; int buttonState = 0; int buttonStateOld = buttonState; void setup() { pinMode(buttonPin, INPUT); digitalWrite(buttonPin, HIGH); //Pull-Up-Widerstand Serial.begin(9600); } void loop(){ buttonState = digitalRead(buttonPin); if ( buttonState != buttonStateOld){ if (buttonState == HIGH) { Serial.println("An"); } else { Serial.println("Aus"); } } buttonStateOld = buttonState; }
Multitasking
Beim Multitasking werden scheinbar mehrere Aktionen gleichzeitig ausgeführt, insbesondere um auf Delays zu verzichten, die den gesamten Programmablauf verzögern. Wer Interrupts und Timer vermeiden möchte, kann mittels Zählern auf eine flexible Lösung für Multitasking-Probleme zurückgreifen. Der folgende Code lässt auf Tastendruck eine LED dreimal blinken, gibt aber dennoch den Wert des Potis aus.
// Der Poti hängt an Analog 5 int readPin = 5; // Der Drucktaster ist an Digital15 = Analog1 angeschlossen int buttonPin = 15; int buttonState; //Der Zustand des Tasters int ledPin = 5; //Die LED hängt an Digital 5 int blinkCounter = 0; //Der Zähler für die Zeit int ledCounter = 0; //Wie oft wird geblinkt? int ledState = 0; //Ist die LED an oder aus? boolean flag = false; //Wird geblinkt? void setup() { pinMode(buttonPin, INPUT); digitalWrite(buttonPin, HIGH); //Pull-Up-Widerstand pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop(){ buttonState = digitalRead(buttonPin); if (buttonState == LOW){ flag = true; //Es darf geblinkt werden } if (flag == true) { ledCounter++; if(ledCounter > 100){ //Zähle bis 100 ledCounter = 0; if(blinkCounter < 6){ //Wurde schon 6 mal geblinkt? blinkCounter++; ledState=blinkCounter%2; //Rest 1 oder 0 //Schalte die LED abwechselnd an oder aus digitalWrite(ledPin,ledState); } else { //alles wieder auf 0 blinkCounter = 0; ledCounter = 0; flag = false; } } } //Gib in jedem Fall den Wert des Potis aus. Serial.println(analogRead(readPin)); }
Schwellwert (Threshold)
Tue erst etwas, wenn der Sensor einen vorgegebenen Wert überschreitet. Der folgende Sketch ist lediglich als Pseudocode umgesetzt.
loop{ Lies den Sensorwert If Sensorwert größer als Schwellwert { Tu etwas } }
Schwellwert mit Kanten
Tue erst etwas, wenn der Sensor zum ersten Mal einen vorgegebenen Wert überschreitet. Der folgende Sketch ist lediglich als Pseudocode umgesetzt.
loop{ Lies den Sensorwert If Sensorwert größer als Schwellwert { If SensorwertAlt kleinr als Schwellwert { Tu etwas } } SensorwertAlt = Sensorwert }
Spitzenwerte (Peaks)
Sobald der Sensor oberhalb eines vorgegebenen Schwellwerts liegt, wird der Spitzenwert gesucht. Unterschreitet der Sensor den Schwellwert wieder, war dieser Spitzenwert das lokale Maximum.
loop { Lies Sensor if sensorWert >= schwellwert { if sensorWert >= sensorWertAlt { spitzenWert = sensorWert } } else { //Die Auslöseschwell wurde unterschritten if spitzenWert >= schwellwert { Tu etwas } spitzenwert = 0 } }
Glätten (Smoothing)
Beim Glätten werden jeweils die letzten n Werte zusammen gezählt und der Mittelwert ausgegeben. Damit wird das System träger, aber auch weniger anfällig für Störungen.
int lesePin = 5; const int laenge = 150; // Mittelwert aus den letzten Werten int gelesenerWert[laenge]; //Ringspeicher int zeiger = 0; //Wir fangen vorne an long summe = 0; void setup() { Serial.begin(9600); for (int i=0; i<laenge; i++){ //Initialisieren des Arrays gelesenerWert[i] = 0; } } void loop() { //Schreibe den aktuellen Wert an die nächste freie Stelle gelesenerWert[zeiger] = analogRead(lesePin); zeiger++; //Wenn wir am Ende des Speichers sind, fangen wir wieder vorne an if (zeiger>=laenge){ zeiger = 0; } //Addiere alles auf. for (int i=0; i<laenge; i++){ summe += gelesenerWert[i]; } //Und gibt den Mittelwert aus Serial.println(summe/laenge, DEC); summe = 0; }