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:
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;
	}
}
Ich habe es auch ohne delay(20) in der kompass_lesen()-Routine versucht, bringt aber auch nichts.
Mache ich etwas verkehrt? Hast du wieder einen Tipp für mich, vielleicht auch Erfahrungswerte?
Bin gespannt.
Gruß
Klaus