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
:-)
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"
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 ;-)