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;  
}

};