Magnetometer Compass

Wer schon einmal mit dem Gedanken gespielt hat, einen kleinen Fahrroboter zu bauen, der wird sich sicherlich Gedanken über die Positionierung gemacht haben. Neben dem GPS benötigt man eine weitere Komponente, welche sicherlich genau so wichtig ist: dem Kompass. Man braucht ihn, damit der Roboter weis, in welche Richtung er gerade schaut. Ohne diesen müsste er sich nur mit dem GPS in eine beliebige Richtung bewegen, aus der man anschließend den Kurs bestimmen müsste.

Ich möchte in diesem Beitrag zeigen, wie man das mit einem HMC5883L-Modul einfach und schnell schaffen kann. Außerdem habe ich noch eine größere Erweiterungen parat, welche ich ebenfalls präsentieren werde. Hierfür benötigt man neben dem Kompass auch einen Schrittmotor (hier bereits gezeigt).

Das Modul

Bei dem Modul HMC5883L handelt es sich um ein preiswertes, baukleines Magnetometer, welches mit dem Mikrocontroller via I²C kommunizieren kann. Hierfür benötigt man die Wire.h Programmbibliothek, welche mit der Arduino IDE mit installiert wird. Dazu mehr bei der Code-Erklärung. Das Modul habe ich auf eBay um 1€ neu gekauft, sogar mit kostenlosen Versand!

Compass

Bei meinem Modul habe ich darauf geachtet, dass es einen Spannungsregler verbaut hat, sodass ich es in einem Bereich von 3.3V bis 5V betreiben kann. Laut Hersteller lässt sich eine Genauigkeit von 1 – 2 Grad Kurs errechnen.

Doch wie funktioniert das Modul? Wie bereits erwähnt, handelt es sich hierbei um ein Magnetometer. Dieses misst die Flussdichte des magnetischen Feldes der Erde. Hierfür werden dünne Nickel-Eisen Streifen als Widerstandselement verbaut. Legt man nun Spannung an und setzt diese Streifen einem Magnetfeld aus, so ändert sich der Brückenwiderstand. Man misst das Magnetfeld also als Spannungsänderung. Diese Elemente sind so aufgebaut, dass sich 3 verschiedene Achsen ergeben (x, y, z). Diese sind auch dementsprechend auf der Platine gekennzeichnet.

Axis

Das Modul verfügt über 3 Betriebsmodi. Continous-Mode, Single-Mode und Idle-Mode. Bei ersterem sendet das Modul durchgehend seine Daten. Beim Single-Mode sendet es nur einmal den Messwert und versetzt sich dann in den Idle-Mode. Dieser ist vergleichbar eines Energiesparzustandes. Das Modul eignet sich also auch perfekt für Anwendungen abseits dauerhaft verfügbarer Spannungsquellen.

Übrigens: Das Modul wird auch in manchen Handys, Tablets oder anderen mobilen Geräten verwendet.

Der Aufbau

Viel bedarf es nicht, lediglich dem Arduino (UNO oder Nano), dem Kompass einem Steckbrett, und (optional) einem kleinen I²C Display, welches ich hier bereits vorgestellt habe. Wer direkt die Programmbibliothek für das kleine OLED Display herunterladen möchte, der kann dies hier tun.

Compass+Display

Bei der Verdrahtung muss man sich an die Regeln des I²C-BUS halten. Dieses BUS-System nutzt lediglich 2 Datenleitungen, um Daten zu senden und zu empfangen. Insgesamt benötigt man jedoch 4 Kabel, denn die Geräte müssen mit Spannung versorgt werden (Vcc & GND).

Bei diesem Projekt lässt sich auch gleich der Vorteil des BUS-Sytsems erkennen. Ich habe zwei I²C-Module einfach miteinander verbunden. So kann man mit wenig Aufwand viele Geräte betreiben, ohne dabei wichtige Pins zu belegen.

Die Anschlüsse müssen wie folgt miteinander verbunden werden:

  • SDA ⇒ Arduino Pin A4
  • SCL ⇒ Arduino Pin A5
  • Vcc ⇒ Arduino +5V
  • GND ⇒ Arduino Ground
Sollte es dennoch etwaige Unstimmigkeiten geben, findet man hier die schematische Zeichnung sowie das Steckbrett.
,
Magnetometer_Compass_Schaltplan
,
Magnetometer_Compass_Steckplatine

Das Programm

Das Programm findet man auf GitHub.

Zuerst möchte ich die Datei Magnetometer_Compass.ino vorstellen, die Erweiterung folgt zum Schluss.

Die ersten paar Zeilen dienen der Festlegung der Adressen des Kompass-Modules. Wichtig ist vor allem die Hauptadresse des HMC5883. Diese ist einmalig, sodass man das Modul auch dann noch verbinden kann, wenn auch mehrere I²C Geräte angeschlossen sind.

#define HMC5883L_Address             0x1E
#define HMC5883L_Mode_Register       0x02
#define HMC5883L_Continuous_Mode     0x00
#define HMC5883L_Data_Output_Address 0x03

