09.電子水平儀(GY-521)

#include "Wire.h"

#include "I2Cdev.h"

#include "MPU6050.h"

#include <LiquidCrystal_I2C.h>

#include <Kalman.h>

LiquidCrystal_I2C lcd(0x3F,16,2);   // 若LCD 無法啟用,請將0X3F 改為0X27

Kalman kalmanX , kalmanY, kalmanZ;

MPU6050 accelgyro;

int16_t ax, ay, az, gx, gy, gz;

double accX, accY, accZ, gyroX, gyroY, gyroZ;

uint32_t timer;

double pitch, roll, yaw, AngleX, AngleY, AngleZ, Xrate, Yrate, Zrate;

void setup() {

  Wire.begin();

  lcd.init();                     

  lcd.backlight(); 

  lcd.clear();

  Serial.begin(115200);

  accelgyro.initialize();

  accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

  accX = ax; accY = ay; accZ = az; gyroX = gx; gyroY = gy; gyroZ = gz;

  pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;

   roll = atan2(accY  , accZ) * RAD_TO_DEG;

   yaw = atan2(accX  , accY) * RAD_TO_DEG;

  kalmanY.setAngle(pitch);

  kalmanX.setAngle(roll);

  kalmanZ.setAngle(yaw);

}

void loop() {

    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

    accX = ax; 

    accY = ay; 

    accZ = az; 

    gyroX = gx; 

    gyroY = gy; 

    gyroZ = gz;

    double dt = (double)(micros() - timer) / 1000000; // Calculate delta time

    timer = micros();

    pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;

    roll = atan2(accY,accZ) * RAD_TO_DEG;

    yaw = atan2(accX  , accY) * RAD_TO_DEG;

    Yrate = gyroY / 131.0; // Convert to deg/s

    Xrate = gyroX / 131.0;

    Zrate = gyroZ / 131.0;

    AngleY = kalmanY.getAngle(pitch, Yrate, dt);

    AngleX = kalmanX.getAngle(roll, Xrate, dt);

    AngleZ = kalmanZ.getAngle(yaw, Zrate, dt);

   disp();

  

}

void disp(){

if(AngleX>0){

lcd.setCursor(0,0);

lcd.print("X=");

lcd.setCursor(2,0);

lcd.print("+");

lcd.print(AngleX,1);

lcd.print("        ");

}else{

lcd.setCursor(0,0);

lcd.print("X=");

lcd.print(AngleX,1); 

lcd.print("        ");

}

if(AngleY>0){

lcd.setCursor(8,0);

lcd.print("Y=");

lcd.setCursor(10,0);

lcd.print("+");

lcd.print(AngleY,1);

lcd.print("        ");

}else{

lcd.setCursor(8,0);

lcd.print("Y=");

lcd.print(AngleY,1); 

lcd.print("        ");

}

if(AngleZ>0){

lcd.setCursor(0,1);

lcd.print("Z=");

lcd.setCursor(2,1);

lcd.print("+");

lcd.print(AngleZ,1);

lcd.print("        ");

}else{

lcd.setCursor(0,1);

lcd.print("Z=");

lcd.print(AngleZ,1); 

lcd.print("        ");

}

}