hier endlich mal ein echter IMU-Sensor (3D-Gyro, 3D-Kompass, 3D-Accelerometer) mit interner Sensorfusion,
funktioniert per I2C oder UART !


http://www.robot-electronics.co.uk/htm/cmps11i2c.htm
http://de.manu-systems.com/CMPS11.shtml
http://www.roboter-teile.de/Oxid/Naviga ... MPS11.html
Lässt sich sicher auch für den EV3 programmieren (ev3dev, C#/Mono, leJOS), ähnlich wie das C/C++ Arduino-Beispiel (s.u.).
Das CMPS11 ist mit Ausnahme des PWM-Interfaces kompatibel zum Vorgänger CMPS10, alle Beispiele, die die I2C oder serielle Schnittstelle nutzen funktionieren ohne Einschränkungen
Auflösung: 0,1°
Genauigkeit: besser als 2%, nach Kalibrierung
Messprinzip: 3 Achsen Magnetfeldsensor + 3 Achsen Beschleunigungsmesser + 3 Achsen Gyro
Ausgang 1: I2C Interface, SMBUS kompatibel, 0-255 und 0-3599 , 100khz/li>
Ausgang 2: Serieller Port, 9600 baud, keine Parität, 2 Stopbit und 3.3V-5V Pegel
Betriebsspannung: 3,6V-5V
Stromaufnahme: 35mA
Abmessungen: 24mm x 18mm
Gibt mit 4 Bytes per I2C direkt heading (yaw), pitch und roll aus! Magnetisch, Temperatur- und Inklinations-kompensiert, ohne nachträgliche Rechnerei!
Und wer will, kann sich von den Einzelsensoren auch die ursprünglichen raw-Werte anzeigen lassen!
Hier ein Arduino-Sketch (C/C++), an dem man sieht, wie einfach es geht (bzw. gehen könnte, wenn man die richtige PL für Mindstorms hätte^^)!
(spezielle Routinen für das im Beispiel-Sketch verwendete serielle Arduino-lcd03 (UART) müssen ntl ggf. durch andere ersetzt werden, ich selber benutze ein 220x176 True-Color-TFT per SPI!)
Code: Alles auswählen
/****************************************************************
* Arduino CMPS10 example code *
* CMPS10 running I2C mode *
* by James Henderson, 2012 *
* // http://www.robot-electronics.co.uk/htm/cmps11i2c.htm // *
*****************************************************************/
#include <Wire.h>
// #include <SoftwareSerial.h>
#define ADDR_CMPS11 0x60 // Defines address of CMPS10
#define LCD_RX 0x02 // RX and TX pins used for LCD0303 serial port
#define LCD_TX 0x03
#define LCD03_HIDE_CUR 0x04
#define LCD03_CLEAR 0x0C
#define LCD03_SET_CUR 0x02
SoftwareSerial lcd03 = SoftwareSerial(LCD_RX, LCD_TX); // Defines software serial port for LCD03
void setup(){
Wire.begin(); // Conects I2C
lcd03.begin(9600);
lcd03.write(LCD03_HIDE_CUR);
lcd03.write(LCD03_CLEAR);
}
void loop(){
uint8_t bHiByte, bLoByte, fine; // store high and low bytes of the bearing; fine stores decimal place of bearing
int8_t pitch, roll; // Stores pitch and roll values of CMPS11, support signed value
int16_t bearing; // Stores full bearing
float fbearing; // optional as float number
Wire.beginTransmission(ADDR_CMPS11); // starts communication with CMPS11
Wire.write(2); // Sends the register we wish to start reading from
Wire.endTransmission();
Wire.requestFrom(ADDR_CMPS11, 4); // Request 4 bytes from CMPS11
while(Wire.available() < 4); // Wait for bytes to become available
bHiByte = Wire.read();
bLoByte = Wire.read();
pitch = Wire.read();
roll = Wire.read();
bearing = ((bHiByte<<8)+bLoByte)/10; // Calculate full bearing
fine = ((bHiByte<<8)+bLoByte)%10; // Calculate decimal place of bearing
fbearing = ( (float)(bHiByte<<8) + (float)bLoByte) / 10.0; // optional
display_data(bearing, fine, pitch, roll); // Display data to the LCD03
delay(100);
}
void display_data(int b, int f, int p, int r){ // pitch and roll (p, r) are recieved as ints instead oif bytes so that they will display corectly as signed values.
lcd03.write(LCD03_SET_CUR); // Set the LCD03 cursor position
lcd03.write(1);
lcd03.print("CMPS10 Example V:");
lcd03.print(soft_ver()); // Display software version of the CMPS10
delay(5); // Delay to allow LCD03 to proscess data
lcd03.write(LCD03_SET_CUR);
lcd03.write(21);
lcd03.print("Bearing = "); // Display the full bearing and fine bearing seperated by a decimal poin on the LCD03
lcd03.print(b);
lcd03.print(".");
lcd03.print(f);
lcd03.print(" ");
delay(5);
lcd03.write(LCD03_SET_CUR); // Display the Pitch value to the LCD03
lcd03.write(41);
lcd03.print("Pitch = ");
lcd03.print(p);
lcd03.print(" ");
delay(5);
lcd03.write(LCD03_SET_CUR); // Display the roll value to the LCD03
lcd03.write(61);
lcd03.print("Roll = ");
lcd03.print(r);
lcd03.print(" ");
}
int soft_ver(){
int data; // Software version of CMPS10 is read into data and then returned
Wire.beginTransmission(ADDR_CMPS11);
Wire.write((byte)0); // Sends the register we wish to start reading from
Wire.endTransmission();
Wire.requestFrom(ADDR_CMPS11, 1); // Request byte from CMPS10
while(Wire.available() < 1);
data = Wire.read();
return(data);
}
Verkabelung mit NXT/EV3-Stecker/Buchsen: