Gyrometer GY-521 / MPU6050 am Wemo
Für unser Raketenprojekt brauchen wir natürlich einen automatischen Fallschirmauslöser. Wir bauen die einzelnen Komponenten und auf einem Steckbrett zusammen testen sie anschließend. Später soll auch noch eine passende Platine erstellt werden.
Um zu wissen, wann der Fallschirm ausgelöst werden soll, benutzen wir ein MPU6050 auf einem GY-521 Board, welcher die Temperatur, Beschleunigung und Neigung messen kann. Die Ergebnisse wollen wir als erstes an einem Display anzeigen.
Um die genaue Funktion des Sensores besser zu verstehen habe ich hier noch ein schönen Link gefunden: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf
Da für das Projekt nur die Beschleunigung wichtig ist, werten wir auch nur die drei Achsenwerte aus. Das Beispielprogramm findet Ihr hier:
//WEMO Logo und Display _ mpu6050 Test #include <Wire.h> #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display breite, in pixeln #define SCREEN_HEIGHT 64 // OLED display hoehe, in pixeln // Zuordung der Pins fuer SDA und SCL am SSD1206 Display #define OLED_RESET 0 // Reset pin Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // TowiLab Logo const unsigned char towilab_logo [] PROGMEM = { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x7f, 0x03, 0xf0, 0x3e, 0x0f, 0xcf, 0xc7, 0x00, 0x07, 0xf8, 0x0e, 0x3c, 0x00, 0x01, 0xf8, 0x01, 0xff, 0xc3, 0xf8, 0x7e, 0x1f, 0xcf, 0xc7, 0x00, 0x0f, 0xfc, 0x0e, 0xff, 0x00, 0x01, 0xf8, 0x03, 0xff, 0xe1, 0xf8, 0x7e, 0x1f, 0x8f, 0xc7, 0x00, 0x0f, 0xfe, 0x0f, 0xff, 0x80, 0x01, 0xf8, 0x07, 0xff, 0xf1, 0xf8, 0x7f, 0x1f, 0x8f, 0xc7, 0x00, 0x0c, 0x0f, 0x0f, 0x87, 0x80, 0x01, 0xf8, 0x07, 0xe3, 0xf1, 0xf8, 0xff, 0x1f, 0x8f, 0xc7, 0x00, 0x00, 0x07, 0x0e, 0x03, 0x80, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xf8, 0xff, 0x1f, 0x0f, 0xc7, 0x00, 0x00, 0x07, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xfc, 0xff, 0x1f, 0x0f, 0xc7, 0x00, 0x00, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xfc, 0xff, 0xbf, 0x0f, 0xc7, 0x00, 0x07, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xbe, 0x0f, 0xc7, 0x00, 0x0f, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xbe, 0x0f, 0xc7, 0x00, 0x1f, 0x87, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xfe, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7f, 0xc3, 0xfe, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x03, 0xc0, 0x01, 0xf8, 0x07, 0xe3, 0xf0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x03, 0x80, 0x01, 0xf8, 0x07, 0xff, 0xf0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0x00, 0x1e, 0x1f, 0x0e, 0x07, 0x80, 0x01, 0xf8, 0x03, 0xff, 0xe0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0xff, 0xcf, 0xff, 0x0f, 0xff, 0x00, 0x01, 0xf8, 0x01, 0xff, 0xc0, 0x1f, 0x81, 0xf8, 0x0f, 0xc7, 0xff, 0xcf, 0xf7, 0x0f, 0xfe, 0x00, 0x01, 0xf8, 0x00, 0x7f, 0x00, 0x1f, 0x81, 0xf8, 0x0f, 0xc7, 0xff, 0xc3, 0xc7, 0x0e, 0xfc, 0x00 }; const int MPU_addr=0x68; // I2C address of the MPU-6050 int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; int umrechnung; int winkel; void setup(){ //starte I2C Wire.begin(); //starte MPU 6050 Wire.beginTransmission(MPU_addr); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); //starte SSD1306 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Adresse des OLED's //programm display.clearDisplay(); //Display loeschen display.drawBitmap(3, 20, towilab_logo, 122, 23, WHITE); //Logo zeichnen display.display(); //Werte setzen delay(2000); } void loop(){ //einlesen MPU6050 Wire.beginTransmission(MPU_addr); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L) GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L) GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L) //ausgabe Display display.clearDisplay(); //Display loeschen display.setCursor(0, 0); //Cursor setzen display.setTextSize(1); //Text groeße einstellen display.setTextColor(WHITE); //Farbe einstellen display.println("Beschleunigung"); umrechnung = map(AcX, -16800, 16800, -90, 90); winkel = constrain(umrechnung, -90, 90); display.print("X: ");display.print(winkel); umrechnung = map(AcY, -16800, 16800, -90, 90); winkel = constrain(umrechnung, -90, 90); display.print(" Y: ");display.print(winkel); umrechnung = map(AcZ, -16800, 16800, -90, 90); winkel = constrain(umrechnung, -90, 90); display.print(" Z: ");display.println(winkel); display.println(); display.println("Temperatur"); display.print("Tmp: ");display.println(Tmp/340.00+36.53); display.display(); //Werte setzen delay(50); }
Ein weiteres Beispiel mit Glättung der Werte:
//WEMO Logo und Display _ mpu6050 Test #include <Wire.h> #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display breite, in pixeln #define SCREEN_HEIGHT 64 // OLED display hoehe, in pixeln // Zuordung der Pins fuer SDA und SCL am SSD1206 Display #define OLED_RESET 0 // Reset pin Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // TowiLab Logo const unsigned char towilab_logo [] PROGMEM = { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x7f, 0x03, 0xf0, 0x3e, 0x0f, 0xcf, 0xc7, 0x00, 0x07, 0xf8, 0x0e, 0x3c, 0x00, 0x01, 0xf8, 0x01, 0xff, 0xc3, 0xf8, 0x7e, 0x1f, 0xcf, 0xc7, 0x00, 0x0f, 0xfc, 0x0e, 0xff, 0x00, 0x01, 0xf8, 0x03, 0xff, 0xe1, 0xf8, 0x7e, 0x1f, 0x8f, 0xc7, 0x00, 0x0f, 0xfe, 0x0f, 0xff, 0x80, 0x01, 0xf8, 0x07, 0xff, 0xf1, 0xf8, 0x7f, 0x1f, 0x8f, 0xc7, 0x00, 0x0c, 0x0f, 0x0f, 0x87, 0x80, 0x01, 0xf8, 0x07, 0xe3, 0xf1, 0xf8, 0xff, 0x1f, 0x8f, 0xc7, 0x00, 0x00, 0x07, 0x0e, 0x03, 0x80, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xf8, 0xff, 0x1f, 0x0f, 0xc7, 0x00, 0x00, 0x07, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xfc, 0xff, 0x1f, 0x0f, 0xc7, 0x00, 0x00, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xfc, 0xff, 0xbf, 0x0f, 0xc7, 0x00, 0x07, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xbe, 0x0f, 0xc7, 0x00, 0x0f, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xbe, 0x0f, 0xc7, 0x00, 0x1f, 0x87, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xfe, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7f, 0xc3, 0xfe, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x03, 0xc0, 0x01, 0xf8, 0x07, 0xe3, 0xf0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x03, 0x80, 0x01, 0xf8, 0x07, 0xff, 0xf0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0x00, 0x1e, 0x1f, 0x0e, 0x07, 0x80, 0x01, 0xf8, 0x03, 0xff, 0xe0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0xff, 0xcf, 0xff, 0x0f, 0xff, 0x00, 0x01, 0xf8, 0x01, 0xff, 0xc0, 0x1f, 0x81, 0xf8, 0x0f, 0xc7, 0xff, 0xcf, 0xf7, 0x0f, 0xfe, 0x00, 0x01, 0xf8, 0x00, 0x7f, 0x00, 0x1f, 0x81, 0xf8, 0x0f, 0xc7, 0xff, 0xc3, 0xc7, 0x0e, 0xfc, 0x00 }; const int MPU_addr=0x68; // I2C address of the MPU-6050 int umrechnung; int winkel; int anzahl_messungen = 32; void setup(){ //starte I2C Wire.begin(); //starte MPU 6050 Wire.beginTransmission(MPU_addr); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); //starte SSD1306 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Adresse des OLED's //programm display.clearDisplay(); //Display loeschen display.drawBitmap(3, 20, towilab_logo, 122, 23, WHITE); //Logo zeichnen display.display(); //Werte setzen delay(2000); } void loop(){ int16_t AcX,AcY,AcZ,Tmp = 0; for(int i = 0; i < anzahl_messungen; ++i){ //einlesen MPU6050 Wire.beginTransmission(MPU_addr); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers AcX += Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY += Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) AcZ += Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L) Tmp += Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L) } AcX /= anzahl_messungen; AcY /= anzahl_messungen; AcZ /= anzahl_messungen; Tmp /= anzahl_messungen; //ausgabe Display display.clearDisplay(); //Display loeschen display.setCursor(0, 0); //Cursor setzen display.setTextSize(1); //Text groeße einstellen display.setTextColor(WHITE); //Farbe einstellen display.println("Beschleunigung"); umrechnung = map(AcX, -16800, 16800, -90, 90); winkel = constrain(umrechnung, -90, 90); display.print("X: ");display.print(winkel); umrechnung = map(AcY, -16800, 16800, -90, 90); winkel = constrain(umrechnung, -90, 90); display.print(" Y: ");display.print(winkel); umrechnung = map(AcZ, -16800, 16800, -90, 90); winkel = constrain(umrechnung, -90, 90); display.print(" Z: ");display.println(winkel); display.println(); display.println("Temperatur"); display.print("Tmp: ");display.println(Tmp/340.00+36.53); display.display(); //Werte setzen }
Ein weiteres Beispiel wie der Sensor über die ADAFRUIT Bibliothek ausgewertet werden kann…
#include <Adafruit_MPU6050.h> #include <Adafruit_SSD1306.h> #include <Adafruit_Sensor.h> Adafruit_MPU6050 mpu; Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire); // TowiLab Logo const unsigned char towilab_logo [] PROGMEM = { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc7, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x7f, 0x03, 0xf0, 0x3e, 0x0f, 0xcf, 0xc7, 0x00, 0x07, 0xf8, 0x0e, 0x3c, 0x00, 0x01, 0xf8, 0x01, 0xff, 0xc3, 0xf8, 0x7e, 0x1f, 0xcf, 0xc7, 0x00, 0x0f, 0xfc, 0x0e, 0xff, 0x00, 0x01, 0xf8, 0x03, 0xff, 0xe1, 0xf8, 0x7e, 0x1f, 0x8f, 0xc7, 0x00, 0x0f, 0xfe, 0x0f, 0xff, 0x80, 0x01, 0xf8, 0x07, 0xff, 0xf1, 0xf8, 0x7f, 0x1f, 0x8f, 0xc7, 0x00, 0x0c, 0x0f, 0x0f, 0x87, 0x80, 0x01, 0xf8, 0x07, 0xe3, 0xf1, 0xf8, 0xff, 0x1f, 0x8f, 0xc7, 0x00, 0x00, 0x07, 0x0e, 0x03, 0x80, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xf8, 0xff, 0x1f, 0x0f, 0xc7, 0x00, 0x00, 0x07, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xfc, 0xff, 0x1f, 0x0f, 0xc7, 0x00, 0x00, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0xfc, 0xff, 0xbf, 0x0f, 0xc7, 0x00, 0x07, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xbe, 0x0f, 0xc7, 0x00, 0x0f, 0xff, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xbe, 0x0f, 0xc7, 0x00, 0x1f, 0x87, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7d, 0xe7, 0xfe, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x01, 0xc0, 0x01, 0xf8, 0x0f, 0xc1, 0xf8, 0x7f, 0xc3, 0xfe, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x03, 0xc0, 0x01, 0xf8, 0x07, 0xe3, 0xf0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0x00, 0x1c, 0x07, 0x0e, 0x03, 0x80, 0x01, 0xf8, 0x07, 0xff, 0xf0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0x00, 0x1e, 0x1f, 0x0e, 0x07, 0x80, 0x01, 0xf8, 0x03, 0xff, 0xe0, 0x3f, 0xc3, 0xfc, 0x0f, 0xc7, 0xff, 0xcf, 0xff, 0x0f, 0xff, 0x00, 0x01, 0xf8, 0x01, 0xff, 0xc0, 0x1f, 0x81, 0xf8, 0x0f, 0xc7, 0xff, 0xcf, 0xf7, 0x0f, 0xfe, 0x00, 0x01, 0xf8, 0x00, 0x7f, 0x00, 0x1f, 0x81, 0xf8, 0x0f, 0xc7, 0xff, 0xc3, 0xc7, 0x0e, 0xfc, 0x00 }; void setup() { mpu.begin(); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); //Display loeschen display.drawBitmap(3, 20, towilab_logo, 122, 23, WHITE); //Logo zeichnen display.display(); //Werte setzen delay(2000); // Pause for 2 seconds display.setTextSize(1); display.setTextColor(WHITE); display.setRotation(0); } void loop() { sensors_event_t a, g, temp; mpu.getEvent(&a, &g, &temp); display.clearDisplay(); display.setCursor(0, 0); display.println("Accelerometer - m/s^2"); display.print(a.acceleration.x, 1); display.print(", "); display.print(a.acceleration.y, 1); display.print(", "); display.print(a.acceleration.z, 1); display.println(""); display.println("Gyroscope - rps"); display.print(g.gyro.x, 1); display.print(", "); display.print(g.gyro.y, 1); display.print(", "); display.print(g.gyro.z, 1); display.println(""); display.display(); delay(100); }