sitemap link mailform link home

Kompass-Modul

Der PRO-BOT128 hat Schwierigkeiten, geradeaus zu fahren.

Die sogenannten Odometer funktionieren auch meist nur mangelhaft.

Einen Ausweg bietet der Einsatz des Kompassmoduls HDMM01 von der Externer Link Firma Pollin.
Das Fertigmodul kostet 6,95 € und ist der schnelle und preiswerte Weg, das Manko des PRO-BOT128 auszugleichen.
Herzstück der Platine ist der 2-Achsen-Magnetsensor MMC2120 von MEMSIC.

Allerdings darf man keine Wunder erwarten, da die Abweichung etwa 3 Grad beträgt - das ergibt also nur ca. 1 % Messgenauigkeit.

PDF Beschreibung von Pollin (englisch)

PDF Datenblatt (englisch)

Für die erste Inbetriebnahme kann einfach eine 6-polige Wannenbuchse an das Kompassmodul angelötet werden, die dem Anschluss-Schema des I2C-Busses auf dem Breadboard des PRO-BOT entspricht.

Man entfernt also einfach das Breadboard (die oberste Etage des PRO-BOT) und schließt an das Flachbandkabel nun das Kompassmodual an:

Anschluss des HDMM01

Oder man lötet das Kompassmodul direkt auf das Breadboard. Von der Einbaulage hängt natürlich auch die Normierung der Himmelsrichtungen ab.

Bei dieser Einbaulage bringt der Sensor MMC2120 einen maximalen X-Messwert, wenn der PRO-BOT mit seiner Vorderseite (Pfeil auf dem Breadboard) nach Süden zeigt. Der Y-Messwert hat sein Maximum, wenn der PRO-BOT nach Westen zeigt.

Breadboard

Der Kompass-Chip MMC2120 des HDMM01 besitzt ein Schreibregister mit der Adresse 0x00 und fünf Leseregister 0x00 bis 0x04, in denen die Inhalte des Statusregisters und die 2 Messwerte wie folgt abgelegt sind:

AdresseInhalt des Leseregisters
0x00Statusregister
0x01MSB X-Messwert
0x02LSB X-Messwert
0x03MSB Y-Messwert
0x04LSB Y-Messwert

Die X- und Y-Messwerte (MSB*256 + LSB) sind jeweils 12 Bit lang. Die obersten 4 Bit sollten auf NULL maskiert werden (X_WERT = X_WERT & 0x0F). Das ist im folgenden PAP allerdings nicht berücksichtigt!

Die I2C-Schreib-Adresse ist fest auf 0x60 (Hex) eingestellt. Daher ergibt sich eine I2C-Lese-Adresse von 0x61 (Hex).

Zur Programmierung findet man eine genaue (aber chaotische)  Beschreibung im Datenblatt.
Ich habe mal versucht, die Anweisungen in einen Programmablaufplan (PAP) zu überführen:

PAP

Für erste Tests, ob wirklich "etwas rauskommt", habe ich das folgende Programm geschrieben:

/*******************************************************************************
 Projektname:     KOMPASS_NIKO_CC.cprj
 Benötigte Libs:  IntFunc_lib.cc
 Routinen:          kompass.cc, PRO-BOT128C_Lib_V2.cc
 Autor:                Niko
 Datum:              3. 12. 2012

 Funktion:          Kompass starten und abfragen
*******************************************************************************/

// I2C-Adresse und Wartezeit definieren:
#define I2C_ADDR_KOMPASS 0x60
#define WAIT1 5 // Millisekunden

// Der MMC2120-Kompass-Chip besitzt ein Schreibregister, in das die Befehle ge-
// schrieben werden können sowie 5 Leseregister, in das der Inhalt des Status-
// registers und die Messwerte abgelegt werden:
// STATUS-Register - Adresse 0x00
// MSB des X-Messwertes - Adresse 0x01
// LSB des X-Messwertes - Adresse 0x02
// MSB des Y-Messwertes - Adresse 0x03
// LSB des Y-Messwertes - Adresse 0x04

#define WRITE_ADDRESS 0x00 // Adresse des Schreibregisters
#define READ_ADDRESS 0x00 // Basisadresse der 5 Leseregister
#define TAKE_MEASURE  0x01 // Befehl zum Start der Messung
#define SET_COIL 0x02 // Setzen der Magnetspule
#define RESET_COIL 0x04 // Löschen der Magnetspule
#define HIGH_NIBBLE_MASK 0x08 //Maskierung für das Vorzeichen (Byte)

