基于Arduino红外控制机械臂+流水线操作

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();  //机械臂初始化
///

 

 

  • 9
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值