1)设计目的
•完成物体的抓取与运输:
•尽可能的实现该装置的易操作性,以适应广大需求;
•验证机械臂的功能并熟悉操作。
2)设计任务
利用嵌入式编程的基础知识和Arduino 软件运行一个四轴机械臂的抓取和搬运,将
相应的代码写入Arduino板并能够通过一些外部控制将机械臂的整个工作流程实现出来。
3)具体视频去b站搜索标题内容即可查找
#include <IRremote.h> //使用IRemote库
#include <Servo.h> //使用servo库
int RECV_PIN = A0; //红外接收器输出口连接A0用于信号输出控制机械臂
int moveStep = 3; //舵机每次移动3度
char serialCmd;
IRrecv irrecv(RECV_PIN); //红外遥控初始化
decode_results results //定义变量results用来存储红外遥控信息
Servo base, fArm, rArm, claw ; //创建4个servo对象
//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0; //底座舵机转动极限为0-180度
const int baseMax = 180;
const int clawMin = 0; //爪子舵机转动极限为0-60度
const int clawMax = 60;
const int rArmMin = 40; //后臂转动极限为40-50度
const int rArmMax = 150;
const int fArmMin = 30; //前臂转动极限为30-100度
const int fArmMax = 100;
int DSD = 15; //Default Servo Delay (默认电机运动延迟时间)
//此变量用于控制电机运行速度.增大此变量数值将
//降低电机运行速度从而控制机械臂动作速度。
/(1)相应引脚连接,和红外信号接收,赋值操作。
void setup()
{
Serial.begin(9600);
// 假如启动过程出现问题,提示用户启动失败
Serial.println("Enabling IRin");
irrecv.enableIRIn(); // 启动红外接收功能
Serial.println("Enabled IRin");
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); // 稳定性等待
base.write(90); //四个舵机分别写入90,90,90,60初始化机械臂,使机械臂
delay(10); 初始化到相应角度。
fArm.write(90);
delay(10);
rArm.write(90);
delay(10);
claw.write(60);
delay(10);
Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial");
}
//
void loop() {
if (irrecv.decode(&results)) //如果该函数成功解析红外信号则返回非0数值,如果无法解析则返回0,从而检查是否接收到红外遥控信号。
{
Serial.println(results.value, HEX); · //result.value为红外遥控信号的具体数值以16进制显示
if(results.value==0xFD30CF) serialCmd='i'; //根据按不同的按键,接受不同的红外信号,对serialCmd进行相应赋值进行不同功能判断和实现
if(results.value==0xFDB04F) serialCmd='p';
if(results.value==0xFD6897) serialCmd='4';
if(results.value==0xFD28D7) serialCmd='6';
if(results.value==0xFD8877) serialCmd='d';
if(results.value==0xFD9867) serialCmd='u';
if(results.value==0xFD50AF) serialCmd='2';
if(results.value==0xFD10EF) serialCmd='8';
if(results.value==0xFD20DF) serialCmd='o';
if(results.value==0xFD609F) serialCmd='c';
armJoyCmd(serialCmd);
irrecv.resume(); //接收下一个红外遥控信号
}
delay(100);
}
///
/(2)不同舵机功能的角度赋值操作
void armJoyCmd(char serialCmd){ //Arduino根据手柄按键执行相应操作
int baseJoyPos;
int rArmJoyPos;
int fArmJoyPos;
int clawJoyPos;
switch(serialCmd){
case '4': // Base向左
Serial.println("Received Command: Base Turn Left");
baseJoyPos = base.read() - moveStep; //底座舵机减小3度
servoCmd('b', baseJoyPos, DSD);
break;
case '6': // Base向右
Serial.println("Received Command: Base Turn Right");
baseJoyPos = base.read() + moveStep; //底座舵机增加3度
servoCmd('b', baseJoyPos, DSD);
break;
case 'd': // rArm向下
Serial.println("Received Command: Rear Arm Down");
rArmJoyPos = rArm.read() + moveStep; //后臂舵机增加3度
servoCmd('r', rArmJoyPos, DSD);
break;
case 'u': // rArm向上
Serial.println("Received Command: Rear Arm Up");
rArmJoyPos = rArm.read() - moveStep; //后臂舵机减小3度
servoCmd('r', rArmJoyPos, DSD);
break;
case '2': // fArm向上
Serial.println("Received Command: Front Arm Up");
fArmJoyPos = fArm.read() + moveStep; //前臂舵机增加3度
servoCmd('f', fArmJoyPos, DSD);
break;
case '8': // fArm向下
Serial.println("Received Command: Front Arm Down");
fArmJoyPos = fArm.read() - moveStep; //前臂舵机减小3度
servoCmd('f', fArmJoyPos, DSD);
break;
case 'c': // Claw关闭
Serial.println("Received Command: Claw Close Down");
clawJoyPos = claw.read() + moveStep; //爪部舵机增加3度
servoCmd('c', clawJoyPos, DSD);
break;
case 'o': // Claw打开
Serial.println("Received Command: Claw Open Up");
clawJoyPos = claw.read() - moveStep; //爪部舵机减小3度
servoCmd('c', clawJoyPos, DSD);
break;
case 'i'://机械臂初始化
armIniPos();
break;
case 'p'://机械臂流水线操作
playDice();
break;
case 'm': // 输出舵机状态信息
reportStatus();
break;
default:
Serial.println("Unknown Command.");//输出未知指令
return;
}
}
///
/(3)机械臂移动和初始化,流水线功能函数具体操作
void servoCmd(char servoName, int toPos, int servoDelay){
Servo servo2go; //创建servo对象
//串口监视器输出接收指令信息
Serial.println("");
Serial.print("+Command: Servo ");
Serial.print(servoName);
Serial.print(" to ");
Serial.print(toPos);
Serial.print(" at servoDelay value ");
Serial.print(servoDelay);
Serial.println(".");
Serial.println("");
int fromPos; //建立变量,存储电机起始运动角度值
switch(servoName){
case 'b':// Base左右操作
if(toPos >= baseMin && toPos <= baseMax){
servo2go = base;
fromPos = base.read(); // 获取当前电机角度值用于“电机运动起始角度值”
break;
} else {
Serial.println("+Warning: Base Servo Value Out Of Limit!");
return;
}
case 'c'://Claw开关操作
if(toPos >= clawMin && toPos <= clawMax){
servo2go = claw;
fromPos = claw.read(); // 获取当前电机角度值用于“电机运动起始角度值”
break;
} else {
Serial.println("+Warning: Claw Servo Value Out Of Limit!");
return;
}
case 'f'://前臂上下操作
if(toPos >= fArmMin && toPos <= fArmMax){
servo2go = fArm;
fromPos = fArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”
break;
} else {
Serial.println("+Warning: fArm Servo Value Out Of Limit!");
return;
}
case 'r'://后臂上下操作
if(toPos >= rArmMin && toPos <= rArmMax){
servo2go = rArm;
fromPos = rArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”
break;
} else {
Serial.println("+Warning: rArm Servo Value Out Of Limit!");
return;
}
}
//指挥电机运行
if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”进行角度增加
for (int i=fromPos; i<=toPos; i++){
servo2go.write(i);
delay (servoDelay);
}
} else { //否则“起始角度值”大于“目标角度值”进行角度减小
for (int i=fromPos; i>=toPos; i--){
servo2go.write(i);
delay (servoDelay);
}
}
}
void reportStatus(){ //舵机状态信息
Serial.println("");
Serial.println("");
Serial.println("+ Robot-Arm Status Report +");
Serial.print("Claw Position: "); Serial.println(claw.read());
Serial.print("Base Position: "); Serial.println(base.read());
Serial.print("Rear Arm Position:"); Serial.println(rArm.read());
Serial.print("Front Arm Position:"); Serial.println(fArm.read());
Serial.println("++++++++++++++++++++++++++");
Serial.println("");
}
void armIniPos(){ //机械臂初始化操作
Serial.println("+Command: Restore Initial Position.");
int robotIniPosArray[4][3] = {
{'b', 90, DSD},
{'r', 90, DSD},
{'f', 90, DSD},
{'c', 60, DSD}
};
for (int i = 0; i < 4; i++){
servoCmd(robotIniPosArray[i][0], robotIniPosArray[i][1], robotIniPosArray[i][2]);
}
}
void playDice(){ //此处通过上面reportStatus()函数,在机械臂不同状态时获取舵机相应角度信息,分别记录下来从而实现机械臂流水线操作。
Serial.println("+Command: Let's play some dice!");
armIniPos(); //机械臂初始化
int diceMove1[21][3] = { //机械臂抓取右边物体
{'c', 0, DSD},
{'b', 90, DSD},
{'f', 43, DSD},
{'r', 126, DSD},
{'c', 60, DSD},
{'r', 90, DSD},
{'b', 60, DSD},
{'f', 36, DSD},
{'r', 135, DSD},
{'c', 0, DSD},
{'r', 90, DSD},
{'b', 90, DSD},
{'f', 36, DSD},
{'r', 135, DSD},
{'c', 60, DSD},
{'r', 90, DSD},
{'b', 60, DSD},
{'f', 48, DSD},
{'r', 123, DSD},
{'c', 0, DSD},
{'r', 90, DSD},
};
for (int i = 0; i < 21; i++){
servoCmd(diceMove1[i][0], diceMove1[i][1], diceMove1[i][2]);
delay(200);
}
armIniPos(); //机械臂初始化
int diceMove2[21][3]{ //机械臂将抓取物放置左边
{'c', 0, DSD},
{'b', 58, DSD},
{'f', 48, DSD},
{'r', 120, DSD},
{'c', 60, DSD},
{'r', 90, DSD},
{'b', 90, DSD},
{'f', 36, DSD},
{'r', 135, DSD},
{'c', 0, DSD},
{'r', 90, DSD},
{'b', 60, DSD},
{'f', 36, DSD},
{'r', 135, DSD},
{'c', 60, DSD},
{'r', 90, DSD},
{'b', 90, DSD},
{'f', 43, DSD},
{'r', 125, DSD},
{'c', 0, DSD},
{'r', 90, DSD},
};
for (int i = 0; i < 21; i++){
servoCmd(diceMove2[i][0], diceMove2[i][1], diceMove2[i][2]);
delay(200);
}
armIniPos(); //机械臂初始化
///