2-12、13 调试机械臂及控制运行速度(meArm机械臂)
2-12 调试mearm机械臂
注意
在进行调试机械臂时,若是使用USB扩展器串口为COM11,发现打开arduino串口监视器会不断的初始化(arduino的初始化程序不断被执行,影响串口通信),当使用电脑上的稳定的接口如COM5时,需要重新上传程序到arduino,然后
演示
输入r45
发现状态如右侧,后臂座机基本达到极限状态了,再输入新的指令要非常小心(r40,不动了,基本肯定45为其向后的极限,所以在常量设置rArmMin=45如下)
同理,经过不断的试探,得到机械臂的相关电机的各个极限角度如下图所示(在使用串口通信时输入的角度转动值不要超出此极限范围,不然容易损坏设备)
上述极限值为教程上的,与自己的可能会有一些出入,建议找到自己的极限值
常量存储极限值(一旦固定不能改变,若使用变量可能会发生变化(主程序内部的更改等))
常量
/*
MeArm机械臂控制程序-1
by 太极创客 (2017-06-02)
WWW.TAICHI-MAKER.COM
本程序用于太极创客《零基础入门学用Arduino教程 - MeArm篇》。
1 使用串口获得电机数据,设置机械臂动作
将串口指令解读改写为函数,加入状态汇报函数reportStatus
如需要获得具体电路连接细节,请查阅太极创客制作的
《零基础入门学用Arduino教程 - MeArm篇》页面。
*/
#include <Servo.h> //使用servo库
Servo base, fArm, rArm, claw ; //创建4个servo对象
// 建立4个int型变量存储当前电机角度值
// 初始角度值为设备启动后初始状态所需要的电机角度数值
int basePos = 90;
int rArmPos = 90;
int fArmPos = 90;
int clawPos = 90;
//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;
void setup(){
base.attach(11); // base 伺服舵机连接引脚11 舵机代号'b'
delay(200); // 稳定性等待
rArm.attach(10); // rArm 伺服舵机连接引脚10 舵机代号'r'
delay(200); // 稳定性等待
fArm.attach(9); // fArm 伺服舵机连接引脚9 舵机代号'f'
delay(200); // 稳定性等待
claw.attach(6); // claw 伺服舵机连接引脚6 舵机代号'c'
delay(200); // 稳定性等待
Serial.begin(9600);
Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial.");
}
void loop(){
if (Serial.available()>0) { //使用串口监视器输入电机指令控制机械臂电机
char serialCmd = Serial.read();//指令举例: b45,将底盘舵机调整到45度位置
armDataCmd(serialCmd);
}
//重新设置各个电机参数(全局变量角度参数会在armDataCmd中被改变,下方会设置)
base.write(basePos);
delay(10);
fArm.write(fArmPos);
delay(10);
rArm.write(rArmPos);
delay(10);
claw.write(clawPos);
delay(10);
}
void armDataCmd(char serialCmd){//b45
Serial.print("serialCmd = ");
Serial.print(serialCmd); //显示字符b
int servoData = Serial.parseInt(); //servoData =45
switch(serialCmd){
case 'b':
basePos = servoData; //basePos全局变量存储角度数值的
Serial.print(" Set base servo value: ");
Serial.println(servoData); //显示输出电机角度
break;
case 'c':
clawPos = servoData;
Serial.print(" Set claw servo value: ");
Serial.println(servoData);
break;
case 'f':
fArmPos = servoData;
Serial.print(" Set fArm servo value: ");
Serial.println(servoData);
break;
case 'r':
rArmPos = servoData;
Serial.print(" Set rArm servo value: ");
Serial.println(servoData);
break;
case 'o':
reportStatus();
break;
default:
Serial.println(" Unknown Command.");
}
}
void reportStatus(){
Serial.println("");
Serial.println("");
Serial.println("++++++ Robot-Arm Status Report +++++");
Serial.print("Claw Position: clawPos = "); Serial.println(claw.read());
Serial.print("Base Position: basePos = "); Serial.println(base.read());
Serial.print("Rear Arm Position: rArmPos = "); Serial.println(rArm.read());
Serial.print("Front Arm Position: fArmPos = "); Serial.println(fArm.read());
Serial.println("++++++++++++++++++++++++++++++++++++");
Serial.println("");
}
2-13 控制机械臂运行速度
通过之前的学习可以是机械臂做出一些动作了,但动作生硬,速度较快
接下来就是升级控制程序,是机械臂流畅运行
效果演示
可以明显看到机械臂动作顺畅
通过调节舵机转动速度进行其动作的顺畅
直接从90度转到0度时不够流畅的,可以在起始与目标状态之间增加状态步数以及等待时间
可以通过控制等待时间,控制舵机旋转速度
代码如下
(1)直接转动,无中间步数及等待时间
/*
MeArm机械臂控制程序-1
by 太极创客 (2017-06-02)
www.taichi-maker.com
本程序用于太极创客《零基础入门学用Arduino教程 - MeArm篇》。
1 使用串口获得电机数据,设置机械臂动作
将串口指令解读改写为函数,加入状态汇报函数reportStatus
如需要获得具体电路连接细节,请查阅太极创客制作的
《零基础入门学用Arduino教程 - MeArm篇》页面。
*/
#include <Servo.h> //使用servo库
Servo base, fArm, rArm, claw ; //创建4个servo对象
// 建立4个int型变量存储当前电机角度值
// 初始角度值为设备启动后初始状态所需要的电机角度数值
int basePos = 90;
int rArmPos = 90;
int fArmPos = 90;
int clawPos = 90;
//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;
void setup(){
base.attach(11); // base 伺服舵机连接引脚11 舵机代号'b'
delay(200); // 稳定性等待
rArm.attach(10); // rArm 伺服舵机连接引脚10 舵机代号'r'
delay(200); // 稳定性等待
fArm.attach(9); // fArm 伺服舵机连接引脚9 舵机代号'f'
delay(200); // 稳定性等待
claw.attach(6); // claw 伺服舵机连接引脚6 舵机代号'c'
delay(200); // 稳定性等待
Serial.begin(9600);
Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial");
}
void loop(){
if (Serial.available()>0) { //使用串口监视器输入电机指令控制机械臂电机
char serialCmd = Serial.read();//指令举例: b45,将底盘舵机(舵机代号'b')调整到45度位置
armDataCmd(serialCmd);
}
base.write(basePos);
delay(10);
fArm.write(fArmPos);
delay(10);
rArm.write(rArmPos);
delay(10);
claw.write(clawPos);
delay(10);
}
void armDataCmd(char serialCmd){
Serial.print("serialCmd = ");
Serial.print(serialCmd);
int servoData = Serial.parseInt();
switch(serialCmd){
case 'b':
basePos = servoData;
Serial.print(" Set base servo value: ");
Serial.println(servoData);
break;
case 'c':
clawPos = servoData;
Serial.print(" Set claw servo value: ");
Serial.println(servoData);
break;
case 'f':
fArmPos = servoData;
Serial.print(" Set fArm servo value: ");
Serial.println(servoData);
break;
case 'r':
rArmPos = servoData;
Serial.print(" Set rArm servo value: ");
Serial.println(servoData);
break;
case 'o':
reportStatus();
break;
default:
Serial.println(" Unknown Command.");
}
}
void reportStatus(){
Serial.println("");
Serial.println("");
Serial.println("++++++ Robot-Arm Status Report +++++");
Serial.print("Claw Position: clawPos = "); Serial.println(claw.read());
Serial.print("Base Position: basePos = "); Serial.println(base.read());
Serial.print("Rear Arm Position: rArmPos = "); Serial.println(rArm.read());
Serial.print("Front Arm Position: fArmPos = "); Serial.println(fArm.read());
Serial.println("++++++++++++++++++++++++++++++++++++");
Serial.println("");
}
(2)已改进代码,可控制速度
/*
MeArm机械臂控制程序-1
by 太极创客 (2017-06-02)
www.taichi-maker.com
本程序用于太极创客《零基础入门学用Arduino教程 - MeArm篇》。
1 使用串口获得电机数据,设置机械臂动作
将串口指令解读改写为函数,加入状态汇报函数reportStatus
如需要获得具体电路连接细节,请查阅太极创客制作的
《零基础入门学用Arduino教程 - MeArm篇》页面。
*/
#include <Servo.h> //使用servo库
Servo base, fArm, rArm, claw ; //创建4个servo对象
// 建立4个int型变量存储当前电机角度值
// 初始角度值为设备启动后初始状态所需要的电机角度数值
int basePos = 90;
int rArmPos = 90;
int fArmPos = 90;
int clawPos = 90;
//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;
void setup(){
base.attach(11); // base 伺服舵机连接引脚11 舵机代号'b'
delay(200); // 稳定性等待
rArm.attach(10); // rArm 伺服舵机连接引脚10 舵机代号'r'
delay(200); // 稳定性等待
fArm.attach(9); // fArm 伺服舵机连接引脚9 舵机代号'f'
delay(200); // 稳定性等待
claw.attach(6); // claw 伺服舵机连接引脚6 舵机代号'c'
delay(200); // 稳定性等待
Serial.begin(9600);
Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial");
}
void loop(){
if (Serial.available()>0) {
char serialCmd = Serial.read();
armDataCmd(serialCmd);
}
base.write(basePos);
delay(10);
fArm.write(fArmPos);
delay(10);
rArm.write(rArmPos);
delay(10);
claw.write(clawPos);
delay(10);
}
void armDataCmd(char serialCmd){
Serial.print("serialCmd = ");
Serial.print(serialCmd);
int servoData = Serial.parseInt();
int fromPos;
int toPos;
switch(serialCmd){
case 'b':
fromPos = base.read();
toPos = servoData;
if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”
for (int i=fromPos; i<=toPos; i++){
base.write(i);
delay (15);
}
} else { //否则“起始角度值”大于“目标角度值”
for (int i=fromPos; i>=toPos; i--){
base.write(i);
delay (15);
}
}
basePos = servoData;
Serial.print(" Set base servo value: ");
Serial.println(servoData);
break;
case 'c':
clawPos = servoData;
Serial.print(" Set claw servo value: ");
Serial.println(servoData);
break;
case 'f':
fArmPos = servoData;
Serial.print(" Set fArm servo value: ");
Serial.println(servoData);
break;
case 'r':
rArmPos = servoData;
Serial.print(" Set rArm servo value: ");
Serial.println(servoData);
break;
case 'o':
reportStatus();
break;
default:
Serial.println(" Unknown Command.");
}
}
void reportStatus(){
Serial.println("");
Serial.println("");
Serial.println("++++++ Robot-Arm Status Report +++++");
Serial.print("Claw Position: clawPos = "); Serial.println(claw.read());
Serial.print("Base Position: basePos = "); Serial.println(base.read());
Serial.print("Rear Arm Position: rArmPos = "); Serial.println(rArm.read());
Serial.print("Front Arm Position: fArmPos = "); Serial.println(fArm.read());
Serial.println("++++++++++++++++++++++++++++++++++++");
Serial.println("");
}