Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1211673
  • 博文数量: 124
  • 博客积分: 5772
  • 博客等级: 大校
  • 技术积分: 1647
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-27 10:39
文章分类

全部博文(124)

文章存档

2020年(1)

2019年(1)

2018年(5)

2017年(2)

2016年(17)

2015年(3)

2014年(7)

2013年(11)

2012年(13)

2011年(30)

2010年(34)

分类: 嵌入式

2018-05-23 21:10:13

【1.关于SG90舵机】

SG90舵机是Arduino中常用的一种舵机。这是一种模拟舵机,和数字舵机不同,模拟舵机需要持续发送控制脉冲,才能使舵机旋转到某个角度并保持。

Arduino中使用SG90舵机,常用方法是使用servo库。但是servo库使用了timer1定时器,和arduino产生pwm信号也使用了timer1定时器,因此使用servo库和使用pwm产生冲突。其中一个解决方法是把舵机的控制口接到一个非PWM口(如2号口),利用软件从2号口输出控制舵机的波形。

要控制SG90u舵机,需要持续不断给SG90发送周期为20ms的脉冲,单个脉冲周期中高电平的持续时间t决定了舵机的旋转角度。其中t为500微秒到2500微秒,对应着舵机旋转角度0到180度。并且高电平持续时间t和舵机旋转角度保持着线性对应关系。如2号口产生了高电平保持500微秒的脉冲,SG90舵机角度为0度,2号口产生了高电平保持2500微秒的脉冲,SG90舵机角度为180度,

【2.使用mblock产生舵机控制脉冲】

使用mblock自带的标准模块,产生控制SG90舵机的脉冲信号,如图1所示 


                                   图1
根据图1,产生了80个周期为20ms的脉冲,脉冲高电平的持续时间由angle决定。该模块产生的控制舵机旋转角度的精度不够。经过分析发现,这里使用的延时模块(等待x秒)由millis()函数产生,而millis函数的精度为ms级,因此不能产生精度为微秒级的延迟。所以导致产生的脉冲高电平持续时间不精确,进而造成控制舵机旋转角度不精确。

【3.自定义mblock模块,控制SG90舵机】

Arduino中有delayMicroseconds()函数,可以产生微秒级的延迟,但是mblock中并没有提供该函数相应的模块。决定自定义mblock扩展模块,使用delayMicroseconds()函数,产生精度为微秒级的舵机控制脉冲。

自定义的舵机控制模块一共使用了5个文件:Ext_yoyoba.s2e,demo.cpp,demo.h,myservo.c,myservo.h,内容分别如下:

ext_yoyoba.s2e文件内容:

  1. {    
  2.     "extensionName": "Ext_yoyoba",
  3.     "description": "Extention by YOYOBA",
  4.     "version": "1.1",
  5.     "author": "yoyoba(stuyou@126.com)",
  6.     "homepage": "youhaidong.cn",
  7.     "sort":0,
  8.     "javascriptURL":"",
  9.       "firmware":"1.0",
  10.       "extensionPort":0,
  11.     "tags" : "makeblock",
  12.     "blockSpecs": [
  13.         [
  14.             "w",
  15.             "servo_init( %n )",
  16.             "servo_init",
  17.             "2",
  18.             {
  19.                 "setup":"",
  20.                 "inc":"#include \"demo.h\"",
  21.                 "def":"DemoClass demo; \n",
  22.                 "work":"demo.servo_init({0}); \n",
  23.                 "loop":""
  24.             }
  25.         ],
  26.         [
  27.             "w",
  28.             "servo_ctrl( %n )",
  29.             "servo_ctrl",
  30.             "90",
  31.             {
  32.                 "setup":"",
  33.                 "inc":"#include \"demo.h\"",
  34.                 "def":"DemoClass demo; \n",
  35.                 "work":"demo.servo_ctrl({0}); \n",
  36.                 "loop":""
  37.             }
  38.         ],
  39.     ],
  40.     "translators":{
  41.         "zh_CN":{
  42.                   "servo_init( %n )":"设置S90G舵机的I/O口( %n )",
  43.                   "servo_ctrl( %n )":"设置S90G舵机的角度( %n )"
  44.         }
  45.     }
  46. }
demo.cpp文件内容

  1. #include "demo.h"
  2. #include "myservo.h"
  3. DemoClass::DemoClass(){//构造函数
  4.     pinMode(13,OUTPUT);
  5. }
  6. DemoClass::~DemoClass()//析构函数
  7. {
  8. }

  9. void DemoClass::servo_init(int pin)
  10. {
  11.     servo_pin=pin;
  12.     servo_init_t(servo_pin);
  13. }

  14. void DemoClass::servo_ctrl(int arg)
  15. {
  16.     servo_arg=arg;
  17.     servopulse(servo_arg);
  18. }
demo.h文件内容:

  1. #ifndef demo_h
  2. #define demo_h

  3. #include <Arduino.h>
  4. ///@brief Class for DemoClass
  5. class DemoClass
  6. {
  7.     public:
  8.     
  9.         DemoClass();
  10.         ~DemoClass();

  11.         //S90G舵机使用的arduino I/O口;
  12.         void servo_init(int pin);

  13.         //设置S90G舵机角度为arg(0~180)
  14.         void servo_ctrl(int arg);
  15.     private:
  16. };
myservo.c文件内容:

  1. #include <Arduino.h>
  2. #include "myservo.h"

  3. int servo_pin;
  4. int servo_arg;

  5. void servo_init_t(int pin)
  6. {
  7.     pinMode(pin,OUTPUT);
  8. }

  9. void servopulse(int angle)
  10. {
  11.     int i=0;
  12.      int pulsewidth=(angle*11)+500; //将角度转化为500-2480微秒的脉宽值
  13.      for(;i<70;i++){//周期性发送70个脉冲,使得S90G舵机偏转一定角度
  14.          digitalWrite(servo_pin,HIGH); //将舵机接口电平至高
  15.          delayMicroseconds(pulsewidth); //延时脉宽值的微秒数
  16.          digitalWrite(servo_pin,LOW); //将舵机接口电平至低
  17.          delayMicroseconds(20000-pulsewidth);
  18.      }
  19. }
servo.h文件内容:

  1. #ifndef MYSERVO__H__
  2. #define MYSERVO__H__

  3. #ifdef __cplusplus
  4. extern "C"
  5. {
  6. #endif//__cplusplus

  7. extern int servo_pin;
  8. extern int servo_arg;

  9. //初始化S90G舵机使用的arduino的I/O口pin    
  10. void servo_init_t(int pin);
  11. //设置s90G舵机的偏转角度angle(0~180)
  12. void servopulse(int angle);
  13.     
  14. #ifdef __cplusplus
  15. }
  16. #endif//__cplusplus

  17. #endif

【4.实验结果】

在mblock中使用自定义的控制舵机的扩展模块,并编写测试程序,如图2所示,表明能较好的控制舵机的运行。 

            图2














阅读(2690) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~