Ein Frequenzzähler für niedrige Frequenzen mit dem Arduino Uno und der Periodendauer Messung

Über die Messung der Pulslängen HIGH und LOW kann aus einem Rechtecksignal, oder einem ähnlichen Signal, die Frequenz bestimmt werden.
Der Arduino bietet hierzu die Funktion pulseIn(pin, signal) an. Die funktioniert an jedem Digital Pin und misst, wenn man die HIGH und die LOW Zeit addiert die Periodendauer T in Mikrosekunden.

Die Grenzwertbetrachtung

Bei einer Periodendauer von 100 Mikrosekunden entspricht +- 1 Mikrosekunde Fehler 1%, sodass bis ca. 10 kHz gemessen werden kann mit einem Fehler <1%.

Die Periodendauer T wird als unsigned long angegeben und kann somit bis maximal 4.294.967.295 zählen. Das entspricht 230 Mikroherz und somit ist der Millihertz Bereich voll erfasst und 3 Kommastllen sind bei niedrigen Frequenzen möglich.

Der Messbereich beträgt also 1 Millihertz bis 10 kHz.

Das Programm

void loop() {
  time=micros();
  do {
    T = pulseIn(pin, HIGH) + pulseIn(pin, LOW);
    if (T==0) {
      Serial.println("Timeout.");
    }
    else {
      f=1/(double)T;        // f=1/T   
      k++;    
    }  
    fsum+=f*1e6;
  } while( micros() < (time+1e6)); // 1 Sekunde mitteln
  f = fsum/k*0.9925;         // Korrekturwert einrechnen
  Serial.println(f);
  fsum=0.0;
  k=0;
}

Im Programm wird über 1 Sekunde (1e6 Mikrosekunden) gemittelt, deshalb sind nur Frequenzen bis runter zu ca. 3 Hz messbar.

Für niedrigerer Frequenzen muss entsprechend länger gemittelt werden, zum Beispiel 10, 100 oder 1000 Sekunden um 3 Millihertz erfassen zu können.

Fazit

Mit dieser einfachen und flexiblen Routine sind Messung von 3Hz bis 10 kHz möglich incl. einiger Nachkommastellen.

Links

Für höher Frequenzen wird die hier beschriebene Technik verwendet.

von Matthias Busse

7 Gedanken zu „Ein Frequenzzähler für niedrige Frequenzen mit dem Arduino Uno und der Periodendauer Messung

  1. Pingback: Frequenzzähler mit LCD Display am Arduino Uno. | Shelvin – Elektronik ausprobiert und erläutert

  2. Pingback: Den Frequenzzähler mit LCD auf Platine aufgebaut. | Shelvin – Elektronik ausprobiert und erläutert

  3. GeorgK

    Funktioniert dies auch bei Sinuswellen?
    Muss ich bei dieser Methode 10 Sekunden messen, wenn ich Netzfrequenz im Bereich 49 – 51 Hz auf mindestens 1 Nachkommastelle genau bestimmen will? 1 Sample jede Minute dürfte genügen, allerdings sollte auf dem gleichen Arduino ein 2. Prozess mit etwa 2 Sekunden Zyklus parallel dazu laufen können (Abfrage eines Spannungswertes an einem anderen Pin und evtl. Verzweigung in einen anderen Programmteil) …

    Antworten
  4. admin Beitragsautor

    Hallo Georg,

    bei einem Fehler von +-1 Mikrosekunde ist das theoretisch bei 50 Hz (10ms pro Halbwelle) eine Genauigkeit von 1/10000, also 0,01%. Und das für jede Messung.
    ABER
    1. Vorsicht bei Netzspannung.
    2. Die Wellen sind unter Umständen nicht Symetrisch um die 0 Spannung, also die positive und die negative Halbelle einzeln messen
    3. Netz Spannungsstörungen / Spitzen können das Ergebnis völlig verfälschen.
    4. Ein Schmitttrigger mit einer ordentlichen Hysterese sollte vorgeschaltet werden.
    5. So genau ist die Arduino Quarzfrequenz dann auch nicht.

    Viel Spass beim Tüfteln
    Matthias

    Antworten
  5. Harald

    Hallo Matthias,
    das Thema ist ja schon gan zgut abgehangen, aber vielleicht liest du ja trotzdem Fragen… 🙂

    Im Programm hast du eine Magic Number „Korrekturwert“ ohne weitere Erklärung verwendet.
    Kannst du bitte kurz erkloären, woher der Faktor kommt und warum er eingeführt werden muss?

    Danke!

    Antworten
  6. Harald

    Ich vergaß…
    Ich habe mit deinem Programm auf einem Arduino Nano ein DS3231 Modul vermessen und erhalte mit Korrekturwert Periodendauern in der Größenordnung „0.997086“.
    Mit einem eigenen Programm habe ich über Messung mittels micros() Periodendauern von 1.00133 s ermittelt.
    Benutze ich den mit den beiden Programmen vermessenen DS3231 zur Steuerung einer Uhr, bekomme ich Abweichungen von 2,898550725 ms je Sekunde (32 Sekunden Abweichung gemittelt über 3 Stunden), die Periodendauer ist also 1.002898.
    Lasse ich den Korrekturwert in deinem Programm weg, erhalte ich eine Periodendauer von 1.004629 s.

    Da meine Uhr zu langsam geht, sollte also eine Periodendauer von größer 1.0 Sekunde am SQW Ausgang des DS3231 vorhanden sein, oder?

    Woher also der Korrekturwert, und kann der ggf. je Arduino unterschiedlich ausfallen?
    Danke!

    Harald

    Antworten
  7. Christian Wetzel-Graf

    ich war einfach zu faul, selber „nachzudenken“ und suchte nur eine Möglichkeit die Frequenz eines NE555 (dahinter sind 3 reihen a 2 74hc595 geschalten, für Bass, Mitten und höhen, jeweils 16 LEds die dann halt nach „oben“ feuern) zu messen. dieser „dreizeiler“ ist genau das richtige und ich wollte nicht ständig werte haben. Die Mittelung hier auf die Sekunde passt. Und die Messung ist auch genau (im bereich bis ca 150 Hz para mit einem Frequenzmesser gemessen). Ausgegeben wird 3 stellig auf 7 Segmentanzeigen, welche, wer häts gedacht auch an 3x 74595 hängen 🙂 (<100hz mit einer nachkommastelle)
    Chris

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

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