基于STM32与TB6600的机械臂项目(代码开源)_基于stm32的机械臂源码

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

        前言本文为手把手教学STM32的机械臂项目——Robot Arm本次项目采用的是STM32作为MCU。该机械臂的基础模型为国外开源项目诸多前辈经过长时间的验证与改进其机械臂精度可以满足日常需求。本项目机械臂为三自由度机械臂42步进电机搭配TB6600驱动器作为动力支撑。整体项目框架具有极高的可拓展性方便后期实现视觉抓取等高级嵌入式开发应用。 机械臂的控制选用JDY-31蓝牙控制结合手机上位机APP进行联动。文末有代码与3D打印件开源

        实验硬件STM32F103ZET6TB6600驱动器42步进电机JDY-31蓝牙模块5V步进电机ULN2003驱动板机械臂3D打印件

        硬件实物图

        效果图

一、机械臂简介

        机械臂是机械人技术领域中得到最广泛实际应用的自动化机械装置在工业制造、医学治疗、娱乐服务、军事、半导体制造以及太空探索等领域都能见到它的身影。尽管它们的形态各有不同但它们都有一个共同的特点就是能够接受指令精确地定位到三维或二维空间上的某一点进行作业。机械臂是指高精度多输入多输出、高度非线性、强耦合的复杂系统。因其独特的操作灵活性已在工业装配、安全防爆等领域得到广泛应用。

        本项目的机械臂目前为被动控制方案需要使用手机蓝牙APP作为上位机人为控制抓取目标物。考虑到目前设计的机械臂已拥有较高的机械精度后续可以附加树莓派等开发板进行视觉抓取开发。

二、42步进电机与TB6600驱动器

2.1 42步进电机

        42步进电机是指安装机座尺寸是42mm×42mm的步进电机又叫NEMA 17步进电机这里的NEMA是National Electrical Manufacturers Association的缩写美国电气制造商协会是美国最大的电气设备制造商协会如下图所示相同机座尺寸的步进电机又有不同长度和不同绕组参数的型号一般相同机座尺寸的情况下步进电机越长定子上能够绕下的绕组就越多电机的输出力矩就越大。

42 57 86步进电机的主要区别是什么即42 57 86的意义是什么

答42 57 86步进电机的区别主要是步进电机的机座不同尺寸分别是42×42mm、57×57mm、86×86mm一般来说步进电机的机座尺寸越大电机的静力矩就越大电机运行时的转矩就越大电机能够承受的负载就越大。

        本项目中所使用的为四线二相42步进电机步距角是1.8度在无细分的情况下转一圈走200步360/1.8=200。切记42这个数字的含义仅与电机的尺寸有关。而电机步距角细分程度只与电机驱动器的配置有关。

机械臂由3台42步进电机驱动实现三自由度控制。限位器则可以用来初始化机械臂位置合理校准机械臂对应的笛卡尔空间坐标下的状态。

2.2 TB6600驱动器

        驱动步进电机往往需要驱动器帮助常见的步进电机驱动器有TB6600、A4988、DM542、DMA860HULN2003等。其中大部分步进电机驱动器用法和接线思路大致相同驱动电机的原理也基本一样。

        项目中使用的步进电机驱动器为TB6600TB6600是一款专业的两相步进电机驱动器兼容STM32Arduino其他多种主控器可实现电机正反转控制旋转角度控制等功能。步进电机驱动是一种电子设备通常作为桥梁来连接控制器、电源和步进电机。虽然控制器的处理性能很强大但是它本身的输出能力电流却很弱小。它需要一个中间桥梁去连接电机和主控并同时为电机提供足够的电源。

        TB6600步进电机驱动器采用H桥双极恒相流驱动可直接用9~42VDC供电可选择7档细分控制1、2/A、2/B、4、8、16、328档电流控制0.5A、1A、1.5A、2A、2.5A、2.8A、3.0A、3.5A。最高支持4A电流输出。信号端都有配有高速光电隔离防止信号干扰并且支持共阴共阳两种信号输入方式。出于安全考虑驱动器支持脱机保持功能能够让用户在通电状态下调试。内置温度保护和过流保护可适应更严苛的工作环境。 驱动器适合驱动57、42型两相、四相混合式步进电机能达到低振动、低噪声、高速度的驱动效果。可以适用于机械人控制3D打印等高精度应用领域中。

       通过拨动TB6600侧边的拨码开关设置步进电机的细分电流 当拨码开关向下拨动则为ON上图为作者设置的步进电机为16细分电流设置为1.0A分析正常情况下步进电机的步距角为1.8°转动一圈需要200脉冲当设置为16细分则需要16×200=3200脉冲一个脉冲步距角为0.1125°。而电流拨码开关的设置只要保证输出电流别超过步进电机电流的运载上限就行。

