Tropfenzählerprobleme und Lösungen

Ziel:

Es gibt einen Strauß von Sensoren, die ausgelesen und dessen Daten ausgewertet werden wollen. Natürlich sollen die Daten in regelmäßigen Intervallen gelesen, übermittelt und/oder gespeichert werden. Regelmäßige Intervalle? Gleichmäßige Pausen? Klarer Fall, einfache Lösung „Delay“! Könnte man denken und versuchen. Irgendwie funktioniert während der Delay-Zeit aber nicht alles wie geplant.

Das Problem und seine Ursache findet sich in der Hilfe der Arduino-IDE (bzw. auf der Arduino-Webseite). Zitat: „No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function„.

Als mögliche Lösung bietet sich das Tutorial „Blink Without Delay“ der Arduino.cc-Webseite an. Der Trick besteht in der Verwendung der millis(). Die Funktion millis() zählt die Zeit seit dem Einschalten des Arduino in Millisekunden. Damit eine Aktion in gleichmäßigen Abständen stattfindet, benötigt man die aktuelle Zeit, die vorgesehene Zeitdifferenz und die Zeit des letzten Auftretens der Aktion. Dafür sind entsprechend geeignete Variablen zu definieren.

unsigned long jetzt = 0;
unsigned long vorhin = 0;
long intervall = 60000;

Während des Programmablaufs wird stetig überprüft, ob der Unterschied zwischen der „jetzt“-Zeit und der „vorhin“-Zeit das vorgesehene Intervall übersteigt. Ist das der Fall verzweigt das Programm zur geplanten Aktion. Da hier eine der geplanten Aktionen ablaufen soll, ist es an der Zeit, den Zeitpunkt in der Variablen „vorhin“ festzuhalten. Dem schließt sich die geplante Aktion an.

int photoPin = 2;
int interruptNumber = 0;
unsigned long vordropcount = 0;
volatile unsigned long dropCount = 0;
unsigned long jetzt = 0;
unsigned long vorhin = 0;
volatile boolean geaendert = false;
long intervall = 60000;

void setup() {
  // put your setup code here, to run once:
  pinMode(photoPin, INPUT);
  attachInterrupt( interruptNumber, interruptRoutine, RISING);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (geaendert == true) {Serial.println(dropCount);}
  geaendert = false;
  jetzt = millis();
  if (jetzt - vorhin > intervall)
  {
    vorhin = jetzt;
    Serial.print((dropCount - vordropcount));
    Serial.println(" Tropfen pro Minute");
    vordropcount = dropCount;
    Serial.println(dropCount);  
  }
}

void interruptRoutine()
{
  dropCount++;
  geaendert = true;
  delay(2);
}

Der vorangestellte Sketch zählt mit Hilfe einer Lichtschranke Tropfen und gibt sowohl die Gesamtzahl der gezählten Tropfen als auch die pro Minute gezählten Tropfen an. Die letztere Angabe erfolgt jeweils minütlich auf den Serial-Monitor.

Damit der Tropfenzählsensor kein Signal übersieht und zählen kann, muss die laufende Arbeit des Arduino unterbrochen werden. Dies leistet die Interruptfunktion. Der Arduino UNO kennt zwei externe Interrupts. Diese sind nur auf bestimmten Digitalpins verfügbar. https://www.arduino.cc/en/Reference/AttachInterrupt

Dem Aufruf der Funktion „AttachInterrupt“ sind einige Parameter beizugeben. Für den Tropfenzähler hat sich ein Aufruf der Routine bei steigenden Signalen „RISING“ als geeignet herausgestellt. Zudem wird eine Funktion benannt, die im Fall eines Signalanstiegs (LOW auf HIGH) am benannten Digitalpin ablaufen soll. Die Funktion sollte möglichst knapp gehalten sein und keine (oder nur sehr kurze) Delay-Aufrufe enthalten. Sollen im ganzen Programm gültige Variable innerhalb der Interruptfunktion verändert werden, müssen sie als Veränderliche „volatile“ deklariert werden, damit andere Teile des Programms mit die jeweiligen Veränderungen geeignet aufnehmen und umsetzen können (Näheres siehe Link auf „Arduino Interruptsteuerung (Teil1)“) .

Getestet wird der Aufbau mit Hilfe zum Beispiel einer Lichtschranke / Fotounterbrecher aus einem der vielen Sensor-Kits für den Arduino.

DSC_0092

Die Belegung geht aus der rückseitigen Beschriftung des Sensormoduls hervor. Natürlich eignet sich auch ein eigener Ersatzaufbau mit Hilfe eines Tasters, wie im Beispielprogramm Button (https://www.arduino.cc/en/Tutorial/Button).

 

Quellen:

„Blink Without Delay“ https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

Erik Bartmann Arduino Interruptsteuerung (Teil1)

 

 

1 Gedanke zu „Tropfenzählerprobleme und Lösungen“

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.