Forum: Mikrocontroller und Digitale Elektronik Pulsweitenmessung 16 Bit Carry-Flag addieren


von Mech-Michi (Gast)


Lesenswert?

Hi,

ich habe ein Programm zum auslesen der Pulsweite geschrieben und
bin im Moment an der Optimierung.
Das Auslesen erfolgt mit 16Bit Genauigkeit.

Bisheriger Vorgang:
______________________________________
Sobalt High Signal, springe zu MESSUNG

MESSUNG:
Erhöhe X1 -> Wenn Carry Bit Gesetzt springe zu ERHÖHUNG_2.BIT (rcall)
-> Frage nach, ob noch immer High Signal -> Wenn ja, Springe wieder zu
MESSUNG, wenn nicht beende Messung

ERHÖHUNG_2.Byte:
Erhöhe X2 -> kehre wieder zurück (ret)
______________________________________

Meine Idee wäre nun, dass ich anstatt den Sprung in ERHÖHE_2.Byte,
einfach immer das Carry Flag zu X2 addiere.

Gibt es einen Befehl in dieser Art, z.B   "add X2, CARRYFLAG".

Falls Jemand noch eine schnelleren Variante hat, würde ich mich auch
freuen.

Momentan brauch ich pro Erhöhung um 1 ca. 6 Takte.

von Hannes L. (hannes)


Lesenswert?

Ich belege mir grundsätzlich ein unteres Register mit 0 und nenne das
auch noch 'null'

Wenn ich dann etwas mit Übertrag addieren muss, dann ist das meist so:
1
add wl,irgendeinregister   ;irgendein Register zum L-Byte addieren
2
adc wh,null                ;Null (0) und Carry zum H-Byte addieren

wl und wh sind meine Leibundmagenregister, meist r24 und r25.

...

von Mech-Michi (Gast)


Lesenswert?

Echt cooler Tip!!!

Jetzt hab ich auch das Problem nichtmehr, dass ich extra in ein
Unterprogramm springen muss und so die "Abtastrate" durch die erhöhte
Anweisungszahl verfälscht wird.

THX a lot!!!

von Hannes L. (hannes)


Lesenswert?

> Jetzt hab ich auch das Problem nichtmehr, dass ich extra in ein
> Unterprogramm springen muss und so die "Abtastrate" durch die
> erhöhte
> Anweisungszahl verfälscht wird.

Muss ich das JETZT verstehen???

Die Abtastrate hat doch nix mit der Anzahl der Anweisungen oder
Unterprogramme zu tun.

Entweder lässt man den ADC im FreeRun-Mode laufen und stellt sich einen
Timer-Interrupt zum Auslesen so ein, dass garantiert eine (oder mehrere)
neue Wandlungen stattgefunden haben, oder man nutzt gleich den
ADC-Complete-Interrupt.
In beiden Fällen kann der AVR während der Wandlung andere Aufgaben
erledigen oder schlafen.

Schau mal bei http://www.hanneslux.de/avr/index.html vorbei, da findest
du einige Beispiele. Die Quelltexte sind meist gut kommentiert.

...

von Mech-Michi (Gast)


Lesenswert?

Ok, war etwas unverständlich erklärt, ist aber nicht so wichtig.

Mit den Interrupts muss ich noch etwas experimentieren. Dann lässt sich
aber nur ein Eingang "Überwachen",oder?

von Hannes L. (hannes)


Lesenswert?

> Mit den Interrupts muss ich noch etwas experimentieren. Dann lässt
> sich
> aber nur ein Eingang "Überwachen",oder?

Es kommt darauf an, was du machen willst. Also welche Frequenzen du
überwachen willst.

Input-Capture gibt es leider nur einmal (zumindest bei den üblichen
AVRs im Gehäuse DIL20, DIL28, DIL40). Aber es gibt auch andere
Möglichkeiten, mehrere Impulse auszuwerten.

