|
STM32搬运 Arduino搬运 颜色分拣 |
1. 功能描述
R265样机是一款拥有5自由度的串联机械臂。本文提供的示例所实现的功能为:实现5自由度串联机械臂搬运物品的功能。
2. 电子硬件
在这个示例中,我们采用了以下硬件,请大家参考:
主控板 | STM32主控板 |
扩展板 | STM32扩展板 |
舵机 | 270°伺服电机、标准舵机 |
电池 | 7.4V锂电池 |
物料编号 | 舵机1 | 舵机2 | 舵机3 | 舵机4 | 舵机5 | 舵机6 |
主控板引脚 | PB15 | PB14 | PB9 | PB8 | PE6 | PE5 |
/*------------------------------------------------------------------------------------ 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved. Distributed under MIT license.See file LICENSE for detail or copy at https://opensource.org/licenses/MIT by 机器谱 2023-02-07 https://www.robotway.com/ ------------------------------*/ #include "sys.h" #include "led.h" #include "pwm.h" #include "stdio.h" #include "string.h" #include "time.h" #include "stdlib.h" void split(char *src,const char *separator,char **dest,int *num);//字符串拆分函数 void Steering_Gear_Angle(u8 num, u16 ang);//时间最少20ms 控制舵机移动 void mysplite(char *src, char **p, const char *separator, const char *separator1, int *num);//字符串拆分函数 void buf_init(void);//清空接受数组 void all_servo_angle_init(); void all_servo_move(float value0, float value1, float value2, float value3,float value4,float value5,float _f,int _delay_time_servos); char *pwm[30]; char *tim[2] = {0}; const int servo_num = 6; float value_init[6]={1200, 950, 1350, 1800, 1500, 1500}; float f = 50.0; int delay_time_servo = 10; int main(void) { u8 rxlen; int num = 0, num1 = 0; delay_init(168);//初始化延时,168为CPU运行频率 uart_init(115200); //串口初始化 LED_Init();//初始化LED灯 TIM12_PWM_Init(20000-1,84-1); TIM11_PWM_Init(20000-1,168-1); TIM10_PWM_Init(20000-1,168-1); TIM9_PWM_Init(20000-1,168-1); //42M/42=1Mhz的计数频率,重装载值20000,所以PWM频率为 1M/20000=50hz. while(1) { all_servo_angle_init(); all_servo_move(1200, 950, 1350, 1800, 1500, 1550,f,delay_time_servo);//初始化动作(直立状态) all_servo_move(1200, 950, 1350, 1800, 1500, 1550,f,delay_time_servo); all_servo_move(1200, 1086, 620, 1480, 2480, 1550,f,delay_time_servo);//delay_ms(1000);//准备抓取 all_servo_move(1200, 1086, 620, 1480, 2480, 1360,f,delay_time_servo);delay_ms(300);//抓取 all_servo_move(1200, 650, 850, 2200, 1500,1360,f,delay_time_servo);delay_ms(300);//中间动作 all_servo_move(1700, 1086, 620, 1480, 600,1360,f,delay_time_servo);delay_ms(300);//转动底盘 all_servo_move(1700, 1086, 620, 1480, 600,1550,f,delay_time_servo);delay_ms(300);//释放 all_servo_move(1200, 650, 850, 2200, 1500,1550,f,5);delay_ms(30);//中间动作 all_servo_move(1200, 950, 1350, 1800, 1500, 1500,f,5);delay_ms(300);//初始化动作(直立状态) while(1){ } } } void buf_init(void) { for(int i = 0; i < 20; i++){ pwm[i] = 0; } for(int i = 0; i < 2; i++){ tim[i] = 0; } for(int i = 0; i < USART_REC_LEN; i++){ USART_RX_BUF[i] = 0; } } void mysplite(char *buffer, char **p, const char *separator, const char *separator1, int *num) { int in = 0; char *buf = buffer; char *outer_ptr = NULL; char *inner_ptr = NULL; while ((p[in] = strtok_r(buf, separator, &outer_ptr)) != NULL) { buf = p[in]; while ((p[in] = strtok_r(buf, separator1, &inner_ptr)) != NULL) { in++; buf = NULL; } buf = NULL; } p[in] = strtok(p[in], "T"); *num = in; } void split(char *src,const char *separator,char **dest,int *num) { char *pNext; int count = 0; if (src == NULL || strlen(src) == 0) return; if (separator == NULL || strlen(separator) == 0) return; pNext = strtok(src,separator); while(pNext != NULL) { *dest++ = pNext; ++count; pNext = strtok(NULL,separator); } *num = count; } void Steering_Gear_Angle(u8 num, u16 ang) { switch(num){ case 0 : TIM_SetCompare2(TIM12, ang);//修改比较值,修改占空比 break; case 1 : TIM_SetCompare1(TIM12, ang);//修改比较值,修改占空比 break; case 2 : TIM_SetCompare1(TIM11, ang);//修改比较值,修改占空比 break; case 3 : TIM_SetCompare1(TIM10, ang);//修改比较值,修改占空比 break; case 4 : TIM_SetCompare2(TIM9, ang);//修改比较值,修改占空比 break; case 5 : TIM_SetCompare1(TIM9, ang);//修改比较值,修改占空比 break; default: break; } delay_ms(100); } void all_servo_angle_init() { TIM_SetCompare2(TIM12, value_init[0]); TIM_SetCompare1(TIM12, value_init[1]); TIM_SetCompare1(TIM11, value_init[2]); TIM_SetCompare1(TIM10, value_init[3]); TIM_SetCompare2(TIM9, value_init[4]); TIM_SetCompare1(TIM9, value_init[5]); } void all_servo_move(float value0, float value1, float value2, float value3,float value4,float value5,float _f,int _delay_time_servos) { float value_arguments[6] = {value0, value1, value2, value3, value4, value5}; float value_delta[servo_num]; for(int i=0;i<servo_num;i++) { value_delta[i] = (value_arguments[i] - value_init[i]) / _f; } for(int i=0;i<f;i++) { for(int k=0;k<servo_num;k++) { value_init[k] = value_delta[k] == 0 ? value_arguments[k] : value_init[k] + value_delta[k]; }
for(int j=0;j<servo_num;j++) { if(j==0){TIM_SetCompare2(TIM12, value_init[0]);} if(j==1){TIM_SetCompare1(TIM12, value_init[1]);} if(j==2){TIM_SetCompare1(TIM11, value_init[2]);} if(j==3){TIM_SetCompare1(TIM10, value_init[3]);} if(j==4){TIM_SetCompare2(TIM9, value_init[4]);} if(j==5){TIM_SetCompare1(TIM9, value_init[5]);} delay_ms(_delay_time_servos); } } } |
按下图进行电路连接: 我们先对舵机进行编号(见下图)
接下来与扩展板进行连接(见下图),1到6号舵机从右向左去接线。
相应的引脚编号见下表,这些引脚号在编程中将会用到。
3. 功能实现
编程环境:keil5
功能:实现机械臂搬运的效果。
给大家提供一个参考例程(USER\test.uvprojx),下面是main.c的代码:
4. 资料清单
序号 | 内容 |
1 | R265-程序源代码 |
2 | R265-样机3D文件 |
【整体打包】-【R265】5自由度串联机械臂-概述-资料附件.zip | 15.53MB | 下载54次 | 下载 |
Arduino搬运
1. 功能描述
本文提供的示例所实现的功能为:实现5自由度串联机械臂搬运物品的功能。
2. 电子硬件
在这个示例中,我们采用了以下硬件,请大家参考:
主控板 | |
扩展板 | |
舵机 | 270°伺服电机、标准舵机 |
电池 | 7.4V锂电池 |
/*------------------------------------------------------------------------------------ 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved. Distributed under MIT license.See file LICENSE for detail or copy at https://opensource.org/licenses/MIT by 机器谱 2023-02-20 https://www.robotway.com/ ------------------------------*/ /* 本程序要实现一个5自由度串联机械臂搬运物品的功能。 由机械臂从夹爪到底座的舵机依次连接在Bigfish扩展板的D4、D7、D11、D3、D8、D12接口上。 */ #define EYEINIT 174 #define HEADINIT 90 #define NECKINIT 124 #define UPBODYINIT 72 #define DOWNBODYINIT 100 #define FOOTINIT 88
#define EYE0 130 #define HEAD0 90 #define NECK0 170 #define UPBODY0 160 #define DOWNBODY0 79 #define FOOT0 36
#define EYE1 130 #define HEAD1 90 #define NECK1 170 #define UPBODY1 160 #define DOWNBODY1 80 #define FOOT1 130
#include<Wire.h> #include <Servo.h> #define PIN_SERVO_EYE 4 //定义各个舵机所对应的端口; #define PIN_SERVO_HEAD 7 #define PIN_SERVO_NECK 11 #define PIN_SERVO_UPBODY 3 #define PIN_SERVO_DOWNBODY 8 #define PIN_SERVO_FOOT 12
#define OPERATE_TIME 3000
#define SERVO_EYE 0 //定义各个舵机所对应的端口; #define SERVO_HEAD 1 #define SERVO_NECK 2 #define SERVO_UPBODY 3 #define SERVO_DOWNBODY 4 #define SERVO_FOOT 5
int servoPin[6] = {PIN_SERVO_EYE, PIN_SERVO_HEAD, PIN_SERVO_NECK, PIN_SERVO_UPBODY,PIN_SERVO_DOWNBODY,PIN_SERVO_FOOT}; Servo myServo[6];
void setup() { // put your setup code here, to run once: delay(1000); Serial.begin(9600); resetArm(); }
void loop() { // put your main code here, to run repeatedly:
resetArm(); //机械臂复位 getCube(); //机械臂开始抓取货物 putCube(); //机械臂开始释放货物 delay(2000);//等待2秒 }
void resetArm(){ //舵机复位函数; for(int i = 0; i < 6; i++) myServo[i].attach(servoPin[i]); myServo[SERVO_EYE].write(EYEINIT); myServo[SERVO_HEAD].write(HEADINIT); myServo[SERVO_NECK].write(NECKINIT); myServo[SERVO_UPBODY].write(UPBODYINIT); myServo[SERVO_DOWNBODY].write(DOWNBODYINIT); myServo[SERVO_FOOT].write(FOOTINIT); delay(1500); }
void getCube(){ //抓取物料动作序列函数;
ServoMove(SERVO_FOOT, FOOTINIT, FOOT0, OPERATE_TIME); ServoMove(SERVO_UPBODY, UPBODYINIT,UPBODY0, OPERATE_TIME); ServoMove(SERVO_HEAD, HEADINIT, HEAD0, OPERATE_TIME); ServoMove(SERVO_NECK, NECKINIT, NECK0, OPERATE_TIME); ServoMove(SERVO_EYE, EYEINIT, EYE0, OPERATE_TIME); ServoMove(SERVO_DOWNBODY, DOWNBODYINIT, DOWNBODY0, OPERATE_TIME);
ServoMove(SERVO_HEAD, HEAD0, HEADINIT, OPERATE_TIME); ServoMove(SERVO_UPBODY, UPBODY0, UPBODYINIT, OPERATE_TIME); ServoMove(SERVO_EYE, EYE0, EYEINIT, OPERATE_TIME); ServoMove(SERVO_NECK, NECK0, NECKINIT, OPERATE_TIME); ServoMove(SERVO_DOWNBODY, DOWNBODY0, DOWNBODYINIT, OPERATE_TIME); }
void putCube() //机械臂开始释放货物 { ServoMove(SERVO_FOOT, FOOT0, FOOT1 , OPERATE_TIME); ServoMove(SERVO_HEAD, HEADINIT, HEAD1, OPERATE_TIME); ServoMove(SERVO_NECK, NECKINIT, NECK1, OPERATE_TIME); ServoMove(SERVO_UPBODY, UPBODYINIT,UPBODY1, OPERATE_TIME); ServoMove(SERVO_EYE, EYEINIT, EYE1, OPERATE_TIME); ServoMove(SERVO_DOWNBODY, DOWNBODYINIT, DOWNBODY1, OPERATE_TIME);
ServoMove(SERVO_HEAD, HEAD1, HEADINIT, OPERATE_TIME); ServoMove(SERVO_UPBODY, UPBODY1, UPBODYINIT, OPERATE_TIME); ServoMove(SERVO_EYE, EYE1, EYEINIT, OPERATE_TIME); ServoMove(SERVO_NECK, NECK1, NECKINIT, OPERATE_TIME); ServoMove(SERVO_DOWNBODY, DOWNBODY1, DOWNBODYINIT, OPERATE_TIME); ServoMove(SERVO_FOOT, FOOT1, FOOTINIT , OPERATE_TIME); }
void ServoMove(int which, int _start, int _finish, long t) //舵机动作函数:它有四个参数,舵机号,初始角度,目标角度,动作时间; { static int direct; static int diff; static long deltaTime; if(_start <= _finish) direct = 1; else direct = -1; diff = abs(_finish - _start); deltaTime = (long) (t / 180);
for(int i = 0; i < diff; i++){ myServo[which].write(_start + i * direct); Serial.println(_start + i * direct); delay(deltaTime); } } |
电路连接说明:
舵机接线:由上至下依次连接在Bigfish扩展板的D4、D7、D11、D3、D8、D12接口上。
3. 功能实现
编程环境:Arduino 1.8.19
编写并烧录以下代码(5df_handling.ino)
4. 资料下载
序号 | 内容 |
1 | 【R265】-Arduino搬运-例程源代码 |
样机-【R265】5自由度串联机械臂-Arduino搬运-资料附件.rar | 2.88KB | 下载1次 | 下载 |
这段代码通过PWM信号控制舵机,实现了5自由度串联机械臂的精确控制,并通过预设的动作序列完成对物体的抓取和释放。
颜色分拣
1. 功能描述
本文提供的示例所实现的功能为:实现5自由度串联机械臂按颜色分拣的功能。将红、蓝两种颜色的工件分别放置在传感器上时,机械臂会根据检测到的颜色,将红色工件搬运至右侧区域;将蓝色工件搬运至左侧区域。
2. 电子硬件
在这个示例中,我们采用了以下硬件,请大家参考:
主控板 | |
扩展板 | |
传感器 | |
电池 | 7.4V锂电池 |
/*------------------------------------------------------------------------------------ 版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved. Distributed under MIT license.See file LICENSE for detail or copy at https://opensource.org/licenses/MIT by 机器谱 2023-08-24 https://www.robotway.com/ ------------------------------*/ #include <MsTimer2.h> #include <Wire.h> #include <ECT_IA02S.h> ECT_IA02S device; String serialString = ""; boolean serialComplete = false; char stringBuf[100]; void setup() { Serial.begin(9600); Colour_set(); serialString = "1@0:act.write(75);@"; StringDeal(); serialString = "1@1:act.write(90);@"; StringDeal(); delay(1000); serialString = "2@0:act.write(100);@"; StringDeal(); serialString = "2@1:act.write(90);@"; StringDeal(); delay(1000); serialString = "3@0:act.write(45);@"; StringDeal(); serialString = "3@1:act.write(90);@"; StringDeal();
}
void loop() { int c = Get_colour(); Serial.println(c); if(c<2) device.startShoal(0, c, 7000); delay(2000); }
void StringDeal() { String outString; static int stringlength; serialString = serialString.substring(0,serialString.length()-1); serialString+="*"; serialString+=serialString.length()-1; serialString+="\n"; stringlength=serialString.length();
//split the string to certain part, each part as 30 char, send parts one by one for(int i=0;i<((stringlength/30)+1);i++){ outString = serialString.substring(0,min(serialString.length(),30)); outString.toCharArray(stringBuf, outString.length()+1); serialString=serialString.substring(min(serialString.length(),30),serialString.length()+1);
Wire.beginTransmission(1); Wire.write(stringBuf); Wire.endTransmission(); } } |
在5自由度串联机械臂底座上安装一个 TCS3200颜色识别传感器 ,用于检测工件的RGB值。
3. 功能实现
编程环境:Arduino 1.8.19
下面提供一个实现5自由度串联机械臂按颜色分拣的参考程序(colour.ino):
4. 资料清单
序号 | 内容 |
1 | 【R265】-颜色分拣-程序源代码 |
【整体打包】-【R265】5自由度串联机械臂-颜色分拣-资料附件.rar | 4.71KB | 下载2次 | 下载 |
【R265】5自由度串联机械臂
作者:机器谱