TB6600信号线的共阴和共阴接法

(1)共阴接法分别将PUL-DIR-EN-连接到控制系统的地端脉冲输入信号通过PUL+接入方向信号通过DIR+接入使能信号通过EN+接入。若需限流电阻限流电阻R的接法取值与共阳极接法相同。

(2)共阳接法分别将PUL+DIR+EN+连接到控制系统的电源上如果此电源是+5V则可直接接入如果此电源大于+5V则须外部另加串联限流电阻R保证给驱动器内部光藕提供8到15mA的驱动电流。脉冲输入信号通过PUL-接入方向信号通过DIR-接入使能信号通过EN-接入。

特别注意作者建议大家采用共阴接法方便且不容易犯错。

特别注意

初学者接触步进电机与步进电机驱动器时很容易接错相位线导致出现缺陷漏项发现。所以当发现信号线电源线都满足驱动要求但无法驱动步进电机亦或是步进电机驱动异常时出现丢步转动噪音等问题往往可能出现在相位线接错了读者朋友们可以去找步进电机厂商去拿一下步进电机的相位线说明。

三、5V步进电机与ULN2003驱动器

        5V五线四相步进电机是一种常见的小扭矩电机本项目中采用此电机通过机械结构驱动机械臂爪子进行物体抓取。该型号电机往往使用ULN2003驱动器配合使用UNL2003器件是高电压大电流达林顿晶体管阵列。

        该直流减速电机直径28mm 电压5V 步距角度5.625×1/64 减速比1/64步距角5.625 / 64 = 0.087度 也就是说理论上你给一个脉冲电机外部轴转动0.087度也就是说一个脉冲内部转子转5.625度但是由于减速64倍所以外部轴只转了0.087度那么外部轴要转一圈的话需要360/0.087=4096个脉冲。采用4相8拍驱动的话8个脉冲是一个周期那么就需要4096/8=512个周期外部轴刚好转一圈。

电机的驱动一般分为3种方法

一.  1相励磁法每一瞬间只有一个线圈相通其它休息。

优点简单耗电低精确性良好。缺点力矩小振动大每次励磁信号走的角度都是标称角度。1相励磁法A->B->C->D

二、 2相励磁法每一瞬间有两个线圈导通。

优点力矩大震动小。缺点每励磁信号走的角度都是标称角度。2相励磁法  AB->BC->CD->DA

三、 1-2相励磁法1相和2相交替导通。

优点精度较高运转平滑每送一个励磁信号转动1/2标称角度称为半步驱动。前两种称为4相4拍这一种称为4相8拍1-2相励磁法  A-->AB-->B->BC->C-->CD->D-->DA

        ULN2003驱动板上的IN1、IN2、IN3、IN4四个引脚和单片机的IO口直接使用杜邦线连接为了方便初次学习ULN2003驱动板的朋友理解这里仅具体给大家讲解1相励磁法如下图所示

        上图4个定子线圈分别为A、B、C、D我们依次给A、B、C、D通电则可实现电机的转动这个就是上面提到的1相励磁法。使用ULN2003驱动板时我们只需要将IN1、IN2、IN3、IN4四个引脚分别去逐个给予高电平即可使用定时器

四、机械臂控制

