系列目錄
點擊查看
- STM32 HAL庫快速實戰【一】《32點燈》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【三】《pwm控制舵機》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【四】《串口簡單使用》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【五】《控制串口電機》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【六】《藍牙控制》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【七】《機械臂控制》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【八】《聲音傳感器的使用》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【九】《超聲波傳感器的使用以及自由避障》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【十】《顏色傳感器的使用》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
- STM32 HAL庫快速實戰【十一】《紅外傳感器的使用及巡線循跡》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
接線
總共六個舵機,使用PB3-PB9引腳。
從下面支撐舵機到上面夾子舵機依次接DJ0到DJ5接口。
配置CubeMX
可以使用上節配置好的demo復制后繼續配置,也可以重新生成,這里不多贅述。
勾選PB3-PB8,打開定時器。由於涉及到多個舵機,歸零可能會造成干涉,所以所有舵機一定要調整到中位后在安裝。
調整中位只需要將所有定時器通道的Pulse設置為1500即可。
配置方法同STM32 HAL庫快速實戰【三】《pwm控制舵機》--基於黑龍江科技大學機電工業機器人實訓 - USTHzhanglu - 博客園 (cnblogs.com)
記住每個舵機對應的通道。
編寫代碼
生成代碼后,新建robot-arm.c和robot-arm.h,放入對應文件夾以及工程中。
初始化舵機
在.h文件中添加依賴,並聲明初始化函數
#include "tim.h"
#include "motor.h"
void arm_init(void);
在.c文件中定義初始化函數
#include "robot-arm.h"
/**
* @brief :初始化舵機0到舵機5,均初始化到中間位置。
* @param :void
* @retval None
**/
void arm_init(void)
{
//__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,500);修改DJ0的初始化角度為0度。
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//DJ0,PB3
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);//DJ1,PB8
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);//DJ2,PB9
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);//DJ3,PB6
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);//DJ4,PB7
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//DJ5,PB4
return;
}
}
由於設置的Pulse為1500,所以每個舵機的初始位置都在中間位。如果需要初始時位置不同,可以修改配置工程,或者在Start之前使用__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,rad);
來修改初始化位置。
控制舵機
由於我們需要一次控制六個舵機,每個舵機單獨控制屬實有夠麻煩。我們可以定義一個數組,里面儲存每次每個舵機需要運動到的角度,這樣每次我們只需要修改數組,就能很方便的控制六個舵機。
/**
* @brief :控制舵機0到舵機5,左上轉為正,右下轉為負,DJ0-5 +-135°,DJ6+-90°
* @param :rad[6],分別儲存每個舵機轉動角度
* @retval None
**/
void arm_set(const int rad[6])
{
需要注意的是,__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,rad);
傳入的參數是占空比,但是我們需要控制的是角度,因此需要進行一個簡單的運算(假設舵機處在中間位時為0°):1500+rad[x]*1000/135
。同時,由於安裝原因,有些舵機可能裝反了,拆卸安裝有夠惡心的,我們可以定義一個數組聲明舵機運動狀態,裝反的舵機只需要聲明該舵機運動狀態相反即可。
在robot-arm.c頂部中添加
#include "robot-arm.h"
/* 定義一個數組,說明舵機運動方向,如果實際轉向相反與輸入相反,則修改對應位為-1
*/
const int arm_toggle[6]={1,1,1,1,1,1};
然后我們就可以定義舵機控制函數
/**
* @brief :控制舵機0到舵機5,左上轉為正,右下轉為負,DJ0-5 +-135°,DJ6+-90°
* @param :rad[6],分別儲存每個舵機轉動角度
* @retval None
**/
void arm_set(const int rad[6])
{
int compare[6]={
1500+rad[0]*arm_toggle[0]*1000/135,
1500+rad[1]*arm_toggle[1]*1000/135,
1500+rad[2]*arm_toggle[2]*1000/135,
1500+rad[3]*arm_toggle[3]*1000/135,
1500+rad[4]*arm_toggle[4]*1000/135,
1500+rad[5]*arm_toggle[5]*1000/90,
};
__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,compare[0]);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_3,compare[1]);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,compare[2]);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_1,compare[3]);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_2,compare[4]);
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,compare[5]);
}
在main.c中初始化arm
/* USER CODE BEGIN 2 */
motor_init();
arm_init();
HAL_Delay(2000);
HAL_GPIO_WritePin(led_GPIO_Port,led_Pin,GPIO_PIN_RESET);
/* USER CODE END 2 */
燒錄程序后,機械臂會直立起來。如果角度不對,請重新安裝各關節舵機。
調節各關節角度
有了舵機控制代碼,我們可以方便的調節舵機角度,但是手動控制過於繁瑣,實際使用時更偏向於自動化控制。最好的方法是建立機械臂運動模型,但是難度較高。在這里我們選擇一種簡單類似於示教機器人的方法,通過記錄每次動作的角度狀態,在不同動作間直接切換即可。
首先,需要實時獲取當前關節角度。為了方便使用,這里封裝成一個函數:
/**
* @brief 打印當前關節角度
* @param :arm_rad[6],分別儲存每個舵機轉動角度
* @retval None
**/
void printf_rad(const int arm_rad[6])
{ char cmd_return[128];
sprintf(cmd_return, "{rad:%d,%d,%d,%d,%d,%d}",arm_rad[0],arm_rad[1],arm_rad[2],arm_rad[3],arm_rad[4],arm_rad[5]);
usart_send_str(&huart3,(unsigned char *)cmd_return);
return;
}
然后定義一個get_rad函數,用於獲取輸入的命令,調節舵機角度
點擊查看代碼
/**
* @brief :控制舵機0到舵機5,並打印當前角度
* @param :None
* @retval None
**/
void get_rad(void)
{
char menu;
int arm_status=1;
int rad[6]={0,0,0,0,0,0};
while( arm_status)
{menu=get_cmd();
switch(menu)
{
case 'A':rad[0]++;break;
case 'B':rad[0]--;break;
case 'C':rad[1]++;break;
case 'D':rad[1]--;break;
case 'E':rad[2]++;break;
case 'F':rad[2]--;break;
case 'G':rad[3]++;break;
case 'H':rad[3]--;break;
case 'I':rad[4]++;break;
case 'J':rad[4]--;break;
case 'K':rad[5]++;break;
case 'L':rad[5]--;break;
case 'Q':arm_status=0;break;
}
printf_rad(rad);
arm_set(rad);
menu=NULL;
}
return;
}
同時在.h文件中聲明函數
#include "tim.h"
#include "motor.h"
void arm_init(void);
void arm_set(const int rad[6]);
void printf_rad(const int arm_rad[6]);
void get_rad(void);
在main.c的switch中新增一個選項
switch(input)
{
case '0':get_rad();break;
通過藍牙控制,輸入0進入舵機調節菜單,然后輸入A-L調節關節,輸入Q退出調節菜單。
可以在BlueSPP中切換到鍵盤界面,快速調節
然后在CHAT界面查看當前角度。
記錄不同動作的角度,例如待機時為{0,85,-135,-54,0,0},在.c文件頂部定義:
/* 關節初始狀態*/
const int arm_begin[6]={0,85,-135,-54,0,0};
然后就可以直接執行關節動作。例如初始化舵機時直接初始化到待機位置
void arm_init(void)
{
arm_set(arm_begin);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//DJ0,PB3
工程源碼
國內用戶請使用gitee克隆或是使用代理訪問Github
https://github.com/USTHzhanglu/stm32-hal/tree/main/robot-arm