PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Kompass GY-271 am Arduino



basteluwe
12.11.2017, 16:31
Hallo Gemeinde,
ich versuche brauchbare Ergebnisse mit einem GY-271 Kompass-Modul am Arduino zu erzielen und habe dazu zwei Fragen.
33044
Zuerst aber der Stand: Mein Modul ist offensichtlich nicht das Original, sondern ein Clone. Es reagiert auf die I2C Adresse 0x0D (normal wäre wohl 0x1E). Nach längerer Suche im Netz und ausprobieren mehrerer Scripte, habe ich jetzt zumindest eine halbwegs brauchbare Funktion gefunden.
Das Script sieht im Moment so aus:

#include <Wire.h> // I2C Arduino library

#define addr 0x0D // unusual I2C address for compass module!

void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(addr); // start talking
Wire.write(0x0B); // tell the HMC5883 to continuously measure
Wire.write(0x01); // set the register
Wire.endTransmission();
Wire.beginTransmission(addr);
Wire.write(0x09);
Wire.write(0x1D);
Wire.endTransmission();
}

void loop() {

int x, y, z; // triple axis data
Wire.beginTransmission(addr); // tell the HMC what regist to begin writing data into
Wire.write(0x00); // start with register 3.
Wire.endTransmission();

Wire.requestFrom(addr, 6); // read the data.. 2 bytes for each axis.. 6 total bytes
if (6 <= Wire.available())
{
x = Wire.read(); // MSB x
x |= Wire.read() << 8; // LSB x
z = Wire.read(); // MSB z
z |= Wire.read() << 8; // LSB z
y = Wire.read(); // MSB y
y |= Wire.read() << 8; // LSB y
}
int angle = atan2(-y , x) / M_PI * 180; // angle is atan(-y/x)
if(angle < 0) angle = angle + 360; // angle from 0 to 359 instead of plus/minus 180


Serial.println(angle);
delay(1000);

}

Meine erste Frage bezieht sich auf das Script, speziell die beiden farblich (rot/grün) markierten Teile. In allen anderen, von mir getesteten Scripts ist jeweils nur ein solcher Block enthalten. Hier sind es zwei, die gleich aussehen, aber verschiedenen Adressen benutzen. Ich habe versucht jeweils einen davon wegzulassen, dann funktioniert das Script nicht mehr. Die Frage ist also: Warum wird das hier zweimal gebraucht und was genau macht das?

Die zweite Frage ist bezüglich der Arbeitslage des Moduls. In diversen Tutorials sehe ich die Module immer flach auf dem Tisch liegen. In dieser Lage bringt mein Script nur Werte zwischen 68 und 133 Grad, die nichts mit der realen Richtung zu tun haben.
Nur wenn ich mein Modul senkrecht stelle, wie auf dem Foto unten, erhalte ich Werte zwischen 0 ond 360 Grad, die in etwa der realen Himmelsrichtung entsprechen. Kann das Normal sein?
33045
Wenn er so senkrecht steht, sind die Werte halbwegs logisch!?

Für Ideen wäre ich sehr Dankbar.
Gruß Uwe

