目标:
做一个四轮驱动小车,实现通过GD32F427控制小车前进,后退,左移,右移,左前,右前,左后,右后的移动,以及左转,右转,自旋转等运动;
主要器件:
- GD32F427开发板;
- L298N电机驱动模块*2;
- 纳姆轮小车;
- 减速电机*4;
- 车架;
实现过程介绍
L298N模块
网上资料较多,此处就不多赘述了。
只需要知道两个IO可以控制一个轮子的正反转和停止,还有一路可以接pwm实现输出电压控制进而实现速度控制就行。
纳姆轮
纳姆轮分A,B两种轮,安装时候需要注意;
安装好以后俯视图如下:
此时通过控制四个轮子不同的旋转方向即可达到控制小车前进,后退,左移,右移,左前,右前,左后,右后的移动,也可以控制小车左转,右转,自旋转等运动,比较好玩;
代码主要先实现对轮子的控制,然后通过封装一个小车结构体,调用轮子控制接口来实现小车运动。
成果视频
https://www.bilibili.com/vide...
代码介绍
1.轮子控制:
主要控制轮子正转,反转和暂停;
ps.把向前移动的轮子转向定义为正转,即看轮子外侧为顺时针旋转。
控制轮子代码如下:
void wheel_set_scroll(wheel_type *wheel,e_wheel_scroll scroll)
{
wheel->wheel_scroll = scroll;
switch(scroll)
{
case wheel_stop:
gpio_ctl(0,wheel->ios[0]);
gpio_ctl(0,wheel->ios[1]);
break;
case wheel_go:
gpio_ctl(1,wheel->ios[0]);
gpio_ctl(0,wheel->ios[1]);
break;
case wheel_back:
gpio_ctl(0,wheel->ios[0]);
gpio_ctl(1,wheel->ios[1]);
break;
case wheel_mini:
case wheel_max:
default:
gpio_ctl(1,wheel->ios[0]);
gpio_ctl(1,wheel->ios[1]);
break;
}
}
2.小车控制:
通过控制四个轮子的正反转达到控制小车移动的目的;
小轮我们分别命名为0,1,2,3号轮,如下所示
`
*0*-----*1*
*** | ***
|
*** | ***
*2*-----*3*
*** ***
`
控制小车代码如下:
int car_move(car_type *pCar, e_car_direction direction)
{
int ret = 0;
pCar->car_direction = direction;
switch(direction) {
case car_stop: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[1], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[2], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[3], wheel_stop);
break;
}
case car_forward: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_go);
wheel_set_scroll(&pCar->car_wheels[1], wheel_go);
wheel_set_scroll(&pCar->car_wheels[2], wheel_go);
wheel_set_scroll(&pCar->car_wheels[3], wheel_go);
break;
}
case car_back: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_back);
wheel_set_scroll(&pCar->car_wheels[1], wheel_back);
wheel_set_scroll(&pCar->car_wheels[2], wheel_back);
wheel_set_scroll(&pCar->car_wheels[3], wheel_back);
break;
}
case car_left: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_back);
wheel_set_scroll(&pCar->car_wheels[1], wheel_go);
wheel_set_scroll(&pCar->car_wheels[2], wheel_go);
wheel_set_scroll(&pCar->car_wheels[3], wheel_back);
break;
}
case car_right: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_go);
wheel_set_scroll(&pCar->car_wheels[1], wheel_back);
wheel_set_scroll(&pCar->car_wheels[2], wheel_back);
wheel_set_scroll(&pCar->car_wheels[3], wheel_go);
break;
}
case car_forward_left: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[1], wheel_go);
wheel_set_scroll(&pCar->car_wheels[2], wheel_go);
wheel_set_scroll(&pCar->car_wheels[3], wheel_stop);
break;
}
case car_forward_right: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_go);
wheel_set_scroll(&pCar->car_wheels[1], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[2], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[3], wheel_go);
break;
}
case car_back_left: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_back);
wheel_set_scroll(&pCar->car_wheels[1], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[2], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[3], wheel_back);
break;
}
case car_back_right: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[1], wheel_back);
wheel_set_scroll(&pCar->car_wheels[2], wheel_back);
wheel_set_scroll(&pCar->car_wheels[3], wheel_stop);
break;
}
case car_turn_left: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_back);
wheel_set_scroll(&pCar->car_wheels[1], wheel_go);
wheel_set_scroll(&pCar->car_wheels[2], wheel_back);
wheel_set_scroll(&pCar->car_wheels[3], wheel_go);
break;
}
case car_turn_right: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_go);
wheel_set_scroll(&pCar->car_wheels[1], wheel_back);
wheel_set_scroll(&pCar->car_wheels[2], wheel_go);
wheel_set_scroll(&pCar->car_wheels[3], wheel_back);
break;
}
default: {
wheel_set_scroll(&pCar->car_wheels[0], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[1], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[2], wheel_stop);
wheel_set_scroll(&pCar->car_wheels[3], wheel_stop);
break;
}
}
return ret;
}
int car_init(car_type *pCar)
{
int ret = -1;
int i,j;
car_type car;
if(pCar == NULL)
{
printf("pCar is NULL");
return ret;
}
memset(&car, 0x00, sizeof(car_type));
//wheel init GPIO
car.car_wheels[0].ios[0] = GPIO_00;
car.car_wheels[0].ios[1] = GPIO_01;
car.car_wheels[1].ios[0] = GPIO_02;
car.car_wheels[1].ios[1] = GPIO_03;
car.car_wheels[2].ios[0] = GPIO_04;
car.car_wheels[2].ios[1] = GPIO_05;
car.car_wheels[3].ios[0] = GPIO_06;
car.car_wheels[3].ios[1] = GPIO_07;
for(i=0;i<4;i++)
{
for(j=0;j<2;j++)
{
gpio_init(car.car_wheels[i].ios[j]);
}
}
memcpy(pCar, &car, sizeof(car_type));
ret = 0;
return ret;
}
代码仓库链接
https://gitee.com/lyzcc/gd32-...
遇到的问题
小车在横向或者斜向移动时候,容易出现调整不准或者路面颠簸出现方向偏差,因为也是刚刚接触这类产品,不知道是不是有啥好的技术或者解决方案可以解决这种问题,目前暂时没有好办法,各位如果有好的建议欢迎留言交流。
鄙人是找了一个小地毯。。。
后续计划
1.添加无线通信模块,实现远程控制,初步规划蓝牙通信;
2.添加变速功能,通过pwm控制;