PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeit messen



Ringelkrat
05.01.2006, 11:58
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:
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:
'------------------------------------------------------------
' 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.

ruediw
05.01.2006, 12:49
Ich würde Dir folgendes vorschlagen:

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

MfG
Ruedi

Torsten_G
05.01.2006, 13:04
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

Ringelkrat
05.01.2006, 14:38
Ja erst mal Danke,

ich versteh nur eins (erst mal) nicht:
Torsten sagte:
Zeitmessung:
Stop Timer0
Zeit=Timer0
Return

https://www.roboternetz.de/wissen/index.php/Avr#Die_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

Torsten_G
05.01.2006, 14:52
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