树莓派4b控制机械手臂_STM32与树莓派(上位机)交互控制机械臂

通常的机械臂都是由多路舵机组成,我使用的是某宝上(并不)常见的五自由度机械臂。尽管商家称它为六自由度。

这里使用STM32F407VGT6的6路PWM输出通道来控制6个舵机的运动,树莓派(上位机)通过USB转TTL模块与STM32进行串口通讯

PWM舵机控制原理

标准的 PWM 舵机有三条控制线,分别为:电源、地及信号线。

1_meitu_1.jpg (37.71 KB, 下载次数: 2)

2020-9-22 09:53 上传市面上大多数180°舵机需要的PWM波周期通常为20ms,高电平接收时间通常为0.5 ~ 2.5ms,对应舵机旋转角度为0 ~ 180°。用PWM波控制舵机时,只需将时钟的周期设置为20ms(50Hz),并且通过改变比较值pulse改变PWM波的高电平时间来控制舵机旋转的角度.

STM32CubeMx主要配置

对于STM32,我使用的是STM32CubeIDE + Mx 进行开发。时钟框图为默认配置,如图。

2_meitu_2.jpg (114.98 KB, 下载次数: 1)

2020-9-22 09:53 上传TIMER

由于需要控制6个舵机,我选择了TIM3(4路PWM输出)和TIM9(2路PWM输出)。

PWM输出的频率由时钟APB2决定,由时钟框图可知此处的APB2频率为16MHz;PWM波频率计算公式为:

W = APB2 / (PSC + 1)(ARR + 1)

其中PSC为分频系数,ARR为自动重装载值。这里我将PSE设置为39,ARR设置为7999。

3_meitu_3.jpg (17.75 KB, 下载次数: 2)

2020-9-22 09:53 上传注意,这里的计数模式(Counter Mode)不同时,会导致接下来比较值值相同时舵机的旋转方向不同。

由于PWM波高电平时间需控制在0.5 ~ 2.5ms内,所以各PWM通道的比较值(pulse)必须控制在200 ~ 1000之内; (8000 x 0.5 / 20 = 200)(8000 x 2.5 / 20 = 1000)

当舵机旋转角度为90°时,pulse值应为600。这里我将各个PWM输出通道的比较值均设置为600。

4_meitu_4.jpg (15.04 KB, 下载次数: 1)

2020-9-22 09:53 上传由于我手头上的机械臂中的一个舵机用于控制机械爪,其为90°舵机,所以在配置控制该舵机的PWM通道时,比较值范围仅能为200 ~ 600,中间值为400我使用的单片机为STM32F407VGT6,其TIM3和TIM9所对应的PWM输出通道分别为PA6, PA7, PB0, PB1和PE5, PE6。

这里只需将这些IO口设置为复用推挽输出以及上拉即可。

5_meitu_5.jpg (33.78 KB, 下载次数: 1)

2020-9-22 09:53 上传串口配置

这里我选择USART_2用作串口通讯,其Tx与Rx分别对应为PA2、PA3。

串口的配置如图所示。

6_meitu_6.jpg (58.69 KB, 下载次数: 1)

2020-9-22 09:53 上传

这里使用异步通信模式,注意波特率等参数需与上位机相匹配。

7_meitu_7.jpg (53.31 KB, 下载次数: 1)

2020-9-22 09:53 上传

PA2与PA3均设置为复用推挽输出,上拉。

中断控制

由于这里我只使用了串口接收中断,所以NVIC这里可以不用配置;若STM32除了控制机械臂外还有其余任务,则可能需要配置NVIC。

STM32CubeIDE代码实现

在STM32CubuMx配置完毕并生成工程之后,我们的主要任务只有设计上位机与单片机的通讯协议,以及完成串口接收中断函数即可。

通讯协议设计

我初步的设计为串口发送一次数据,控制单个舵机的角度;所以发送的数据中需要包括舵机的编号以及舵机的目标角度(或者由角度转换而成的比较值)。

在这里我没有设计通讯头以及对舵机转速的控制,因为这里我的串口只用于传输控制舵机的指令,以及我使用的是小型舵机,其转速并不是很快,可以满足我的要求,无需控制其速度。

设计思路如下:

上位机每次发送16位的数据(2个uint8_t类型,串口只能发送串口),舵机编号为0~5,发送的pulse值为 (200 ~ 1000) - 200,将舵机编号数值乘以1000加上pulse值减去200得到一个uint16_t类型的数值;再将其转换为十六进制进行发送。

例:对3号舵机进行操作,角度为45°。

数据处理:

3 x 1000 + (45° / 180°) x 800 = 3200;

3200转换为十六进制为:0x0C80。

STM32进行逆向操作得到原数据。

STM32代码实现

由于串口发送的是两个uint8_t类型的数据,所以在解码之前还需将两个uint8_t类型数据转换为一个uint16_t类型的数据。

在打开USART2的接收中断时,设置为接受到两个uint8_t类型的数据进入接收中断,以便于在接收中断处理函数中进行数据处理。

uint8_t pulse[2];

HAL_UART_Receive_IT(&huart2, pulse, sizeof(pulse));复制代码

串口接受中断函数代码如下:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

if(huart->Instance == USART2)

{

uint8_t rec0, rec1;

// 获取接收到的两个字节的数据

rec0 = *((huart->pRxBuffPtr) - 2);

rec1 = *((huart->pRxBuffPtr) - 1);

uint16_t numPart[2], armControl, arm targetPulse;

// 通过移位与强制转换得到uint16_t类型数据

numPart[0] = (uint16_t) rec0;

numPart[1] = (uint16_t) rec1;

armControl = ((numPart[0] << 8) | numPart[1]);

// 逆向解码

arm = armControl / 1000;  // 舵机编号

targetPulse = armControl % 1000 + 200;        // 目标比较值

// 通过switch语句改变指定PWM通道的比较值

switch(arm)

{

case 1:

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, targetPulse);

break;

case 2:

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, targetPulse);

break;

case 3:

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, targetPulse);

break;

case 4:

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, targetPulse);

break;

case 5:

__HAL_TIM_SET_COMPARE(&htim9, TIM_CHANNEL_1, targetPulse);

break;

case 6:

__HAL_TIM_SET_COMPARE(&htim9, TIM_CHANNEL_2, targetPulse);

break;

}

}

}复制代码

在进入while循环之前还需将PWM通道使能;

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);

HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_1);

HAL_TIM_PWM_Start(&htim9, TIM_CHANNEL_2);复制代码

并且在USART2_IRQHandler函数中使能串口接收中断:

void USART2_IRQHandler(void)

{

/* USER CODE BEGIN USART2_IRQn 0 */

/* USER CODE END USART2_IRQn 0 */

HAL_UART_IRQHandler(&huart2);

/* USER CODE BEGIN USART2_IRQn 1 */

HAL_UART_Receive_IT(&huart2, pulse, sizeof(pulse));

/* USER CODE END USART2_IRQn 1 */

}复制代码

测试

在测试时我使用的环境是安装有Ubuntu 18.04的树莓派,串口调试工具为CuteCom;由5V锂电池为单片机与舵机(机械臂)供电,每次手动发送两个字节的数据,十进制转十六进制在科学计算器上进行。机械臂的运动符合预期。

经过测试,同时发送12个字节的数据,机械臂也能够正常运行。

这里需要注意,在接线时,舵机的地线必须与单片机共地。

之后就可以将上位机串口发送的代码写入C++或者Python程序,通过上位机控制机械臂。


版权声明:本文为weixin_39668479原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。