Hallo,
Ich bin daran ein Geschwindigkeitsmesser zu bauen mit Hilfe von 2
Lichtschranken. Wird die erste Lichstschranke durchbrochen wird in
folgendes Unterprogramm gesprungen.
startchron: inc a ;Register A inkrementieren (1Zyklus)
jz startchron2 ;2 Taktzyklen
jnz startchron ;2 Taktzyklen
startchron2:inc r5 ;Register r5 + 1
jnb Taster3,chronene ;(Reset funktion) 2 Taktzyklen
sjmp startchron ;warte auf interrupt 2 Taktzyklen
Dieses UP soll 2 Register hochzählen, (16Bit), also ist das Register a
voll, wird r5 um 1 inkrementiert, und a wird wieder null usw.
Ich benutze ein 8252µC von Atmel und keine Sorge 16Bit reichen bei
diesen Geschwindigkeiten völlig aus (~60m/s).
An die Taktzyklen(1µs) wurde gedacht und in der nachfolgenden Rechnung
miteingerechnet (wird durch einen Interrupt ausgelöst).
jetzt meine Frage:
Habe ich irgendetwas falsch gemacht, denn es die LCD Ausgabe bringt
immer sehr komische Werte (mal 300km/h, dann 800km/h usw., sehr
unkonstant, die Sache die gemessen wird schwankt aber in Wirklichkeit
zwischen 10 und 15km/h)
Danke im Voraus
Benjamin Müller
Prinzipiell würde ich hier keinen Registerüberlauf abfragen, sondern
einfach ein Add With Carry machen, das vereinfacht den Code.
Dein Zähler läuft mit etwa 300kHz, d.h. r5 läuft nach etwa 0,2 Sekunden
über. Bei 10-15km/h (3-4m/s) sind das etwa 60-80cm. Wie weit sind Deine
Lichtschranken denn voneinander entfernt?
mit 300Khz ? Ich hab gedacht, dass der bloss 1 Taktzyklus = 1µs um 1x
zum inkrementieren braucht.
Meine Lichtschranken sind genau 14,94300cm von einander entfernt
Das incrementieren braucht nur einen Zyklus, aber die gesamte Schleife
braucht mehr Zeit. Hmm... 4 oder 5 Takte? Ich hab' keine Takttabelle für
den 8252, aber im Prinzip sind es dann 200 oder 250kHz (vergiß die
300kHz, es ist halt schon spät).
bye
Markus
Hab ich alles in der Nachfolgenden Berechnung beachtet.
Ich hab das Ergebnis aus beiden Registern mit 5 multipliziert, danach
mit 0.000001 multiplieziert weil ich denke, das 1Taktzyklus 1µs
entspricht, aber das ist nicht das Problem, das Problem ist, dass er
falsch zu zählen scheint. Ich bekomme nicht wirklich anständige
Messergebnisse.
Was machst Du denn sonst noch nebenher (im Interrupt) ? Irgendwelche
Daten verschicken (per RS232), eine Anzeige multiplexen oder so?
Aus Neugierde: Was mißt Du überhaupt was 200km/h schnell ist? Auto oder
Moped?
Im Interrupt werden bloss die Werte bearbeitet, die er vom Zählen davor
übernimmt, er stoppt ja das Zählen nachdem die hintere Lichtschranke
durchbrochen wurde(dann Interrupt). Ich geb dann das Ganze am Ende über
ein LCD Display aus. Danach springt er wieder in das Zählunterprogramm
zurück und man muss um erneute zu messen die Reset Funktion anwenden
(Taster)
Ich messe Paintballs und was wiederum Painball (der Sport) ist kannst du
hier nachlesen www.paintball2000.de oder www.pbportal.de
Falls die Interruptroutine den Zähler im Überlauf unterbricht
ist das eine register schon auf 0, das 2te ist aber noch nicht
incrementiert worden, somit fehlen als zählwert halt 256
Während des incrementierens den Interrupt verbieten und danach wieder
freigeben, um den Zählvorgang auf jeden Fall abgeschlossen zu haben
bevor er verarbeitet wird.
Der Interrupt wird aber ausgelöst wenn die 2 Lichtschranke durchbrochen
wird, das Zählen wird durch die erste Lichtschranke ausgelöst welche
einen Taster simuliert, soll ich das ganze dann einfach mal umdrehen,
also 1 Lichtschranke = Interrupt und 2Lichtschranke = Taster ?
Das mit der "inc dptr" Lösung von Peter Dannegger: Kann man mit dem
Datenpointer ?
Der Interupt durch die 2 Lichtschranke kommt aber mitten ins Zählen und
kann somit die Verarbeitung des Übertrags unterbrechen.
inc dptr kann nicht durch eine Interrupt unterbrochen werden:
damit kann man dann auf Interrupt sperren während des Zählens
verzichten. der datenpointer ist ein "normales" register nur eben 16 bit
gross.
Wies aussieht kann ich das Register dann aber nicht verarbeiten, ich
sollte 16 Bit in Form von 2 Registern haben, aufgrund von
multiplikationen und Division über Math Subroutines
Wenn man von 200kHz Zählfrequenz ausgeht, dann ist bei etwa 210km/h ein
Überlauf. Geht der Überlauf verloren, dann kommt als Ergebnis etwa
400km/h raus. Das würde allerdings die von Dir beobachteten 800km/h noch
nicht erklären.
Außer der Lösung mit dem DPTR kannst Du ja einfach mal ein Nop einbauen,
dann ist die Schleife langsamer und der Übertrag findet nicht gerade
dann statt, wenn der Interrupt kommt. Das sollte man aber nur für
Testzwecke machen, schließlich behebt es das Problem nicht, sondern
verschiebt es nur.
Ansonsten könnte man noch die Interrupts während des Zählvorgangs
abschalten. Das ist z.B. dann nötig, wenn Dein 16Bit Zähler nicht mehr
ausreichen sollte und Du z.B. 32 Bit Variablen brauchst.
bye
Markus
16 Bit reichen vollkommen aus, es dreht sich ausschließlich um
Geschwindigkeiten im 60-80m/s Bereich.
Was ist ein NOP ?
Bist du dir sicher, das ich nur 200kHz Zählfrequenz haben, schließlich
läuft der µC mit 12Mhz und braucht 12 Oscillator Periods für 1TZ => 1µs
Das mit den 32Bit war eher allgemein gemeint, nicht speziell für diese
Projekt.
NOP= No OPeration. Ein Befehl, der nichts macht, aber Zeit kostet.
Zur Zählfrequenz: Du brauchst doch für einen Schleifendurchgang 5 Zyklen
zu je 1µs ?
Ja ich brauche 5 Zyklen für 1x inkrementieren (jz,jnz etc.) = 5µs, das
höhere Register r5 nehm ich dann auch noch mit 5 mal. -> Reg A * 5 ;Reg
r7 * 5, mit der nachfolgenden Rechnung gibts dann keine Probleme mehr.
@ Ripper
Jep genau, ich spiele Paintball und ja es handelt sich um einen Chrony
jedoch mit Lichtschranken und nicht mit Radar :-)
@Ben: Wenn Du 5µs für einmal zählen brauchst, dann kannst Du in einer
Sekunde bis 200.000 zählen. Bei 60m/s ist braucht der Ball für 15cm ca.
0,0025s. Und 200kHz * 0,0025 ergibt 500. Dann kommt der Interrupt
ungefähr zu der Zeit, in der der zweite Interrupt kommt.
bye
Markus
Ich habs jetzt geändert und zwar wie folgt:
Wenn die 1. Lichtschranke durchbrochen wird, wird ein Interrupt
ausgeführt und es wird aufwärts gezählt, ich hab in diesem
Aufwärtszählen eine Tasterabfrage drin, dieser Taster entspricht der
Lichtschranke, Taktzyklen natürlich wieder mit eingerechnet, jetzt
findet erst ein überlauf statt bevor er erneut den Taster abfrägt. Damit
ist dieses Problem auch aus der Welt ;) Danke !!
Ich weiss aber immer noch nicht was du mit den 200kHz meinst ich hab
doch 12MHz.
Noch was: Ich hab jetzt etwa 10x durchgeschossen, meistens waren die
Werte konstant jedoch ziemlich niedrig 140km/h, und 1x hatte ich mal
wieder um die 740km/h. Das kann doch gar nicht sein :(
Bekommst Du irgendwelche Fehlimpulse von der Lichtschranke? Unterbrich
doch mal nur die erste Lichtschranke von Hand und schau, wie oft Du
trotzdem ein Ergebnis bekommst.
Machst Du Deine Berechnung mit Ganzzahl oder Fließkommaarithmetik? Falls
Ganzzahl: Die Rundungseffekte die dabei auftreten sind Dir bekannt?
Wenn ich nur die 1. Lichtschranke unterbreche passiert gar nix, der
zählt ja nur hoch. Erst wenn ich die 2. unterbreche springt er ins
rechen programm.
Habe das Zählprogramm etwas verändert
startchron: inc a ;Register A inkrementieren (1Zyklus)
jz startchron2 ;2 Taktzyklen
jb Taster2,endechron ;Wenn Lichtschranke2 unterbrochen, starte
den Rechenvorgang und stoppe die Inkrementierung (2 Zyklen)
jnz startchron ;2 Taktzyklen
startchron2:inc r5 ;Register r5 + 1
sjmp startchron ;warte auf interrupt 2 Taktzyklen
Rechne mit den Werten dann wie folgt:
Reg A * 7 (da 1x inc = 7 TZ) wird dann in 2 Register gespeichert r6 und
r7 (r6 = highbyte r7 = low-byte)
dann Reg r5 * 7, dieser wert wird dann in r6 dazu addiert.
danach nehme ich r5 (das ursprüngliche nicht das ergebnis von r5*7) und
multipliziere es mit 3, das wird dann ebenfalls zu r6 dazu addiert, und
ich bekomme ein 16Bit wert heraus der für die enstandenen µs steht.
Dann teile ich 149430 durch diesen wert und ich erhalte einen zwei
stelligen Wert wie z.b. 60(m/s)
Dieser wird dann mit 36 multipliziert und dann durch 1000 geteilt (2,16)
die zahl vor dem komma gebe ich aus, die zahl hinter dem komma wird dann
durch 10 geteilt. (1,6) die zahl 1 wird dann nach der 2 geschrieben,
direkt danach wird die hinterkomma zahl (6) ---> 216km/h
Nach einer Reihe von Testversuchen, bin ich 100% davon überzeug, dass es
sich um einen Fehler bei der inkrementierung handelt, z.b. hab ich mit
etwa 65m/s (auf 15cm) geschossen und das register a hat 28 und das
Register r5 hat 11 angezeigt, die Taktzyklen der Abfragen etc.
eingerechnet hätte der Ball auf die 15cm genau 19967µs gebraucht, das
sind 0,019967s.
In echt hätte er aber nur 0,0022989s gebraucht.
Hat jemand noch Vorschläge ?
Wie sind die Lichtschranken elektrisch aufgebaut? Ist da vielleicht
irgendwo noch ein Kondensator mit drin der das Signal verzögert? Du
kannst ja mal beide Lichtschranken gleichzeitig unterbrechen und schauen
ob dann wirklich fast 0 als Zählerwert rauskommt.
Sie sind mit 2 Fotodioden aufgebaut, welche schon bereits im nano
bereich reagieren. Kondensatoren sind keine enthalten. Wir haben es
versucht gleichzeitig zu unterbrechen raus kam fast immer REG A = 10 R5
= 0, dann wieder erneute versuche mit dem Paintball Markierer, und wir
kommen immer wieder auf die selben werte, manchmal sind sogar die
register fast voll, was praktisch unmöglich ist :(
Wie lange ist denn das Kabel zu den Lichtschranken? Mehrere Meter?
Wie komplex ist denn Dein Programm insgesamt? Kannst Du es mal
vereinfachen bzw. versuch einmal, andere Register zu benutzen.
Wir haben die Sache nun anders angegangen. Anstatt zu inkrementieren,
dekrementieren wir und rechnen die dekrementierschritte aus. Wir haben
es gerade ausprobiert (5h vor Projektabeitabgabe) und es funktioniert
einwandfrei !!!!!!!!!!
Danke nochmals an alle die uns geholfen haben, besonders an Markus
!!!!!!!
Hi!
ich habe soeben deinen Beitrag über den Geschwindigkeitsmesser gelesen.
Aber wie ich sehe, ist dieser Beitrag schon etwas länger her. Ich habe
derzeit ein ähnliches Projekt und versuche den Geschwindigkeitsmesser
zum laufen zu bekommen.
Bei mir liegt das Problem aber sehr wahrscheinlich an der Hardware. D.h
die Lichtschranken wollen nicht so wie ich es will und die Werte
weichen stark voneinander ab.
Hast du zufällig noch infos zum Schaltungstechnischen Aufbau?
MfG Christoph