-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: Atmega8 Frequenzmessung

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    08.08.2007
    Beiträge
    36

    Atmega8 Frequenzmessung

    Anzeige

    Hallo
    ich habe ein Problem und find leider keinen Lösungsansatz.
    Ich möchte mir einen Rundenzähler für meine Autorennbahn bauen.

    Fakten:
    jedes der einzelnen Autos sendet per IR LED eine festgelegte Frequenz
    Auto1 15,625kHz, Auto2 7,8125kHz, Auto3 5,208 kHz usw.....

    So ich wollte nun hergehen und mit dem Atmega die kHz messen bei jeder Überfahrt und dann anhand des Wertes dem entsprechen Auto die Runde hochzählen.
    Alles was ich bisher an Bascom Code zu Frequenzmessung gefunden hab geht irgendwie nicht, meist wird bei der Geschwindigkeit garnix erkannt oder die Werte sind einfach nicht auswertbar.
    OK in den Codeschnippseln geht es meist um Messung im Hz Bereich.

    So meine Frage an euch, kann jemand Helfen?
    Die Messung geht auch nicht über den Capture Eingang B0 weil ich ja 2 Sensoren auslesen/abfragen muss.

    Über Lösungshinweise wäre ich euch Dankbar, evtl Links oder Codeschnipsel helfen nochmehr.

    DANKE kollimann

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Ich meine, so einfach ist das gar nicht.
    Es können ja zum Beispiel auch mehrere Autos gleichzeitig über die Ziellinie fahren.
    Dann müssten auch 2 Frequenzen gleichzeitig ausgewertet werden.

    Ich würde das über Filter realisieren, die auf die Frequenz des entsprechenden Autos abgestimmt sind.
    Am Ausgang des entsprechenden Filters kommt ein Gleichrichter mit Schmitt Trigger, der dann die Zählimpulse für deinen Controller liefert.

    Rein theoretisch könnte man auch eine einfache Fast Fourier Transformation von der Infrarot Empfängerdiode berechnen lassen.

    Das dürfte aber bei 15kHz Signalfrequenz nur mehr in Assembler gehen

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    08.08.2007
    Beiträge
    36
    Hm, 2 Autos ja, aber dann eben auf 2 Spuren und damit an 2 Sensoren und somit wieder an 2 Eingängen des Controllers.

    Die Auswrtung sprich die Anzeige auf einem LCD oder sontswas muss ja auch nicht genau bei Überfahren geschehen.
    Weiterhin muss ich ja die Frequenz nich wirklich auswerten, ich brauch die Frequenz ja nur zur Unterscheidung der Autos.

    Kann auch gut sein das ich das Problem garnicht richtig verstanden hab im Kopf und somit völlig auf dem Holzweg bin mit meinen Gedanken.

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    ich brauch die Frequenz ja nur zur Unterscheidung der Autos
    Wenn Du sicher Stellen kannst, das immer nur ein Auto an einem Empfänger vorbeikommt, kannst Du das über Input Capture und INT0 realisieren.

    Der Timer 1 läuft frei, es werden die Zeiten zwischen mindestens 2 Nulldurchgängen der Wechselspannung gemessen.
    Daraus lässt sich dann die Frequenz bestimmen und dem entsprechenden Fahrzeug zuordnen.
    Beim ersten Nulldurchgang wird dder aktuelle Zählerstand ( TCNT1 ) des Timers 1 abgespeichert. Beim nächsten nulldurchgang in gleicher Richtung ( komplette Periode ) wird der vorherige Wert von dem vorher ermittelten abgezogen. Aus diesem Wert lässt sich dann die Frequenz ermitteln.
    Man kann auch die erste Periode verwerfen und dann die nächsten 2 Auswerten, oder, oder, oder...

    Eine Impulsaufbereitung die Dir wieder saubere Rechteckimpulse liefert musst Du aber trotzdem Vorschalten.
    Ich würd da einen Vorverstärker, einen Bandpaß und dann einen Begrenzer Verstärker hinterherschalten.

    Um ein Auto nur einmal pro Runde zu zählen, kann man nach einem erkannten Fahrzeug eine Totzeit von ca. 2 Sekunden für dieses Fahrzeug in das Programm integrieren.

    Ich würde für diese Aufgabe einen ATMEGA 16 Controller verwenden, da der auch genügend Ports für eine vernünftige Anzeige hat.
    Wenn Du unbeding sparen willst wird es auch ein ATMEGA 8 tun, vom Preis her ist es aber kein großer Unterschied.
    LapTime und Durchschnitts LapTime sind dann nur noch ne Frage von Deiner Programmierkunst.

    Beispielprogramme kann ich Dir leider nicht liefern - Arbeite mit C.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    08.08.2007
    Beiträge
    36
    ein Auto an einem Empfänger vorbeikommt
    eher drüber fährt ! Daher es kann immer nur 1 Auto über den Sensor fahren.
    Klar können 2 Autos direkt hintereinander drüber fahren, das ist evtl ein Zeitproblem. So ein Auto ist gut 14cm lang, nun müsste man errechnen wie schnell die fahren könnten und somit könnte man denn errechnen wie schnell der Controller fertig sein muss mit Auto1 wenn Auto2 hinten an der Stoßstange klemmt.

    Naja muss weiter lesen und testen.
    C nutz mir leider nix, hab nur den einen C Code den dann jemand nach Bascom übersetzt hat, das geht aber nich richtig.
    http://www.mikrocontroller.net/topic/62517#new

    Hab aber den Sensor eben direkt am Atmega, mh der Hersteller machts bei seinen Weichen auch so, soll ja auch nur die Weiche gestellt werden wenn auch das richtige Auto drüber fährt. Und da iss auch nen Mega8 drinne ohne ext Quarz also 8Mhz max. OK die stellen nur die Weiche und werten nix aus, aber die Frequenz müssen sie ja auch irgendwie erkennen.

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Daher es kann immer nur 1 Auto über den Sensor fahren.
    Dann müsste es so funktionieren, wie ich es oben beschrieben hab.
    Sollte auch in Bascom nicht wirklich ein Problem sein.

    Im Prinzip benötigt der Controller 200µs ( Eine Periodendauer bei 5kHz ) um ein Auto zu indentifizieren.
    Da hat sich das Auto bei 20km/h gerade mal 1,1mm weiterbewegt.
    Wenn mehrere Perioden ausgewertet werden sollen natürlich mehr.

    Auch 2 hintereinanderfahrende Autos sind somit kein Problem.

    Die Totzeit wird ja nur für ein bereits erkanntes Fahrzeug aktiviert, um das gleiche Fahrzeug bei einer Überfahrt nicht mehrfach zu zählen.
    Kommt ein anderes auf der gleichen Spur, kann das sofort erkannt werden.

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.01.2006
    Beiträge
    4.556
    Zitat Zitat von kollimann
    ein Auto an einem Empfänger vorbeikommt
    eher drüber fährt !
    Der Empfänger ist also in der Bahn, die SendeLED im Boden
    des Fahrzeugs? Da ist der Abstand Sender/Empfänger sehr
    gering, entsprechend die Stecke in welcher sie sich sehen können
    auch! So gaaanz langsam sind solche "Rennwagen" dann auch
    nicht, ich fürchte da wird die Zeit zur Erkennung selber schon
    nicht reichen. Versuche einmal zu ermitteln wiefiele m/s so
    ein Wagen bei Max Geschwindigkeit zurücklegt und emittel den
    Radius der IR Led bei dem Abstand zum Entfänger. Damit kannst
    Du dann ausrechnen Wieviel Zeit zur Frequenzbestimmung bleibt.

    Gruß Richard

  8. #8
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.970
    Hallo!

    @ kollimann

    Wie wäre es mit Frequenzdekodierung per NE567 und zählen damit erzeugten Impulsen ?

    MfG

  9. #9
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    So schwer sollte die Frequenzmessung mit der input capture funktion (oder auch der entsprechenden Software version davon) nicht sein. Die zeiten sind mit maximal etwa 0,5 ms relativ kurz, so daß man beim 16 Bit timer ohne Überlauf auskommt.

    das Verfahren ist dann folgendes:
    Im ICP Interrupt die Zeit auslesen, für später merken und davon die vorherige Zeit abziehen. Schon hat man die Periodendauer. Analog geht das auch mit einem ext. Interrupt, nur daß man da die Zeit direkt aus dem Timer ausließt und ggf. etwas größere Fehler hat.

    Für die Messung am Auto muß man ggf. die erste Periode verwerfen, denn da ist das Auto vielleicht noch nicht ganz über dem Sensor. Die zweite und ggf. 3. Periodet sollte dann zum Messen reichen.

    @Picture: die Lösung mit dem NE567 hat den Nachteil, daß man mehr Perioden (ca. 5-20) braucht, und es ist einiges an Hardware nötig.

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    08.08.2007
    Beiträge
    36
    Erstmal DANKE für eure Vorschläge und Tipps.

    Ich war warscheinlich etwas voreilig mit meiner Frage weil ich den ganzen Tag immer nur per Hand die Autos über den Empfänger geschuppst hab.
    Jetzt hab ich mal die Bahn aufgebaut und siehe da es gibt erste Erfolge.

    Also ich habe 2 Codevarianten aus dem Inet versucht beide haben Probleme, die eine mehr die andere weniger.

    Version1, messen über INT0 mit folgendem Code
    Code:
    $regfile = "m8def.dat"
    $crystal = 8000000
    $hwstack = 32
    $swstack = 10
    $framesize = 40
    $baud = 9600
    
    
    Config Portd.2 = Input                                      'int 0
    Portd.2 = 1
    
    
    Config Timer1 = Timer , Prescale = 64
    'Tccr1b.6 = 0
    Stop Timer1                                                 'we stop the timer , because it will be activated
                                                                 'inside the int0 routine
    
    Config Int0 = Falling                                       'or rising
    On Int0 Int0isr                                             'Nosave                                      'nosave .. saves time and code
    Enable Int0
    
    On Ovf1 T1overflow                                          'Nosave                                   'again nosave
    Enable Ovf1
    
    'about nosave : if you use the int routines "called ORIGINAL BASCOM" please comment
    'out the NOSAVE DIRECTIVE
    Enable Interrupts
    ' **************************************************************************************
    ' *** hier kommen zwei spezialkonstukte, die rechenzeit sparen  .. was zum nachdenken !!
    Dim Periodelow As Word
    Dim Periodehigh As Word
    Dim Pericount As Long At Periodelow Overlay
    Dim T1overlow As Byte
    Dim T1overhigh As Byte
    Dim T1overflows As Word At T1overlow Overlay
    
    ' ** ENDE von *** hier kommen zwei spezialkonstukte, die rechenzeit sparen  .. was zum nachdenken !!
    ' **************************************************************************************
    
    
    Dim Messzyklus As Byte                                      'fertig = 0 --  also eine ganze periode gemessen
    Messzyklus = 0
    Dim Status As Byte                                          ' 0=stop timer    1 = start timer
    Status = 0
    Wait 2                                                      '
    
    Do
    '************  do not change below this line, if you are not sure what you are doing
    If Messzyklus = 0 Then
    Periodelow = Timer1
    Periodehigh = T1overflows
    '************  do not change above this line, if you are not sure what you are doing
    ' ##### your code below this line #####
    
    Print "timer" ; Timer1
    Print "ovr" ; T1overflows
    Print "pericount  " ; Pericount
    
    '************  do not change below this line, if you are not sure what you are doing
    Pericount = 0
    T1overflows = 0
    Timer1 = 0
    Messzyklus = 1
    Status = 1
    End If
    '************  do not change above this line, if you are not sure what you are doing
    Loop
    End
    
    Int0isr:                                                    'ORIGINAL Bascom
    Tccr1b = Status
    If Status = 0 Then
    Messzyklus = Status
    End If
    Status = 0
    Return
    
    
    
    'Int0isr:                                                    ' FASTER VERSION
    
    'push r23
    'PUSH R24                                                    ' since we are going to use R24 we better save it
    'IN r24, SREG                                                ' get content of SREG into R24
    'PUSH R24
                                                      ' we can save a register
    
    'lds r24,{status}
    '!out tccr1b,r24
    'cpi r24,0
    
    'brne exitthis
    'sts {messzyklus},r24
    
    'Exitthis:
    'cbr r24,1
    'sts {status},r24
    
    'POP R24                                                     'get content of SREG
    '!OUT SREG,r24                                               ' save into SREG
    'POP R24
    'pop r23                                                     ' get r24 back
    'Return
    
    
    
    'T1overflow:                                                ' ORIGINAL Bascom
    'T1overflows = T1overflows + 1
    'Return
    
    
    T1overflow:                                                 ' FASTER VERSION
    
    push r23
    PUSH R24                                                    ' since we are going to use R24 we better save it
    IN r24, SREG                                                ' get content of SREG into R24
    PUSH R24                                                    ' we can save a register
    
    lds r23,{t1overlow}
    lds r24,{t1overhigh}
    
    inc r23
    brne kein_uebertrag
    inc r24
    
    Kein_uebertrag:
    sts {t1overlow} , r23
    sts {t1overhigh} , r24
    
    POP R24                                                     'get content of SREG
    !OUT SREG,r24                                               ' save into SREG
    POP R24
    pop r23                                                     ' get r24 back
    
    Return
    Also diese Variante zählt erstmal wirklich jede Runde egal wie schnell man fährt, bei einem Auto sind die Werte 98% zu verwerten soll heißen manchmal zählt er doppelt oder mal 1 Wert stimmt völlig nicht. Das 2.Auto macht rießige Sorgen, da ist irgend eine Störung wohl vorhanden, da zählt er wirr egal wo das Auto auf der Bahn ist nur nicht am Sensor.
    Auch wenn beide Autos Stoßstange an Stoßstange fahren also direkt hinternander werden beide gezählt, nur eben stört bei einem irgendwas. Wenns geht gehts zu 98% sauber. Also Zeit zum messen hat der Mega8.
    Wobei ich gestehen muss das ich den Code fast garnicht verstehe was da gemacht wird.

    2.Variante mit Capture und folgendem Code
    Code:
    $regfile = "m8def.dat"
    $crystal = 8000000
    Baud = 9600
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
    Config Lcdbus = 4
    
    ' ++++++++++++++++++++++++++++++++++   hier wird $crystal ausgelesen
    Dim Quartzfrequenz As Long
        Quartzfrequenz = _xtal
    ' ********************************************** hier den prescaler für timer1 definieren
    ' zulässig sind 1,8,64,256,1024
    Const Prescalerwert = 1
    ' in dieser version wird der overflow von T1 ausgewertet und mitgezählt
    ' daher kann man mit prescale = 1 d.h. volle auflösung fahren
    
    '******************** und den capturetimer configurieren  ********************
    Config Timer1 = Timer , Capture Edge = Falling , Prescale = 1       'Prescalerwert
    Start Timer1
    ' ****************************************************************************
    
    ' *********** das zu messende digitalsignal  wird am ICP1 eingang (hier PB0) eingespeist
    
    
    
    Dim Starttime As Word
    Dim Endtime As Word
    Dim Nroverflows As Byte
    Dim Ersteflanke As Bit
    Dim Updatedisplay As Bit
    Dim Taktejesekunde As Long
    Dim Periodendauer As Single
    Dim Frequenz As Single
    Dim Counterticks As Long
    Taktejesekunde = Quartzfrequenz / Prescalerwert
    Dim Maxoverflows As Long
    Maxoverflows = Taktejesekunde / 31375
    '*****  zwei werte zur verzögerung des seriellen ausgabe
    '*****  sonst verschluckt sich das terminalprogramm
    '*****   kleinerer wert = schnellerer output
    Dim Outputcounter As Byte
    Const Anzeigeinterval = 10
    '***************************
    Ersteflanke = 1
    Updatedisplay = 0
    
    '*********************************  option eingangscomparator
    ' diese 2 zeilen sind optional zu verwenden
    ' da der icp1 eingang ja logigpegel benötigt
    'besteht hier die möglichkeit anstelle des icp den ain1 eingang des comparators zu verwenden
    ' der eingang ist dann empfindlicher --- schwelle etwa 1,23 volt '
    ' der icp1 eingang gilt dann nicht mehr als eingang und kann als normaler port verwendet werden
    'Config Aci = On , Compare = On
    'Acsr.6 = 1                                                  'interne bandgap als ref
    '*********************************  ende option eingangscomparator
    
    
    '  ******************* und die int routinen  definieren
    On Ovf1 T1overflow
    Enable Ovf1
    
    On Capture1 Captureint                                      'wenn pb0 auf low geht  dann capture int
    Enable Capture1
    Enable Interrupts
    ' *************  und los gehts
    Cls
    Do
    
         'If Nroverflows > Maxoverflows Then
         'Cls
         'Lcd "freq kleiner 2 Hz"
         'Nroverflows = 0
         'Updatedisplay = 0
         'Ersteflanke = 1
         'End If
    
    If Updatedisplay = 1 Then
        If Outputcounter = Anzeigeinterval Then
    
        'Disable Capture1
        'Disable Ovf1
        Disable Interrupts
    
         ' //
         ' // Die Zeitdauer zwischen den Flanken bestimmen
         ' // Da EndTime und StartTime unsigned sind, braucht nicht
         ' // darauf Ruecksicht genommen werden, dass EndTime auch
         ' // kleiner als StartTime sein kann. Es kommt trotzdem
         ' // das richtige Ergebnis raus.
         ' // Allerdings muss die Anzahl der Overflows in der Messperiode
         ' // beruecksichtigt werden
         ' //
         ' // Die Zeitdauer wird als Anzahl der Taktzyklen zwischen den
         ' // beiden gemessenen Flanken berechnet ...
    
          Counterticks = Nroverflows * 65536
          Counterticks = Counterticks + Endtime
          Counterticks = Counterticks - Starttime
    
          '// ... mit der bekannten Taktfrequenz ergibt sich dann die Signalfrequenz
          Periodendauer = Counterticks / Taktejesekunde
          Frequenz = 1 / Periodendauer
         ' // Das Ergebnis fuer die Anzeige aufbereiten ...
         ' // ... und ausgeben
         ' //
          'Locate 1 , 1
          'Lcd "ti=" ; Counterticks
          'Locate 1 , 8
          'Lcd " Pe=" ; Periodendauer
          'Locate 2 , 1
          Print Frequenz
          'Lcd " Fr=" ; Frequenz
         ' // Das wars: Display ist wieder up to date
          '// die naechste Messung kann starten
          '//
    
         Outputcounter = 0
         'Timer1 = 0
         'Enable Capture1
         'Enable Ovf1
         Enable Interrupts
         End If
    
          Outputcounter = Outputcounter + 1
          Counterticks = 0
          Updatedisplay = 0
    
      End If
    Loop
    End                                                         'end program
    
    
    
    T1overflow:
    Nroverflows = Nroverflows + 1
    'Print "timer1 overflow"
    Return
    
    
    Captureint:
    If Updatedisplay = 1 Then Return                            '// Das Display wurde mit den Ergebnissen der vorhergehenden
                                                                 '// Messung noch nicht upgedated. Die naechste Messung
                                                                 '// verzögern, bis die Start und EndTime Variablen wieder
                                                                 '// gefahrlos beschrieben werden koennen
    If Ersteflanke = 1 Then
     Starttime = Capture1
     Nroverflows = 0
     Ersteflanke = 0                                            ' / / Die Naechste Flanke Ist Das Ende Der Messung
    Else
    
    Endtime = Capture1
    Updatedisplay = 1                                           ' / / Eine Vollständige Messung. Sie Kann Ausgewertet Werden
    Ersteflanke = 1                                             '/ / Bei Der Naechsten Flanke Beginnt Der Naechste Messzyklus
    End If
    Return
    So diesen Code versteh ich eher, da gibts auch keinerlei Störungen und wenn er mal was anzeigt dann stimmt das auch, ABER die Version zählt nur mal aller 5 Runden und nur wenn man langsam fährt.
    Auf jeden Fall wenn was ausgewertet wird stimmt das super genau nur eben ist irgendwas viel zu lahm.

    Und die Variante mit dem NE567 hatte ich auch schon ins Auge gefasst, nur muss man dem nicht per Widerstände und Kondensatoren was vorgeben an Frequenz?

    So also weiter basteln....und Infos sammeln

    DANKE für eure Hilfe

    EDIT jetzt gehts bei Version 1 wieder mit beiden Autos, hab das störende mal zerlegt, weiß nich was da war.
    Auf jeden Fall wenn man die Fehlmessungen weggbekommt würde es schon gehen, bestimmt was mit Timing oder sowas.........

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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