Hallo!
Ich versuche jetzt seit zwei Wochen des HMC5883L Kompassmodul mit meinem
Raspberry über die wiringpi und I2C zum Laufen zu bekommen - leider ohne
Erfolg.
Ich habe hier schon viel gelesen und habe viel versucht, nur komme ich
nicht an sinnvolle Werte.
Was sich mir nicht erschließt, ist zum Einen, wie ich an den Wert zur
Skalierung komme. Ich versteh es einfach nicht. Brett vorm Kopf?
Zum Anderen komme ich an die Tilt-Kompensierung nicht heran.
Dazu brauche ich die skalierten Werte =(
Hier mal mein Versuchscode. Nicht gerade schick, aber zumindest gibt er
Werte aus.
Ich bin heute Abend gegen 21 Uhr wieder zu hause und werde dann mal die
Werte posten.
Ich bekomme Rohdaten aus den Registern. Maximal immer um die 32700 (?).
Und das auf allen Achsen.
Aber diese sind dann leider nicht durchgehend von zB 0 bis ~32700,
sonder immer mit Sprüngen verbunden, die sich mir nicht erklären.
Hier scheitert es warscheinlich auch an der Skalierung.
Anhand der Rohdaten errechne ich mir dann den Offset, aber wie gesagt,
ich komme mir der Skalierung nicht klar. Es erschließt sich mir einfach
nicht, wie ich richig skaliere und warum.
Das wird auch der Grund sein, warum ich keine verwertbaren Werte
bekomme, die ich zur endgültigen Winkelberechnung brauche.
Ich hoffe, dass ich dann mit den Werten wieder selbstständig in der Lage
bin, mir die richtigen Winkel berechnen zu lassen.
Und dann kann ich auch Feinheiten wie die Dekination einzubinden, aber
so weit will ich im Moment noch gar nicht denken :D
Die Werte aus dem Modul sind 16-Bit Zahlen im 2-er Komplement. D.h.
dezimal läuft der Wertebereich von -32768 bis +32767.
Was du kriegst sind die Komponenten des Vektors der Feldlinien an dieser
Position.
Wenn wir uns mal auf den 2D Fall konzentrieren, dann hast du einen
Vektor in irgendeine Richtung. Du kriegst den Vektor in Form der
Projektion auf die X-Achse bzw. in Form der Projektion auf die Y-Achse.
Erinnere dich zurück an deine Schulzeit, als ihr dort mit Trigonometrie
angefangen habt. Die Projektionen auf die Achsen sind genau das, was als
Sinus bzw. Cosinus bekannt sind.
Deine Aufgabe ist genau anders herum. Du hast den Sinuswert gegeben bzw.
den Cosinuswert und fragst dich welcher Winkel da dazugehört. Das ist
der Winkel um den die magnetische Nordrichtung von deiner Ausrichtung
des Sensors abweicht.
Einen kleinen Unterschied gibt es noch. In der Mathematik bespricht man
Sinus und Cosinus am Einheitskreis. Du hast keinen Einheitskreis,
sondern dein Kreis hat den Radius sqrt(x*x + y*y). D.h um die
Komponenten auf einen Einheitskreis zu normieren, damit du die
Arcus-Funktionen anwenden kannst, müssen die Komponenten durch diesen
Radius dividiert werden.
Allerdings ist das alles eine Standardaufgabe, die oft vorkommt, so dass
es dafür eine fertige Funktion gibt - atan2
Stopf deine Komponenten in die atan2 Funktion rein und du kriegst den
Winkel des Vektors schon fix fertig aufbereitet und im richtigen
Quadranten in Radianten (Achtung darauf!) ausgerechnet zurück. Ja, wenn
du die Inklination erst mal ignorierst ist es tatsächlich so einfach,
wie eiin einziger Funktiosaufruf und eine Umrechnung von Radianten in
Grad (x*180/pi). Das Ergebnis ist der Winkel um den die Nordrichtung
verdreht ist. D.h natürlich nur, wenn es keine anderen magnetischen
Beeinflussungen gibt
Schau mal, was i2cdetect -y 1 sagt, ob das Modul überhaupt erkannt wird.
Auf jeden Fall die Pullups vom Modul ablöten, falls vorhanden, da der
Raspi diese schon on board hat.
Hey! Erstmal danke für die schnellen Antworten!
Ja, genau: -32768 bis 32767 - daran erinnere ich mich.
Verstehe ich das richtig, dass es quasi einfach reicht, mir die Wert aus
dem Modul, so wie sie jetzt sind, einfach über
1
bearing = atan2(YMsb,XMsb);
ausrechnen zu lassen? Ohne Skalierung? YMsb und XMsb sind ja dabei die
entsprechenden Werte aus den X- und Y-Registern.
Die Umrechnung "auf den richtigen Quadranten" und die letztliche
Umrechnung in Degree brauche ich ja trotzdem, wenn ich keine Radangaben
haben möchte.
Ja, das Modul wird über i2cdetect -y 1 erkannt: 1e ist die Bezeichnung,
die auftaucht.
Die Pullups müssen wirklich runter? o.O
Marco He schrieb:> Ja, genau: -32768 bis 32767 - daran erinnere ich mich.> Verstehe ich das richtig, dass es quasi einfach reicht, mir die Wert aus> dem Modul, so wie sie jetzt sind, einfach über>>
1
bearing = atan2(YMsb,XMsb);
>> ausrechnen zu lassen?
Im Prinzip müsste es das sein.
> Ohne Skalierung? YMsb und XMsb sind ja dabei die> entsprechenden Werte aus den X- und Y-Registern.
Genau.
> Die Umrechnung "auf den richtigen Quadranten" und die letztliche> Umrechnung in Degree brauche ich ja trotzdem, wenn ich keine Radangaben> haben möchte.
Die Quadrantensache erledigt alles schon atan2. Du brauchst nur noch von
Radianten in Grad umzurechnen.
Was dir natürlich noch einen Strich durch die Rechnung machen kann, das
ist ein Sensoroffset. Da wäre es zb mal vernünftig mit einem echten
magnetischen Kompass die Nordrichtung festzustellen, den Sensor dazu
parallel zu stellen und dann nachzusehen, ob alle bis auf 1 Komponente
zu 0 verschwinden oder ob es eine Verschiebung gibt.
Ebenfalls sichtbar müssen sich derartige Probleme machen, wenn man den
Sensor um 180° dreht. Dann sollten sich theoretisch alle Werte im
Vorzeichen umdrehen. Tun sie das wirklich?
Was ist bei Drehungen um 90°? Die Werte sollten die Achsen tauschen aber
ansonsten in ihrer Größe gleich bleiben. Tun sie das?
Daraus ergibt sich ann ein Satz von Korrekturwerten, die
berücksichtigen, dass die Sensoren in den einzelnen Achsen natürlich
nicht alle gleich empfindlich sind bzw. einen Offsetfehler haben können.
Oookay, jetzt heißt es für mcih erstmal ran an den Raspberry und gucken,
dass ich das alles mal fix umsetze.
Ich werde mich heute Abend dann nochmal hören lassen!!!
Danke erstmal bis hierhin!
So ich hab gerade mal eine Messreihe aufgenommen, indem ich den Sensor
auf ne Schalchtel geklebt habe, mit der Z-Achse in Bodenrichtung.
Dabei habe ich dann nur mit
1
2
bearing = atan2(YMsb,XMsb);
3
bearing *= (180 / 3.4159265);
mir die Werte ausgeben lassen. Rotation gegen den Uhrzeigersinn:
133 bis runter auf 30, dann Sprung auf 140
140 bis runter auf 18, dann Sprung auf 147
147 bis runter auf 70 dann Zählrichtungsumkehr
70 bis rauf auf 140, dann Sprung auf 24
24 bis rauf auf 134, dann Sprung auf 30
30 bis rauf auf 133.
Es ergeben sich also keine sauberen 90°-Positionen.
Die Werte sind mit und ohne Offsetberücksichtigung recht ähnlich.
Wenn die Zählrichtungsumkehr stattfindet, also bei 70, dann ist die
Ausrichtung der X-Achse schon ziehmlich gut nach Norden gerichtet,
soweit man das nun mit nem Kompass im Handy sagen kann. Ich weis
allerdings, dass dort definitiv Norden ist.
Das ist doch schonmal viel Wert! Allerdings wundern mich die Zahlen
trotzdem.
Was läuft da in der Auflösung falsch?
Marco He schrieb:> Es ergeben sich also keine sauberen 90°-Positionen.> Die Werte sind mit und ohne Offsetberücksichtigung recht ähnlich.
Dann lass doch erstmal die ganze Winkelrechnerei weg. Bevor du nicht
weißt, dass der Offset richtig abgezogen ist und die Werte gleich
skaliert sind, kommt sonst nur mehr oder weniger Unfug raus.
Mach erstmal eine Scatterplot der Rohdaten, während du den Sensor sauber
horizontal ausgerichtet hast und langsam ein paar Mal um die vertikale
Achse drehst. Und den zeigst du dann mal.
Vielleicht eine blöde Frage, aber hast du eine Empfehlung, mit was ich
den Scatter Plot auf dem Raspberry erstelle? Oder soll ich mir die
Wertepaare einfach in eine Datei ausgeben lassen und sie mit Excel
darstellen?
Ist mir ein wenig peinlich, aber das sind jetzt rund 150 Messwerte...
Edit: Selbst mit rund 550 sieht das Bild nicht großartig besser aus.
Mach ich was falsch?
Kann doch alles irgendwie nicht sein...
Marco He schrieb:> Edit: Selbst mit rund 550 sieht das Bild nicht großartig besser aus.> Mach ich was falsch?
Das scheint so. Bei einem vernünftigen Magnetfeldsensor muss sich bei
einem xy-Plot ein ggf. verzerrter Kreis ergeben, dessen Mittelpunkt
möglicherweise gegen den Ursprung verschoben ist. Vorher braucht man gar
nicht anfangen, mit den Daten zu rechnen.
Was liefert denn der Selbsttest?
Gegenüber den Achsenbezeichnungen im Datenblatt hast du Y und Z
vertauscht. Welche Daten sind im Plot dargestellt und worum hast du den
Sensorchip gedreht?
Den verzerrten Kreis habe ich auch erwartet. Deswegen wundere ich mich
und fange langsam an, an mir zu zweifeln...
Der Selbsttest (mit Defaultwerten), so, wie er im ersten Post
eingestellt ist, liefert in den drei Registern folgende Werte:
XMsb: -3323
YMsb: 30725
ZMsb: -19707
Im Plot habe ich die X zu Y - Daten dargestellt und um die Z-Achse
gedreht...
Der Sensor liegt also gerade auf seinen Chips auf der Schachtel auf und
sinnbildlich auf der Chipseite gedreht.
Marco He schrieb:> Den verzerrten Kreis habe ich auch erwartet. Deswegen wundere ich mich> und fange langsam an, an mir zu zweifeln...
Die Messwerte bilden doch einen verzerrten Kreis (mit mehreren
Überläufen auf der Excel-X-Achse)!
LG, Sebastian
Ich habe mal ein wenig aufgeräumt und ein neues Programm geschrieben,
nur um die Werte des Selbsttests auszugeben, denn für mich machten die
obigen Werte keinen Sinn.
Ich führe mit den default-Einstellungen 8 Messungen durch, lasse mir das
Ergebnis der letzten Messung ausgeben und den Durchschnittswert der
Messungen.
Im Bild ist das Ergebnis zu sehen.
Warum hab ich aber so kleine Werte?
Hier das Programm dazu:
Write CRA (00) – send 0x3C 0x00 0x70 (Exit self test mode and
31
this procedure)
32
End If
Noch ein Detail:
Auch wenn das 16 Bit Ergebnisse sind, aus dem Datenblatt (das ich jetzt
auch studiert habe) geht hervor, dass der erwartete Wertebereich von
-2048 bis 2047 geht - in allen Gain Stufen.
Woher also deine ca 32700 von oben stammen, ist mir nicht ganz klar.
Laut Datenblatt kannst du diese Ergebnisse nicht erhalten. Vielleicht
hat dir die 16 Bit Leseroutine die Bytes verkehrtr rum zusammengesetzt?
Dann scheine ich ein Problem mit dem Verständnis von Punkt 5 zu haben:
1
5. Loop
2
Send 0x3D 0x06 (Read all 6 bytes. If gain is changed then this data
3
set is using previous gain)
4
Convert three 16-bit 2’s compliment hex values to decimal values
5
and assign to X, Z, Y, respectively.
6
Send 0x3C 0x03 (point to first data register 03)
7
Wait about 67 ms (if 15 Hz rate) or monitor status register or
8
DRDY hardware interrupt pin
9
End_loop
Ich versteh nicht, was ich machen soll. Ich bin echt fertig... hau das
Ding bald in die Tonne...
Ich lese doch alle 6 Register aus =(
Selbst, wenn ich die 6 Register als 3x16-Bit auslese, also mir die
2er-Komplemente ausgeben lasse, erhalte ich nur die Werte wie auf dem
Bild zu diesem Post hier.
Was soll das mit dem "Send 0x3D 0x06 "?
0x3D ist lesen,
0x06 ist das YLSB-Register,
also ist der Befehl für den Raspberry:
(wiringPiI2cReadReg8(fd, 0x06))
wobei fd der Sensor ist.
Den Wert lese ich doch aber schon aus....
So wie die anderen 5 Werte doch auch.
Ihr glaubt nicht, wie ich aufm Schlauch stehe...
Deine Werte für die X Achse sollten ein wenig schwanken und wenn du den
Sensor (flach am Tisch liegend) um die Hochachse drehst, sollten sie
sich verändern.
Da das Magnetfeld der Erde ca 0.7 Gauss an den Polen und 0.2 Gauss am
Äquator beträgt, wird es bei uns ein Wert irgendwo da dazwischen sein.
Ich nehm mal 0.5 Gauss an. Bei dem eingestellten Gain, wird 1 Gauss mit
einem Wert von 1090 autauchen. Erwartungswerte für die X Achse bewegen
sich also von ca. -540 bis ca +540. Je nachdem wie stark dein lokales
Magnetfeld ist und wie stark die Inklination ist, auch mehr oder
weniger. Aber in etwa in diesem Bereich.
Wenn du zur Ausgabe der X Werte noch die Y-Werte mit dazu nimmst, dann
sollte man bei einer Drehung auch sehen, wie die X Werte zu bzw.
abnehmen und im Gegenzug dazu die Y-Werte zu bzw. abnehmen, so wie man
das beim Zusammenhang zwischen Cosinus und Sinus erwarten würde.
Was ich verändert habe: Ich habe vor allen Dingen mal auf Continous
Measurement umgestellt. Denn mit einer Einzelmessung hat man wenig
angefangen, wenn man 'Action' beim Drehen sehen möchte.
Und dann lass ich mir natürlich in der Schleife ausgeben:
DIe Bytes wie sie vom Sensor kommen und das was ich daraus mache. Damit
ich sehen kann, ob die Zusammensetzung klappt oder ob ich irgedwo
falsche Annahmen gemacht habe. Die Bytes lass ich mir sinnvollerweise
Hex ausgeben, der mich eigentlich interessierende Wert dann dezimal.
Und dann schau mer mal.
Und noch was:
Der Datentyp der Wahl ist immer ein uint8_t wenn man es mit Bytes zu
tun hat. Das was du vom Sensor kriegst sind zuallererst mal Bytes. Und
erst wenn 2 Bytes zu einer 16 Bit Einheit zusammengesetzt sind, ist der
Zeitpunkt gekommen, die Interpretation dieser Einheit zu einem int zu
wechseln. Also: zuerst die beiden uint8_t zu 16 Bit zusammensetzen und
erst dann die Anweisung geben, dass das Ganze als int aufzufassen ist.
Wenn dein Pi mit 32 Bit ints operiert, dann muss man noch einen
Zwischenschritt einfügen und die 16 Bit Einheit erst mal auf einen
int16_t casten, ehe man dann auf int geht.
Und noch was:
Je nach Situation auf deinem Schreibtisch können da auch ganz schöne
Fehler auftreten. Jeder Trafo, jeder (Röhren-)Monitor, jeder Motor
erzeugt ein Magnetfeld, dass sich mit dem Erdmagnetfeld natürlich
überlagert.
Selbst wenn du also weisst wo Norden ist, ist beileibe nicht
sichergestellt, dass sich diese Richtung in deinen Daten auch mit exakt
einem Maximum in einem der X bzw. Y Werte bemerkbar macht.
Also erstmal danke für deine Hilfe - ich bin wie gesagt am
verzweifeln...
Zu den neuen Werten, die sich durch dein Script ergeben, nur für die
X-Achse:
Drehrichtung im Uhrzeigersinn:
0 --> 397
397 --> 0
65335 --> 65412
65421 --> 65335
Ich habe die Y-Werte noch nicht mit anzeigen lassen, denn ich glaube
erstmal ist wichtig zu wissen, ob die Werte Sinn machen, bevor ich
wieder alles durcheinanderbringe...
Marco He schrieb:> Also erstmal danke für deine Hilfe - ich bin wie gesagt am> verzweifeln...>> Zu den neuen Werten, die sich durch dein Script ergeben, nur für die> X-Achse:>> Drehrichtung im Uhrzeigersinn:>> 0 --> 397> 397 --> 0> 65335 --> 65412
Wie sehen die Bytes dazu aus? Sind die plausibel?
Mach mal:
Zu den neuen Werten, die sich durch dein Script ergeben, nur für die
X-Achse:
Drehrichtung im Uhrzeigersinn:
0 --> 400
400 --> 0
0 --> -105
-105 --> 0
Ja, die Bytes sehen plausibel aus, jedenfalls gibts keine wirren
Ausgaben, sondern saubere Werte zwischen 0x00 bis 0xFF.
Marco He schrieb:> Zu den neuen Werten, die sich durch dein Script ergeben, nur für die> X-Achse:>> Drehrichtung im Uhrzeigersinn:>> 0 --> 400> 400 --> 0> 0 --> -105> -105 --> 0
Da scheint aber ein ordentlicher Offset drinn zu sein.
Irgendwelche gröberen Metallteile in der Nähe?
Es wird Zeit die Y-Achse mit dazu zu nehmen. Ausgabe am besten: X und Y
in einer Zeile. Wenn die zu lang wird, dann die Byteausgabe wegzulassen.
Die Werte sehen ja erst mal von der Größenordnung her nicht schlecht
aus.
Marco He schrieb:> Herr schmeiß Hirn vom Himmel oder erschlag mich...>> Ich kenne printf zwar als Pendant zu cout, aber was mache ich hier schon> wieder falsch?>>
Wo ist denn der Format String.
Eine ganz simple Lösung wäre gewesen, die printf Anweisung zu
duplizieren, X gegen Y zu tauschen und in der 'X_Zeile' den
Zeilenvorschub \n gegen ein Leerzeichen zu tauschen. Minimaler Aufwand
und für ein Testsystem gut genug
Oh man... =(
Naja... so: Die Y-Werte drehen sich um 280, je nachdem, wie ruhig ich
den Sensor um die Hochachse drehe.
Die Bits sehen dabei auch wieder nicht wirr aus.
Marco He schrieb:> Oh man... =(>> Naja... so: Die Y-Werte drehen sich um 280, je nachdem, wie ruhig ich> den Sensor um die Hochachse drehe.
d.h. die bleiben immer so um die 280?
dann nimm mal die Z Achse dazu. Denn die Frage ist ja: welche beiden
Achsen hast du in deiner Haltung waagrecht zum Boden ausgerichtet.
Wir gehen immer davon aus, dass das die X und die Y Achse sein werden.
Muss aber nicht so sein.
Haa ich hab nen printf-Befehl selbst kopiert und verändert :D :D :D
X-Werte:
0 --> 400
400 --> 0
0 --> -105
-105 --> 0
Y-Werte:
~280, je nach ruhiger Hand beim Rotieren um die Hochachse
Z-Werte: Angefangen bei X=0, dann weiter wie oben
115 --> 163 --> -140
140 --> -370 --> -316
-316 --> -105
-105 --> 97
Also Wenn x = 0, dann zeigt Z 115,
Wenn x = 400, dann zeigt Z 140 usw...
Sind da Y und Z vertauscht?!
Was mich beim HMC5883L fast einen halben Tag gekostet hat, war die
Tatsache, dass die Daten nicht in XYZ angeordnet sind, sondern in XZY.
Den Fehler machst du offensichtlich auch gerade.
Da der Z Wert springt denke ich, dass das wirklich die Richtung zum
Boden ist. Die Frage ist jetzt nur: was ist mit deinem Y Wert los?
Sensor nicht in der Hand halten! Leg ihn auf den Tisch zum drehen. Damit
hast du auf einfachste Weise eine gleichbleibende Drehebene.
Verkippe mal den Sensor um 90°, so dass die Achse die vorher in den
Tisch reingegangen ist (und um die gedreht wird) sich jetzt in der Ebene
drehen kann. Aber so kippen, dass die vorhergehende Y-Achse jetzt in den
Tisch reinschaut.
-> X hat nach wie vor gleiches Verhalten, aber die Y und die Z Achse
tauschen die 'Plätze'. Hast du dann immer noch das Verhalten, dass eine
Achse ziemlich konstante Werte anzeigt und die andere Achse springt?
Da scheinen wirklich Y und Z vertauscht zu sein...
Karl Heinz schrieb:> Verkippe mal den Sensor um 90°, so dass die Achse die vorher in den> Tisch reingegangen ist (und um die gedreht wird) sich jetzt in der Ebene> drehen kann. Aber so kippen, dass die vorhergehende Y-Achse jetzt in den> Tisch reinschaut.
Dann bleibt Z relativ konstant und Y ändert fröhlich seine Werte :D
Ja.
Aber wenn du einigermassen langsam und konstant drehst, können die Werte
nicht so rasant springen.
Würde man die Werte jeder Achse plotten, müssten sich eigentlich 2
Sinuskurven ergeben, die um 90° phasenverschoben sind.
Also die Werte spingen ja nicht, sondern gehen schon fließend.
Ich habe nur die markanten Punkte hier aufgeschrieben.
Wenn ich mir zum beispiel die X-Achse nur von den werten her angucke,
würde ich schon eine Sinus-Form vermuten.
X-Werte:
0 --> 400 (Maximum)
400 --> 0
0 --> -105 (Minimum)
-105 --> 0
Die Kurve müsste ja um[(400 + 105)/2] = 252,5 schwingen.
Wenn ich die Werte jetzt in ne Textdatei ausgeben will,
wie stelle ich das am schlausten an?
Also wie lasse ich mir XMsb als geshifteten Wert mit dem Umweg über
(int)(int16_t) richtig ausgeben?
Über
ofstream Dateix ("")
{
Dateix << XMsb = ( XMsb << 8 ) | XLsb ) << endl;
}
würde mir ja diese Wandlung fehlen...
Du kannst natürlich über die Stream Funktionen gehen. Dazu sind sie da.
Trotzdem tendiere ich persönlich auch hier zu den alten C Mechanismen,
wenn ich schon selbst im Programm auf eine Datei schreiben will und
nicht einfach den redirect Mechanismus der Shell ausnutze.
Aber ehe du umbaust, probier doch einfach mal, ob dir deine Shell nicht
ganz simpel den Output in ein File redirecten kann.
heisst dein Programm "kompass" und startest du es in der shell mittels
1
kompass
dann probier einfach mal
1
kompass > Daten.txt
und sieh nach, ob eine derartige Datei erzeugt wird und die Ausgabe
deines Programms dorthin umgeleitet wurde.
Es gibt durchaus Dinge, in denen sind die textbasierten Shells jedem
Klickibunti System überlegen. Nur umgehen muss man eben damit können.
Ich hab leider null Plan von C, geschweige denn, was du mit starten aus
der Shell meinst.
Ich schreibe mein rudimentäres Wissen mit C++ in Codeblocks nieder und
starte meine Programme darüber... =/ ich komm mir echt bescheuert vor...
Karl Heinz schrieb:> Da scheint aber ein ordentlicher Offset drinn zu sein.> Irgendwelche gröberen Metallteile in der Nähe?
Metallteile in der Nähe verursachen beim Drehen keinen Offset. Dazu
müßte der Magnetfeldanteil schon auf dem Bord selbst entstehen und sich
mitdrehen.
Ein Kreis, ein Kreis, ein Kreis!!!
Endlich!
Hab an dem Output erwas zu knobeln gehabt, aber jetzt hab ich die Werte
mal geplottet!
Ich habe den Sensor dabei so liegen gehabt, dass die Y-Achse wieder in
den Tisch zeigt,
Karl Heinz schrieb:> Verkippe mal den Sensor um 90°, so dass die Achse die vorher in den> Tisch reingegangen ist (und um die gedreht wird) sich jetzt in der Ebene> drehen kann. Aber so kippen, dass die vorhergehende Y-Achse jetzt in den> Tisch reinschaut.>> -> X hat nach wie vor gleiches Verhalten, aber die Y und die Z Achse> tauschen die 'Plätze'.
Gibt mir das den Offset?
Marco He schrieb:> Gibt mir das den Offset?
Logisch. Der Anteil, der sich beim drehen nicht ändert, ist der Offset,
d.h. x0=130, y0=-615, z0=0
Marco He schrieb:> Hab an dem Output erwas zu knobeln gehabt.
Prima, besonders der X-Z Plot. Was hast du geändert?
Der output wollte mit "w" nicht gelingen, sondern nur mit "a" für
append.
Und ich habe mir nur die Zahlen ausgeben lassen, ein Wert pro Zeile.
War für mich als C-neuling mit ein wenig Recherche verbunden, aber das
war nicht mehr schlimm, als ich wieder etwas mehr Geduld hatte.
Den Offset würde ich jetzt einfach mit den Wertepaaren der Achsen
verrechnen.
Also X - 130, Y + 615
Jetzt aber folgende Wissenslücke:
Wir wandeln doch (int)(int16_t)(( XMsb << 8 ) | XLsb ) );
Nur dadurch erhalten wir doch überhaupt erst unsere Werte.
Wenn ich jetzt aber sage Xoffset = ((int)(int16_t)(( XMsb << 8 ) | XLsb
) ); wie muss ich dann Xoffset als Variable deklarieren?
Als int16_t?
Habe jetzt den Code etwas angepasst und den Offset wie beschrieben
reingerechnet.
Ich werde mir hoffentlich heute nachmittag, spätestens morgen nachmittag
die Werte nochmal Plotten und die neuen Ergebnisse sowie den aktuellen
Code posten.
Die xwerte springen noch etwas herum, die ywerte laufen schonmal sauber.
Ich bin gespannt, was die neuen Plotts zeigen!
Hey!
Es ist vollbracht!
Ich habe endlich einen Ursprungskreis!
Eine Winkelberechnung mit atan2 und einer Umrechnung wegen
Vorzeichenwechsel ergibt jetzt eine fortlaufende Gradangabe von 0 bis
360 mit einer Abweichung von -11 Grad zur Angabe meines Kompass im
Handy.
Ich werde also mit dem Offset noch minimal herumspielen und dann sollte
die Gradanzeige gut arbeiten!
Jetzt muss ich mal gucken, ob ich den Neigungsfehler, wenn das Modul
nicht 100%ig gerade ausgerichtet ist, auch noch rausgerechnet bekomme.
Eine Formel habe ich dazu schon, nur kann ich die erst später
ausprobieren. Muss jetzt erstmal wieder zur Spätschicht...
Ich melde mich spätestens morgen Mittag wieder!
Marco He schrieb:> Jetzt muss ich mal gucken, ob ich den Neigungsfehler, wenn das Modul> nicht 100%ig gerade ausgerichtet ist, auch noch rausgerechnet bekomme.
Da brauchst du deinen 3D-Magnetfeldvektor und den Schwerkraftvektor vom
Beschleunigungssensor. Der Magnetfeldvektor wird auf die
Schwerkraft-Normalenebene projiziert und dann hast du die Komponenten
für die Azimut-Berechnung.
Hey Hey!
Also ich habe das Kompassmodul nun auf nahezu 0 Grad abweichung
gefummelt.
Klar gibt es eine minimale Abweichung, aber ich will ja keine
hochpräzise Anlage entwickeln :D
Danke erstmal dafür an alle, die mich angeleitet haben!!!!
Jetzt knobel ich ein wenig am ADXL345 3-Achs-Beschleunigungsaufnehmer,
um hinterher die Tilt-Kompensation zu realisieren.
Ich bekomme die Register ausgelesen und erhalte auch Werte, jedoch bin
ich mir nicht sicher, ob eine exakte Kalibrierung notwendig ist, sodass
wieder alle drei Vektoren einen gemeinsamen Nullpunkt haben oder ob ich
nicht einfach über die Verhältnisse der Achsen gehen kann.
Hier mal meine min / max - Werte:
x min -445
x max 578
y min -512
y max 422
z min 530
z max 1152
Die Winkel ergeben sich ja nachher aus atan2(y,z) und atan2(x,z)...
Ich würde jetzt die Min-Werte einfach über den Offset auf Null setzen
uind die Idee war dann, zB x ins Verhältnis zu Z zu setzen und mit dem
Wert den Winkel auszurechnen. Nur wo liegt mein Denkfehler?
Mit dem Taschenrechner bekomme ich es nicht sinnvoll hin, die Achsen so
zu skalieren, dass ich damit rechnen kann...
Wenn ich jetzt schon die atan2 anwende und von Rad in Grad umrechne,
komme ich auf Winkel zwischen -15 und 22 Grad statt 0 (Horizontal) und
90 (senkrecht) Grad.
Hier kommt mein Code:
1
#include <stdlib.h>
2
#include <iostream>
3
#include <wiringPi.h>
4
#include <wiringPiI2C.h>
5
#include <inttypes.h>
6
#include <fstream>
7
#include <cmath>
8
9
10
using namespace std;
11
int8_t fd;
12
int xmsbacc, xlsbacc, ymsbacc, ylsbacc, zmsbacc, zlsbacc, xrawacc, yrawacc, zrawacc,