Frequenz-Messung mit Nano und FreqMeasure

Hallo,

irgendwie stehe ich gerade auf dem Schlauch.
Ich versuche, mit der FreeqMEasure Bibliothek und meinem Nano-Nachbau (ATmega328P) eine Frequenz zu messen.
Ich gehe mal davoin aus, das mein Eingang Pin 8 ist? Auszug aus der FreqMeasureCapture.h:

// Arduino Uno, Duemilanove, LilyPad, Mini, Fio, etc
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
  #define CAPTURE_USE_TIMER1       // ICP1 is pin 8

An Pin 8 liegt ein sauberes 5V Rechteck-Signal an, Frequenz zwischen 10Hz und 200Hz.

Mein Sketch:

#include <FreqMeasure.h>
#ifdef __AVR__
#include <avr/power.h>
#endif


int pause=500; // 100 Millisekunden Pause bis zur Ansteuerung der nächsten LED.
int sum = 0;
int count = 0;

void setup() 
{
  Serial.begin(9600);
  FreqMeasure.begin();
  pinMode(LED_BUILTIN, OUTPUT);
}


void loop() 
{
//Frequenzmessung Beispiel
if (FreqMeasure.available()){
  //einige Messungen mitteln
  sum = sum + FreqMeasure.read();
  count = count + 1;
  if (count > 10){
    float frequency_meas = FreqMeasure.countToFrequency(sum / count);
    sum =0;
    count = 0;
    Serial.println(frequency_meas);
  }
}

delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
digitalWrite(LED_BUILTIN, HIGH);
}

Der Output daraus ist aber Schrott.
häufig 0Hz, ab un zu mal irgendwas von ein Paar kHz.
Mit pulseIn() bekomme ich plausible Werte...

Was mach ich falsch?

Gruß
Dodger

Hi @dodgertherunner ,

im Beispiel von Paul Stoffregen gibt es keine Delays in der loop(). Die würde ich mal weglassen ...

Wie sehen die Ergebnisse dann aus?

Gruß
ec2021

Wenn Du es blinken lassen willst, versuche es mal so (nicht getestet, sollte es aber eigentlich gleich tun ...):

#include <FreqMeasure.h>
#ifdef __AVR__
#include <avr/power.h>
#endif


unsigned long pause = 100; // 100 Millisekunden Pause bis zur Ansteuerung der nächsten LED.
int sum = 0;
int count = 0;

void setup()
{
  Serial.begin(9600);
  FreqMeasure.begin();
  pinMode(LED_BUILTIN, OUTPUT);
}


void loop()
{
  //Frequenzmessung Beispiel
  if (FreqMeasure.available()) {
    //einige Messungen mitteln
    sum = sum + FreqMeasure.read();
    count = count + 1;
    if (count > 10) {
      float frequency_meas = FreqMeasure.countToFrequency(sum / count);
      sum = 0;
      count = 0;
      Serial.println(frequency_meas);
    }
  }
  blink();
}

void blink() {
  static unsigned long lastChange = 0;
  static byte state = LOW;
  if (millis() - lastChange >= pause) {
    lastChange = millis();
    state = !state;
    digitalWrite(LED_BUILTIN, state);
  }
}

Auch wenn delay() nachgesagt wird, dass es keine Interrupts sperrt, ist das anscheinend nur ein Teil der Wahrheit, da es auf micros() zurückgreift. Diese Funktion wiederum sperrt - wenn auch nur kurz - Interrupts beim Einlesen von timer0_overflow_count, alle 1024 Mikrosekunden.

Generell sollte man - wo immer es geht - auf delay() verzichten und nichtblockierenden Code bevorzugen.

Auch nicht wirklich vertrauenswürdig.
Die Frequenz steigt kontinuierlich :slight_smile:

Wobei ich auch noch glaube, dass ich den falschen Pin verwende.
In der h-Datei steht ICP1 is pin 8
Demnach hab ich mein Eingangssignal an D8 angeschlossen, was auf jeden Fall falsch ist :slight_smile:

Ich habe dieses Board:
https://www.makershop.de/plattformen/arduino/nano-v3/

Dort it eine Atmell ATmega328P drauf. Laut Datenblatt https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf wäre der ICP1 auf Pin 12.
Der könnte an D8 gehen...

Sicher bin ich aber nicht.

Nööö....

Gerade mit einem UNO gegen getestet!
Das original Beispiel funktioniert bei mir, dein gezeigter Code funktioniert nicht.

Kann nur empfehlen, mal das Beispiel zu testen:

FreqMeasure/examples/Serial_Output/Serial_Output.ino at master · PaulStoffregen/FreqMeasure · GitHub

Falls das zu vergleichbaren Problemen führt, stimmt etwas mit Deiner Hardware nicht ... Falls es funktioniert, ist es wohl doch der Code ... :wink:

Man muss den Fehler auch mal bei anderen suchen (aber erst wenn man ganz sicher ist ...)

Ok, das Original funktioniert.
Einziger Unterschied:
double sum (original) vs. int sum (bei mir)

Na, wenn das mal keinen Unterschied macht ... :wink:

Arduinos bzw dessen Nachbauten mit Resonator als Taktfrequenzbestimendes Element sind sehr ungenau ( 0,5% typisch). Solche Vertreter sind: UNOR3, NANO, MINI ecc.
Da ist ein Arduino wie einer mit einem ATmega32U4 mit Quarz vorzuziehen.
Genauigkeit 100ppm oder 0,001%.
Grüße Uwe

Nee, lass mal.
Ich woll damit die Drehzahl eines Motorrads auf 40 LEDs ausgeben.
Da reicht ein Resonator :slight_smile:

Ok, dafür ist ein Resonator genau genug.
Wichtig ist es informiert zu sein.

Grüße Uwe

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.