Seite 1 von 1

Der Magnetfeldsensor HMC5883L

Verfasst: Sa 1. Aug 2015, 20:40
von Heinrichs
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.

gy_273.jpg
Abb. 1: GY-273-Modul
gy_273.jpg (13.76 KiB) 30196 mal betrachtet

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).

registertabelle.jpg
Abb. 2: Register-Tabelle (Datenblatt zum HMC5883L der Firma Honeywell
registertabelle.jpg (75.14 KiB) 30196 mal betrachtet

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
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.

Re: Der Magnetfeldsensor HMC5883L - Modul GY-271

Verfasst: Mo 10. Aug 2015, 16:54
von Heinrichs
Für den Magnetfeldsensor HMC5883L gibt es auch eine Modulvariante mit der Bezeichnung GY-271. Bei ihr gibt es nicht nur für die Versorgungsspannung, sondern auch für die Signalleitungen SDA und SCL eine Pegelanpassung von 5V auf 3,3 V. Der Preis ist (inkl. Porto) etwa 3 mal so hoch wie beim GY-273.

GY-271_schematic.jpg
GY-271-Modul (Schaltskizze)
GY-271_schematic.jpg (115.48 KiB) 30135 mal betrachtet