|
本帖最后由 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);
- }
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|