Sisor
12.11.2017, 20:54
Zu Frage 1:
Mit den rot/grünen Befehlen wird der Sensor eingestellt ( 1.Wert: Registeraddresse, 2.Wert: Registerwert).
Was da gemacht wird kannst du im Chip-Datenblatt (https://github.com/e-Gizmo/QMC5883L-GY-271-Compass-module/raw/master/QMC5883L%20Datasheet%201.0%20.pdf) erfahren:

Control Register 09H, Wert 1DH:

Mode: Continuous
Output Data Rate: 200Hz
Full Scale: 8Gauss
Over Sample Ratio: 512

Set/Reset Period Register 0BH:

Setzen der Periode -> 1 startet Messungen

Zu Frage 2:

Wenn du

if (6 <= Wire.available())
{
x = Wire.read(); // MSB x
x |= Wire.read() << 8; // LSB x
z = Wire.read(); // MSB z
z |= Wire.read() << 8; // LSB z
y = Wire.read(); // MSB y
y |= Wire.read() << 8; // LSB y
}
int angle = atan2(-y , x) / M_PI * 180; // angle is atan(-y/x)
in
if (6 <= Wire.available())
{
x = Wire.read(); // MSB x
x |= Wire.read() << 8; // LSB x
y = Wire.read(); // MSB y
y |= Wire.read() << 8; // LSB y
z = Wire.read(); // MSB z
z |= Wire.read() << 8; // LSB z
}
int angle = atan2(y , x) / M_PI * 180; // angle is atan(y/x)
änderst, sollte das auf dem Board aufgedruckte Koordinatensystem verwendet werden.

Klebwax
13.11.2017, 01:04
ich versuche brauchbare Ergebnisse mit einem GY-271 Kompass-Modul am Arduino zu erzielen und habe dazu zwei Fragen.

Zuerst aber der Stand: Mein Modul ist offensichtlich nicht das Original, sondern ein Clone. Es reagiert auf die I2C Adresse 0x0D (normal wäre wohl 0x1E).
Clone ist nicht der richtige Begriff hier. Der original GY-271 war mit dem HMC5883L von Honeywell bestückt. Der hat die Adresse 0x1e, wird aber nicht mehr hergestellt. Es gibt aber einen ähnlichen Chip, den QMC5883L. Dieser hat nicht nur eine andere I2C Adresse sondern auch eine andere Registerbelegung, ist aber Pinkompatibel. Es gibt daher Module, die mit HMC5883L beschriftet aber mit dem QMC bestückt sind (es waren wohl noch viele Platinen übrig). Da die Register der Chips aber komplett unterschiedlich sind, funktioniert eine Library für den HMC5883L nicht mit dem QMC5883L, selbst wenn man die I2C Adresse ändert. Zur Sicherheit sollte man sich die Pinbeschriftung in den beiden Datenblättern ansehen und mit dem eigenen Modul vergleichen. Mit der zum Chip passenden Library sollte es funktionieren, wenn man nicht sowieso etwas eigenes schreiben will.

MfG Klebwax

Rabenauge
13.11.2017, 14:57
Hallo Uwe.
Ja, mit dem Gy271 hatte ich auch schon sehr viel "Spass".
Meiner lief dann irgendwann, und das, auch liegend.
Eine gute Anleitung, um das Ding überhaupt erst mal auf brauchbare Werte zu kalibrieren, gibts hier (http://diydrones.com/profiles/blogs/advanced-hard-and-soft-iron-magnetometer-calibration-for-dummies)

Ohne diese Kalibrierung ist das Teil nahezu unbrauchbar. Der Bursche ist so empfindlich, dass ihn alles Mögliche stört-selbst, mittig aufm Steckbrett montiert, klappte es nur "so halbwegs". Wenn die Kalibrierung aber mal erfolgt ist, geht er ziemlich gut.
Und keine Sorge: die muss man nur dann mal neu machen, wenn sich am Einbau was ernsthaftes ändert, da laufend mit den Korrekturdaten (die man mit der Mehtode ermittelt) gerechnet wird..

basteluwe
16.11.2017, 17:50
Jetzt bin ich erst mal geplättet!
Ich war der Meinung, auf Eure Antworten vorgestern umfangreich geantwortet zu haben und sehe nun, mein Post ist gar nicht da!
Seltsam, aber wohl meine eigene Schussligkeit. Irgendwo hab ich wohl einen falschen Klick gemacht :(
Nun also nochmal:
Dank Sisors excellenter Antwort geht nun alles. Das Ändern der Reihenfolge X,Z,Y in X,Y,Z und die Anpassung der Formel haben es tatsächlich gebracht. Danke dafür!
Was ich aber immer noch nicht verstehe ist dieser Codeteil:

Wire.beginTransmission(addr); // start talking
Wire.write(0x0B); // tell the HMC5883 to continuously measure
Wire.write(0x01); // set the register
Wire.endTransmission();
Wire.beginTransmission(addr);
Wire.write(0x09);
Wire.write(0x1D);
Wire.endTransmission();
Warum läuft mein Script nur mit den beiden Codeteilen (rot+grün) zusammen, wenn z.B. hier (https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=172244) (Siehe Post vom User kumardas) das selbe Script NUR mit dem grünen Teil funktioniert. Offensichtlich braucht man den roten Teil unter bestimmten Bedingungen nicht!?
Ich würde das einfach nur gern verstehen ;)
Gruß Uwe

Klebwax
17.11.2017, 06:28
Ich würde das einfach nur gern verstehen ;)
Gruß Uwe

Da werden zwei Register gesetzt, einmal das mit der Adresse 0x0B (SET/RESET Period Register) und dann das mit der Adresse 0x09 (Control Register 1). Die Bedeutung der einzelnen Werte stehen im Datenblatt.

Und noch einmal der Hinweis, findet sich auch in deinem Link


I've just bought of few of these and found the '5883' IC is a QMC5883 which has different registers. The datasheet is here:

Also das richtige Datenblatt benutzen

MfG Klebwax

basteluwe
18.11.2017, 15:57
Da werden zwei Register gesetzt, einmal das mit der Adresse 0x0B (SET/RESET Period Register) und dann das mit der Adresse 0x09 (Control Register 1). Die Bedeutung der einzelnen Werte stehen im Datenblatt.

Ja, die Register hab ich im Datenblatt gefunden und das Setzen von 0x0B und 0x09 leuchtet mir auch ein.
Warum das Script in dem Link (kumardas) bei gleichem Chip angeblich auf das Setzen von 0B verzichten kann, versteh ich zwar immer noch nicht, aber vielleicht geht's ja auch gar nicht wirklich.
Egal, meins läuft jetzt ja und damit schließ ich das dann mal ab.

Danke und Gruß Uwe

Klebwax
18.11.2017, 19:10
Ja, die Register hab ich im Datenblatt gefunden und das Setzen von 0x0B und 0x09 leuchtet mir auch ein.
Warum das Script in dem Link (kumardas) bei gleichem Chip angeblich auf das Setzen von 0B verzichten kann, versteh ich zwar immer noch nicht, aber vielleicht geht's ja auch gar nicht wirklich.

Sowas soll vorkommen. Das Internet ist voll von nicht funktionierendem Code, der selten korrigiert wird. Hier könnte es so sein: der Chip, und nicht nur dieser, arbeitet völlig unabhängig von der CPU. Er kann daher in einem früheren Versuch mit der SW richtig eingestellet worden sein und behält diesen Zustand, solange er genügend Versorgungsspannung hat. Es ist daher immer hilfreich vor einem Softwaretest die Spannung einmal abzuschalten oder, wie hier z.B. möglich, beim Initialisieren einen Reset des Chips zu programmieren. Dann sieht man, ob man den Chip richtig initialisiert hat.

Was mir an dem Code auch auffällt, daß nie, noch nicht mal beim Senden der I2C Adresse, auf ACK/NAK geprüft wird. Wenn man doch ein Modul mit dem HMC erwischt oder der I2C Bus ein Problem hat, werden munter sinnlose Ergebnisse produziert ohne daß es auffällt. Außerdem steht in den Kommentaren HMC obwohl der Code offensichtlich für den QMC ist. Wer ihn versucht nachzuvollziehen landet beim falschen Datenblatt.

MfG Klebwax

basteluwe
19.11.2017, 14:14
Er kann daher in einem früheren Versuch mit der SW richtig eingestellet worden sein und behält diesen Zustand, solange er genügend Versorgungsspannung hat.
Über genau DAS Problem bin ich selbst auch bei der ganzen Fummelei gestolpert. Die Schaltung hing permanent über USB am Computer, also eigentlich immer unter "Saft". Bei mancher SW Änderung hatte ich dann nach einfachem Reset das Ergebnis "A", aber nach echtem Power OFF/ON Ergebnis "B". ;)
Man lernt halt nie aus.

Gruß Uwe