shihaipeng04 发表于 2014-3-27 03:08:41

把舵机和陀螺仪捆在一起

本帖最后由 shihaipeng04 于 2014-3-27 03:16 编辑

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


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

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

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

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

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

#define Register_ID 0
#define Register_2D 0x2D
#define Register_X0 0x32
#define Register_X1 0x33
#define Register_Y0 0x34
#define Register_Y1 0x35
#define Register_Z0 0x36
#define Register_Z1 0x37

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


//滤波用的变量
double Filter_Value;
double Value=0;

void setup()
{
myservo.attach(9);//舵机的pin口号9
Wire.begin();               
Serial.begin(9600);   
delay(100);
// enable to measute g data
Wire.beginTransmission(ADXAddress);
Wire.write(Register_2D);
Wire.write(8);                //measuring enable
Wire.endTransmission();   // stop transmitting

}

void loop()
{
//--------------X 只取X轴角度
Wire.beginTransmission(ADXAddress); // transmit to device
Wire.write(Register_X0);
Wire.write(Register_X1);
Wire.endTransmission();
Wire.requestFrom(ADXAddress,2);
if(Wire.available()<=2)   
{
    X0 = Wire.read();
    X1 = Wire.read();
    X1=X1<<8;
    X_out=X0+X1;   
}
Xg=X_out/3.00;//换算成角度 -90~+90


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

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

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

迷你强 发表于 2014-3-29 09:46:21

这个貌似挺深的,留个脚印,慢慢看

tangcheng12353 发表于 2014-4-5 12:41:48

写的貌似不错的样子,看看先

单车Up 发表于 2014-5-7 11:04:48

adxl345是加速度计{:soso_e127:}

单车Up 发表于 2014-5-9 09:19:58

单车Up 发表于 2014-5-7 11:04 static/image/common/back.gif
adxl345是加速度计

加速度计只有在不受外界作用力干扰的情况下(也就是静止或者匀加速运动),才可以用来检测角度
页: [1]
查看完整版本: 把舵机和陀螺仪捆在一起