-
        

Ergebnis 1 bis 5 von 5

Thema: Zeit messen

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    28.03.2004
    Beiträge
    56

    Zeit messen

    Anzeige

    Hallo Roboter-Freunde,

    Ich möchte für Ultraschall-Entfernungsmessung* eine Zeit möglichst genau messen. Das Problem ist, dass ich zur Aufzeichnung der Zeit eine Variable hochzähle. Das dauert aber bei meinem ATTiny26 zu lange. Deswegen zählt er die Zeit nicht richtig.

    Beispiel:
    Code:
    Schleife(bis Signal eintrifft)
      increase(zeit)
    next
    Nun dauert das increase(zeit) so lange, dass es für 0.0029s*, 147 zählt. Das würde bedeuten, dass er für jedes increase 19,8µs braucht. Für meinen Geschmack viel zu viel, denn dadurch wird die Messung ungenau.

    Nun habe ich mir gedacht, dass das Problem irgendwie lösbar sein muss. Ich hatte da an so etwas wie ON INTERRUPT gedacht, habe es aber noch nie benutzt, weiß auch nicht wie das funktioniert...

    Habt Ihr ne Idee?

    Ich benutze einen ATTiny26 und programmiere mit Bascom AVR. Meine Zeit-Variable habe ich als byte deklariert, da diese schneller bearbeitet wird. Da ich aber schon bei 1,5m 214 zähle, und bei 255 Schluss ist, werde ich bei größeren Distanzen auch Probleme haben.

    Hier mein Quellcode:
    Code:
    '------------------------------------------------------------
    '                 ATTINY26 Ultrasonic file   D.H. 2006-01
    '------------------------------------------------------------
    $regfile = "at26def.dat"
    
    ' default the internal osc runs at 1 MHz
    $crystal = 1000000
    
    ' Led connected to portb.4 via 1 kOhm to + 5V
    
    ' LCD connected to port A
    Dim Zeitus As Byte
    Dim S As Long
    Dim S2 As Long
    'Dim Msg As String * 20
    
    
    Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , Rs = Porta.4 , E = Porta.5
    Config Lcd = 16 * 2
    Config Pina.7 = Input
    Config Pina.6 = Input
    
      Zeitus = 0
      S = 0
    
    Do
      Cls
      Locate 1 , 1
      Lcd "Warte... t=" ; Zeitus
      Locate 2 , 1
      S2 = S / 10000
      Lcd "s=" ; S ; " mm"
    
      Zeitus = 0
      S = 0
    
      'Zuerst auf Startsignal warten
      While Pina.6 = 0
       'nichts
      Wend
    
      'Nun zählen
    
      '---> HIER IST DER KRITISCHE TEIL:
      While Pina.7 = 0
    ' Das hab ich rausgenommen, da er für das Zeitus++ eh lange braucht   'Waitus 1  'wartet 1 µS
        Zeitus = Zeitus + 1          'Zählt 1 mehr
      Wend
      'ENDE DES KRITISCHEN TEILS <---
      'Nun Ausgabe
      Cls
      Locate 1 , 1
      'Msg = "t=" ; Zeitus ; "µs"
      Lcd "t=" ; Zeitus ; "µs"
      Locate 2 , 1
      S = Zeitus - 5
      S = S * 10000
      S = S / 1403
    
    
      'Msg = "t*v=" ; S ; "µm"
      Lcd "t*v=" ; S ; "µm"
    
    '  Zeitus = Zeitus * 100         'µs * µm/µs = µm
    '  S = S / 1000
      While Pina.6 = 1                                          'warte bis signal weg
        'nichts
      Wend
    
    
    
    Loop
    
    
    End
    *= Ich sende ein Ultraschall-Signal und messe die Zeit bis es eintrifft. Die 29ms ergeben sich durch meine Messung.

    PS: Die Entfernungsmessung mit Ultraschall ist Thema meiner Facharbeit.
    Angehängte Dateien Angehängte Dateien

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    30.12.2005
    Ort
    Tann / ZH
    Alter
    61
    Beiträge
    264
    Ich würde Dir folgendes vorschlagen:

    1.Mit Timer Interuppt arbeiten
    2.Deine Variable 16 Bit breit machen (wegen Überlauf)

    MfG
    Ruedi

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    25.02.2005
    Beiträge
    175
    Oder so:

    -Den Empfänger an einen Hardware-Interrupt (Hat der Tiny26, doch, oder?)

    Signal senden, Timer nullen + starten
    Timer0 =0
    Start Timer0

    Kommt der HW-Interrupt, Timer stoppen und Zeitwert verarbeiten.
    Z. B.
    On Int0 Zeitmessung
    ....
    Zeitmessung:
    Stop Timer0
    Zeit=Timer0
    Return

    Läuft der Timer über (Signal ging verloren), in eine ISR zum Fehlerhandling hüpfen

    z.B.
    On Timer0 ErrorHandler
    ....
    ErrorHandler:
    'Hier steht die Fehlerauswertung
    return

    Du solltest aber vorher unbedingt einen Rahmen für die minimale und maximale Laufzeit Deines Signal festlegen.
    Dann kannst Du bestimmen, ob du einen 8- oder 16-Bit-Timer verwendest und wie der Prescaler einzustellen ist.

    Reicht der 8-Bit-Timer nicht hin, kannst Du natürlich auch mehrere Durchläufe des Timers zählen (im errorHandler...) und aufaddieren.

    Viele Grüße

    Torsten

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    28.03.2004
    Beiträge
    56

    Kurz danke

    Ja erst mal Danke,

    ich versteh nur eins (erst mal) nicht:
    Torsten sagte:
    Zeitmessung:
    Stop Timer0
    Zeit=Timer0
    Return
    http://www.roboternetz.de/wissen/ind...e_Betriebsmodi sagt aber,
    Der Zähler des Timers (im Diagramm oben, die aufsteigende und dann wieder zurückgesetzte Linie) ist in dem Register TCNTx gespeichert, wobei x für eine Zahl steht
    also nicht in Timer0. Was ist denn nun der Zähler?

    Bascom hinterlegt bei mir Timer0 in dunkelblau, Tcnt0 in braun.

    MfG, Ringelkrat

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    25.02.2005
    Beiträge
    175
    Doch in Timer0, probiers aus!

    Bascom liefert Dir den Timer/Counter-Wert netterweise auf diese Art zurück ("Zeit" muß natürlich als Byte oder Wort deklariert sein).

    Aber Du kannst auch direkt ins Register schauen/schreiben, beides ist möglich, siehe Bascom-Hilfe:

    ...
    'Again you can access the value with the tcnt0 register
    Print Tcnt0
    'or
    Print Timer0
    ...

    Viele Grüße

    Torsten

Berechtigungen

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