Der Magnetfeldsensor HMC5883L
Verfasst: Sa 1. Aug 2015, 20:40
Unter der Bezeichnung GY-273 wird ein preiswertes Modul (Preis unter 2 Euro) angeboten, mit dem Magnetfelder gemessen werden können. Herzstück dieses Moduls ist der Baustein HMC5883L. Hierbei handelt es sich um einen 3-Achsen-Magnetfeldsensor, der auf der Basis des Magnetowiderstandes eines dünnen Permalloy-Films arbeitet.
Das Datenblatt des HMC5883L gibt als maximale Versorgungsspannung 3,6 V an. Das Modul kann dennoch direkt an unsere Mikrocontroller-Platine angeschlossen werden, es reduziert nämlich die Versorgungsspannung auf 3,3 V. Die Kommunikation erfolgt über das I2C-Protokoll; die erforderlichen Pullup-Widerstände (4,7 k) sind auch schon auf dem Platinchen vorhanden, so dass wir uns die Pullup-Jumper schenken können. Die Schreibadresse ist $3C, die Leseadresse dementsprechend $3D.
Der HMC5883L-Baustein besitzt 13 Register mit den Adresse 0 bis 12. Über diese Register läuft die gesamte Kommunikation: Steuerung, Kontrolle und Übermittlung der gemessenen Magnetfeldwerte (vgl. Abb. 2).
Wie geht man nun mit diesem Baustein um? Zunächst muss der Baustein initialisiert werden. Dies geschieht über die ersten 3 Register. Die Bedeutung aller dort auftauchenden Datenbits wird auf den Seiten 12 bis 14 des Datenblattes dargelegt; hier soll nur an einem Beispiel eine mögliche Initialisierung erläutert werden.
Register A = &B 0101 1000 bedeutet:
Es werden die Ergebnisse von 4 Messungen gemittelt; diese Mittelwerte werden dann als Output zur Verfügung gestellt. (Man beachte, dass die Einzelwerte verrauscht sind!). Dabei beträgt die Messrate 75Hz. Es findet eine normale Messung (kein Selbsttest) statt.
Register B = &B 1100 0000 bedeutet:
Der Baustein stellt verschiedene Messbereiche zur Verfügung. Hier wird als Verstärkung (Gain) der Wert 6 gewählt. In diesem Fall entspricht der in den Output-Registern abgelegte Rohwert r einer magnetischen Flussdichte von r ⋅ 3.03/10 μT (vorletzte Zeile der Tabelle 9 des Datenblattes). Da der Baustein als Rohwerte 12-Bit-Werte ausgibt (von - 2048 bis + 2047) können damit Werte bis ca. 600 μT erfasst werden; das Datenblatt (Tabelle 9) empfiehlt aber als obere Grenze für diesen Messbereich 5,6 Gauss (560 μT).
Mode Register = &B 0000 0000 bedeutet:
Der Baustein legt fortwährend (genauer: mit einer Rate von 75 Hz, s. o.) Messergebnisse (genauer: Mittelwerte davon, s. o.) in den Output-Registern ab.
Wie man diese Werte in die Register des HMC5883L-Bausteins schreibt, kann man dem Bascom-Code weiter unten entnehmen.
Es werden insgesamt 6 Messwerte vom Typ Byte geliefert. In den Output-Registern 3 und 4 findet man z. B. das High-Byte und das Low-Byte des Rohwertes für das Magnetfeld in x-Richtung (vgl. Abb. 1). Da die übliche Kodierung der negativen Werte als 2-Komplement erfolgt, bietet es sich an, diese beiden Bytes als High- und Low-Bytes einer Variablen vom Typ integer zu interpretieren:
Dim Bx As Integer
Dim Bx1 As Byte At Bx + 1 Overlay
Dim Bx2 As Byte At Bx Overlay
In dem folgenden Bascom-Programm werden - nach einer entsprechenden Initialisierung - die Daten für das Magnetfeld ausgelesen und die Werte (in μT) für die y- und die z-Richtung auf einem 8*2-LCD ausgegeben. Zusätzlich wird nach der Initialisierung der Inhalt des Statusregisters angezeigt.
Bei schwachen Magnetfeldern (z. B. Erdmagnetfeld) macht sich leider ein Offset bei den Messwerten bemerkbar. Dies erkennt man, wenn man den Sensor einmal um seine Achse dreht: Nach einer Drehung von 180° sollte sich bis auf eine Vorzeichenänderung wieder derselbe Wert zeigen. Dies wird in der Regel aber zunächst nicht der Fall sein; man misst z. B. -20 μT und +40 μT. Dies weist auf einen Offset von +10μT hin; diesen kann man kompensieren, indem man von allen Messwerten diesen Offset subtrahiert. Das muss natürlich für jede Achse getrennt durchgeführt werden.
Neben dem Offset gibt es noch eine weitere Quelle von Ungenauigkeiten: Je nach Temperatur und anderen äußeren Einflüssen muss ggf. auch der Skalierungsfaktor angepasst werden. Hierzu wird ein Selbsttest eingesetzt; er ist auf S. 19 des Datenblattes dargelegt. Da bei meinem Baustein die Abweichung nur ca. 2% betrug, habe ich auf eine Korrektur verzichtet.
Das Datenblatt des HMC5883L gibt als maximale Versorgungsspannung 3,6 V an. Das Modul kann dennoch direkt an unsere Mikrocontroller-Platine angeschlossen werden, es reduziert nämlich die Versorgungsspannung auf 3,3 V. Die Kommunikation erfolgt über das I2C-Protokoll; die erforderlichen Pullup-Widerstände (4,7 k) sind auch schon auf dem Platinchen vorhanden, so dass wir uns die Pullup-Jumper schenken können. Die Schreibadresse ist $3C, die Leseadresse dementsprechend $3D.
Der HMC5883L-Baustein besitzt 13 Register mit den Adresse 0 bis 12. Über diese Register läuft die gesamte Kommunikation: Steuerung, Kontrolle und Übermittlung der gemessenen Magnetfeldwerte (vgl. Abb. 2).
Wie geht man nun mit diesem Baustein um? Zunächst muss der Baustein initialisiert werden. Dies geschieht über die ersten 3 Register. Die Bedeutung aller dort auftauchenden Datenbits wird auf den Seiten 12 bis 14 des Datenblattes dargelegt; hier soll nur an einem Beispiel eine mögliche Initialisierung erläutert werden.
Register A = &B 0101 1000 bedeutet:
Es werden die Ergebnisse von 4 Messungen gemittelt; diese Mittelwerte werden dann als Output zur Verfügung gestellt. (Man beachte, dass die Einzelwerte verrauscht sind!). Dabei beträgt die Messrate 75Hz. Es findet eine normale Messung (kein Selbsttest) statt.
Register B = &B 1100 0000 bedeutet:
Der Baustein stellt verschiedene Messbereiche zur Verfügung. Hier wird als Verstärkung (Gain) der Wert 6 gewählt. In diesem Fall entspricht der in den Output-Registern abgelegte Rohwert r einer magnetischen Flussdichte von r ⋅ 3.03/10 μT (vorletzte Zeile der Tabelle 9 des Datenblattes). Da der Baustein als Rohwerte 12-Bit-Werte ausgibt (von - 2048 bis + 2047) können damit Werte bis ca. 600 μT erfasst werden; das Datenblatt (Tabelle 9) empfiehlt aber als obere Grenze für diesen Messbereich 5,6 Gauss (560 μT).
Mode Register = &B 0000 0000 bedeutet:
Der Baustein legt fortwährend (genauer: mit einer Rate von 75 Hz, s. o.) Messergebnisse (genauer: Mittelwerte davon, s. o.) in den Output-Registern ab.
Wie man diese Werte in die Register des HMC5883L-Bausteins schreibt, kann man dem Bascom-Code weiter unten entnehmen.
Es werden insgesamt 6 Messwerte vom Typ Byte geliefert. In den Output-Registern 3 und 4 findet man z. B. das High-Byte und das Low-Byte des Rohwertes für das Magnetfeld in x-Richtung (vgl. Abb. 1). Da die übliche Kodierung der negativen Werte als 2-Komplement erfolgt, bietet es sich an, diese beiden Bytes als High- und Low-Bytes einer Variablen vom Typ integer zu interpretieren:
Dim Bx As Integer
Dim Bx1 As Byte At Bx + 1 Overlay
Dim Bx2 As Byte At Bx Overlay
In dem folgenden Bascom-Programm werden - nach einer entsprechenden Initialisierung - die Daten für das Magnetfeld ausgelesen und die Werte (in μT) für die y- und die z-Richtung auf einem 8*2-LCD ausgegeben. Zusätzlich wird nach der Initialisierung der Inhalt des Statusregisters angezeigt.
Code: Alles auswählen
' Attiny-Platine von E. Eube, G. Heinrichs und U. Ihlefeldt
' Magnetfeldsensor HMC5883L
' Pull-Up-Widerstände nicht vergessen!
'----------------------------------------------------------------------------
$regfile = "attiny2313.dat" 'Attiny2313
$crystal = 4000000 '4 MHz
'**********************************************************
'******************* Deklarationen ************************
Declare Sub Init
Declare Sub Messung
Declare Sub Zeige_hmc_status
Dim Hmc_status As Byte
Dim By As Integer
Dim Bz As Integer
Dim Bx1 As Byte
Dim Bx2 As Byte
Dim By1 As Byte At By + 1 Overlay
Dim By2 As Byte At By Overlay
Dim Bz1 As Byte At Bz + 1 Overlay
Dim Bz2 As Byte At Bz Overlay
Dim Test As Integer
'****************** Initialisierung ***********************
Ddrb = &B11111111 'Port B als Ausgangsport
Ddrd = &B01110000 'D4, D5, D6 als Ausgang; Rest als Eingang
Portd = &B10001111 'Eingänge auf high legen
Waitms 50 'u. A. zum Aufladen des Kondensators bei Ta0
Config Lcd = 16 * 2 'LCD konfigurieren
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.6
Cursor Off
Config Scl = Portb.7 'Konfigurieren von I2C
Config Sda = Portb.5
Const W_adr = &H3C 'Adressen des HMC5883L
Const R_adr = &H3D
Const By_offset = 16 'in uT, durch Drehung im Erdmagnetfeld ermittelt
Const Bz_offset = 42
'**********************************************************
'******************** Hauptprogramm ***********************
Call Init
Call Zeige_hmc_status
Do
Waitms 100
Call Messung
Cls
'Kalibrieraktor 3.03/10
By = By * 3 'nur 1% Fehler, aber Rechnen mit Single-Werten vermieden
By = By / 10
By = By + By_offset
Lcd "y:"
Lcd By
Lcd "uT"
Bz = Bz * 3
Bz = Bz / 10
Bz = Bz + Bz_offset
Locate 2 , 1
Lcd "z:"
Lcd Bz
Lcd "uT"
Loop
'**********************************************************
'******************* Unterprogramme ***********************
Sub Init
Cls
I2cstart
I2cwbyte W_adr
If Err = 0 Then Lcd "HMC gef." Else Lcd "HMC ???"
I2cwbyte 'Register A adressieren
I2cwbyte &B01011000 '4 samples averaged, 75Hz, normal
'HMC wechselt automatisch zum nächsten Register
I2cwbyte &B11000000 'Gain=6 -> 1 Rohwert gleich 3.03/10 uT
I2cwbyte &B00000000 'Running mode
I2cstop
Wait 1
End Sub
Sub Zeige_hmc_status
I2cstart
I2cwbyte W_adr
I2cwbyte &H09 'Status-Register
I2cstart
I2cwbyte R_adr 'Lesen
I2crbyte Hmc_status , Nack
I2cstop
Locate 2 , 1
Lcd "Stat="
Lcd Hmc_status
Wait 1
End Sub
Sub Messung
I2cstart
I2cwbyte W_adr
I2cwbyte &H03 'Startadresse
I2cstart
I2cwbyte R_adr
I2crbyte Bx1 , Ack 'ACK -> nächstes Register
I2crbyte Bx2 , Ack
I2crbyte Bz1 , Ack
I2crbyte Bz2 , Ack
I2crbyte By1 , Ack
I2crbyte By2 , Nack
I2cstop
End Sub
Neben dem Offset gibt es noch eine weitere Quelle von Ungenauigkeiten: Je nach Temperatur und anderen äußeren Einflüssen muss ggf. auch der Skalierungsfaktor angepasst werden. Hierzu wird ein Selbsttest eingesetzt; er ist auf S. 19 des Datenblattes dargelegt. Da bei meinem Baustein die Abweichung nur ca. 2% betrug, habe ich auf eine Korrektur verzichtet.