4.1 JDY-31蓝牙控制

        JDY-31蓝牙模块基于蓝牙3.0 SPP设计这样可以支持 Windows、Linux、android数据透传工作频段 2.4GHZ调制方式GFSK最大发射功率8db最大发射距离30米支持用户通过AT命令修改设备名、波特率等指令方便快捷使用灵活。

        其通常使用时接入串口引脚UART即可成功与蓝牙模块建立通信后会发送CONNECTED。简单的说JDY-31蓝牙模块本质上就是一个蓝牙转串口的设备使用的时候直接当串口通讯进行使用即可。

        而上位机作者则选用现成开源的蓝牙调试器APP直接创建一个针对本项目机器人的控制上位机工程。利用该APP极大的缩短了上位机开发的时间与工作量也可以快速检验出机器人的运动控制是否满足要求需要蓝牙调试APP的可以私信作者提供

JDY-31蓝牙模块的AT指令集

序号

目的

指令

参数

响应

备注

1

查询版本号

AT+VERSION

NONE

+VERSION=…

2

复位

AT+RESET

NONE

+OK

3

断开连接

AT+DISC

NONE

+OK

蓝牙连接后有效

4

BLE蓝牙MAC地址

AT+LADDR

NONE

+LADDR=…

5

波特率设置/查询

AT+BAUD[参数]

4-9600;5-19200;6-38400;7-57600;8-115200;9-128000

+OK

128000也不丢包

6

SPP蓝牙密码配对/查询

AT+PIN[参数]

4位密码

+OK

默认1234

7

广播名设置/查询

AT+NAME[参数]

18字节以下

OK

8

恢复出厂设置

AT+DEFAULT

NONE

OK

默认JDY-31-SPP

9

串口输出状态使能查询

AT+ENLOG

1:打开 0关闭

OK

默认为1

特别注意购买的JDY-31蓝牙模块可能初试化的波特率不一样读者朋友一定要去询问到厂家的初试波特率或自己使用AT指令去设置一下否则对后续的蓝牙控制会造成很大影响。

4.2 机械臂运动学建模

        合格的机械臂产品往往都需要根据其设计的机械结构去解算其运动模型即仅输入需要的笛卡尔空间坐标系下的位置点\left ( x,y,z \right )即可解算出各台电机需要运转的情况。考虑到博客篇幅有限这里仅给大家提供该机械臂的几何模型算法后续基于树莓派与STM32的视觉抓取机械臂给大家详细介绍一下。

五、 CubeMX配置

1、RCC配置外部高速晶振精度更高——HSE

2、SYS配置Debug设置成Serial Wire否则可能导致芯片自锁

3、TIM2配置利用TM2定时器配置us级脉冲

4、UART3配置 JDY-31模块与STM32的蓝牙串口通讯开启串口中断

5、GPIO配置PA5、PA6、PA7为机械臂方向控制引脚PD9、PD10、PD11、PD12为5V步进电机的四相输入PF13、PF14、PF15为机械臂电机驱动脉冲输入引脚

6、时钟树配置

7、工程配置

六、代码与解析

6.1 机械臂电机控制代码

        机械臂的驱动器件为3台42步进电机通过TB6600驱动器进行驱动。单片机MCU主要控制的是TB6600上的DIRPUL端口其控制过程也很简单——GPIO控制即可作者选择共阴接法DIR-与PUL-都需接地只需要控制DIR+与PUL+即可

        其中DIR+端口的控制为GPIO的高低电平控制该DIR+端口的高低电平输入决定了步进电机的转动方向PUL+端口则需要输入脉冲信号进行控制脉冲频率的高低决定了步进电机的转速。当然这里的PUL+端口的脉冲输入有2种主流方式1us级延迟函数GPIO电平翻转2设置定时器翻转GPIO这里作者使用us级延迟函数翻转实现脉冲。

Motordrive.h代码

#ifndef __MOTORDRIVER_H
#define __MOTORDRIVER_H

#include "main.h"

//电机方向控制引脚
//正转
#define MOTOR1Forward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
#define MOTOR2Forward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET);
#define MOTOR3Forward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
//反转
#define MOTOR1Backward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET)
#define MOTOR2Backward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_RESET)
#define MOTOR3Backward HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET) 