In der loop() wird der Winkel stetig zur Ausgabe gebracht. Dies habe ich über 2 „Timer“ gelöst, da ich den Bildschirm schneller aktualisieren will, als ich die Daten in den seriellen Monitor schreibe. Ist das Projekt in Betrieb, und hat man den seriellen Monitor gestartet, so sollte man folgenden Datenstrom erkennen.

Serial_Monitor

Das Arduino sendet also konsequent die magnetische Flussdichte aller 3 Hauptachsen, sowie den daraus errechneten Kurs.

In der Funktion readHMC5883L() werden lediglich die Messdaten des Moduls aufgerufen. Jede Achse hat 2 Register (LSB & MSB). Aus diesem Grund muss man auch insgesamt 6 Messwerte einlesen.

if(6 <= Wire.available())
{
    compass.X_Axis  = Wire.read() << 8 | Wire.read();
    compass.Z_Axis  = Wire.read() << 8 | Wire.read();
    compass.Y_Axis  = Wire.read() << 8 | Wire.read();
}

Kommen wir nun zur wichtigsten Funktion, der getAngle(). Natürlich müssen zuerst die Daten vom Sensor ausgelesen werden, doch dann beginnt der eigentliche Spaß an der Sache. Man muss sich überlegen, wie man aus der magnetischen Flussdichte den Kurs errechnen kann.

Heading

Aus der Grafik, welche die Erde darstellen soll, lässt sich erkennen, dass sich dies mit Hilfe des Arkustangens bewerkstelligen lässt. Erhält man beispielsweise als Datenwert für x=1 und für y=1.7235 (Wurzel aus 3), so erkennt man, dass der Arkustangens den Wert 1.0472 (PI / 3) zurückgibt.

float Angle = atan2(-compass.Y_Axis, compass.X_Axis);

Das Ergebnis erhält man in Radiant. Für eine sinnvolle Kursangabe benötigt man den Wert jedoch in Grad. Die Umrechnung ist hier sehr einfach, denn

GRAD = RADIANT * (180 / PI)

Und schon hat man den Kurs im Bereich von -180° bis 180° berechnet. Um das auf das etwas leserlichere Format von 0° bis 360° zu bringen, muss man den Winkel, sofern er kleiner als Null ist, einfach mit 360 addieren.

if (Angle < 0)
    Angle += 360;

Nun könnte man das Ergebnis auch dabei belassen, wenn es da nicht auch noch die Missweisung gäbe. Das Erdmagnetfeld verläuft nicht konstant von Süd- nach Nordpol. Es ändert seinen Winkel immer wieder etwas. Des weiteren liegen magnetischer Nordpol und geografischer Nordpol nicht übereinander. Aus diesem Grund existiert für jeden Ort auf der Welt eine Deklination. Man kann diese für seine aktuelle Position auf der folgenden Webseite herausfinden: http://magnetic-declination.com/

Deklination

Quelle: Wikipedia

Die Missweisung wird in Grad und Minuten angegeben. Um sie korrekt zum Winkel addieren zu können, muss man diese in Grad umrechnen. Die Grade können auch negativ sein (Ost = positiv, West = negativ) und müssen auch dementsprechend eingesetzt werden.. Dazu gibt es die folgende Formel:

(DEGREE + (MINUTES / 60)) / (180 / PI)

Zur besseren Übersicht habe ich die Grade und die Minuten als eigene Variable deklariert.

byte  Declination_Degree = +3;
byte  Declination_Minute = 57;
float Declination = (Declination_Degree + (Declination_Minute / 60)) / (180 / M_PI);
Angle += Declination;

Das wars. So einfach kann man sich selbst einen kleinen Kompass bauen!

Erweiterung

Hier möchte ich mit einem Schrittmotor eine Kompassnadel simulieren. Dazu habe ich die selbe selbst gebastelte Gradscheibe genutzt, wie ich sie im hier beschriebenen Tutorial bereits verwendet habe. Auch die Verdrahtung des Schrittmotors mit dem Arduino ist ident:

  • IN1 ⇒ Pin 2
  • IN2 ⇒ Pin 3
  • IN3 ⇒ Pin 4
  • IN4 ⇒ Pin 5

Es ist quasi nur eine Erweiterung des Schrittmotors um einen Kompass.

Compass+Stepper

Wenn alles zusammengebaut ist, sollte es so ähnlich aussehen. Das kleine Board ganz rechts auf dem Steckbrett ist ein MPU6050 Beschleunigungssensor. Diesen werde ich demnächst einmal näher beschreiben.

Das Programm besteht nun aus zwei kombinierten Programmen. Zum einen aus der Goto_Position.ino und zum anderen aus der Magnetometer_Compass.ino. Zusammen ist aus beiden das hier beschriebene File Magnetometer_Compass_With_Stepper.ino entstanden.

Ist das Programm auf das Arduino übertragen, so wartet dieses auf die momentane Position des Schrittmotors in Grad (0° – 360°), denn das Arduino kann ja nicht wissen, wo der Zeiger gerade steht. Erst wenn die Position via seriellen Monitor übertragen wurde, beginnt das Arduino den Zeiger auf die vom Kompass ermittelte Position zu drehen.

Das war’s. Einfach eine kleine Spielerei!

Advertisements

4 Gedanken zu “Magnetometer Compass

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s