arduino驱动带拨片的ST90S微型舵机完成货物拨取任务

您所在的位置:网站首页 舵机怎么使用 arduino驱动带拨片的ST90S微型舵机完成货物拨取任务

arduino驱动带拨片的ST90S微型舵机完成货物拨取任务

2024-07-16 16:08| 来源: 网络整理| 查看: 265

arduino驱动带拨片的ST90S微型舵机完成货物拨取任务 worker 分类:创客DIY教程 发布时间 2021.05.16阅读数 5244 评论数 4 图片概览 舵机/拨片安装方法

舵机驱动板

思路以及实现

可以看到上图中我们总共有5个拨片,每个拨片都是由一个舵机去控制的,因此我们总共需要5个小舵机,为了区分他们,我将其进行了标号并且他们的变量名称我是按照他们的位置来描述的

#include Servo UpLeftServo; // 上左,从后往前看,下同 Servo UpRightServo ; // 上右 Servo DownLeftServo; // 下左 Servo DownRightServo ; // 下右 Servo DownMidServo ; // 下中

arduino自带舵机驱动的库,叫Servo.h,因此在使用之前我们先要将其包含进来。定义好名字之后就要进行初始化了,前面我们定义了舵机控制对象,在这里我们要将其进行初始化,函数就是XXX.attach(pin),XXX是定义的舵机名字,pin是该舵机的信号引脚,在我们用的板子中‘D’开头的信号引脚初始化的时候不用带‘D’,否则会提示找不到该引脚,还请注意

void AngleInit() {//开始都是先都打到90度 UpLeftServo.write(90); delay(20); DownLeftServo.write(90); delay(20); DownMidServo.write(90); delay(20); DownRightServo.write(90); delay(20); UpRightServo.write(90); } void setup() { for(uint8_t i = 1 ; i < 6;i++){ last_turn_angle[i] = 90; } UpLeftServo.attach(7); //定义舵机的引脚为 DownLeftServo.attach(10); DownMidServo.attach(A0); DownRightServo.attach(A3); UpRightServo.attach(A2); AngleInit(); Serial.begin(9600); //设置波特率 while (Serial.read() >= 0) {}; }

因为舵机打角是连续的才比较稳定,因此我是让舵机按照1°的变化趋势进行打角。如果一次性舵机让舵机打一个很大的角度,舵机很有可能会用力过猛,导致打到相应的角度之后进入一个抖动的状态,如下图所示同时还有一个问题,那就是如果我不知道某一时刻舵机的打角,那么我按照1°打角变化的话,那就不知道是按1°递增还是按1°递减了,因此我就在初始化的时候都把舵机打到某一个特定的位置,我设定的是90°下层3个舵机角度与状态关系上层2个舵机角度与状态关系那么之后相对于给90°进行偏移打脚,即我们串口送给arduino板子的舵机打脚范围是-90~90°时即可完成世界坐标下的0 ~ 180°打脚。但是这样还是不够,因为在后面打脚变化了之后我还需要知道上一次的打脚位置,因此我就设置了一个last_turn_angle数组,专门用来存放每个舵机上一次的打脚,并且根据上一次的打脚来打这次需要的角度,程序实现如下

int last_turn_angle[6]; void setup() { for(uint8_t i = 1 ; i < 6;i++){//初始化里的赋值操作,初始化打脚都是90度 last_turn_angle[i] = 90; } } void TestServo() { send_sta = Serial.write("&"); char symbol; char angle; char steer_pos; uint8_t now_id; steer_pos = mov_cmd[0]; symbol = mov_cmd[1]; angle = mov_cmd[2]; if(symbol == '+'){ turn_angle = angle - '0'; }else if(symbol == '-'){ turn_angle = -(angle - '0'); } turn_angle *= 10; turn_angle = 90 + turn_angle; if(turn_angle > 177) turn_angle = 177;//限幅 else if(turn_angle < 2) turn_angle = 2;//限幅 now_id = (steer_pos - '0'); if(steer_pos == '1'){ServoCtl(UpLeftServo,last_turn_angle[now_id]);} else if(steer_pos == '2'){ServoCtl(DownLeftServo,last_turn_angle[now_id]);} else if(steer_pos == '3'){ServoCtl(DownMidServo,last_turn_angle[now_id]);} else if(steer_pos == '4'){ServoCtl(DownRightServo,last_turn_angle[now_id]);} else if(steer_pos == '5'){ServoCtl(UpRightServo,last_turn_angle[now_id]);} last_turn_angle[now_id] = turn_angle; Serial.println(turn_angle); send_sta = Serial.write("#"); } void ServoCtl(Servo steer,uint8_t last_turn_angle) { int symbol = 0; if(turn_angle > last_turn_angle){ symbol = 1; }else{ symbol = -1; } for(uint8_t i = last_turn_angle;i != turn_angle; i += symbol){ steer.write(i); } }

但是即使我做了这样的1°变化缓冲操作之后,舵机打脚时还是会出现抖动的状态,百思不得其解,遂上网搜索原因,有说servo库所用定时器和串口定时器冲突的,有说没有共地的,我都试了,但是没有用,只好冷静下来自己思考了。灵感总是来得出乎意料,我想是不是因为我每次打脚都打到底的原因了呢?因为我每次都让舵机打到0°或者180°,相当于是都打到了舵机的极点,这样可能不够稳定,因此我就想着给舵机打角限幅,限制到了2~177°,程序如下

if(turn_angle > 175) turn_angle = 175;//限幅 else if(turn_angle < 5) turn_angle = 5;//限幅

最终解决了问题,实现了舵机的稳定控制打角,效果如下

串口命令

因为程序是串口接收命令的,因此loop()里面是这样写的

void loop() { delay(50); while (Serial.available() > 0) { delay(100); send_sta = Serial.readBytes(mov_cmd,6); TestServo(); break; } while (Serial.read() >= 0){} }

为了保证控制的稳定性,我在程序里面设置了应答措施,当arduino板子接收到命令之后会通过send_sta = Serial.write("&");语句,也就是通过串口发送一个&符号告诉上层自己接收到了命令,当arduino完成了动作之后会通过send_sta = Serial.write("#");语句,也就是通过串口发送一个#符号告诉上层自己完成了命令。具体的命令传递数组含义如下图所示

烧写问题

在烧写程序的时候,偶尔会报这样一个错误我也在网上查了很多资料,有说板子型号没选对的,有说没有共地的,我都尝试了一下,发现并没有什么用,最终还是通过插拔烧写线和重启arduino IDE来解决这个问题的,目前并不知道该问题的具体解决方法,但是通过上述操作还是顺利的将程序烧写进了arduino板子。

实际上,就算烧写的时候arduino IDE报了如上错误,程序还是会被烧写进arduino板子里的。

(づ ̄3 ̄)づ╭❤~一键三连,这次一定(๑•̀ㅂ•́)و✧

单片机嵌入式

原创文章作者:worker。如若转载,请注明出处:古月居 https://www.guyuehome.com/33961

打赏 0

点赞 0

收藏 0

分享

微信 微博 QQ 图片 上一篇:arduino控制步进电机移动丝杆实现拨片架水平移动 下一篇:STM32CubeMX配置STM32F103C8Tx芯片制作串口数据管理器


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3