Mit dem Magnetfeldsensor HMC5883L (auf dem GY-271 Breakoutboard) bauen wir uns heute einen digitalen Kompass, zusätzlich zur besseren Visualisierung verwenden wir ein 1.8 Zoll TFT-Display und natürlich einen Arduino.

Digitaler Kompass: HMC5883L (GY-271), TFT (HY-1.8) und ein Arduino – blog.simtronyx.de
Schaltplan
Zuerst verdrahten wir unsere Komponenten nach folgender Tabelle/Schaltplan:
Arduino (Nano, Uno, Pro Mini) |
HMC5883L GY271-Breakoutboard |
TFT-Display HY-1.8 SPI |
5V (VCC) | VCC | VCC, LED+ VCC |
GND | GND | GND, LED- GND |
A4 (SDA) | SDA | |
A5 (SCL) | SCL | |
D9 | A0 | |
D10 | CS | |
D11 | SDA | |
D13 | SCK | |
D8 | RESET |
mit der Maus über Elemente fahren (oder im Touch-Modus: Elemente antippen)...
Sketch
Nun installieren wir noch eine Bibliothek für die Verwendung des HMC5883L und laden anschließend folgenden Sketch auf unseren Arduino:
#include <Wire.h> // Wire-Bibliothek - fuer I2C #include <HMC5883L.h> // HMC5883L-Bibliothek #define cs 10 // Arduino-Pin an Display CS #define dc 9 // Arduino-Pin an Display A0 #define rst 8 // Arduino Reset-Pin #include "Adafruit_GFX.h" // Adafruit Grafik-Bibliothek #include "Adafruit_ST7735.h" // Adafruit ST7735-Bibliothek #include <SPI.h> Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst); // Display-Bibliothek Setup HMC5883L compass; int error = 0; void setup(void){ Serial.begin(9600); Wire.begin(); // HMC5883L compass = HMC5883L(); error=compass.SetScale(1.3); if(error!=0)Serial.println(compass.GetErrorText(error)); Serial.println("Setting measurement mode to continous."); error=compass.SetMeasurementMode(Measurement_Continuous); if(error != 0)Serial.println(compass.GetErrorText(error)); // Display tft.initR(INITR_BLACKTAB); tft.setTextWrap(true); display_show(); } // Deklination (siehe Text) hier fuer Berlin 3" 19' = 0.0578 rad float declinationAngle=0.0578; float heading_degrees=0; float heading_degrees_old=360; float heading_degrees_correction=-90; float heading_correction=heading_degrees_correction*M_PI/180; void loop(void){ MagnetometerScaled scaled=compass.ReadScaledAxis(); float heading=atan2(scaled.YAxis,scaled.XAxis); heading+=declinationAngle; if(heading<0)heading+=2*PI; if(heading>=2*PI)heading-=2*PI; heading_degrees=heading*180/M_PI+heading_degrees_correction; if(heading_degrees<0)heading_degrees+=360; if(heading_degrees>=360)heading_degrees-=360; if(heading_degrees!=heading_degrees_old){ display_info(); display_graphic(); heading_degrees_old=heading_degrees; } delay(250); } // Ausgabe TFT-Display #define cx 64 #define cy 80 #define cr 45 #define cb 5 void display_show(){ tft.fillScreen(ST7735_BLACK); set_text(14,3,"Digitaler Kompass",ST7735_BLUE,1); set_text(14,149,"blog.simtronyx.de",ST7735_GREEN,1); set_text(59,17,"N",ST7735_WHITE,2); set_text(59,130,"S",ST7735_WHITE,2); set_text(4,74,"W",ST7735_WHITE,2); set_text(114,74,"O",ST7735_WHITE,2); tft.drawCircle(cx,cy,cr+1,rgb565(128,128,128)); tft.drawCircle(cx,cy,cr-1,rgb565(128,128,128)); tft.drawCircle(cx,cy,cr,ST7735_WHITE); } void display_graphic(){ int m=0; int h=heading_degrees_old+90; tft.drawLine((int)cx,(int)cy,(int)(cx+(cr-4)*cos(M_PI/180*h)),(int)(cy-(cr-4)*sin(M_PI/180*h)),ST7735_BLACK); h=heading_degrees+90; tft.drawLine((int)cx,(int)cy,(int)(cx+(cr-4)*cos(M_PI/180*h)),(int)(cy-(cr-4)*sin(M_PI/180*h)),ST7735_WHITE); } void display_info(){ int h=heading_degrees_old; String s=String((int)h); set_text(103+(h<10?12:(h<100?6:0)),24,String((int)h),ST7735_BLACK,1); tft.write(247); h=heading_degrees; s=String((int)h); set_text(103+(h<10?12:(h<100?6:0)),24,s,rgb565(40,40,40),1); tft.write(247); } void set_text(int x,int y,String text,uint16_t color,byte size){ tft.setTextSize(size); tft.setCursor(x,y); tft.setTextColor(color); tft.print(text); } uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b){ return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); }
(Magnetische) Deklination
Da die Magnetlinien der Erde jedoch nicht exakt gerade verlaufen, gibt es regionale Unterschiede in ihrer Ausrichtung. Dafür gibt es magnetische Karten und Modelle, die die entsprechenden Abweichungen ausgleichen und unseren Kompass noch genauer machen können. Glücklicherweise sind die Abweichungen ziemlich leicht über einige Seiten im Internet abrufbar, wie zum Beispiel hier für Deutschland oder hier weltweit. Haben wir die Abweichungen ermittelt, so tragen wir einfach die Werte unten ein und drücken auf „Ausrechnen“. (Im Beispiel unten ist die aktuelle Deklination für Berlin (DE) eingetragen.)
float declinationAngle = 0.0578;
Die Zeile oben wird dann einfach im Sketch ersetzt. Natürlich kann die Deklination auch auf „0.00“ gesetzt werden, wenn der Kompass weltweit eingesetzt werden soll. Allerdings ist dann natürlich die Magnetnadel auch den regionalen Schwankungen ausgesetzt und ist somit deutlich ungenauer.
Ergänzende Bemerkungen
Die Genauigkeit des digitalen Kompasses hängt natürlich auch von örtlichen Magnetfeldern ab. So beeinflussen beispielsweise Lautsprecher durch ihre Magneten, die Messung enorm. Dies können wir zum Beispiel einfach dadurch testen, in dem wir den Sensor in die Nähe eines Lautsprechers bewegen. Auch Mobiltelefone können den Ausschlag der Magnetnadel beeinflussen. Ebenfalls abweichende Ergebnisse erhalten wir, wenn der Sensor um die X- oder Y-Achse gedreht wird, deshalb sollte der Sensor in Ebene gehalten und nur um die Z-Achse gedreht werden.
Bauteile (Bezugsquellen):
eBay: | 1.8 Zoll TFT SPI Display Arduino Breadboard Breadboard Kabel GY-271 HMC5883L |
Amazon: | Arduino Breadboard Breadboard Kabel GY-271 HMC5883L |
Gut?











