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
Noch etwas, ich meinte die Geschwindigkeiten, von dem was ich messe beträgt etwa 60m/s und schwankt zwischen 10-15km/h also 226km/h und 206km/h
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
Versuchs mal damit: count: inc dptr jb taste3, count Dauert 4 Zyklen je Zählwert Peter
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 ?
frage @ ben: bei dem gerät handelt es sich nicht zufällig um einen chrony fürs spielerische bunt anmalen? wenn doch mail mal.
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
...sollte natürlich heißen: Der Interrupt kommt zu der Zeit, wenn gerade der zweite Überlauf stattfindet.
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 !!!!!!!
Hallo Ben, kannst du vielleicht deinen Code mal posten? Ich wollte mir auch einen Chrony bauen. Gruß Bastian
Hallo, eine komplette Anleitung für einen Tacho mit Lichtschrankensteuerung und AT89C2051 gibts hier: http://home.t-online.de/home/k.leidinger/RC-Elektronik/Tester/index.html Ciao, /St
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.