极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14098|回复: 1

使用mpu6050 PID問題

[复制链接]
发表于 2013-7-9 13:15:26 | 显示全部楼层 |阅读模式
以下是我的程式碼
  1. #include "Wire.h"
  2. #include "I2Cdev.h"
  3. #include "MPU6050.h"
  4. #include "PID_v1.h"
  5. #include  "Servo.h"

  6. MPU6050 accelgyro;
  7. int16_t ax, ay, az;
  8. int16_t gx, gy, gz;

  9. #define Gry_offset_X 45//陀螺仪X轴的静态飘移。
  10. #define Gry_offset_Y 271
  11. #define Gyr_Gain -0.00763//由陀螺仪X轴读数转换为角速度值,=1/131,向前方向与X轴为反方向,故乘以-1

  12. #define ACC_Gain 0.000061//由读数转换为加速度值,=1/16384
  13. #define pi 3.1415926
  14. #define K_x 0.715//一阶互补滤波权重取值,不知由来,可更改。
  15. #define k_Y 1.3

  16. unsigned long preTime = 0;
  17. Servo myservo;
  18. float angle_X = 0;
  19. float angle_Y = 0;

  20. float Kp=5; //Initial Proportional Gain
  21. float Ki=0; //Initial Integral Gain
  22. float Kd=0; //Initial Differential Gain
  23. float  Input, Output;
  24. float  Setpoint=45;
  25. int  Direction;
  26. PID myPID(&Input, &Output, &Setpoint,Kp,Ki,Kd, DIRECT);
  27. void setup()
  28. {
  29.   Wire.begin();
  30.   Serial.begin(9600);
  31.   accelgyro.initialize();//MPU6050初始化。
  32.   myservo.attach(6,1000,2200);
  33.   delay(2500);
  34.   myservo.writeMicroseconds(1000);
  35.   delay(2000);
  36.   
  37.   
  38.   myPID.SetMode(AUTOMATIC);
  39. }

  40. void loop()
  41. {
  42.   accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);//读取六轴数值
  43.   MPU6050_Angle();
  44.   Input = angle_X;
  45.   myPID.Compute();
  46.   myservo.write(Output);
  47.   
  48.   //delay(10);

  49.     Serial.print(angle_X); Serial.print("\t");
  50.     Serial.print(angle_Y); Serial.print("\t");
  51.     Serial.println(Output);
  52.     }
  53. void  MPU6050_Angle()
  54. {
  55.   unsigned long now = millis();//当前时间(ms)
  56.   double dt = (now - preTime);//微分时间(s)
  57.   preTime = now;//上一次采样时间(ms)
  58.   double Ay = ay * ACC_Gain;//转换为向前的加速度(g),为负值
  59.   double Az = az * ACC_Gain;//转换为向下的加速度(g)
  60.   double Ax = ax * ACC_Gain;
  61.   
  62.   double angleA_X= atan(Ay / Az)* 180/ pi;        //加速度仪,反正切获得弧度值,乘以180度/pi
  63.   double angleA_Y= atan(Ax / Az)*180/pi;          //获得角度值,乘以-1得正

  64.   double gx_revised = gx + Gry_offset_X;//陀螺仪x轴静态时修正后的角速度读数,向前为负值
  65.   double gy_revised = gy + Gry_offset_Y;
  66.   double omega_X= Gyr_Gain* gx_revised;//陀螺仪,转换为向前的角速度(o/s),Gyr_Gain取负,故负负得正
  67.   double omega_Y= Gyr_Gain* gy_revised;
  68.   
  69.   double angle_dt_X = omega_X * dt;//角度的单次积分值
  70.   double angle_dt_Y = omega_Y * dt;

  71.   angle_X+= (Gyr_Gain * (gx + Gry_offset_X)) * dt;
  72.   angle_Y+= (Gyr_Gain * (gy + Gry_offset_Y)) * dt;


  73.   double A_X= K_x/ (K_x+ dt);
  74.   //陀螺仪的权值
  75.   double A_Y= k_Y/(k_Y+dt);
  76.   angle_X= A_X* (angle_X+ omega_X* dt)+ (1-A_X)* angleA_X;//一阶互补滤波后的输出角度(o)
  77.   angle_Y= A_Y*(angle_Y+omega_Y*dt)+(1-A_Y)*angleA_Y;
  78. }
  79.    
复制代码

我使用的arduino mega 2560
執行一段時間arduino都會停住
請問是程式碼有問題還是硬體部分呢?
回复

使用道具 举报

发表于 2013-11-7 20:52:54 | 显示全部楼层
对于我们不懂算法的有很大帮助,谢啦
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-13 22:59 , Processed in 0.113949 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表