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.