极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 81654|回复: 22

ProtoThreads多线程实例

[复制链接]
发表于 2012-3-21 21:43:07 | 显示全部楼层 |阅读模式
发一个我前段时间用ProtoThreads写的一个读取Serial角度并用模拟的方式驱动舵机
关于ProtoThreads的介绍:
http://www.geek-workshop.com/for ... &extra=page%3D1
代码如下
  1. #include <PT_timer.h>
  2. #include <pt.h>
  3. int servopin=8;//定义舵机接口数字接口7
  4. int myangle=100;//定义角度变量
  5. int val=0;
  6. static struct pt pt1,pt2;
  7. PT_timer servotimer;
  8. static int servoMove(struct pt *pt)
  9. {  
  10.   PT_BEGIN(pt);  
  11.   while(1)
  12.   {
  13.         servotimer.setTimer(25);
  14.         PT_WAIT_UNTIL(pt,servotimer.Expired());
  15.         int pulsewidth;//定义脉宽变量
  16.         myangle%=156;//视舵机而定,防止越界
  17.         pulsewidth=myangle*11+500;//将角度转化为500-2205的脉宽值
  18.         digitalWrite(servopin,HIGH);//将舵机接口电平至高
  19.         delayMicroseconds(pulsewidth);//延时脉宽值的微秒数
  20.         digitalWrite(servopin,LOW);//将舵机接口电平至低
  21.   }
  22.   PT_END(pt);
  23. }

  24. String inString = "";
  25. static int angleRead(struct pt *pt)
  26. {
  27.   PT_BEGIN(pt);
  28.   while(1) {   
  29.     PT_WAIT_UNTIL(pt, Serial.available()>0);
  30.         int inChar = Serial.read();
  31.     if (isDigit(inChar))
  32.       inString += (char)inChar;
  33.     if (inChar == ' '||inChar=='\n') {
  34.       myangle=inString.toInt();
  35.           Serial.print("myangle=");
  36.           Serial.println(myangle);
  37.       inString = "";
  38.         }
  39.   }
  40.   PT_END(pt);
  41. }
  42. void setup()
  43. {
  44.   pinMode(servopin,OUTPUT);//设定舵机接口为输出接口
  45.   PT_INIT(&pt1);
  46.   PT_INIT(&pt2);
  47.   Serial.begin(9600);
  48. }
  49. void loop()//
  50. {
  51.     servoMove(&pt1);
  52.     angleRead(&pt2);
  53. }
复制代码
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
附上

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2012-3-23 08:38:26 | 显示全部楼层
不错,学习了
回复 支持 反对

使用道具 举报

发表于 2012-7-20 22:02:12 | 显示全部楼层
这个可以顶一下,感谢楼主分享。。。。
回复 支持 反对

使用道具 举报

发表于 2012-8-20 10:42:59 | 显示全部楼层
前辈,我想使用定时器在一定的时间内对外部的脉冲进行计数不知可以吗?希望指点一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-20 11:56:31 | 显示全部楼层
提线木偶 发表于 2012-8-20 10:42
前辈,我想使用定时器在一定的时间内对外部的脉冲进行计数不知可以吗?希望指点一下

额。。我不是什么前辈。。
我觉得可以采用外部中断+定时器实现,伪代码:
attachInterrupt(interrupt, function, mode)
pmillis=millis();
Interrupts()
...
if(millis()-pmillis>1000)//假设1秒
{
counter=0;//counter就是计数器,清零
noInterrupts();
}
中断函数、中断计数你可以参考坛里的WIKI
回复 支持 反对

使用道具 举报

发表于 2012-8-22 09:48:17 | 显示全部楼层
Malc 发表于 2012-8-20 11:56
额。。我不是什么前辈。。
我觉得可以采用外部中断+定时器实现,伪代码:
attachInterrupt(interrupt,  ...

如果一直用外部中断会不会影响整个程序的执行呀,如果来一个脉冲进一次中断的话,不停地有脉冲的话程序的其他部分就没法执行了,我是想能不能用定时器来产生一个中断,在执行定时期间采集脉冲数,定时结束发一个中断来进行处理
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-22 12:10:47 | 显示全部楼层
提线木偶 发表于 2012-8-22 09:48
如果一直用外部中断会不会影响整个程序的执行呀,如果来一个脉冲进一次中断的话,不停地有脉冲的话程序的 ...

我上面的代码就可以改成你说的这样,定时器计时到某一时刻,开中断Interrupts(),过一段时间,再关闭中断noInterrupts(),其他你不想计数的时候中断是一直关闭的
回复 支持 反对

使用道具 举报

发表于 2012-10-8 09:37:37 | 显示全部楼层
mark一下mark一下mark一下
回复 支持 反对

使用道具 举报

发表于 2012-10-8 11:35:59 | 显示全部楼层
mark一下。
回复 支持 反对

使用道具 举报

发表于 2012-11-20 16:03:59 | 显示全部楼层
好啊,又是这个库的例子,学一个
回复 支持 反对

使用道具 举报

发表于 2013-2-12 20:41:05 | 显示全部楼层
赞!!! 是直接调用在 IDE硬件的文件夹里用的 WIRING.C这个现有文件啊,看来 ARDUINO 还是作了一些中间件来操作 AVR 底层 硬件寄存器!!!
回复 支持 反对

使用道具 举报

发表于 2013-4-28 23:59:43 | 显示全部楼层
mark一下。
回复 支持 反对

使用道具 举报

发表于 2013-5-22 13:34:05 | 显示全部楼层
好东东,谢谢分享。
回复 支持 反对

使用道具 举报

发表于 2013-5-22 17:22:03 | 显示全部楼层
马克。。。以及头像的妹纸不错~
回复 支持 反对

使用道具 举报

发表于 2014-2-14 19:00:06 | 显示全部楼层
马克。。。。。。。。。。。。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-28 21:39 , Processed in 0.060430 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表