Arduino自带的Servo库小实验
由 动力老男孩 发表于 2012/03/23 23:59:04之前有很多朋友问过我,为什么不用Arduino自带的Servo库来控制电机。我在动手做四轴之前,其实也大概看了下Servo库的说明,当时看到
servo.write(angle) 这个函数,其中angle(int)是角度,取值范围是0 到 180
我想当然的认为,这个servo库最多也就是180级的梯度来设置PWM,这样说来精度完全不够啊;另外也没有看到有地方能修改PWM频率。
总结了下我当时不用Servo库的原因:
1. 控制的级数太少,不够精确;
2. 不可修改PWM频率;
3. 需要使用特殊的几个脚;(不知道在什么地方看错了,留下的错误印象)
这几天obK仔给了很多建议,我也看了看源代码。现在看来,上面这几点都是我瞎操心了。
首先,0~180是servo库对应的从min到max的控制,对应于0.9ms到2.1ms的电调来说,angle参数加1对应的时间变化为:
(2.1-0.9)*1000/180 = 6.7微秒,已经是比较精确了。
即使这样如果还觉得不够精确,还可以使用servo.writeMicroseconds,这个函数可以直接用微秒作为参数。
其次,PWM频率是可以修改的,在Servo.h文件中,修改下面这行可以把PWM频率升到400Hz:
#define REFRESH_INTERVAL 2500
不过这只能在编译之前改,不能在程序运行的过程中动态修改。当然修改源代码也可以解决这个问题,把这个参数做成一个变量,用接口进行修改控制即可。
最后,Servo库可以绑定所有digitalWrite的脚,这一点来说,比原生的PWM还方便!
做了一个简单的小程序,测试Servo库同时控制4个电机的情况。实验结果看上去还不错,不过没有测试4个电机转速各不相同的情况。
代码果然看上去简洁多了:
Servo powerServo[4]; void setup() { motorPins[0] = 38; //x1 motorPins[1] = 43; //x2 motorPins[2] = 42; //y1 motorPins[3] = 39; //y2 for(int i = 0; i < 4; i++) powerServo[i].attach(motorPins[i]); } void loop() { long t0 = micros(); //记录进入loop的时间 while(Serial.available()) { // 这里是获取控制指令 pushData(Serial.read()); } double T = 2500; // 一个周期的微秒值 double len = 900 + ctrlPower * 5; //(0~200对应总周期0.9ms~1.9ms) for(int i = 0; i < 4; i++) powerServo[i].writeMicroseconds(len); int leftMs = (int) (t0 + T - micros()); delayMicroseconds(leftMs); }
Yeah~~~沙发一下~~咔咔~~
这两日加上PID的库再继续试飞一下..
一齐努力吧动大哥:)
呼呼,今天心急了,没仔细测试就去试飞了,结果又炸鸡了,呵呵
但应该会更加消耗CPU。
因为“原生PWM”是硬件实现的,设置好参数后不需要CPU干预。
而Servo库可以通过所有Digital Pin输出,应该是计时器+中断实现的,每个周期中断两次,如果频率高,会比较占CPU。
总结的好,各有利弊,必须根据自己的需求来选择
关注中,努力呀,支持你。我最近也在研究这个,想要使用wifi方式,同时可以支持摄像头。
希望成功了也可以发个教程出来,我一直想学者做一个。
同研究者
受益匪浅
PWM的频率可调老大能不能改一下,我们这些小白对底层了解少啊
动力博主:
请教一下,你如何控制这个四个马达的反转呢?直升机的特技飞行中有一种完全倒过来飞的状态,是通过变桨的螺距来实现的,但四轴上没有这类可变螺距结构,同样车模上面如果要后退怎么办,这种情况下,如果能让马达倒转都好,但这个SERVO库我想做不到了……
硬件结构根本不一样,四轴用的是类似半桥的驱动电路,前后的话得全桥
motorPins[0] = 38; //x1
motorPins[1] = 43; //x2
motorPins[2] = 42; //y1
motorPins[3] = 39; //y2
为什么后面的数字是那么大的?不应该是脚管的编号吗?
我这个版本的arduino,管脚就是比较多啊
arduino是哪个型号。
我现在用的是Intel的Galileo板子,为什么我的Servo.h文件里面没有REFRESH_INTERVAL。我想把频率改成50hz。
这个没用过,不太清楚