Ich nehme mal an, dass du mit Servoimpulsen im Modellbau
experimentierst. Wenn dem so ist, dann wirst du auf dem oben genannten
Link einige Ideen aufgreifen können. Die Modellbausachen sind zwar
schon etwas älter, also vom Programmierstil noch nicht so ganz optimal,
aber doch ganz brauchbar. Meine Quelltexte sind meist üppig kommentiert,
die müssten eigentlich verständlich sein.

...

von Mech-Michi (Gast)


Lesenswert?

>Es kommt darauf an, was du machen willst. Also welche Frequenzen du
>überwachen willst.

Ich habe vor aus 4 Beschleunigungssensoren einen Neigungssensor zur
Flugregelung zu bauen und dafür muss ich von 8 Ausgängen das
Puls/Pausenverhältniss auslesen.

Ich hab mir es halt so gedacht, dass ich alle nacheinander auslese.
Natürlich wäre es eleganter alle 8 Pins parallel auszulesen, aber das
wird nun mal nicht möglich sein.

Kannst ja mal auf die Homepage schaun, falls es dich interessiert

http://homepages.fh-regensburg.de/~dem31194/

Die Beispiele von deiner Site sind recht hilfreich. Das lässt sich
sicherlich darauf anwenden.

von Hannes L. (hannes)


Angehängte Dateien:

Lesenswert?

Also mit diesen Beschleunigungs-Sensoren kenne ich mich nun überhaupt
nicht aus. - Sorry.

Aber im Prinzip kannst du doch einen 16-Bit-Timer frei durchlaufen
lassen und mit dem Pinchange-Interrupt die 8 Impulse erfassen. Bei
jeder Änderung an einem der Eingänge erfasst du erstmal den gesamten
Port und den Zeitstempel des laufenden Timers, prüfst dann, welche(s)
Bit(s) den Interrupt ausgelöst haben (Vergleich mit gemerktem
Portzustand vom letzten PC-Interrupt) und weist den neuen Zeitstempel
(oder die Differenz zum vorherigen dieses Eingangs) den zu jedem
Eingang gehörenden Variablen (SRAM) zu.

Du brauchst Variablen für
- das Eingangsbyte des letzten Interrupts
- für jeden Kanal den Zeitstempel des letzten Interrupts, in dem
  dieser Kanal einen Pegelwechsel hatte
- für jeden Kanal die Differenz neuer Zeitstempel-alter Zeitstempel

Die Bits, die bei jedem PCI verändert wurden, isolierst du ganz einfach
durch eine EXOR-Verknüpfung.
Z.B.:
 alten Portzustand aus SRAM in Hilfsregister1 laden
 neuen Portzustand von PINx in Hilfsregister2 einlesen
 neuen Portzustand ins SRAM für nächsten Vergleich
 eor hr2,hr1 ergibt dann das Bitmuster der neu veränderten Bits
Durch Einzelabfrage dieser Bits (sbrs / rjmp) kann man dann die
einzelnen Variablen updaten. Die Berechnungen erfolgen dann in der
Mainloop.

Etwas Ähnliches hatte ich mal als Beispiel für Mega48 programmiert,
(Anhang) da ging es aber nur ums Prinzip. Da es in dem Beispiel um die
Erkennung von RC-Servoimpulsen geht, die garantiert NACHEINANDER
eintreffen, ist die Aufgabenstellung etwas einfacher als bei deinem
Vorhaben. Aber vielleicht inspiriert dich dieses Beispiel zu eigenen
Ideen zur Optimierung.

Achja, manchmal ist es schneller, wenn man Dinge, die man normalerweise
in einer Schleife tun würde, einfach mehrfach hintereinander schreibt.
Denn die Behandlung eines Schleifenzählers und die Rücksprünge kosten
auch Rechenzeit, manchmal mehr, als die eigentliche Arbeit.

Übrigens: Cooles Projekt...

...

von Hagen (Gast)


Lesenswert?

>Ich hab mir es halt so gedacht, dass ich alle nacheinander auslese.
>Natürlich wäre es eleganter alle 8 Pins parallel auszulesen, aber das
>wird nun mal nicht möglich sein.

