Einen Feelspace Belt mit Arduino bauen und programmieren (Teil 3): GY-271 und HMC/QMC5883L

In diesem Teil beschäftigen wir uns nun mit den Daten aus dem Kompasssensor, die wir benötigen, um unsere Motoren immer gen Norden vibrieren zu lassen. Und hier lernen wir zunächst, dass es manchmal durchaus sinnvoll sein kann, lieber gleich bei namhaften Herstellern zu kaufen. Ich bestellte nämlich ursprünglich ein generisches GY-271 Breakout Board aus Hong Kong, das normalerweise mit einem HMC5883L Chip bestückt ist. Ich bekam aber auf Gedeih und Verderben mit keiner Bibliothek und keinem Code aus dem Internet Signale ausgelesen. Frustriert gab ich auf und bestellte einen generischen MPU9250 aus China. Und was geschah? Auch nicht auslesbar. Das ist das Problem mit Knockoff-Bauteilen aus China: Man kann sich selten darauf verlassen, dass auch drin ist, was draufsteht. Zwar zahlt man nur einen Bruchteil des Geldes, handelt sich aber wochenlange Wartezeiten und gelegentlich Chips ein, die einfach nicht sind, was sie vorgeben zu sein. Das Skurrilste am „MPU9250“ Board war, dass ich herausfand, dass es auch die Temperatur misst. Das war aber auch alles an Daten, was ich (absolut zuverlässig) heraus bekam.

An dieser Stelle kann es sich lohnen, einen I2C-Scan laufen zu lassen, den findet man hier bei Arduino direkt. Der ergab bei meinem angeblichen „GY-271/HMC5883L“ eine Registeradresse, 0x0D. Als ich beides zusammen googlete, beförderte ich massenweise Forenthreads von frustrierten Bastlern zutage, die mit dem bei Amazon ausgesprochen häufig verkauften China-Modul Probleme hatten. Ein User, dem mein ewiger Dank nachschleichen wird, stellte fest, dass bei einer Serie ein QMC statt ein HMC Chip verbaut wurde (eine andere Serie scheint komplett unbrauchbar zu sein). Diese hatte eben die Adresse 0x0D. Besagter User hat entsprechend eine passende Bibliothek geschrieben, an der wir uns nun orientieren werden: Hier der Link.

Das GY-271 ist ein dreiachsiges Magnetometer, es misst entsprechend Tesla (ja, genau der mit den Blitzspulen!), die magnetische Flussdichte, und zwar auf der X-, Y- und Z-Achse. Uns interessiert erst einmal nur eine einzige Achse. Welche das ist, hängt maßgeblich davon ab, wie herum ihr später den Sensor anbringt. Auf jeden Fall haben wir jetzt einen digitalen Kompass.

Hookup für meinen Knockoff-GY271 mit falschem QMC5883L ist allerdings identisch. VCC auf 5V, GND auf GND, SDA auf A4, SCL auf A5. Wir kommunizieren über das I2C-Protokoll, mit dem man mehrere Module hintereinander schalten kann. SDA ist in dem Fall der serielle Datenkanal, SCL steht für Serial Clock, denn Timing ist für die Signalübertragung nun einmal entscheidend. Um das Signal zu verbessern, schalten wir zwei Pullup-Widerstände zu 5k Ohm in diese Leitungen.

Hier dann noch der Code, um die Daten aus diesem China-Imitat auszulesen und direkt in eine Gradangabe umzuwandeln:

#include <Wire.h>
#include <MechaQMC5883.h>

MechaQMC5883 qmc;

void setup() {
 Wire.begin();
 Serial.begin(9600);
 qmc.init();
 //qmc.setMode(Mode_Continuous,ODR_200Hz,RNG_2G,OSR_256);
}

void loop() {
 int x, y, z;
 int azimuth;
 //float azimuth; //is supporting float too
 qmc.read(&x, &y, &z);
 //azimuth = qmc.azimuth(&y,&x);//you can get custom azimuth
 Serial.print("x: ");
 Serial.print(x);
 Serial.print(" y: ");
 Serial.print(y);
 Serial.print(" z: ");
 Serial.print(z);
 Serial.println();

float heading = atan2(x, y);

// Set declination angle on your location and fix heading
 // You can find your declination on: http://magnetic-declination.com/
 // (+) Positive or (-) for negative
 // For Bytom / Poland declination angle is 4'26E (positive) for Kiel +2,49°
 // Formula: (deg + (min / 60.0)) / (180 / M_PI);
 float declinationAngle = (2.0 + (49.0 / 60.0)) / (180 / M_PI);
 heading += declinationAngle;

// Correct for heading < 0deg and heading > 360deg
 if (heading < 0)
 {
 heading += 2 * PI;
 }

if (heading > 2 * PI)
 {
 heading -= 2 * PI;
 }

// Convert to degrees
 float headingDegrees = heading * 180/M_PI;

// Output
 Serial.print(" Heading = ");
 Serial.print(heading);
 Serial.print(" Degress = ");
 Serial.print(headingDegrees);
 Serial.println();

 delay(1000);
}

Ein paar Hinweise noch: Je nachdem, in welche Richtung der Chip montiert wurde, müssen natürlich die Variablen für die float heading Berechnung (x,y) eventuell durch andere ersetzt werden. Wie im Quelltext schon steht, sollte man der Präzision wegen seine magnetische Deklination in Erfahrung bringen. Das kann man unter Angabe der Stadt bei www.magnetic-declination.com, in meinem Fall ist es Kiel mit 2’49°. Der delay am Schluss ist nur auf 1000ms gesetzt, um die Beobachtung der Messergebnisse einfacher zu machen, er kann für den Betrieb deutlich herabgesetzt werden.

Was bei Beobachtung der Messergebnisse schnell auffällt, ist, dass die Gradangaben natürlich deutlich unpräziser ausfallen und schwanken, wenn das Magnetometer in eine bestimmte Richtung gekippt oder erschüttert wird. Dafür muss ich mir noch etwas einfallen lassen.

So, nun haben wir alle Einzelteile zusammen und programmiert. Im nächsten Teil basteln wir das gesamte Gerät zusammen und gehen in den Selbstversuch!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*