Hallo Hannes,
will mich mal wieder melden. Ich war nicht untätig, habe den Kompass-Sensor nun in mein eigentliches Nibo2-Programm eingebaut.
Und - es funktioniert wirklich, dass der Roboter, wenn er um 90° nach links drehen soll, da auch tut. Und das mit deutlich besserer Genauigkeit als vorher, wo ich sozusagen nur die Umdrehungszahl der Räder als Maß hatte, ob der Roboter nun gerutscht ist oder nicht, also ob er seine Zielrichtung erreicht hat oder nicht.
Jetzt kommt aber ein ABER - aber komischerweise klappt das 2 bis 3 mal gut im Labyrinth, und plötzlich hört er nach 90° nicht auf, macht mehrere volle 360°-Drehungen, um dann anschließend wieder ordentlich zu reagieren.
Ich weiß beim besten Willen nicht, woran das liegt!?! Ob das Probem am Lesen der Sensordaten über den i2c-Bus liegt?
Schau bitte nochmals auf meine Routine, die in der while-Hauptschleife liegt:
Code:
/********************** Registereinstellungen für Kompass-Sensor ************************************/
void kompass_init()
{
i2c_start(KOMPASS_ADR+I2C_WRITE); // set device address and write mode
i2c_write(0x09); // write address = 9
i2c_write(0x1D); // Define OSR = 512, Full Scale Range = 8 Gauss, ODR = 200Hz, set continuous measurement mode)
i2c_write(0x0A); // write address = 10
i2c_write(0x40); // The I2C data pointer will automatically roll, 6.Bit = 1 setzen
i2c_write(0x0B); // write address = 11
i2c_write(0x01); // Define Set/Reset period
i2c_stop(); // set stop conditon = release bus
}
/********************** Kommpasswerte lesen *********************************************************/
int16_t kompass_lesen()
{
int16_t winkel;
i2c_start_wait(KOMPASS_ADR+I2C_WRITE); // set device address and write mode
i2c_write(0x00); // write Register = 0 = welcher Wert aus welchem Register soll zuerst gelesen werden
i2c_rep_start(KOMPASS_ADR+I2C_READ); // set device address and read mode
x = i2c_readAck(); // read one byte from address 0 LSB x
x |= i2c_readAck()<<8; // " " " " " 1 MSB x (um 8 Bit nach links verschieben und addieren)
y = i2c_readAck(); // " " " " " 2 LSB y
y |= i2c_readAck()<<8; // " " " " " 3 MSB y (um 8 Bit nach links verschieben und addieren)
z = i2c_readAck(); // " " " " " 4 LSB z
z |= i2c_readNak()<<8; // " " " " " 5 MSB z (um 8 Bit nach links verschieben und addieren)
i2c_stop(); // set stop condition = release bus
winkel = atan2 (-y, x) * 180 / PI;
if (winkel < 0)
{
winkel += 360;
}
deklination = (3 + (33 / 60)) / (180 / PI); // Deklination für Gernrode (+3° 33')
winkel += deklination;
return winkel;
}
Im Datenblatt des Sensors lese ich:
Check status register 06H[0] ,”1” means ready.
Read data register 00H ~ 05H.
Vielleicht muss ich ja das Register 06H checken, ob das 0. Bit gesetzt ist?!?
Kannst du mir erklären, wie ich dies in meiner Routine realisieren kann?
Oder hast du evtl. noch eine andere Idee?
Viele Grüße aus dem Harz sendet
Klaus
Lesezeichen