mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Freuqenz auswerten


Autor: wiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.
Ich möchte mithilfe meines Atmega 8 µC ein Rechtecksignal mit ca. 500 
khZ auswerten.
Es handelt sich bei meinen Versuch um einen berührungslosen Sensor, der 
seine Frequenz vermindert, wenn man sich mit den Finger zur die 
Sensorfläche nähert.
MFG

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt im Forum, in der Codesammlung und auch hier
http://www.mikrocontroller.net/articles/AVR_Softwarepool

unzählige Beiträge zum Thema Frequenzmessung.

Welche hast du denn schon studiert?

Autor: Heiko H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Möchstest Du dazu C oder Assembler benutzen?
Soll es über Timer-IRQ im Hintergrund laufen?

Grüße

Heiko

Autor: wiss (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es mit diesem Quelltext versucht, jedoch ich konnte nur 
Frequenzen zwischen 0 und 50 khz ohne Probleme auswerten, alles was 
darüber ist, funktioniert nicht mehr richtig.
Liegt es vielleicht am atmega 8?

Autor: wiss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde Assembler bevorzugen. Ich versteh nicht ganz, was mit dem 
Timer im Hintergrund gemeint ist...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wiss schrieb:
> Ich habe es mit diesem Quelltext versucht, jedoch ich konnte nur
> Frequenzen zwischen 0 und 50 khz ohne Probleme auswerten, alles was
> darüber ist, funktioniert nicht mehr richtig.
> Liegt es vielleicht am atmega 8?

Wie schnell taktest du den?

Die Messung am INTO wird irgendwann schlapp machen.
Aber die Messung am Input Capture sollte mit 500kHz eigentlich noch so 
lala klar kommen.

Allerdings denke ich, dass in dem Code noch Fehler sind. Ich 
konzentriere mich jetzt nur auf den Input Capture.
ISR( TIMER1_CAPT_vect )
{
 static unsigned char ErsteFlanke1 = TRUE;

 if( Update1 && Update0 )
  return;

ändern auf
ISR( TIMER1_CAPT_vect )
{
 static unsigned char ErsteFlanke1 = TRUE;

 if( Update1 )
  return;

--------------------------------

Die Overflow Behandlung ist auch nicht korrekt. Etwas abhilfe (auch wenn 
es noch nicht ganz korrekt ist), würde bringen:
     Erg1 = (NumberOverflow1 * 65536) + EndTime1 - StartTime1;
ändern auf
     if( NumberOverflow1 > 1 )
       Erg1 = (NumberOverflow1 * 65536) + EndTime1 - StartTime1;
     else
       Erg1 = EndTime1 - StartTime1;

Woran machst du fest, dass die Ergebnisse nicht stimmen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im übrigen ist das Messprinzip in beiden Fällen hier die Messung der 
Periodendauer. Diesem Messprinzip ist es zu eigen, dass die 
Messauflösung schlechter wird, je höher die Frequenzen werden.
Bei deinen Frequenzen (wie weit geht die Frequenz eigentlich runter, 
wenn der Sensor anspricht), wäre wahrscheinlich eine Zählung der Pulse 
in einer Torzeit besser geeignet (da wird die Messauflösung schlechter, 
je niedriger die Frequenzen werden)

Autor: Marc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Die Overflow Behandlung ist auch nicht korrekt. Etwas abhilfe (auch wenn
> es noch nicht ganz korrekt ist), würde bringen:
>      Erg1 = (NumberOverflow1 * 65536) + EndTime1 - StartTime1;

Hallo Karl Heinz,
könntest du mir erklären, wieso das nicht korrekt ist? Ich sehe darin 
keinen Fehler (aber ich täusche mich wohl) und möchte nun dazu lernen 
:-)
Danke.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc schrieb:

> könntest du mir erklären, wieso das nicht korrekt ist? Ich sehe darin
> keinen Fehler (aber ich täusche mich wohl) und möchte nun dazu lernen

Weil die Differenz zweier unsigned Werte in diesem Fall auch bei 1 
Overflow das korrekte Ergebnis bringt. Erst wenn ein zweiter Overflow 
dazukommt muss man handeln.

Wobei auch das noch immer nicht korrekt ist, wenn ich es mir recht 
überlege

Die Logik muss sein:
  1 Overflow wird ignoriert, wenn Ende kleiner als Start ist. Ist Ende 
größer/gleich stimmt die Anzahl der Overflows.

Probiers einfach mit kleineren Zahlen durch
Sagen wir Start und Ende können nur Werte von 0 bis 7 annehmen.

  Start sei zb 5

jetzt geben wir dazu noch 4 Zählticks dazu

  Start            5
         (Tick 1)  6
         (Tick 2)  7
         (Tick 3)  0           <- Hier gibt es den ersten Overflow
         (Tick 4)  1

Wir haben also
   Start:            5
   Ende:             1
   Anzahl Overflows: 1

unsigned gerechnet: Ende - Start:   1 - 5    macht 4
                    Overflows:      1*8      macht 8
                                               ------
                                                  12

d.h. so gerechnet, würde bei der Messung rauskommen, dass 12 Ticks 
gezählt wurden. Wir hatten aber nur 4. 1 Overflow wurde zuviel 
eingerechnet

Jetzt das ganz mal mit 9 Ticks vom Start bis zum Ende

      Start:            5
              (Tick  1) 6
              (Tick  2) 7
              (Tick  3) 0          <--- Hier ist der erste Overflow
              (Tick  4) 1
              (Tick  5) 2
              (Tick  6) 3
              (Tick  7) 4
              (Tick  8) 5
              (Tick  9) 6

Unsere gemessenen Kennzahlen sind also:
   Start:            5
   Ende:             6
   Anzahl Overflows: 1

ausgewertet ergibt das

                    Ende - Start:   6 - 5    macht 1
                    Overflows:      1*8      macht 8
                                               ------
                                                   9

Jetzt stimmt die Rechnung. Dieser 1 Overflow darf nicht ignoriert 
werden.
Das Kriterium ist, ob Ende größer/gleich Start ist. Ist das der Fall, 
dann stimmt die Anzahl der Overflows und muss eingerechnet werden. Ist 
das aber nicht der Fall (wie im ersten Beispiel) dann wurde zwar ein 
Overflow detektiert, der sich aber durch die unsigned Rechnung nicht 
auswirkt. Wir müssen also mit 1 Overflow weniger rechnen.


(Das ganze dann natürlich sinngemäs hochskaliert, wenn mehrere Overflows 
auftauchen)
     if( EndTime1 < StartTime1 )
       NumberOverflow1--;

     Erg1 = (NumberOverflow1 * 65536) + EndTime1 - StartTime1;

Wenn du dir leichter tust, dann stell dir eine Uhr vor (damit sind wir 
vertrauter). Wieviele Sekunden sind vergangen, wenn der Sekundenzeiger 
von 55 bis 12 gelaufen ist? Genau. Der Sekundenzeiger ist zwar über die 
60 drübergelaufen (und hat damit 1 'Overflow' registriert), aber das 
spielt hier keine Rolle, es sind trotzdem nur 17 Sekunden vergangen. Ist 
der Sekundenzeiger aber von 15 ... tick, tick, tick, über die Minute 
drüber, tick, ... bis 20 gelaufen, dann sind das 65 Sekunden und der 
eine Overflow über die 60 Sekunden drüber wirkt sich aus.

Autor: Marc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Karl Heinz, ich habe nun verstanden, was daran falsch ist.
Vielen Dank nochmal.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.