Du kannst zumindestens 2*4 Messungen durchführen, d.h. pro ADXL kommst
du mit einer Messung aus. Das geht weil die X,Y Pulsfrequenz identisch
ist und nur der Dutycycle unterschiedlich ist.

Du könntest beide Kanäle über ein XOR Gatter an den ICP Pin legen.
Bei Begin der Messung ist X=0 xor Y=0 == 0, warte in ICP-ISR auf Flanke
L->H. Nun schaue nach ob X oder Y High ist. Dann ICP-ISR auf Flanke H->L
einstellen. Angenommen X=1 xor Y=0 = 1 Flanke. Beim zweiten ICP Event
muß dann X=1 xor Y=1 = 0 Flanke kommen.

Anderersseits sind die ADXL ja nun nicht so dolle schnell. Dh. du
könntest auch alle gemeinsam in einem Timer pollen.

Gruß Hagen

von Axel R. (Gast)


Lesenswert?

[..
If a voltage output is desired, a
voltage output proportional to acceleration is available from the
XFILT and YFILT pins
..]
Datenblatt Seite 1.
den internen ADC verwenden, scheidet aus, oder?

Übrigens dito - cooles Projekt - RESPEKT!

Ich habe mal für einen Freund seine acht PC-Lüfter (Tachoimpuls) im
Timerint. ausgelesen. waren allerdings nur die fallenden Flanken.
Ging auch über xor.
Port einlesen und merken
temp= xor mit alten Portzustand < geänderte Bits
portpins_gesetzt = einglesener Port AND temp
aktuellen(gemerkten) Portzustand als alt deklarieren

So ähnlich war das. Bei genügend hoher abtastrate geht das sehr gut.

Weiterhin viel Spaß und viel Erfolg!

www.emt-penzberg.de schönen Gruß dorthin :-))

Gruß
AxelR

von Axel R. (Gast)


Lesenswert?

http://www.emt-penzberg.de/index.php?id=10

den meinte ich im speziellen...

von Axel R. (Gast)


Lesenswert?

VIel schwieriger stelle ich mir den Regelalgo vor.
PI, PID, welche Parameter?
Wie hast Du vor, das zu lösen?

von Mech-Michi (Gast)


Lesenswert?

>Analogausgang
Darüber hab ich auch schon mal nachgedacht, habe es aber dann wieder
verworfen, weil die analoge Spannung sehr stark überlagert ist, die
A/D-Umwandlung auch seine Zeit braucht und anschließend eine
Mittelwertbildung über 4-6 Werte notwendig wäre, um einen Vernünftigen
Wert zu bekommen.

>EMT
Die Variante mit 2 gegensätzlich rotierenden Propellern ist natürlich
genial. Dabei wird der Seitenschub aufgehoben und über
Drehzahldifferenz der Rotoren kann man manövrieren. Bei einigen
Modellhelis wird das auch so gemacht.

>Regelung
Über die Art der Regelung bin ich mir noch nicht ganz sicher. Momentan
nehmen wir in der Vorlesung die verschiedenen Regler durch. Hatten
bisher aber nur P- & I-Regler.
Im Moment bin ich noch zu sehr damit Beschäftigt die Neigung über die
Beschleunigung zu messen. Als zweites wollte ich dann nochmal mit Gyros
experimentieren, aber die sind halt mal schweineteuer.

von Axel R. (Gast)


Lesenswert?

Gyros .. sind halt mal schweineteuer.

Sind doch schon in fast jedem OffRoad Buggy drinn. Wird im Modellbau
zwischen Empfänger und Fahrregler/Lenkservo angeschlossen. Sind die
Dinger tatsächlich soo teuer?

von Mech-Michi (Gast)


Lesenswert?

@HanneS & Hagen
Die Variante 2 Eingänge über XOR zu verknüpfen ist eine gute Idee.
Ich frage mich nur, ob die X&Y-Ausgänge mit synchroner Frequenz laufen,
d.h. ob sie gleichzeitig von 0->1 gehen und nur der 1->0 Wechsel
unterschiedlich ist. Das hab ich bei meinen Untersuchungen am Oszi
leider vergessen zu untersuchen.