//步进电机控制
void Motor1(short dir,int speed);//步进电机1号机
void Motor2(short dir,int speed);//步进电机2号机
void Motor3(short dir,int speed);//步进电机3号机

#endif

Motordrive.c代码

#include "Motordrive.h"
#include "tim.h"

//1号步进电机,1正转其他反转
void Motor1(short dir,int speed)
{
	if(dir == 1)
	{
		MOTOR1Forward;		
	}
	else
	{
		MOTOR1Backward;
	}
	
	//电机脉冲控制
	HAL_GPIO_WritePin(GPIOF,GPIO_PIN_13,GPIO_PIN_SET);
	Tims_delay_us(speed);
	HAL_GPIO_WritePin(GPIOF,GPIO_PIN_13,GPIO_PIN_RESET);
	Tims_delay_us(speed);	
}

//2号步进电机,1正转其他反转
void Motor2(short dir,int speed)
{
	if(dir == 1)
	{
		MOTOR2Forward;		
	}
	else
	{
		MOTOR2Backward;		
	}
	
	//电机脉冲控制
	HAL_GPIO_WritePin(GPIOF,GPIO_PIN_14,GPIO_PIN_SET);
	Tims_delay_us(speed);
	HAL_GPIO_WritePin(GPIOF,GPIO_PIN_14,GPIO_PIN_RESET);
	Tims_delay_us(speed);		
}

//3号步进电机,1正转其他反转
void Motor3(short dir,int speed)
{
	if(dir == 1)
	{
		MOTOR3Forward;		
	}
	else
	{
		MOTOR3Backward;		
	}
	
	//电机脉冲控制
	HAL_GPIO_WritePin(GPIOF,GPIO_PIN_15,GPIO_PIN_SET);
	Tims_delay_us(speed);
	HAL_GPIO_WritePin(GPIOF,GPIO_PIN_15,GPIO_PIN_RESET);
	Tims_delay_us(speed);		
}

us级延迟函数

void Tims_delay_us(uint16_t nus)
{
	__HAL_TIM_SET_COUNTER(DLY_TIM_Handle, 0);
	__HAL_TIM_ENABLE(DLY_TIM_Handle);
	while (__HAL_TIM_GET_COUNTER(DLY_TIM_Handle) < nus)
	{
	}
	__HAL_TIM_DISABLE(DLY_TIM_Handle);
}

6.2 机械爪控制代码

        机械爪部分使用5V步进电机与ULN2003驱动板驱动将ULN2003驱动器上的IN1、IN2、IN3、IN4四个引脚循环拉高电平即可实现对5V步进电机的控制IN引脚循环周期的快慢决定电机转动的快慢循环引脚顺序决定了电机转动方向

注意ULN2003驱动器驱动5V步进电机的时候电机速度是有一定限制的。技巧可以通过ULN2003上面4个LED灯的闪烁速度来判别驱动电机转速的快慢。

crawl.h代码

#ifndef __CRAWL_H
#define __CRAWL_H

#include "main.h"

//引脚定义
#define IN1_HIGH HAL_GPIO_WritePin(GPIOD,GPIO_PIN_9,GPIO_PIN_SET)
#define IN2_HIGH HAL_GPIO_WritePin(GPIOD,GPIO_PIN_10,GPIO_PIN_SET)
#define IN3_HIGH HAL_GPIO_WritePin(GPIOD,GPIO_PIN_11,GPIO_PIN_SET)
#define IN4_HIGH HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_SET)

#define IN1_LOW HAL_GPIO_WritePin(GPIOD,GPIO_PIN_9,GPIO_PIN_RESET)
#define IN2_LOW HAL_GPIO_WritePin(GPIOD,GPIO_PIN_10,GPIO_PIN_RESET)
#define IN3_LOW HAL_GPIO_WritePin(GPIOD,GPIO_PIN_11,GPIO_PIN_RESET)
#define IN4_LOW HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_RESET)

//5v步进电机控制
void stepper(short dir,int speed);

#endif

crawl.c代码

#include "crawl.h"

