Hallo, und zwar habe ich eine Frage bezüglich Frequenzmessung mit dem ATMega328P. Bin mir total unschlüssig welches Konzept ich verweden soll. Es sollen zwei Frequenzen mit folgenden Daten gemessen werden: 0 - 300Hz 0 - 200Hz Da dies ja sehr niedrige Frequenzen sind, wäre doch ein 16Bit Timer mit einem Prescaler von 1024 am geeignetsten. In der CPU Taktfrequenz habe ich micht noch nicht festgelegt endgültig festgelegt. 20 MHz, falls es mit dem Timer nicht passen sollte und es geschickter wäre eine niedrigere zu wählen sind auch 8 MHz ok. Jetzt hab ich im Netz Ansätze gefunden wo jeder Pin einen Interrupt auslöst und dann den Zählerstand abfrägt. Habe auch aber das Problem gefunden, dass das nicht immer zuverlässig funktioniert. Der Controller soll auch einiges mehr machen als nur die zwei Frequenzen messen. Oder wärs besser den ATMega328P durch einen ATMega328PB zu ersetzen und jede Frequenz auf einen ICP Eingang zu leiten (Der PB hat 3 16Bit Timer)? Wie würdet ihr da ran gehen? Vielen Dank
Frequenzmesser schrieb: > Es sollen zwei Frequenzen mit folgenden Daten gemessen werden: > 0 - 300Hz > 0 - 200Hz Welche Art von Signal? Rechteck? Frequenzmesser schrieb: > Jetzt hab ich im Netz Ansätze gefunden wo jeder Pin einen Interrupt > auslöst und dann den Zählerstand abfrägt. Joar, das geht. Frequenzmesser schrieb: > Habe auch aber das Problem > gefunden, dass das nicht immer zuverlässig funktioniert. Weil? Sehe ich keinen Grund für. Es sei denn, man programmiert das dämlich und irgendwann läuft der Zähler über. Frequenzmesser schrieb: > Oder wärs besser den ATMega328P durch einen ATMega328PB zu ersetzen und > jede Frequenz auf einen ICP Eingang zu leiten (Der PB hat 3 16Bit > Timer)? ICP wäre die Hardwarevariante. Wenn der ATMega328PB auch tatsächlich 3 Input capture pins hat, geht das.
Hallo Bei niederen Frequenzen geht man dazu über, die Periodendauer zu messen, das dann 1/x die Freq ergibt. Habe das bei einem Auto DZM so in Verwendung. Mit einem M8, da Du 2 gleichzeitig brauchst bist Du mit dem 328 besser dran mit 2 ICP Pin's. Mit Arduino Boards bekommst die meist an günstigsten mit Wartezeit. Ciao
Hallo, der Timercounter wird immer überlaufen. Man muss nur die Differenzen richtig ausrechnen. Ggf. noch einen Überlaufzähler vorsehen. Bei den niedrigen Takten wäre auch ein Pin Change Interrupt ausreichend, den hat jeder µC Pin. Ein einziger Timer läuft "nebenbei", der Zählerstand wird bei erkannten Change Interrupt immer ausgelesen und verrechnet.
THOR schrieb: > Frequenzmesser schrieb: >> Es sollen zwei Frequenzen mit folgenden Daten gemessen werden: >> 0 - 300Hz >> 0 - 200Hz > > Welche Art von Signal? Rechteck? Einmal eine Dreickspannung & das andere eine Rechteckspannung. Wird aber beides über einen OPV als Komparator in ein 5V TTL Signal umgewandelt. THOR schrieb: > Frequenzmesser schrieb: >> Habe auch aber das Problem >> gefunden, dass das nicht immer zuverlässig funktioniert. > > Weil? Sehe ich keinen Grund für. Es sei denn, man programmiert das > dämlich und irgendwann läuft der Zähler über. Der Grund war falls die Interrupts zu knapp aneinander kommen. THOR schrieb: > ICP wäre die Hardwarevariante. Wenn der ATMega328PB auch tatsächlich 3 > Input capture pins hat, geht das. Ja hat 3 auf jeweils einem 16Bit Timer. T. A. schrieb: > Habe das bei einem Auto DZM so in Verwendung. Bei mir ebenfalls. Drehzahl und Geschwindigkeit.
Frequenzmesser schrieb: > Oder wärs besser den ATMega328P durch einen ATMega328PB zu ersetzen und > jede Frequenz auf einen ICP Eingang zu leiten (Der PB hat 3 16Bit > Timer)? Kannst Du machen, muß aber nicht sein. Mit Hilfe des ADC-Multiplexers kann man auch die ADC-Eingänge per ICP nacheinander messen. Kleiner Nachteil: bei 0 Hz können ewige Wartezeiten auftreten.
Ein ATMega328P wäre mir natürlich lieber. Wie meinst Du dass mit den Wartezeiten? Also Praktisch ein Timeout programmieren? Dann dauerts X-Sekunden bis 0Hz erkannt werden?
Man kann das alles ausrechnen. Wie oft sollen neue Messungen angezeigt werden und welcher Fehler ist zulässig. Einen Interrupt könnte man in 50 CPU-Zyklen ausführen. D.h. wenn beide gleichzeitig auftreten, ist ein Jitter von 50 Zyklen möglich. Muß die Messung genauer sein, gibt es aber auch Möglichkeiten. Z.B. einen Eingang auf den ICP und den als ISR_NOBLOCK, da der ja keinen Jitter hat.
Frequenzmesser schrieb: > Ein ATMega328P wäre mir natürlich lieber. Wie meinst Du dass mit den > Wartezeiten? Also Praktisch ein Timeout programmieren? Ja, ein Timeout was den Eingangsfrequenzbereich auf >= 1 Hz - 2 Hz begrenzt. Alles, was darunter liegt, erzeugt eine Anzeige 0.00. Welche Auflösung, Genauigkeit und Meßrate brauchst Du überhaupt? Sofern es nur 3 - 4 Stellen bei 2 - 3 Messungen/s sind, kann man auch die Eingänge zyklisch mit 10 - 30 kHz abtasten und Signaländerungen per Software auswerten. Dafür reicht schon ein µC mit 8 Bit Timer.
Frequenzmesser schrieb: >> Weil? Sehe ich keinen Grund für. Es sei denn, man programmiert das >> dämlich und irgendwann läuft der Zähler über. > > Der Grund war falls die Interrupts zu knapp aneinander kommen. Kann passieren, wenn man PC Interrupts nimmt und die in der gleichen PCINT Gruppe sind. Ganz blöd könnte man INT0 und INT1 verwenden, die werden auf jeden Fall hintereinander abgearbeitet und verlieren keine Pulse oder man kann auch Timer mit dem Messsignal takten (T0, T1) und mit einer internen Uhr auslesen. Da gibts so viele Möglichkeiten, das einem schon fast schwindlig wird :-)
:
Bearbeitet durch User
Frequenzmesser schrieb: > Bin mir total unschlüssig welches Konzept ich verweden soll. Arbeite mal den durch: http://shelvin.de/ein-frequenzzaehler-fuer-niedrige-frequenzen-mit-dem-arduino-uno-und-der-pulslaengenmessung/ Dort wird etwas erwähnt, was ich noch nicht gehört habe: "Der Arduino bietet hierzu die Funktion pulseIn(pin, signal) an."
Frequenzmesser schrieb: > Dann dauerts X-Sekunden bis 0Hz erkannt werden? Löse dich von der Vorstellung, jemals in deinem Leben 0Hz messen zu können. Eine halbe Schwingung, die deine Lebensdauer ziemlich sicher übersteigt, hat immer noch eine Frequenz von 0,3nHz ;-) Du solltest eine sinnvolle untere Grenzen festlegen und daran dein Timeout orientieren.
Manfred schrieb: > Dort wird etwas erwähnt, was ich noch nicht gehört habe: > "Der Arduino bietet hierzu die Funktion pulseIn(pin, signal) an." Der Arduino ist ja ein Alleskönner! Einfach eine Funktion aufrufen und schon sind alle Probleme beseitigt. Aber wäre es nicht besser, die Probleme zu lösen? Das Suchwort für die Problemlösung heißt "reziproke Frequenzmessung". Alles andere kann man bei diesen tiefen Frequenzen getrost vergessen.
m.n. schrieb: > Das Suchwort für die Problemlösung heißt "reziproke Frequenzmessung". > Alles andere kann man bei diesen tiefen Frequenzen getrost vergessen. Jein. Bei Frequenzen von maximal 300Hz, einer Referenzfrequenz von bis zu 20MHz und vermutlich gar keinen Anforderungen an die Meßgenauigkeit wird aus der reziproken Frequenzmessung von ganz allein eine schlichte Periodendauermessung. Zweckmäßigerweise erledigt mit der Capture-Funktion eines Timers, für mehrere Kanäle dann halt mit mehreren solchen. Der Punkt mit der unteren Frequenzgrenze wurde ja schon besprochen. Wenn der TE (Troll Editor?) weiterhin auf einer Grenze von 0 Hz beharrt, ist das Thema ja ohnehin durch, oder?
Axel S. schrieb: > wird aus der reziproken Frequenzmessung von ganz allein eine schlichte > Periodendauermessung. Und da der TO keine Periodendauer, sondern eine Frequenz angezeigt bekommen möchte, wird aus der Periodendauermessung wieder eine reziproke Frequenzmessung. Wolfgang schrieb: > Vielleicht hat der TO inzwischen den Artikel Frequenzzählermodul > entdeckt. Und dabei festgestellt, daß diese Schaltung nur für einen Kanal geeignet ist. Mit bis zu 4 Kanälen ist das dann besser geeignet: Beitrag "4-Kanal Drehzahlmessung mit ATmega88"
Ja ihr habt recht. 0Hz ist Unsinn. Wollte damit nur sagen, dass der Zustand auftritt und erkannt werden soll. Der Frequenzbereich lautet: 20Hz - 300Hz 14Hz - 200Hz mindestens auf ein 1Hz genau, besser 0.5Hz. Ist diese Anforderung möglich? Manfred schrieb: > Arbeite mal den durch: > http://shelvin.de/ein-frequenzzaehler-fuer-niedrige-frequenzen-mit-dem-arduino-uno-und-der-pulslaengenmessung/ Ich verwende keinen Arduino. Programmiere in C. m.n. schrieb: > Das Suchwort für die Problemlösung heißt "reziproke Frequenzmessung". Schau ich mir an.
m.n. schrieb: > Der Arduino ist ja ein Alleskönner! Einfach eine Funktion aufrufen und > schon sind alle Probleme beseitigt. Du bist dusselig. Schön hoch die Nase und bloß nicht über das eigene Tellerchen gucken! Frequenzmesser schrieb: > Ich verwende keinen Arduino. Programmiere in C. Welche Sprache verwendet Arduino? Hast Du Dir die Beschreibungen angeschaut? Der Matthias Busse hat da durchaus qualifiziert beschrieben, wie er das angeht. Ich denke, dass man auf dieser Basis vorwärts kommt.
Frequenzmesser schrieb: > Ja ihr habt recht. 0Hz ist Unsinn. Wollte damit nur sagen, dass > der Zustand auftritt und erkannt werden soll. Der Frequenzbereich > lautet: > > 20Hz - 300Hz > 14Hz - 200Hz > > mindestens auf ein 1Hz genau, besser 0.5Hz. Ist diese Anforderung > möglich? Ja, das ist Pillepalle. Wenn 0.5Hz Fehler auf 300Hz erlaubt sind, dann geht das auch ohne ICP, per Pinchange-Interrupt [1]. Das Grundprinzip ist ganz einfach: du läßt einen Timer mit konstanter Frequenz durchlaufen, sagen wir einfach mit 1MHz (8MHz mit Prescaler=8). Bei jedem Interrupt liest du den Timerwert aus und merkst ihn dir. Dann ziehst du den zuletzt gemerkten Wert ab und erhältst direkt die Zeit zwischen zwei Interrupts in µs. Der Kehrwert ist die Frequenz [2]. Jetzt müssen wir noch schauen, ob es ein Problem mit Überläufen geben kann: bei 1MHz läuft ein 16-Bit Timer über mit f = 1MHz/2^16 ~= 15Hz. Das ist blöd, denn es bedeutet, daß du 14Hz nicht mehr messen kannst. Du kannst jetzt entweder den Timer langsamer betreiben, z.B. mit 500kHz oder - besser - du erweiterst den Timer auf 32 Bit indem du den Überlauf-Interrupt aktivierst und bei jedem Überlauf einen uint16_t inkrementierst [3]. Diese Variable ergibt dann zusammen mit dem TCNT Register einen 32-Bit Timer. Die Timestamps, mit denen du im Interrupt rechnest, sind dann halt 32-Bit Werte. Die Erkennung einer niedrigen Eingangsfrequenz ist auch einfach. Dazu brauchst du zwei weitere Variablen, z.B. uint8_t. Jedes Mal, wenn der PC-Interrupt eine Flanke des jeweiligen Signals erkannt hat, setzt er die Variable auf 0. Im Timerüberlauf inkrementierst beide Variablen und prüfst ihren Wert. Ein Wert von 15 bedeutet, daß eine Sekunde lang kein Signal gezählt wurde. [1] wenn dein µC genügend ICP-Einheiten hat, dann solltest du die natürlich verwenden. Oder du kannst auch für ein Signal ICP verwenden und für das anderen einen Pinchange-Interrupt. [2] Wenn du 10.000.000 / T rechnest (wobei T die Periodendauer im µs ist), dann kriegst du die Frequenz in 10-tel Hz raus und kannst alles mit Integer rechnen. Noch besser ist (10.000.000 + T/2) / T. Das rundet gleich noch. [3] hier kann es eine race condition geben, wenn Überlauf und Capture-Event gleichzeitig auftreten. Das mußt du in Software abfangen. Das Problem wurde hier mehrfach durchdekliniert, u.a. im Beitrag "AVR Timer mit 32 Bit"
Manfred schrieb: > Du bist dusselig. Aber nicht so beschränkt, daß ich Frequenzen mit pulseIn() messen würde. Diese Funktion hat ja die Eleganz von delay(10000).
Frequenzmesser schrieb: > 20Hz - 300Hz > 14Hz - 200Hz > > mindestens auf ein 1Hz genau, besser 0.5Hz. Ist diese Anforderung > möglich? Dann zäume das Pferd doch mal anders rum auf und rechne aus, mit welcher Auflösung die Periodendauer gemessen werden muss, damit die von dir gewünschte Frequenzauflösung in deinem Bereich erreicht wird. Das kriegst du fast noch mit einer Stopuhr hin ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.