von Mech-Michi (Gast)


Lesenswert?

@AXEL
Vor ein paar Monaten hab ich mich mal umgeschaut und hab den günstigen
bei DIGIT-Key für 35E gefunden, da muss man aber zusätzlich 13 E
Frachtgebühr entrichten.

Falls du was günstigeres weist wäre ich Dir sehr dankbar

von Axel R. (Gast)


Lesenswert?

Das war es, was mir vorhin noch einfiel:
könntest Du die ADXLs nicht synchronnononisieren?(<-wie jetzt?)
einer gibt den Takt vor und die anderen drei rasten drauf ein. Geht vlt
über den R_set Pin?

von Rolf Magnus (Gast)


Lesenswert?

Beschleunigungssensoren zur Neigungsregelung eines Hubschraubers
funktionieren nicht. Sie setzen nämlich den statischen Betrieb voraus
(also konstante Erdbeschleunigung, deren Richtung man messen kann). Was
ist, wenn dein Fluggerät durch einen Lufthauch seitlich versetzt wird?
Überlege dir mal, was dann passiert und wie deine Regelung darauf
reagieren würde. Ich hab auf der letzten "Faszination Modellbau
(Aussstellung in Sinsheim)" mit einem gesprochen, der schon mehrere
Modelle, die deinem ähnlich sind, gebaut hat, und der hat von diesen
Problemen erzählt. Er hat gesagt, daß es ein Jahr (oder waren's gar
zwei?) gebraucht hat, um überhaupt was halbwegs stabil fliegendes
hinzubekommen. Er muß aber immer noch selbst von Hand die Lage
aussteuern.
Es gibt jetzt von Robbe ein System, das tatsätlich einen Hubschrauber
in konstanter Lage und auch an einer einigermaßen konstanten Position
halten kann. Die benutzen dafür eine Kamera, die den Boden aufnimmt und
ähnlich wie eine optische Maus aus den Verschiebungen zweier
aufeinanderfolgener Frames die Verschiebung des Helis zu messen. Siehe
http://de.robbe-online.net/rims_de.storefront/4425436a003b9e6d271b3e0dc1460657/Product/View/1&2D8493

von Mech-Michi (Gast)


Lesenswert?

@Axel
Das ließe sich vielleicht machen. Aber anhand vom Datenblatt habe ich
so etwas wie ein "synchronisationspin" nicht gefunden. Vielleicht
wäre es möglich, dass man gleichzeitig die Versorgungsspannung
unterbricht.....
Aber ich glaube da bewirken dann geringste Bauteiltoleranzen schon ein
verschieben des Starts.

@Rolf
vor 3 Wochen hatte ich hier im Forum schon änliche Diskussion, ob es
mit Beschleunigungssensoren machbar ist den Neigungswinkel zu messen.
Mein Ansatzt ist folgender:
Ich setzte z.B. für die Neigungsachse VORNE-HINTEN 2 Sensoren ein, die
genau gegensätzlich angeordnet sind(Siehe Bild auf meiner Page), d.h.
wenn X1 bei Drehung z.B. 10° größere Pulsbreite ausgibt, gibt der
andere Sensor an X2 eine kleiner Pulsbreite aus. Dadurch erkenne ich
"Ich drehe mich um den Mittelpunkt->NEIGUNG", wenn nun aber
Beschleunigung durch Bewegung auf den Sensor einwirkt(z.B. Flug nach
Links), dann wirkt auf BEIDE eine gleichgerichtete Beschleunigung,
woraus zu erkennen ist "Ich mache einen Linksflug->KEINE NEIGUNG".

von Axel R. (Gast)


Lesenswert?

Es gibt schlicht keinen Sync-Pin.
Du müsstest etweder einen der ADXL als Master verwenden und mit der
steigenden Flanke ein Flipflop toggeln. Von da aus auf ein XOR. am
anderen Eingang des XOR liegt der zweite ADXL in gleicher Art
angeschlossen. der Ausgang des XOR geht dann über ein Tiefpass
hochohmig an den R-Set eingang des zweiten ADXL. (jezt mal nur so
prinzipiell)
Oder einen "masterclock" bereitstellen, um alle 4 in dieser Art mit
dem Masterclock zu synchronisieren.

