www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Inkrementieren 16Bit


Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs mal damit:

count:
inc dptr
jb taste3, count

Dauert 4 Zyklen je Zählwert


Peter

Autor: Helmut Volmer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Helmut Volmer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Ripper (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
frage @ ben: bei dem gerät handelt es sich nicht zufällig um einen 
chrony fürs spielerische bunt anmalen? wenn doch mail mal.

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...sollte natürlich heißen:
Der Interrupt kommt zu der Zeit, wenn gerade der zweite Überlauf 
stattfindet.

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :(

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :(

Autor: Markus Kaufmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Ben M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 
!!!!!!!

Autor: Bastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ben,

kannst du vielleicht deinen Code mal posten?
Ich wollte mir auch einen Chrony bauen.



Gruß
Bastian

Autor: Ben M. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Hier bitte

Autor: Duke Nukem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Auto fährt auch 200 km/h.

Autor: slotronix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

eine komplette Anleitung für einen Tacho mit Lichtschrankensteuerung
und AT89C2051 gibts hier:

http://home.t-online.de/home/k.leidinger/RC-Elektr...

Ciao,
/St

Autor: Christoph D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.