极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11715|回复: 4

把舵机和陀螺仪捆在一起

[复制链接]
发表于 2014-3-27 03:08:41 | 显示全部楼层 |阅读模式
本帖最后由 shihaipeng04 于 2014-3-27 03:16 编辑

最简陋的自平衡,就是把陀螺仪捆在舵机上,然后用陀螺仪的度数去控制舵机,理论上扭动舵机,陀螺仪就应该保持相对静止的位置上。 这就是自平衡。 但是实际上,会有一些偏差,比如舵机性能差,旋转的时候会有比较明显的抖动,这个抖动传递给陀螺仪,而陀螺仪又会检测到角度变的更大了,于是再次发送更大的角度信号,然后越调节问题越严重。这个问题可以通过更换性能更好的舵机来解决。 另外抓着舵机的手,在陀螺仪眼里和一匹奔跑的马没什么区别,如果你用2只手死死的抓住,会发现舵机会稳当很多。


这是我手工扭动陀螺仪的曲线,明显的毛刺,当然这个问题,还可以通过软件来解决,传说中的各种滤波,让这个参差不齐的曲线变的更平滑。不过目前我还没学会。。

来个代码如果手上有陀螺仪也有舵机的就可以先耍起来了。陀螺仪是adxl345的,舵机无所谓啦,试验正面25克的明显比9克的平稳的多,但是速度不如9的快。
哦对,顺路问一句,为什么adxl345的角度算出来是-270~+270呢? 为什么不是 255或者90?

  1. #include <Wire.h>
  2. #include <Servo.h>

  3. //下面的舵机用的变量和类
  4. Servo myservo;  // create servo object to control a servo
  5.                 // a maximum of eight servo objects can be created

  6. int pos = 0;    // variable to store the servo position

  7. #define Register_ID 0
  8. #define Register_2D 0x2D
  9. #define Register_X0 0x32
  10. #define Register_X1 0x33
  11. #define Register_Y0 0x34
  12. #define Register_Y1 0x35
  13. #define Register_Z0 0x36
  14. #define Register_Z1 0x37

  15. //下面是陀螺仪用的变量
  16. int ADXAddress = 0xA7 >> 1;  // the default 7-bit slave address
  17. int reading = 0;
  18. int val=0;
  19. int X0,X1,X_out;
  20. double Xg,Yg,Zg;


  21. //滤波用的变量
  22. double Filter_Value;
  23. double Value=0;

  24. void setup()
  25. {
  26.   myservo.attach(9);//舵机的pin口号9
  27.   Wire.begin();               
  28.   Serial.begin(9600);   
  29.   delay(100);
  30.   // enable to measute g data
  31.   Wire.beginTransmission(ADXAddress);
  32.   Wire.write(Register_2D);
  33.   Wire.write(8);                //measuring enable
  34.   Wire.endTransmission();     // stop transmitting

  35. }

  36. void loop()
  37. {
  38.   //--------------X 只取X轴角度
  39.   Wire.beginTransmission(ADXAddress); // transmit to device
  40.   Wire.write(Register_X0);
  41.   Wire.write(Register_X1);
  42.   Wire.endTransmission();
  43.   Wire.requestFrom(ADXAddress,2);
  44.   if(Wire.available()<=2)   
  45.   {
  46.     X0 = Wire.read();
  47.     X1 = Wire.read();
  48.     X1=X1<<8;
  49.     X_out=X0+X1;   
  50.   }
  51.   Xg=X_out/3.00;  //换算成角度 -90~+90


  52.   if(((Xg - Value) > 2) || ((Value - Xg) > 2))  //这是个简陋的滤波程序,让数值变化不那么快
  53.     Filter_Value = Xg;
  54.   else
  55.     Filter_Value = Value;
  56.   Value = Filter_Value;   //小于2度的变化就不调节了,当然你也可以删掉这段滤波代码

  57.   myservo.write(Filter_Value+90); //调节舵机的位置,+90 是因为舵机是 0~180,而陀螺仪是-90~+90
  58. //  myservo.write(Xg+90);   //滤波就不起作用了

  59. //下面是调试显示用的代码,运行的时候连delay一起删掉舵机反应会非常迅速
  60. Serial.print("X= ");
  61. Serial.print(Filter_Value);
  62. Serial.print(",");
  63. Serial.print(Xg);
  64. delay(20);
  65. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2014-3-29 09:46:21 | 显示全部楼层
这个貌似挺深的,留个脚印,慢慢看
回复 支持 反对

使用道具 举报

发表于 2014-4-5 12:41:48 | 显示全部楼层
写的貌似不错的样子,看看先
回复 支持 反对

使用道具 举报

发表于 2014-5-7 11:04:48 | 显示全部楼层
adxl345是加速度计{:soso_e127:}
回复 支持 反对

使用道具 举报

发表于 2014-5-9 09:19:58 | 显示全部楼层
单车Up 发表于 2014-5-7 11:04
adxl345是加速度计

加速度计只有在不受外界作用力干扰的情况下(也就是静止或者匀加速运动),才可以用来检测角度
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-24 08:31 , Processed in 0.044619 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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