【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文件内容:
-
{
-
"extensionName": "Ext_yoyoba",
-
"description": "Extention by YOYOBA",
-
"version": "1.1",
-
"author": "yoyoba(stuyou@126.com)",
-
"homepage": "youhaidong.cn",
-
"sort":0,
-
"javascriptURL":"",
-
"firmware":"1.0",
-
"extensionPort":0,
-
"tags" : "makeblock",
-
"blockSpecs": [
-
[
-
"w",
-
"servo_init( %n )",
-
"servo_init",
-
"2",
-
{
-
"setup":"",
-
"inc":"#include \"demo.h\"",
-
"def":"DemoClass demo; \n",
-
"work":"demo.servo_init({0}); \n",
-
"loop":""
-
}
-
],
-
[
-
"w",
-
"servo_ctrl( %n )",
-
"servo_ctrl",
-
"90",
-
{
-
"setup":"",
-
"inc":"#include \"demo.h\"",
-
"def":"DemoClass demo; \n",
-
"work":"demo.servo_ctrl({0}); \n",
-
"loop":""
-
}
-
],
-
],
-
"translators":{
-
"zh_CN":{
-
"servo_init( %n )":"设置S90G舵机的I/O口( %n )",
-
"servo_ctrl( %n )":"设置S90G舵机的角度( %n )"
-
}
-
}
-
}
demo.cpp文件内容
-
#include "demo.h"
-
#include "myservo.h"
-
DemoClass::DemoClass(){//构造函数
-
pinMode(13,OUTPUT);
-
}
-
DemoClass::~DemoClass()//析构函数
-
{
-
}
-
-
void DemoClass::servo_init(int pin)
-
{
-
servo_pin=pin;
-
servo_init_t(servo_pin);
-
}
-
-
void DemoClass::servo_ctrl(int arg)
-
{
-
servo_arg=arg;
-
servopulse(servo_arg);
-
}
demo.h文件内容:
-
#ifndef demo_h
-
#define demo_h
-
-
#include <Arduino.h>
-
///@brief Class for DemoClass
-
class DemoClass
-
{
-
public:
-
-
DemoClass();
-
~DemoClass();
-
-
//S90G舵机使用的arduino I/O口;
-
void servo_init(int pin);
-
-
//设置S90G舵机角度为arg(0~180)
-
void servo_ctrl(int arg);
-
private:
-
};
myservo.c文件内容:
-
#include <Arduino.h>
-
#include "myservo.h"
-
-
int servo_pin;
-
int servo_arg;
-
-
void servo_init_t(int pin)
-
{
-
pinMode(pin,OUTPUT);
-
}
-
-
void servopulse(int angle)
-
{
-
int i=0;
-
int pulsewidth=(angle*11)+500; //将角度转化为500-2480微秒的脉宽值
-
for(;i<70;i++){//周期性发送70个脉冲,使得S90G舵机偏转一定角度
-
digitalWrite(servo_pin,HIGH); //将舵机接口电平至高
-
delayMicroseconds(pulsewidth); //延时脉宽值的微秒数
-
digitalWrite(servo_pin,LOW); //将舵机接口电平至低
-
delayMicroseconds(20000-pulsewidth);
-
}
-
}
servo.h文件内容:
-
#ifndef MYSERVO__H__
-
#define MYSERVO__H__
-
-
#ifdef __cplusplus
-
extern "C"
-
{
-
#endif//__cplusplus
-
-
extern int servo_pin;
-
extern int servo_arg;
-
-
//初始化S90G舵机使用的arduino的I/O口pin
-
void servo_init_t(int pin);
-
//设置s90G舵机的偏转角度angle(0~180)
-
void servopulse(int angle);
-
-
#ifdef __cplusplus
-
}
-
#endif//__cplusplus
-
-
#endif
【4.实验结果】
在mblock中使用自定义的控制舵机的扩展模块,并编写测试程序,如图2所示,表明能较好的控制舵机的运行。
图2
阅读(3494) | 评论(0) | 转发(0) |