void main(void)
{

    byte MSB_X;
    byte LSB_X;
    byte MSB_Y;
    byte LSB_Y;
    int X_VALUE;
    int Y_VALUE;

    PRO_BOT128_INIT();    //PRO-BOT128 Setup
    DELAY_MS(WAIT1);
    ResetSetCoils();

    while(1)
    {
    //ResetSetCoils();
    // Messung starten und Lesen der 5 Byte des Kompassmoduls
    // Die Reihenfolge der Befehle wird im Datenblatt so verlangt:
    I2C_Start();
    I2C_Write(I2C_ADDR_KOMPASS);
    I2C_Write(WRITE_ADDRESS); // Basisadresse der Kompass-Register
    I2C_Write(TAKE_MEASURE); // Messung starten
    I2C_Stop();
    DELAY_MS(WAIT1);  // WAIT erforderlich für die Messung!
    I2C_Start();
    I2C_Write(I2C_ADDR_KOMPASS);
    // STATUS-REGISTER auf Basisadresse soll nicht gelesen werden:
    I2C_Write(READ_ADDRESS+1); // Setze Leseadresse+1 der Kompass-Lese-Register
    I2C_Stop();
    I2C_Start();
    I2C_Write(I2C_ADDR_KOMPASS+1); // Lese-Adresse = I2C-Adresse + 1!
    // Ersten Wert auslesn
    MSB_X = I2C_Read_ACK();
    // Zweiten Wert auslesen
    LSB_X =I2C_Read_ACK();
    // Dritten Wert auslesen
    MSB_Y = I2C_Read_ACK();
     // Vierten Wert auslesen
    LSB_Y =I2C_Read_NACK(); //Hier KEIN ACKNOWLEDGE!
    I2C_Stop();
    DELAY_MS(WAIT1);

    // Anzeige der Messwerte einzeln:

    Msg_WriteText("MSB_X-");
    Msg_WriteInt(MSB_X);
    Msg_WriteText("-LSB_X-");
    Msg_WriteInt(LSB_X);
    Msg_WriteText("-MSB_Y-");
    Msg_WriteInt(MSB_Y);
    Msg_WriteText("-LSB_Y-");
    Msg_WriteInt(LSB_Y);
    Msg_WriteChar(13);

    // Anzeige der fertigen Messwerte:
    X_VALUE = MSB_X*256 + LSB_X;
    Y_VALUE = MSB_Y*256 + LSB_Y;
    Msg_WriteText("X-Wert:-");
    Msg_WriteInt(X_VALUE);
    Msg_WriteText("-Y-Wert:-");
    Msg_WriteInt(Y_VALUE);
    Msg_WriteChar(13);
    }
}

void ResetSetCoils (void)
{

    // RESET / SET Coils
    I2C_Start();
    I2C_Write(I2C_ADDR_KOMPASS);
    I2C_Write(WRITE_ADDRESS); // als WAKE-UP
    I2C_Write(RESET_COIL);
    I2C_Stop();
    DELAY_MS(WAIT1);
    I2C_Start();
    I2C_Write(I2C_ADDR_KOMPASS);
    I2C_Write(WRITE_ADDRESS); // als WAKE-UP
    I2C_Write(SET_COIL);
    I2C_Stop();
    DELAY_MS(WAIT1);
}

//****************************************************************************

Eine gute Beschreibung des HDMM01 mit Messwerten und Quellcode für die Umrechnung in einen Winkel gibt es Externer Link hier.

Externer Link Hier gibt es eine Anweisung in deutsch, wie der HDMM01 programmiert werden nuss, um die Rohwerte zu erhalten:

"I²C Kommunikation | Der Sensor hat fest eingestellt die Adresse &h60. Das LSB der Adresse gibt bei I²C bekanntlich an, ob geschrieben oder gelesen werden soll, dementsprechen ist die Schreibadresse &h60, die Leseadresse ist &h61.
Das Initiieren einer Messung und das Auslesen des Ergebnisses geschieht folgendermaßen: man erzeugt eine Startbedingung (SDA geht auf low während SCL high ist) und adressiert den Sensor zum Schreiben (&h60). Der Sensor hat nur ein Register, das an der Adresse &h00 liegt, man schreibt also diese Adresse auf den Bus, um im nächsten Schritt das Register manipulieren zu können.
Das Setzen des LSB in diesem Register löst eine Messung aus, man überträgt dementsprechend &h01 und erzeugt eine Stopp-Bedingung (SDA geht auf high während SCL high ist).
Nun genehmigt man dem Sensor einige Millisekunden Pause um die eigentliche Messung durchzuführen.
Um die Daten abzuholen, wird zunächst wieder eine Start-Bedingung auf dem Bus erzeugt, dann teilt man dem Sensor mit, welches Datenbyte man lesen will. Dazu wird die Schreibadresse übertragen (&h60) und dann der Index des Datenbytes. Hier sollen alle fünf Bytes (Kontrollregister und Daten), also von Index 0 gelesen werden, man schreibt somit &h00 auf den Bus.
Nach einer erneuten Startbedingung legt man die Leseadresse (&h61) auf den Bus und kann sich dann in Folge fünf Bytes abholen, deren ersten vier mit einen Acknowledge quittiert werden. Nach dem fünften Byte erzeugt man eine Stopp-Bedingung."

Anmerkung:

Es gibt wesentlich bessere Kompassmodule, die gleich einen Winkel von 0 bis 360 Grad ausgeben und eine sogenannte Tilt-Kompensation besitzen ( 3-Achsen-Module mit Mikrocontroller "on board"). Der CMPS10 kostet ca. 27 €:

Externer Link Devantech CMPS10-Beschreibung (englisch)

Noch bequemer geht es, wenn man das Kompassmodul CMPS03 (30 €)  verwendet. Dafür gibt es in dem Buch "PRO-BOT128 selbst bauen und erfolgreich einsetzen" von Ulli Sommer auch gleich eine eigene Library auf CD:

Externer Link Devantech CMPS03


Buchempfehlung:

Buchempfehlung

Externer Link PRO-BOT128 selbst bauen und erfolgreich einsetzen

.

Letzte Änderung:
March 23. 2023 21:04:40
«    top    »