Arduino als Zähler

By | 5. März 2017

Ereignis-Zähler

Möchte man verschiedene Ereignisse die als Signal an einem Eingang des Arduino vorliegen zählen, gibt es die einfache Möglichkeit über das sogenannte Polling-Verfahren die Werte einzulesen und zu verarbeiten. Beim Polling wird der Zustand des digitalen Eingangs durch eine Schleife in regelmäßigen Abständen abgefragt wird:

Der Nachteil bei dieser Methode ist, dass die Abfrageintervalle abhängig vom nachfolgenden Code verschieden lang sein können und dadurch kurze Ereignisse am digitalen Eingang (kurze Zustandswechsel zwischen HIGH und LOW) unbemerkt bleiben können. Der Vorteil dieser Methode ist aber die Einfachheit ihrer Implementierung.

Möchte man auch schnellere Ereignisse sicher erfassen, so bietet sich der Einsatz der Interrupt-Methode an. Der Arduino bietet zwei spezielle Interrupt-Eingänge (INT0 und INT1) an, an denen ein Zustandswechsel die Unterbrechung der bisherigen Programmabarbeitung und den Sprung in eine sogenannte Interrupt Service Routine (ISR) auslöst. Im Beitrag Interrupt-Programmierung wird darauf ausführlicher eingegangen.

Nach dem Durchlauf der ISR wird die Programmabarbeitung an der zuvor unterbrochenen Stelle fortgesetzt. Der Vorteil dieser Methode ist, dass keine Ereignisse am digitalen Eingang mehr “verpasst” werden können und die Reaktion auf einen Zustandswechsel unmittelbar darauf erfolgt.

Das nachfolgende Programm nutzt diesen Mechanismus, um die Signale einer Gabellichtschranke zu zählen. Dazu wurde ein kleiner Versuchsaufbau entwickelt, bei dem ein geregelter Elektromotor die Lichtschranke unterschiedlich schnell unterbricht.

Die Idee hinter diesem Aufbau besteht darin, eine kontinuierliche und definierte Auslösung der Lichtschranke zu erhalten. Ebenso ermöglicht er natürlich die Impulse der Lichtschranke mit Hilfe eines Oszilloskops genauer zu untersuchen.

Bild Oszi-Signale einfügen…

Impulse einer Lichtschranke zählen

Nach dem der erste Versuch erfolgreich abgeschlossen wurde, kann die Lichtschranke mit dem Arduino verbunden werden. Hier ist auf die Spannungspegel zu achten und ggf. über einen Spannungsteiler ein 5V Signal zu erzeugen.

Um nun die Impulse der Lichtschranke zu zählen gibt es verschiedene Möglichkeiten: Das nachfolgende Programm, definiert eine Interrupt Service Routine mit dem Namen counter(), in der die Ereignisse gezählt und ausgegeben werden.

 

Impuls-Zähler pro Zeit

Der Arduino hat eine interessante Advanced IO-Funktion implementiert, die pulseIN(pin,HIGH/LOW) Funktion. Wie man mit dieser Funktion Impulse zählen und sogar Frequenzen messen kann, wird im folgenden Beitrag vorgestellt.

Impulsraten sind Ereignisse aperiodischer Signale pro Zeiteinheit, wie zum Beispiel die Impulsfolge eines Geiger-Müller-Zählrohrs oder die Signale einer Lichtschranke.  Im folgenden Programm wird auf einen Interrupt verzichtet, und mittels der Funktionen (pulseIN() und micros()) die Impulsrate an Pin 7 gemessen.

Als Zeitintervall T ist hier eine Sekunde, bzw. 1000000 (1e6) Mikrosekunden voreingestellt.

In der Hauptschleife wird die Einzelmessung initialisiert und dann während des Zeitintervalls T mittels pulseIn() auf eine ansteigende Flanke gewartet. Anschließend enthält N die Anzahl der Impulse pro Sekunde und wird via Serial.println gesendet.

Frequenz-Zähler

Der Arduino hat eine interessante Advanced IO-Funktion implementiert, die pulseIN(pin,HIGH/LOW) Funktion.

Mit dem Aufruf pulseIn(pin, HIGH) wird solange gewartet, bis das Signal an dem Eingangs-Pin (pin) auf den Logikpegel HIGH geht. In dem Moment wird ein Timer gestartet und gewartet, bis der Pegel LOW erreicht wird. Die verstrichene Zeit wird in Mikrosekunden zurück geliefert. Etwas anders ausgedrückt: puseIn(pin,HIGH) liefert die Dauer T1 des High-Anteils des Signals.

Die Impulspause T2 (also der Low- Anteil) kann analog mit pulsIN(pin,LOW) ermittelt werden. Die Periodendauer T ergibt sich dann einfach aus T = T1 + T2.

Bei einem symmetrischen Rechtecksignal ist T1 = T2, also die Zeit für HIGH-Pegel gleich der Zeit für LOW-Pegel.

Die Funktion kehrt bei einem Timeout mit dem Wert 0 zurück, womit auch bei fehlendem Signal das Programm fortgesetzt werden kann.

Der Kehrwert der Periodendauer T entspricht der Frequenz f. Da die gemessene Zeit in  Mikrosekunden (10^-6s) vorliegt, wird bei der Frequenz-Berechnung dadurch ein Wert mit der Einheit Megahertz (MHz) heraus kommen. Um eine Anzeige in Hertz (Hz) zu bekommen, muss entsprechend umgerechnet werden.

Der Programmcode sieht in der einfachsten Form wie folgt aus: