Hallo Hannes,
irgendwie habe ich mir das alles einfacher vorgestellt mit meinem Kompass-Sensor:
Wenn eine Drehung durchgeführt werden soll, wird zuerst der augenblickliche Startwinkel ermittelt, dann der gewünschte Drehwinkel berücksichtigt und dann der Zielwinkel berechnet. Während der Drehung wird ständig der aktuelle Winkel ermittelt, und wenn der gleich dem Zielwinkel ist, wird die Drehung beendet.
Soweit, so gut - in der Theorie. Praktisch klappt das mal, mal nicht. Ich fand heraus, dass beim Ermitteln des aktuellen Winkels immer mal wieder ein Wert ausgelassen wrd. Und wenn das zufällig der gewünschte Zielwinkel ist, habe ich eben Pech!
Hier ist mein Code:
Ich habe es auch ohne delay(20) in der kompass_lesen()-Routine versucht, bringt aber auch nichts.Code:/********************** Kommpasswerte lesen *********************************************************/ void kompass_lesen() { int8_t status; i2c_start_wait(KOMPASS_ADR+I2C_WRITE); // set device address and write mode i2c_write(0x06); // Statusregister 06H setzen i2c_rep_start(KOMPASS_ADR+I2C_READ); // set device address and read mode do{ // warten, bis Statusregister Bit0 = 1 ist, dann Winkeldaten lesen delay(20); status = i2c_readNak() && 1; // Statusregister lesen }while (status == 0); 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_readNak()<<8; // " " " " " 3 MSB y (um 8 Bit nach links verschieben und addieren) i2c_stop(); // set stop condition = release bus winkel_aktuell = atan2 (-y, x) * 180 / PI; if (winkel_aktuell < 0) // Winkelangabe in den Bereich 0° bis 360° bringen { winkel_aktuell += 360; } } /************************* Soll-Drehwinkelberechnung ************************************************/ void drehwinkel_soll(int16_t winkel) { kompass_lesen(); // winkel_aktuell gibt die augenblickliche Fahrtrichtung an winkel_start = winkel_aktuell; // winkel_start berechnen winkel_ziel = winkel_start + winkel; // winkel_ziel berechnen if (winkel_ziel < 0) // Winkelwert in Bereich 0° bis 360° bringen { winkel_ziel += 360; } else if (winkel_ziel > 360) { winkel_ziel -= 360; } }
Mache ich etwas verkehrt? Hast du wieder einen Tipp für mich, vielleicht auch Erfahrungswerte?
Bin gespannt.
Gruß
Klaus







Zitieren


Lesezeichen