- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: Frequenzmessung per ICP

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78

    Frequenzmessung per ICP

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo liebe Gemeinde,

    heute wende ich mich mit einem erneuten Problem zu euch
    Es geht um die Frequenzmessung mit einem ATmega8 per ICP mit Siebensegment-Anzeige.

    Der Code ist fertig, aber es sind wohl Fehler oder Optimierungen nötig - mir fällt nichts mehr ein. Das Problem ist, dass die Frequenz zu sehr schwankt, so sehr, dass man die Zahlen kaum erkennen kann, was ja eigentlich nicht passieren darf. Sind hauptsächlich Einer-und Zehnerstellen der 4Segmente beteiligt.
    Ist der 16Mhz Quarz wirklich so ungenau?

    Danke schonmal.
    Lg
    Angehängte Dateien Angehängte Dateien
    • Dateityp: c Test.c (5,1 KB, 28x aufgerufen)

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Welche Frequenz misst du? Dein gewählter Ansatz ist sehr präzise bei niedrigen Frequenzen, bei höherfrequenten Signalen bekommst du aber schnell einen mehr oder wenig starken Jitter-Effekt. Dagegen könntest du die gemessene Frequenz noch über einen Mittelwert glätten. Eine andere übliche Lösung besteht darin, die Abtastrate zu reduzieren, also nicht ständig neue Werte aufs Display zu legen sondern nur noch alle 0,2s oder so. Und dann bist du schon fast bei einer Lösung für hochfrequente Signale: Innerhalb eines bestimmten Zeitintervalls Flanken zählen.

    Grüße,
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78
    Mein Problem ist, dass ich den o.g. "Jittereffekt" mehr oder weniger schon in meinem Messbereich, 1-2000Hz, bekomme - was eigentlich nicht sein dürfte. Weshalb ich auch von einem Programmierfehler meinerseits ausgehe. Es flackern immer die Zehner-und Einerstellen, manchmal gibt es sogar einen 100Hz-Sprung zwischendurch! Für diese niedrigen Frequenzen habe ich, ehrlich gesagt, mehr Genauigkeit von ICP erwartet. Wo ist der Denkfehler?

    Da ich möglichst keinen Offset in der Messung haben möchte, würde ich nur ungerne Torzeiten einsetzen... Ist diese Ungenauigkeit üblich?

    MfG,
    Nik

    P.S: Eine hohe Genauigkeit ohne Schwanken erlebe ich bis zu 80Hz, aber da schwankt es stark.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Zitat Zitat von Liquidator Beitrag anzeigen
    Ist diese Ungenauigkeit üblich?
    Nein, da stimmt was nicht. Ich versuche Mal deinen Quelltext etwas zu kommentieren:

    Zeile 83-90: Welchen Zweck haben HighByte und LowByte?
    Davon abgesehen ist es falsch den Overflow-Interrupt vorzuziehen. Entweder gab es bis zum Auftreten des Capture-Ereignisses keinen Überlauf und dann darf z nicht inkrementiert werden, oder es kam zeitgleich oder kurz bevor der Capture-Interrupt abgearbeitet wurde zu einem Überlauf und dann machst du nur einen kleinen Fehler. Ziehst du den Capture dagegen vor machst du einen Fehler von bis zu 2^16.
    Zeile 94: Die Flags werden nur gelöscht wenn der zugehörige Interrupt ausgeführt wird. Wenn der Code nicht sowieso falsch wäre, müsstest du das Flag also tatsächlich hier manuell löschen.
    Zeile 114: Die Berechnung ICR1 - Startzeit funktioniert nur solange du mit 16-Bit rechnest. So führst du bei einem Überlauf eine ungewollte Subtraktion durch.
    Zeile 111, 122-123 : Unnötig

    Grüße,
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  5. #5
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Auch wenn der gemessene Wert nur geringfügig schwankt, kann da von auch die 100er Stelle betroffen sein, z.B. zwischen 199 Hz und 200 Hz.


    An sich kann ich da keinen Fehler mehr erkennen (wohl aber noch Verbesserungspotential). Bei 2000 Hz. hat man noch etwa 8000 Taktzyklen für eine Periode. Das sollte eigentlich noch für 1 Hz Auflösung reichen.

    Die Frage ist auch etwas wo kommt das gemessene Signal her, und wie ist die Wandlung in ein Digitales Signal. Auch da können noch Störungen (z.B. 50 Hz) reinkommen und ggf. einen Jitter bzw. eine scheinbare Frequenzmodulation erzeugen.

    - - - Aktualisiert - - -

    Das selten Vorziehen des Timer overflow interrupts hat schon seine Berechtigung:

    Der ICP Interrupt hat die höhere Priorität (d.h. wird bei gleichzeitig gesetzten Flags zuerst ausgeführt). Es kann also in eher seltenen Fällen vorkommen, dass der ICP Interrupt aufgerufen wird, obwohl der Overflow Interrupt eigentlich vorher dran wäre. Dieser Fall lässt sich daran erkennen, dass das der Overflow interrupt wartet (TOV1-Flag gestetzt) und gleichzeitig der ICP-Wert klein ist (weil die Flanke so kurz nach dem Overflow kam das keine Zeit für die Ausführung war).

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Zitat Zitat von Besserwessi Beitrag anzeigen
    Das selten Vorziehen des Timer overflow interrupts hat schon seine Berechtigung:
    Schon klar, "falsch" war vielleicht etwas übertrieben ausgedrückt, aber: Durch unglückliches Timing kann auch der OVF-Flag gesetzt werden nachdem das Capture-Ereignis eingetreten ist. Wenn dann der Overflow vorgezogen wird, kommt es zu einem Fehler in der Größenordnung von 2^16. Der umgekehrte Fall ist weniger Problematisch, die Abweichung durch die höhere Priorität beträgt dann ja nur wenige Takte (Interrupt-Verzögerung).
    Es gibt aber mindestens einen Fall in dem du chancenlos bist: Start und Stopp bei TCNT=0. OVF und ICP treten gleichzeitig auf und in dem Fall gibt es einen Fehler von -2^16.

    Grüße,
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  7. #7
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von markusj
    aber: Durch unglückliches Timing kann auch der OVF-Flag gesetzt werden nachdem das Capture-Ereignis eingetreten ist. Wenn dann der Overflow vorgezogen wird ...
    Wird er ja aber nicht, dafür ist schließlich der kleiner-Vergleich da.
    OVF gesetzt + ICP ist "klein" -> Overflow vor Capture-Ereignis (mitzählen)
    OVF gesetzt + ICP ist "groß" -> Overflow nach Capture-Ereignis (nicht mitzählen)


    Zitat Zitat von markusj
    Der umgekehrte Fall ist weniger Problematisch, die Abweichung durch die höhere Priorität beträgt dann ja nur wenige Takte (Interrupt-Verzögerung).
    Nein, DANN hat man einen Fehler von 2^16, weil ein Overflow (und damit ein kompletter Timer-Zyklus) nicht mit eingerechnet wird.


    Zitat Zitat von markusj
    Es gibt aber mindestens einen Fall in dem du chancenlos bist: Start und Stopp bei TCNT=0. OVF und ICP treten gleichzeitig auf und in dem Fall gibt es einen Fehler von -2^16.
    Nein, auch der Fall wird durch das gegebene Schema abgedeckt, weil 0 = "klein".
    Geändert von sternst (11.08.2013 um 21:27 Uhr)
    MfG
    Stefan

  8. #8
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Egal wie man es macht, wenn man beim zählen der Überläufe um einen daneben ist, ist der Fehler 2^16 Zyklen. Man sollte es also schon richtig machen - der mögliche Fehler ist zwar selten, aber wenn dann deutlich.
    Wie schon richtig erkannt ist das Problem wenn ICP und Überlauf praktisch gleichzeitig auftreten. Das kann beim ICP Wert von 0 passieren, aber ggf. auch bei einem kleinen ICP Wert bis vielleicht 100, durch die paar Zyklen die es braucht eine Befehl zu Ende auszuführen oder was länger dauert den 3. Interrupt von Timer 2 auszuführen. Wenn beide Interrupts anstehen, wird zuerst der ICP Interrupt ausgeführt, auch wenn eigentlich erst der Überlauf dran wäre. Die IF Anweisung fängt genau diese Fälle ab, ohne einen verbleibenden Fehler. Wenn der ICP Wert klein ist, und gleichzeitig noch ein Overlow Interrupt ansteht heißt das, dass die Flanke kurz nach dem Overflow kam der wartende Overflow Interrupt eigentlich vorher hätte kommen müssen. Der Fall mit ICP=0 ist dabei nicht mal ein Sonderfall, sondern fällt auch in das Schema. Bei der etwas unscharfen Bedingung "ICP klein" hat man recht viel Spielraum: ICP und Overflow fast gleichzeitig passiert halt nur bei sehr kleinen ICP Werten (d.h. in der Regel unter etwa 200, oder wie lang Interrupts maximal gesperrt sind) oder bei sehr großen werten halt ICP so um 65000. Die Grenze mit 128 am High-byte ist da relativ beliebig und unkritisch. Der Fall das das Overflow Ereignis nach dem ICP kommt führt dann zu einen sehr großen ICP Wert, dicht an der oberen Grenze. In dem Fall wird dann der Overflow Interrupt auch nicht vorgezogen.

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78
    Wow, was für ein Ansturm, vielen Dank für soviel Rückmeldung oO
    Fangen wir mal an...

    Zeile 83-90: Welchen Zweck haben HighByte und LowByte?
    Davon abgesehen ist es falsch den Overflow-Interrupt vorzuziehen. Entweder gab es bis zum Auftreten des Capture-Ereignisses keinen Überlauf und dann darf z nicht inkrementiert werden, oder es kam zeitgleich oder kurz bevor der Capture-Interrupt abgearbeitet wurde zu einem Überlauf und dann machst du nur einen kleinen Fehler. Ziehst du den Capture dagegen vor machst du einen Fehler von bis zu 2^16.
    Genau genommen brauche ich zur Überprüfung lediglich das HighByte - doch im Datenblatt stand, dass erst das Lowbyte ausgelesen werden muss, damit das HighByte ins TEMP geschrieben wird. Die ganze Bedingung habe ich mir aus der Wiki abgeschaut, betrifft wohl einen selteneren Fall, dass ein verpasster Interrupt "nachgeholt" wird. Ist die Grenze mit 128 aus dem Beispiel zu klein gesetzt?

    Zeile 94: Die Flags werden nur gelöscht wenn der zugehörige Interrupt ausgeführt wird. Wenn der Code nicht sowieso falsch wäre, müsstest du das Flag also tatsächlich hier manuell löschen.
    An der Stelle hat das Programm erkannt, dass ein Overflow verpasst wurde - anhand des gesetzten TOV1-Flags und relativ kleiner ICR1H - inkrementiert die Zählvariable und löscht den "bereits ausgeführte" Flag.

    Die Berechnung ICR1 - Startzeit funktioniert nur solange du mit 16-Bit rechnest. So führst du bei einem Überlauf eine ungewollte Subtraktion durch.
    Das und den 2^16 Fehler verstehe ich leider nicht ganz. Die Differenz wird ihrer Größe wegen in einer unsigned long-Variable gesichert. Wäre es besser wenn ich es in der main() berechne?

    Zeile 111, 122-123 : Unnötig
    Dürfte stimmen, habe es nur zur Vorsicht getan.

    Herrschaften, ich verstehe das Optimierungspotenzial, doch ist mir ersteinmal die Quelle der Ungenauigkeit wichtiger - soll ich beim Vorziehen des Interupts die Grenze nicht auf 128, sondern größer setzen? Wo genau seht ihr jetzt das Problem in dem Code?
    Danke nochmal.

    MfG,
    Nik

  10. #10
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Grenze für den Vergleich des Highbytes ist unkritisch. Wenn das Overflow Interrupt Flag gesetzt ist, kommen für das High-Byte vom ICP eigentlich nur Werte von vielleicht 0,1, 254 oder 255 in Frage. Durch eine Verzögerung bei der Interrupt-verarbeitung, also insbesondere durch einen anderen Interrupt oder anderes sperren von Interrupts hat man an beiden Ende ein paar mögliche Werte, aber die Reserve ist schon groß. Die anderen ISRs müssen nur sicher unter etwa 32000 Zyklen bleiben - das ist normalerweise kein nennenswertes Problem, wenn man nicht gerade in der ISR (von timer2) mehrfach Fließkommazahlen benutzt. Die jetzige ISR vom Timer 2 liegt mehr so bei 50-100 Zyklen.

    Der Code sieht soweit gut aus, und sollte funktionieren. Den Fehler würde ich eher beim Signal suchen. Um dennoch mögliche Fehler besser zu erkennen wäre es besser nicht gleich in eine Frequenz umzurechnen, sondern erst nur die Zeit auszugeben, ggf. auch nicht auf die LEDs, sondern zum PC schicken.

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. hier ein code für niedrige frequenzmessung mit icp
    Von kolisson im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 10
    Letzter Beitrag: 05.11.2009, 23:23
  2. ICP benutzen ?? (länge von pulsen messen
    Von goara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 30.01.2008, 01:13
  3. AVR - Interner Pullup bei ICP-Betrieb ?
    Von WolleMS im Forum Elektronik
    Antworten: 0
    Letzter Beitrag: 04.05.2007, 16:22
  4. mega168 - ICP vs. Port als Ausgang?!
    Von 0tes_Gesetz im Forum C - Programmierung (GCC u.a.)
    Antworten: 16
    Letzter Beitrag: 02.04.2006, 14:41
  5. 8535 und ICP
    Von wheelchair im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 06.03.2006, 17:04

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus