- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 16

Thema: Wie kann ich mit i2c-Sensoren für Nibo2 kommunizieren?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    02.02.2020
    Ort
    Harz
    Alter
    74
    Beiträge
    8
    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

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.063
    Deine Kompass Lesefunktion funktioniert glaube ich nicht so wie du willst. Speziell die do/while Schleife.

    Vergleiche mein I2C Lese Ablauf von Post 4 und deinen Ablauf. Du ließt den Status aus (nach dem delay(20)), verwendest aber ein NACK, danach sollte aber ein I2C-Stopp kommen. Ein NACK bedeutet das keine weiteren Daten gelesen werden, du ließt aber danach (nach 20ms) noch ein Byte.

    Ich würde es eher so machen:
    Code:
    I2C Start (Adresse + schreiben)
    I2C schreibe (0x06)
    I2C rep Start (Adresse + lesen)
    status = I2C Lese NACK
    I2C Stopp
    
    wenn Status OK (Daten vorhanden und keine Fehler)
    {
    X, Y und Z Daten auslesen
    }

    Was du auch noch machen kannst ist eine Hysterese einbauen, also nicht auf exakt 90° drehen, sondern wenn der Bereich zwischen z.B. 89 und 91° ist, ist er OK.

    Eine weitere Funktion wäre die Geschwindigkeit der Motoren im Bereich um den Zielwinkel zu reduzieren (z.B. Winkelabweichung > 45° => PWM=100%, Winkelabweichung > 25° => PWM = 50%,...)

    Beim Messen könntest du auch versuchen die Motoren abzuschalten. Also Motoren stoppen, Messwert auslesen, Ziel berechnen, Motoren wieder einschalten, delay

    MfG Hannes

Ähnliche Themen

  1. Suche Microcontroller welcher mit Android kommunizieren kann
    Von Mr.P. im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 10
    Letzter Beitrag: 04.10.2012, 11:13
  2. Antworten: 3
    Letzter Beitrag: 17.12.2010, 22:03
  3. Wie kann Mega8 mit ProfiLab Expert kommunizieren?
    Von mikro-VIIV im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 15.12.2007, 14:54
  4. Welche Sensoren kann ich dafür verwenden?
    Von blue_man im Forum Sensoren / Sensorik
    Antworten: 12
    Letzter Beitrag: 20.05.2005, 18:53
  5. Sensoren kommunizieren miteinander
    Von Andreas im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 30.04.2004, 23:51

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test