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.
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. ...
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!!!
> 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. ...
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?
> 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. ...
>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.
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... ...
>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
[.. 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
VIel schwieriger stelle ich mir den Regelalgo vor. PI, PID, welche Parameter? Wie hast Du vor, das zu lösen?
>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.
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?
@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.
@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
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?
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
@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".
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.
@Axel Jep, glaub ich auch. Muss halt mal testen wie es ausschaut mit einer Regelstrecke von 20 ms.
> 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.
@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 ;)
Steht ein paar Zeilen unter deinem Post: http://www.mikrocontroller.net/forum/read-1-89736.html Vlt. ergänzend - oder schon gelesen?
>> @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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.