完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
arduino控制两路舵机
为什么想要用arduino控制舵机呢,说来话长,其实最直接原因就是因为它比较简单易上手吧。 网传控制原理还要看一看 舵机是一种位置伺服的驱动器,主要是由外壳、电路板、无核心马达、齿轮与位置检测器所构成。其工作原理是由接收机或者单片机发出信号给舵机,其内部有一个基准电路,产生周期为 20ms,宽度为 1.5ms 的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。经由电路板上的 IC 判断转动方向,再驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,同时由位置检测器送回信号,判断是否已经到达定位。适用于那些需要角度不断变化并可以保持的控制系统。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为 0,电机停止转动。一般舵机旋转的角度范围是 0 度到 180 度。 其实我也不知道我买的舵机是不是一般的舵机,反正手里的舵机是几个小舵机我看了一下型号 Micro Servo 9g 应该就是江湖上说的SG90舵机记得买的时候是90度舵机,后来实验发现180度也可以转,姑且认为它是180度舵机了。 以上都不重要,重要的是如何接线… 舵机有很多规格,但所有的舵机都有外接三根线,分别用棕、 红、 橙三种颜色进区分,由于舵机品牌不同,颜色也会有所差异, 棕色为接地线, 红色为电源正极线,橙色为信号线。其实我个人感觉知道这些就差不多了,不过鉴于第一次使用arduino驱动舵机我还是决定网上参考一下。 网上说到用 Arduino 控制舵机的方法有两种,一种是通过 Arduino 的普通数字传感器接口产生占空比不同的方波,模拟产生 PWM 信号进行舵机定位。第二种是直接利用Arduino 自带的 Servo 函数进行舵机的控制,这种控制方法的优点在于程序编写,缺点是只能控制 2 路舵机, 因为 Arduino 自带函数只能利用数字 9、 10 接口。 Arduino 的驱动能力有限,所以当需要控制 1 个以上的舵机时需要外接电源。 由于我有四个舵机,其实原本打算做天猫精灵模拟垃圾分类开垃圾箱的,所以决定先尝试第一种方法,毕竟第二种只能驱动两个舵机,太少了。 前人踩过的坑还是要再踩一遍 int servopin=9;//定义数字接口 9 连接伺服舵机信号线 int myangle;//定义角度变量 int pulsewidth;//定义脉宽变量 int val; void servopulse(int servopin,int myangle)//定义一个脉冲函数 { pulsewidth=(myangle*11)+500;//将角度转化为 500-2480 的脉宽值 digitalWrite(servopin,HIGH);//将舵机接口电平至高 delayMicroseconds(pulsewidth);//延时脉宽值的微秒数 digitalWrite(servopin,LOW);//将舵机接口电平至低 delay(20-pulsewidth/1000); } void setup() { pinMode(servopin,OUTPUT);//设定舵机接口为输出接口 Serial.begin(9600);//连接到串行端口,波特率为 9600 Serial.println("servo=o_seral_simple ready" ) ; } void loop()//将 0 到 9 的数转化为 0 到 180 角度,并让 LED 闪烁相应数的次数 { val=Serial.read();//读取串行端口的值 if(val>'0'&&val<='9') { val=val-'0';//将特征量转化为数值变量 val=val*(180/9);//将数字转化为角度 Serial.print("moving servo to "); Serial.print(val,DEC); Serial.println(); for(int i=0;i<=50;i++) //给予舵机足够的时间让它转到指定角度 { servopulse(servopin,val);//引用脉冲函数 } } } 测试效果如图 这段代码可以实现串口发送1到9舵机转动不同的角度,但是我发现了一个问题没法回到0度,而且程序已经设定好了,于是我就看看了作者是如何实现的对应(菜鸡就是这样踩坑的),我把这里进行了修改把0也包括进去了就是把>号换成了>=号 val=Serial.read();//读取串行端口的值 if(val>=‘0’&&val<=‘9’) 注释里说的是0到9对应180度,估计是手误大家都是复制粘贴就导致了将错就错,正确的版本可能就应该带上等于号吧,不管了问题找到了,可是还有一个问题就是我发送10的时候出现了一个奇怪的现象,就是舵机先移动了到了20度后来又移动到了0度,肯定是串口读取把10当成了1和0了,这下我就明白了为啥程序上不设计成0到18对应0度到180度了,那样程序可能就要重新来设计了。这应该是arduino串口的坑,稍后再去探个究竟,先不管,继续改程序,我要控制舵机。 控制两路舵机实现同步的0度到180度连续摆动 参考网上的代码进行了如下修改 #include int servopin_1=9;//定义数字接口 9 连接伺服舵机信号线 int servopin_2=10;//定义数字接口 10 连接伺服舵机信号线 //int myangle_1;//定义角度变量 //int myangle_2;//定义角度变量 int pulsewidth;//定义脉宽变量 int val=0;//初始值 void servopulse(int servopin,int myangle)//定义一个脉冲函数,参数是舵机信号线和角度 { pulsewidth=(myangle*11)+500;//将角度转化为 500-2480 的脉宽值 digitalWrite(servopin,HIGH);//将舵机接口电平至高 delayMicroseconds(pulsewidth);//延时脉宽值的微秒数 digitalWrite(servopin,LOW);//将舵机接口电平至低 delay(20-pulsewidth/1000);//延时周期内剩余时间 } void setup() { pinMode(servopin_1,OUTPUT);//设定舵机1接口为输出接口 pinMode(servopin_2,OUTPUT);//设定舵机2接口为输出接口 Serial.begin(9600);//连接到串行端口,波特率为 9600 Serial.println("servo=o_seral_simple ready" );//串口打印的提示 } void loop() { for(val=0;val<=180;val=val+30) { Serial.print("moving servo to "); Serial.print(val,DEC);//十进制输出 Serial.println();//回车换行 servopulse(servopin_1,val);//1引用脉冲函数 servopulse(servopin_2,val);//2引用脉冲函数 if(val==180)//如果移动到了180度 delay(2000);//暂停两秒钟 } for(val=180;val>=0;val=val-10) { Serial.print("moving servo to "); Serial.print(val,DEC);//十进制输出 Serial.println();//回车换行 servopulse(servopin_1,val);//1引用脉冲函数 servopulse(servopin_2,val);//2引用脉冲函数 if(val==0)//如果移动到了0度 delay(2000);//暂停两秒钟 } } 实现了想要的效果,为了使效果更加明显,我就加了两个大延时(delay大法好) 看人家的程序舵机移动的感觉很迅速,自己的for循环发现舵机跟傻了一样,龟速移动后来修改了for循环的步进值发现速度确实变化了不少,如果想要舵机响应的快一点就可以把步进值30调的更大一些。就这样吧,接下来可能要去填一下arduino串口的坑了。 |
|
|
|
只有小组成员才能发言,加入小组>>
3318 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9063 浏览 16 评论
4088 浏览 18 评论
1182浏览 3评论
608浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
600浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 20:09 , Processed in 1.146900 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号