Kann man aber auch lassen. Wird zu aufregend, oder?
Dann kann man das auch in Software machen.

von Mech-Michi (Gast)


Lesenswert?

@Axel
Jep, glaub ich auch. Muss halt mal testen wie es ausschaut mit einer
Regelstrecke von 20 ms.

von Rolf Magnus (Gast)


Lesenswert?

> Mein Ansatzt ist folgender:
> Ich setzte z.B. für die Neigungsachse VORNE-HINTEN 2 Sensoren ein,
> die  genau gegensätzlich angeordnet sind(Siehe Bild auf meiner
> Page), d.h. wenn X1 bei Drehung z.B. 10° größere Pulsbreite
> ausgibt, gibt der andere Sensor an X2 eine kleiner Pulsbreite aus.
> Dadurch erkenne ich "Ich drehe mich um den Mittelpunkt->NEIGUNG",
> wenn nun aber Beschleunigung durch Bewegung auf den Sensor
> einwirkt(z.B. Flug nach Links), dann wirkt auf BEIDE eine
> gleichgerichtete Beschleunigung, woraus zu erkennen ist "Ich mache
> einen Linksflug->KEINE NEIGUNG".

Hmm, funktioniert das denn? Immerhin wird jede Drehung auch eine
Verschiebung verursachen, da der Schub nicht mehr senkrecht, sondern
schräg nach oben geht.

von Mech-Michi (Gast)


Lesenswert?

@Rolf
K.A. ob es geht, dafür muss ich eben erst mal testen, wie hoch der
Schub bei Drehungen ist. Dazu muss ich aber erst die Messung so genau
wie möglich machen. Bin aber, glaube ich, auf einen Recht guten weg,
was die Genauigkeit angeht. Im Moment habe ich bei einer Pulsweite von
1ms  ca. 2700 Zählschritte => Pro 90° ca 1300 Unterteilungen, woraus
eine theoretische Messgenauigkeit von 0° 4winkelminuten 3winkelsekunden
(bzw. 0,0675°)resultiert. Um diese theoretische Messgenauigkeit zu
erreichen mach ich eine Mittelwertberechnung über die letzten 4
Messungen wobei auch gleichzeitig eine Frequenzsynchronisation erfolgt.
Falls das ganze nur im statischen Fall funktioniert, hab ich
zumindestens eine sehr sehr genaue Wasserwaage oder einen Winkelmesser
;)

von Axel R. (Gast)


Lesenswert?

Steht ein paar Zeilen unter deinem Post:
http://www.mikrocontroller.net/forum/read-1-89736.html

Vlt. ergänzend - oder schon gelesen?

von Hagen (Gast)


Lesenswert?

>> @HanneS & Hagen
>> Die Variante 2 Eingänge über XOR zu verknüpfen ist eine gute Idee.
>> Ich frage mich nur, ob die X&Y-Ausgänge mit synchroner Frequenz
>> laufen,

Ja, laut Datenblatt. Die Frequenz der PWM ist für X&Y identisch und
synchron, nur der Dutycycle unterscheidet sich.

Ich bin aber ebenfalls skeptisch ob das was du dir da vorstellst ohne
Gyro funktionieren kann. Bisher habe ich bei solchen projekten immer
die Kombination Gyro/Bechleunigung gesehen. Die Beschleunigungssensoren
waren dabei nur nötig um den Drift beim Gyro kompensieren zu können.
Heist: damit man mit dem Gyro saubere Resultate berechnen kann hat man
sie mit ADXLs kompensiert.

Gruß Hagen

von Mech-Michi (Gast)


Lesenswert?

THX, schon gelesen, hilft aber nicht so doll weiter. Werde mich mal an
die Idee von HanneS machen...

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
Noch kein Account? Hier anmelden.