[产品应用] 【CW32L031CxTx StartKit评估板测评】机械臂实时控制

[复制链接]
1218|10
 楼主| lulugl 发表于 2023-10-12 21:11 | 显示全部楼层 |阅读模式
本帖最后由 lulugl 于 2023-10-12 21:21 编辑

#申请原创#
【工程目的】用Joystick手柄控制机械臂的自由运转。
舵机也叫也叫 RC 伺服器,通常用于机器人项目,也可以在遥控汽车,飞机等航模中找到它们。
类似舵机这样的伺服系统通常由小型电动机,电位计,嵌入式控制系统和变速箱组成。
电机输出轴的位置由内部电位计不断采样测量,并与微控制器(CW32L031)设置的目标位置进行比较;
根据相应的偏差,控制设备会调整电机输出轴的实际位置,使其与目标位置匹配。这样就形成了闭环控制系统。
控制原理
通过向舵机的信号信号线发送PWM信号来控制舵机的输出量;
一般来说,PWM的周期以及占空比,我们是可控的,所以PWM脉冲的占空比直接决定了输出轴的位置。
下面举个例子;
当我们向舵机发送脉冲宽度为1.5毫秒(ms)的信号时,舵机的输出轴将移至中间位置(90度);
脉冲宽度为1ms时,舵机的输出轴将移至最小的位置(0度);
脉冲宽度为2ms时,舵机的输出轴将移至最小的位置(180度);
具体可以参考下图;
d55949deeb72fb6d24dbe4844af1b6f8
占空比 = t / T 相关参数如下:
t = 0.5ms——————-舵机会转到 0 °
t = 1.0ms——————-舵机会转到 45°
t = 1.5ms——————-舵机会转到 90°
t = 2.0ms——————-舵机会转到 135°
t = 2.5ms——————-舵机会转到 180°
我们要产生50Hz(20ms)的PWM波形,我们需要用了GTIM定时器。
因为:PWM周期为20ms = (40000*24)/48000000=0.02所以:TIM_Period = 23,TIM_Prescaler = 39999,就是我的程序入口参数
为此我们初始化PWM函数如下:
//初始化pwm
void PWM_OutputConfig(void)
{
    GTIM_InitTypeDef GTIM_InitStruct = {0};
    __RCC_GTIM1_CLK_ENABLE();//启用GTIM1时钟
    GTIM_InitStruct.Mode = GTIM_MODE_TIME; //设置为定时器模式
    GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE;  //为连续计时模式
    GTIM_InitStruct.Prescaler = 23;    // 计数时钟TCLKD = TCLK/(PSC+1)
    GTIM_InitStruct.ReloadValue = 40000-1; //GTIM的重载值
    GTIM_InitStruct.ToggleOutState = DISABLE; //GTIM的翻转输出使能选择
    GTIM_TimeBaseInit(CW_GTIM1, >IM_InitStruct);
    GTIM_OCInit(CW_GTIM1, GTIM_CHANNEL3, GTIM_OC_OUTPUT_PWM_LOW);//CHy 通道输出低电平
    GTIM_SetCompare3(CW_GTIM1, 2000); //1ms为2000个计数值
GTIM_Cmd(CW_GTIM1, ENABLE);
}
初始化后,我们就可以输出指定时间的pwm占空比了。根据舵机的控制时间,我们以40000/20ms来获得1ms的计数值2000。
这次我们使用摇杠来实现对机械臂的控制,实现左右旋转,以及上下的移动。
程序流程图如下:
1b209f8d87028ad58ab2633375721325
根据摇柄的ADC值来实现左、右、中间按下以及上、下两个方向的ADC值来判断摇柄的操用动作。基代码如下:
if(valueAdc0<2000)
{
X_state = LEFT;
}
else if(valueAdc0>3900)
{
X_state = MIDD;
}
else if(valueAdc0>3300 && valueAdc0<3500)
{
X_state = RIGHT;
}
else if(valueAdc0>=2710 && valueAdc0<2730)
{
X_state = XLIFT;
}
if(valueAdc1<1860)
{
Y_state = DOWN;
}
else if(valueAdc1>=1900 && valueAdc1<2730)
{
Y_state = YLIFT;
}
else if(valueAdc1>=3300)
{
Y_state = UP;
}
然后我们根据其的状态,来实现PWM占空比的修改,实现舵机的不同角度的修正,来实现机械臂的实理控制。
void joystic_contrl(void)
{
static uint32_t x_sempler = 1500;//0度
static uint32_t y_sempler = 1500;//0度
if(X_state == LEFT)
{
x_sempler = x_sempler - x_step;
if(x_sempler <= X_MIN)
{
x_sempler = X_MIN;
}
}
else if (X_state == RIGHT)
{
x_sempler = x_sempler + x_step;
if(x_sempler >= X_MAX)
{
x_sempler = X_MAX;
}
}
else if(X_state == MIDD)
{
x_sempler = 30000;
}
X_state = XLIFT;
GTIM_SetCompare3(CW_GTIM1, x_sempler);
if(Y_state == UP)
{
y_sempler = y_sempler - y_step;
if(x_sempler <= Y_MIN)
{
x_sempler = Y_MIN;
}
}
else if (Y_state == DOWN)
{
y_sempler = y_sempler + y_step;
if(y_sempler >= Y_MAX)
{
y_sempler = Y_MAX;
}
}
Y_state = YLIFT;
GTIM_SetCompare4(CW_GTIM1, y_sempler);
}【源代码】
cw32l031-机械臂实时控制.zip (302.59 KB, 下载次数: 3)
【实验效果】
编译下载到开发板后实现了游戏摇柄对机械臂的实时控制。



评论

学习一下  发表于 2023-10-24 09:09
Tristan_C 发表于 2023-10-14 12:38 | 显示全部楼层
这个好玩
caigang13 发表于 2023-10-14 18:51 来自手机 | 显示全部楼层
不错,舵机也能这么丝滑。
jf101 发表于 2023-10-16 13:06 | 显示全部楼层
楼主你这个是动态实时频率多少?1ms还是更短?

评论

pwm的频率是50HZ  发表于 2023-10-16 13:23
小小蚂蚁举千斤 发表于 2023-10-23 18:53 | 显示全部楼层
楼主这个实时性如何进行的设计呢
 楼主| lulugl 发表于 2023-10-24 23:16 | 显示全部楼层
小小蚂蚁举千斤 发表于 2023-10-23 18:53
楼主这个实时性如何进行的设计呢

没有上操作系统,可以设计延时程序来处理,还有就舵机的转向占空比的大小来设置吧。
星辰大海不退缩 发表于 2023-10-25 08:45 | 显示全部楼层
lulugl 发表于 2023-10-24 23:16
没有上操作系统,可以设计延时程序来处理,还有就舵机的转向占空比的大小来设置吧。 ...

楼主这个厉害,是不是上一个RTOS是不是更加实时性更好
 楼主| lulugl 发表于 2023-10-25 09:33 | 显示全部楼层
星辰大海不退缩 发表于 2023-10-25 08:45
楼主这个厉害,是不是上一个RTOS是不是更加实时性更好

这个开发内存比较小,上系统不是很适合,如果是L083 F030等系列可以上系统,更加好。
中国龙芯CDX 发表于 2023-11-14 14:32 | 显示全部楼层
通过向舵机的信号信号线发送PWM信号来控制舵机的输出量
您需要登录后才可以回帖 登录 | 注册

本版积分规则

188

主题

844

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部