Hallo Ich möchte mit einen MPU 6050 und einen HMC5883L die X Y Z Winkel auslesen. Dafür lese ich beide Bausteine über I2C aus und vereinige die Daten des Beschleunigungs-, Gyrosensors und des Magnetometers mittels Hoch- und Tiefpässen. Ich programmiere momentan einen Atmega16 mittels AVR Studio 5.1. Warum AVR Studio 5.1? Weil wir das so in der Schule verwenden. Aus den Daten des Beschleunigungssensors berechne ich mittels atan2 die Winkel. Diese stimmen auch. Aber wenn ich (für Testzwecke, ob das Ausgelesene überhaupt funktioniert), die Daten des Gyrosensors zu einen Winkel berechnen will, stimmt das Ergebnis nicht. Im Anhang habe ich das C - File für den MPU angehängt. Dort ist die Initialisierung drin und das Auslesen der Register. Das Bild enthaltet Codezeilen, welche alle 10ms aufgerufen wird und die Daten des MPU's über die hochgeladene Klasse ausliest. Das Problem ist, dass die Winkel so keinen Sinn ergeben. Sie erreichen einen sehr hohen Wert ca. +- 10000 und wenn ich ihn kurz ruhig halte, geht der Winkel langsam gegen 0. Kann mir jemand dort weiterhelfen? Danke für eure Hilfe Marcel
Was liefern die Sensoren? Und wie wird daraus ein Winkel berechnet? Dazu finde ich den Code nicht. Also wird die Winkelberechnung den Fehler in Zeile 42 haben.
Ich nehme direkt die Daten die ich "zusammenschifte" * 0.01 und addiere diese immer in eine Variable. Das ist nicht mein erster Gyro, daher weiß ich dass mann die Daten "integrieren" muss. Darum multipliziere ich die Daten mit 1/100Hz. Was wäre Zeile 42??
:
Bearbeitet durch User
Ich kannte das bisher so, dass man in das Sensordatenblatt schaut, und dann die Zahlenwerte entsprechend der Auflösung in SI-Werte umrechnet. Nur für mich: was steht im Sensordatenblatt, ich habe es ja nicht hier. Aber wenn das immer *100 und aufaddiert wird, dann scheint die Formel richtig zu sein. Auf die Implementation haben wir ja immer noch keinen Blick. Zeile 42 http://de.wikipedia.org/wiki/42_%28Antwort%29
Ich habe das Datenblatt rauf und runter durchsucht und nichts gefunden. Hat einer vlt. ein Beispielcode in c, für das Auslesen des Gyro bzw. die Ausgelesen Daten richtig zu verarbeiten?
Marcel D. V. schrieb: > Hat einer vlt. ein Beispielcode in c, für das Auslesen des Gyro bzw. die > Ausgelesen Daten richtig zu verarbeiten? Wie heißt es auf der Arduino Seite zum MPU6050 so richtig: "Reading raw values is easy, the rest is not" Aber offensichtlich haben sich genug gefunden und sogar die Umrechnung vernünftig hinbekommen. http://playground.arduino.cc/Main/MPU-6050
Was ist denn daran so schwierig, die Werte umzurechnen? Im Datenblatt steht doch klar die Sensitivity. Lustig wird es eher, wenn's an Zero-Bias-Kalibrierung und evtl. Temperaturkompensation geht.
Ich habe schon alles versucht. Ja ich habe den Sensor auf eine Sensitivity von +-2000°/s eingestellt. Darum müsse ich die Daten des Sensors mit 2000/90 = 22.2222 dividieren. Aber dann sind die Werte immer noch nicht richtig. Etwas sehr komisches ist, dass der Ausgabewert immer wieder langsam gegen 0 geht, wenn ich ihn ruhig halte. Und ja ich summiere die Daten des Gyro's immer auf, aber der Winkel geht trotzdem gegen 0. Hat noch keiner von euch das alles schon einmal in C gemacht??? Denn ist halt am einfachsten alles in C anzusehen, anstatt alles in C++.
:
Bearbeitet durch User
Marcel D. V. schrieb: > Und ja ich summiere die Daten des Gyro's immer auf, aber der Winkel geht > trotzdem gegen 0. Irgendwie musst du mit der Drift/Offset eines Gyrosignals umgehen. Was möchtest du denn rausbekommen?
Wo machst du denn die Integration und Umrechnung der Werte? Wenn alles bei stillstehendem Gyro zu 0 konvergiert, haut da irgendwas nicht hin. Poste doch mal deinen Code zur Integration und Kalibrierung.
Ich habe vorher eingebaut, dass ein Offset immer weggerechnet wird. Dafür lese ich zu beginn einfach 1000 Werte aus und addiere diese dann in eine Variable. Anschließend wird diese dann durch 1000 dividiert und dann immer von den RAW Werten abgezogen. Ich möchte schlussendlich mittels dem Gyro einen Winkel berechnen können der sich von -180 bis +180 ° bewegt. Wenn dies funktioniert kombiniere ich die Daten des Gyro's mit den Daten des Beschleunigungssensor.
Hier ist die Kalibration und die Integration. Die Methode GetGyroX GetGyroY GetGyroZ geben einfach den ausgelesen RawWert - berechneten Offset aus.
Marcel D. V. schrieb: > Hier ist die Kalibration und die Integration. > > Die Methode GetGyroX GetGyroY GetGyroZ geben einfach den ausgelesen > RawWert - berechneten Offset aus. Und wo liegt dein problem mal den ganzen code zu posten?
Woher soll dein Compiler wissen, dass er realx, relay und realz nicht in irgendwelche register packen darf, die den Kram mit der ISR nicht überleben. Die müssen als volatile deklariert werden. Und die ganze Rechnerei hat natürlich nicht in der ISR zu suchen.
Mike A. schrieb: > Und die ganze Rechnerei hat natürlich nichts in der ISR zu suchen. p.s. ... und die I2C-Zufgriffe gehören da auch nicht hin.
Okay ich mache das volatile. Ja ich weiß, dass das da nicht reingehört, aber das ist dort nur für Testzwecke. Ich probier es nachher mal aus und dann Bescheid. Wegen der Sensivity ist schon richtig durch 22.2 zu dividieren oder? (Sensitivity = +-2000)
Ich habe nun die realx, realy und realz Variable volatile gemacht, aber konvergieren die Variablen gegen 0, wenn ich keine Bewegung mache. (Und der Winkel stimmt mit 22.2 auch nicht.)
Marcel D. V. schrieb: > Wegen der Sensivity ist schon richtig durch 22.2 zu dividieren oder? > (Sensitivity = +-2000) Rechne es doch einfach mal zu Fuß aus ob das plausibel ist. Der Wert vom Gyro ist ein Maß für die Winkelgeschwindigkeit, irgendwas das sich (möglicherweile mittels eines Faktors, siehe Datenblatt) in °/s umrechnen lässt und dann wenn Du °/s hast und n Messungen pro Sekunde machst teilst Du das nochmal durch n. Also hast Du den Faktor (nennen wir in mal a) den Du brauchst zur Umrechnung in °/s
1 | Winkelgeschwindigkeit = Messwert * a |
und außerdem hast Du n Messungen pro Sekunde, es hat sich also nach jeder Messung um den folgenden Winkel weitergedreht:
1 | Winkel = Winkelgeschwindigkeit * Zeit |
2 | Winkel = Messwert * a * Zeit |
und weil Zeit [in Sekunden] = 1 / n
1 | Winkel = Messwert * a / n |
2 | Winkel = Messwert * a / n |
Rechne also mal zu Fuß aus ob zusammen mit dem Meßwert den der Sensor liefert und dem Umrechnungsfaktor den Du verwendest tatsächlich ein Winkel rauskommt der zu Deiner der tatsächlichen Drehung zwischen zwei Messungen halbwegs plausibel ist.
:
Bearbeitet durch User
Marcel D. V. schrieb: > Ja ich weiß, dass das da nicht reingehört, aber das ist dort nur für > Testzwecke. Und es funktioniert so nicht! Aber lass mal drinn, eventuell gibts noch einen trick wie du es lösen kannst ohne dies umzuschreiben
Marcel D. V. schrieb: > Ich möchte schlussendlich mittels dem Gyro einen Winkel berechnen können > der sich von -180 bis +180 ° bewegt. > Wenn dies funktioniert kombiniere ich die Daten des Gyro's mit den Daten > des Beschleunigungssensor. Um die integrierten Gyro-Daten mit den Beschleunigungs-Daten zusammenzubringen wirst Du auf jeden Fall Euler-Winkel oder besser Quaternionen bemühen müssen. Man kann z.B. einen Würfel durch unterschiedliche Drehoperationen wieder in den Ausgangszustand drehen. Der ACC liefert dann wieder die selben Werte wie vor der Operation. Getrennt nach XYZ aufintegrierte Gyro-Daten können sie ziemlich beliebige Werte aufweisen.
Hä? schrieb: > Marcel D. V. schrieb: >> Ja ich weiß, dass das da nicht reingehört, aber das ist dort nur für >> Testzwecke. > > Und es funktioniert so nicht! Aber lass mal drinn, eventuell gibts noch > einen trick wie du es lösen kannst ohne dies umzuschreiben Das ist nicht mein erster Gyro. Dort habe ich es zu Beginn auch so gemacht und es hat funktioniert. Also schließe ich daraus, dass es so auch möglich sein muss. Und das kann auch nicht der Grund sein warum die Variablen nach 0 konvergieren. Es muss irgendwas anderes sein. Bernd K. schrieb: > Marcel D. V. schrieb: > >> Wegen der Sensivity ist schon richtig durch 22.2 zu dividieren oder? >> (Sensitivity = +-2000) > > Rechne es doch einfach mal zu Fuß aus ob das plausibel ist. Der Wert vom > Gyro ist ein Maß für die Winkelgeschwindigkeit, irgendwas das sich > (möglicherweile mittels eines Faktors, siehe Datenblatt) in °/s > umrechnen lässt und dann wenn Du °/s hast und n Messungen pro Sekunde > machst teilst Du das nochmal durch n. > > Also hast Du den Faktor (nennen wir in mal a) den Du brauchst zur > Umrechnung in °/s > >
1 | > Winkelgeschwindigkeit = Messwert * a |
2 | > |
> > und außerdem hast Du n Messungen pro Sekunde, es hat sich also nach > jeder Messung um den folgenden Winkel weitergedreht: > >
1 | > Winkel = Winkelgeschwindigkeit * Zeit |
2 | > Winkel = Messwert * a * Zeit |
3 | > |
> > und weil Zeit [in Sekunden] = 1 / n > >
1 | > Winkel = Messwert * a / n |
2 | > Winkel = Messwert * a / n |
3 | > |
> > Rechne also mal zu Fuß aus ob zusammen mit dem Meßwert den der Sensor > liefert und dem Umrechnungsfaktor den Du verwendest tatsächlich ein > Winkel rauskommt der zu Deiner der tatsächlichen Drehung zwischen zwei > Messungen halbwegs plausibel ist. Das Problem ist, dass ich nicht weiß was a ist. Und ich habe das Datenblatt schon komplett durchgesehen und bis jetzt nichts dazu gefunden. (Habe es mal angehängt)
Marcel D. V. schrieb: > Das Problem ist, dass ich nicht weiß was a ist. > Und ich habe das Datenblatt schon komplett durchgesehen und bis jetzt > nichts dazu gefunden. (Habe es mal angehängt) Das liegt wohl daran daß es noch ein zweites Datenblatt gibt mit den Registerbeschreibungen etc. Hier: http://invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf Ich tippe mal auf die Tabelle auf Seite 32:
1 | FS_SEL Full Scale Range LSB Sensitivity |
2 | 0 ±250°/s 131 LSB / °/s |
3 | 1 ±500°/s 65.5 LSB / °/s |
4 | 2 ±1000°/s 32.8 LSB / °/s |
5 | 3 ±2000°/s 16.4 LSB / °/s |
Also würd ich mal sagen bei FS_SEL=3 ±2000°/s hieße das 16.4 Einheiten in diesem Register bedeuten 1°/s also
1 | Winkelgeschwindiglkeit = (Messwert / 16.4) °/s |
also in Deinem Falle mit 100 Messungen pro Sekunde:
1 | Winkel = (Messwert / 16.4 / 100) ° |
2 | Winkel = (Messwert / 1640) ° |
:
Bearbeitet durch User
Bernd K. schrieb: > Hier: > http://invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf Und die aktuelle Version 4.2 der Registermap http://www.invensense.com/mems/gyro/documents/RM-MPU-6000A-00v4.2.pdf
Mike A. schrieb: > Bernd K. schrieb: >> Hier: >> http://invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf > > Und die aktuelle Version 4.2 der Registermap > http://www.invensense.com/mems/gyro/documents/RM-MPU-6000A-00v4.2.pdf Oh ja, danke. Google hat erstere als erstes ausgespuckt und ich war zu faul weiterzusuchen. Die Werte aus obiger Tabelle jedoch (jetzt auf Seite 31) scheinen wohl gleich geblieben zu sein (gerade nochmal nachgeschaut).
:
Bearbeitet durch User
Bernd K. schrieb: > Mike A. schrieb: >> Bernd K. schrieb: >>> Hier: >>> http://invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf >> >> Und die aktuelle Version 4.2 der Registermap >> http://www.invensense.com/mems/gyro/documents/RM-MPU-6000A-00v4.2.pdf > > Oh ja, danke. Google hat erstere als erstes ausgespuckt und ich war zu > faul weiterzusuchen. Die Werte aus obiger Tabelle jedoch (jetzt auf > Seite 31) scheinen wohl gleich geblieben zu sein (gerade nochmal > nachgeschaut). Normalerweise gibt es auch nicht zwei Datenblätter und darum habe ich nicht weitergesucht. Bernd K. schrieb: > Marcel D. V. schrieb: > also in Deinem Falle mit 100 Messungen pro Sekunde: >
1 | > Winkel = (Messwert / 16.4 / 100) ° |
2 | > Winkel = (Messwert / 1640) ° |
3 | > |
Ich habe das mal so eingebaut, aber das Problem, dass der Winkel gegen 0 konvergiert ist leider dadurch nicht behoben. Und ich habe keine Idee mehr, warum dies der Fall sein kann.
:
Bearbeitet durch User
Marcel D. V. schrieb: > Ich habe das mal so eingebaut, aber das Problem, dass der Winkel gegen 0 > konvergiert ist leider dadurch nicht behoben. Wieso? Wenn Du es nicht mehr bewegst ist die Winkelgeschwindigkeit 0. Das würde ich so erwarten, scheint also korrekt zu sein.
Bernd K. schrieb: > Wieso? Wenn Du es nicht mehr bewegst ist die Winkelgeschwindigkeit 0. > Das würde ich so erwarten, scheint also korrekt zu sein. Klar. Ich dachte allerdings das Problem wäre, dass der integrierte Wert gegen 0 konvergiert. Dann muss was faul sein.
greg schrieb: > Bernd K. schrieb: >> Wieso? Wenn Du es nicht mehr bewegst ist die Winkelgeschwindigkeit 0. >> Das würde ich so erwarten, scheint also korrekt zu sein. > > Klar. Ich dachte allerdings das Problem wäre, dass der integrierte Wert > gegen 0 konvergiert. Dann muss was faul sein. Ja der integrierte Winkel geht gegen 0. Das die Winkelgeschwindigkeit gegen 0 geht, wenn ich den Sensor nicht bewege ist mir klar.
GetGyroX() gibt ein Integer als returnwert. Diese Integer wird dan multipliziert mit 0,01. Immer wen sie Anfangen mit einen Wert Kleiner dan 100, ist die Ergebnis 0 !! Versuch es mal mit ein float zu machen.
Okay, danke ich werde das heute mal ausprobieren und dann Bescheid geben, ob dass das Problem gelöst hat.
:
Bearbeitet durch User
Deine Kalibrierung sieht mir auch problematisch aus. Bei 1000 Messungen bekommst du leicht einen Overflow in der Summe zusammen.
greg schrieb: > Deine Kalibrierung sieht mir auch problematisch aus. Bei 1000 Messungen > bekommst du leicht einen Overflow in der Summe zusammen. Ja habe ich mir auch schon gedacht. Darum werde ich dort glaub ich einfach eine int32 nehmen. Das dürfte ausreichen.
RP6conrad schrieb: > GetGyroX() gibt ein Integer als returnwert. Diese Integer wird dan > multipliziert mit 0,01. Immer wen sie Anfangen mit einen Wert Kleiner > dan 100, ist die Ergebnis 0 !! Versuch es mal mit ein float zu machen. Habe es nun mal ausprobiert und so wird die Variable wieder so >10000 O.o Ich finde, dass sehr komisch. Bei meinen anderen Gyro habe ich auch alles mit Integer gemacht und das hat auch geklappt. Es muss irgendein anderen Grund haben, dass der Winkel gegen 0 konvergiert. Habe nun nochmals die Winkelgeschwindigkeiten angesehen. --> Diese sind bei keiner Bewegung eig. 0. Machmal kann es sein, dass die Werte so -2, -1, 0, 1, 2 betragen. (Sie schwanken zwischen diesen Werten) Aber diese fallen ja weg, wenn ich die Winkelgeschwindigkeiten mit 0,01 multipliziere.
Marcel D. V. schrieb: > wenn ich die Winkelgeschwindigkeiten mit 0,01 > multipliziere. * Du sollst nicht mit 0.01 multiplizieren sondern mit 1/1640 (siehe Datenblatt) * Nimm double und nicht integer
:
Bearbeitet durch User
Bernd K. schrieb: > Marcel D. V. schrieb: >> wenn ich die Winkelgeschwindigkeiten mit 0,01 >> multipliziere. > > * Du sollst nicht mit 0.01 multiplizieren sondern mit 1/1640 (siehe > Datenblatt) > * Nimm double und nicht integer Gesagt getan. Aber mit double habe ich das gleiche Problem mit den float Werten. Die Werte sind im Bereich von 10000 - 20000. Das ist wirklich sehr komisch O.o
Marcel D. V. schrieb: > Die Werte sind im Bereich von 10000 - 20000. > Das ist wirklich sehr komisch O.o Wenn Du es langsam um X drehst, sagen wir mal du schaffst es halbwegs genau 90° zu drehen in ziemlich genau einer Sekunde. Welchen Wert hat während dieser Drehung das rohe ausgelesene GetGyroX()? Nach meiner obigen Theorie mit dem wie ich das Datenblatt interpretiere wäre der Messwert 90 * 16.4 = 1476 GetGyroX() sollte also ungefähr 1476 ausgeben während Du mit dieser Geschwindigkeit drehst (vorausgesetzt natürlich Du hast die Empfindlichkeit wirklich auf 2000°/s eingestellt). Kommt das hin oder liegt das schon grob daneben? Also dreh mal langsam 90° in eine Richtung während Du "einundzwanzig" sagst und dann poste mal den Wert den es ausgibt.
:
Bearbeitet durch User
Bernd K. schrieb: > Marcel D. V. schrieb: > >> Die Werte sind im Bereich von 10000 - 20000. >> Das ist wirklich sehr komisch O.o > > Wenn Du es langsam um X drehst, sagen wir mal du schaffst es halbwegs > genau 90° zu drehen in ziemlich genau einer Sekunde. Welchen Wert hat > während dieser Drehung das rohe ausgelesene GetGyroX()? > > Nach meiner obigen Theorie mit dem wie ich das Datenblatt interpretiere > wäre der Messwert 90 * 16.4 = 1476 > > GetGyroX() sollte also ungefähr 1476 ausgeben während Du mit dieser > Geschwindigkeit drehst (vorausgesetzt natürlich Du hast die > Empfindlichkeit wirklich auf 2000°/s eingestellt). Kommt das hin oder > liegt das schon grob daneben? > > Also dreh mal langsam 90° in eine Richtung während Du "einundzwanzig" > sagst und dann poste mal den Wert den es ausgibt. Es gibt so ca -1600 - -1800 bekomm ich raus. Ich wenn ich so schnell ich kann den Sensor um 90° drehe. Also kann da irgendwas nicht stimmen. Habe nun was in der Initialisierung geändert, da es zuerst nicht gestimmt hatte. Aber es kann sein, dass dort trotzdem noch nichts alles in der Initialisierung stimmt. Ich werde das nachher nochmals checken. Vielleicht sieht jemand anders auch noch einen Fehler?
Marcel D. V. schrieb: > Es gibt so ca -1600 - -1800 bekomm ich raus. > Ich wenn ich so schnell ich kann den Sensor um 90° drehe. > Also kann da irgendwas nicht stimmen. Was kommt raus wenn Du ihn langsam (während einer Sekunde) drehst, nicht "so schnell wie du kannst" sondern nach dem wert bei 90° / Sekunde hab ich gefragt. Wie sieht Deine GetGyroX() aus, poste die mal. Machst Du darin eventuell schon irgendwelche Berechnungen? Denn wenn ja dann kann das ja alles nicht stimmen, ich bezog mich auf die rohen Messwerte direkt aus den Sensor-Registern.
Habe mich dort verschrieben. Das war schon in 1er Sekunde. Den Code habe ich schon öfters hochgeladen. Die Methode GetGyroX() ist in der Klasse MPU-6050.c und dort werden keine Berechnungen durchgeführt.
Marcel D. V. schrieb: > Das war schon in 1er Sekunde. Na das kommt doch fast hin. 1476 solls sein und 1600 ist es. Wenn man bedenkt daß Du wahrscheinlich nicht exakt genau 1 Sekunde und 90° genau hinbekommst mit der bloßen Hand dann kommt das ungefähr hin, der Faktor 1/1640 stimmt also (bei 100 Hz). Also muss der Fehler irgendwo anders versteckt sein. Auch können sich da niemals 20000 in kurzer Zeit aufsummieren wenn Du diese Werte durch 1640 teilst vor dem Integrieren.
Ja eben, dass ergibt einfach keinen Sinn, zusätzlich konvergiert der Wert auch gegen 0.
hallo zusammen, ich hatte ein ähnliches Problem und habe es so gelöst: siehe gyro.c die werte sind jetzt nicht die genauen Grade aber es komt dem zimlich nahe. jedoch ist hierbei immer noch ein kleiner Fehler drinnen, der zur Folge hat, dass der Sensor, nach dem er eine Minute bewegt wurde einen Fehler von 30° hat. hoffe das Hilft dir weiter. Weiß einer von euch wie das mit dem FIFO genau funktioniert? wenn ich jetzt zb. gyrox und gyrox in den FIFO schreiben lassen woher weiß ich jetzt welcher FIFO wert jetzt zu welcher Messung gehört weil das ist auch ein wichtiger Aspekt der beim messen beachtet werden muss, da ansonsten Fehler(wie jetzt bei mir) entstehe. grüße Basti edit : Code datei
:
Bearbeitet durch User
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.