主页 > 编程资料 > Arduino >
发布时间:2017-10-14 作者:网络 阅读:288次

之前有很多朋友问过我,为什么不用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.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);

原文地址:http://www.guokr.com/blog/127438/

关键字词: