发一个我前段时间用ProtoThreads写的一个读取Serial角度并用模拟的方式驱动舵机
关于ProtoThreads的介绍:
http://www.geek-workshop.com/for ... &extra=page%3D1
代码如下- #include <PT_timer.h>
- #include <pt.h>
- int servopin=8;//定义舵机接口数字接口7
- int myangle=100;//定义角度变量
- int val=0;
- static struct pt pt1,pt2;
- PT_timer servotimer;
- static int servoMove(struct pt *pt)
- {
- PT_BEGIN(pt);
- while(1)
- {
- servotimer.setTimer(25);
- PT_WAIT_UNTIL(pt,servotimer.Expired());
- int pulsewidth;//定义脉宽变量
- myangle%=156;//视舵机而定,防止越界
- pulsewidth=myangle*11+500;//将角度转化为500-2205的脉宽值
- digitalWrite(servopin,HIGH);//将舵机接口电平至高
- delayMicroseconds(pulsewidth);//延时脉宽值的微秒数
- digitalWrite(servopin,LOW);//将舵机接口电平至低
- }
- PT_END(pt);
- }
- String inString = "";
- static int angleRead(struct pt *pt)
- {
- PT_BEGIN(pt);
- while(1) {
- PT_WAIT_UNTIL(pt, Serial.available()>0);
- int inChar = Serial.read();
- if (isDigit(inChar))
- inString += (char)inChar;
- if (inChar == ' '||inChar=='\n') {
- myangle=inString.toInt();
- Serial.print("myangle=");
- Serial.println(myangle);
- inString = "";
- }
- }
- PT_END(pt);
- }
- void setup()
- {
- pinMode(servopin,OUTPUT);//设定舵机接口为输出接口
- PT_INIT(&pt1);
- PT_INIT(&pt2);
- Serial.begin(9600);
- }
- void loop()//
- {
- servoMove(&pt1);
- angleRead(&pt2);
- }
复制代码 ServoMove呢就是自己模拟出来的舵机函数,为什么不用servo库呢?因为arduino自身的servo库有很多限制,第一PWM不能用了,第二最小角度只有1度,当然这个程序里舵机的精度也是1度,只要把相应的变量改成float就能精确到小数了,不过最大的好处是舵机脚可以任意设定
servomove中限定了最大角度为155度,这个与舵机有关
angleRead中使用了stringtoInt,每次可以输入一个角度,角度可以以 空格 或 回车 结尾(操蛋的VC2010 SerialMonitor发送数据不带 回车的。。那就空格了)
程序中使用了定时器,自己用C++写的,第一次写库,照葫芦画瓢了。。。
感谢czad的扩展库翻译http://www.geek-workshop.com/forum.php?mod=viewthread&tid=184
这个库用起来非常简单:
PT_Timer t;//定义一个定时器
t.setTimer(unsinged long time) //定时时间,单位ms
t.Expired()//判断定时器是否溢出,是返回值>0
在上面的代码中,一个舵机周期是20ms,前面的约2.5毫秒是信号周期,剩下的10多ms全是无用的低电平,然而又必不可少,所以果断用定时器取代delay
ok
附上
|