//1是正转其余是反转
void stepper(short dir,int speed)
{
	if(dir == 1)
	{
		IN1_HIGH;
		HAL_Delay(speed);
		IN1_LOW;
		IN2_HIGH;
		HAL_Delay(speed);
		IN2_LOW;
		IN3_HIGH;
		HAL_Delay(speed);
		IN3_LOW;
		IN4_HIGH;
		HAL_Delay(speed);
		IN4_LOW;
	}
	else
	{
		IN1_HIGH;
		HAL_Delay(speed);
		IN1_LOW;
		IN4_HIGH;
		HAL_Delay(speed);
		IN4_LOW;
		IN3_HIGH;
		HAL_Delay(speed);
		IN3_LOW;
		IN2_HIGH;
		HAL_Delay(speed);
		IN2_LOW;
	}
}

6.3 JDY-31蓝牙控制机械臂代码

        项目机械臂采用手机蓝牙APP进行控制且控制所用的蓝牙APP为开源的蓝牙调试助手具体界面如图所示。设置6个控制组件为byte类型按下时分别对应数字1-9松开时为数字0

bluetooth.h代码

#ifndef __BULETOOTH_H
#define __BULETOOTH_H

#include "stm32f1xx_hal.h" 

extern UART_HandleTypeDef huart3;

#define USART3_REC_LEN  500

extern uint8_t  USART3_RX_BUF[USART3_REC_LEN];
extern uint16_t USART3_RX_STA;
extern uint8_t USART3_NewData;

void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart);

#endif

bluetooth.c代码

#include "bluetooth.h"

uint8_t USART3_RX_BUF[USART3_REC_LEN];
uint16_t USART3_RX_STA=0;
uint8_t USART3_NewData;

extern int flag;		//全局变量

void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart)
{
    if(huart ==&huart3)
    {
                              
              USART3_RX_BUF[USART3_RX_STA&0X7FFF]=USART3_NewData; 					
              USART3_RX_STA++;  
			
              if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;
			
							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x01)
							{
								flag = 1;
							}
							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x02)
							{
								flag = 2;
							}
							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x03)
							{
								flag = 3;
							}
							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x04)
							{
								flag = 4;
							}
							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x05)
							{
								flag = 5;
							}							
 							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x06)
							{
								flag = 6;
							}
							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x07)
							{
								flag = 7;
							}
							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x08)
							{
								flag = 8;
							}							
 							if(USART3_RX_BUF[USART3_RX_STA-15] == 0x09)
							{
								flag = 9;
							}							
        HAL_UART_Receive_IT(&huart3,(uint8_t *)&USART3_NewData,1);


    }
}

6.4 main函数代码

        主函数利用switch()函数与蓝牙控制代码中定义的全局变量flag进行组合使用在while()循环函数中实现串口3中断后全局变量flag控制机械臂运动姿态。

main.c

#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "crawl.h"
#include "Motordrive.h"
#include "oled.h"
#include "control.h"
#include "bluetooth.h"

int flag;

int main(void)
{
  //CubeMX配置的初始化代码

  HAL_UART_Receive_IT(&huart3,(uint8_t *)&USART3_RX_BUF,1);  
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    		 switch(flag)    
    		 {
    		 case(1):Motor1(0,2000);;break;
    		 case(2):Motor1(1,2000);;break;
    		 case(3):Motor2(0,2000);;break;
    		 case(4):Motor2(1,2000);;break;
    		 case(5):Motor3(0,2000);;break;
			 case(6):Motor3(1,2000);;break;
    		 case(7):stepper(0,20);;break;		//收缩
    		 case(8):stepper(1,20);;break;		//外扩
			 case(9):stop();break;				 
    		 default:break;
    		 } 	

  }
  /* USER CODE END 3 */
}

七、项目效果

基于STM32与TB6600机械臂项目

八、代码开源

3D打印件与代码地址 基于STM32与TB6600蓝牙控制机械臂项目-嵌入式文档类资源-CSDN文库

如果积分不够的朋友点波关注评论区留下邮箱作者无偿提供源码和后续问题解答。求求啦关注一波吧 

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

“基于STM32与TB6600的机械臂项目(代码开源)_基于stm32的机械臂源码” 的相关文章