【GD32F427开发板试用】基于GD32F427的纳姆轮小车

news2025/2/21 19:27:52

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:Ljfly

目标:

做一个四轮驱动小车,实现通过GD32F427控制小车前进,后退,左移,右移,左前,右前,左后,右后的移动,以及左转,右转,自旋转等运动;

主要器件:

  1. GD32F427开发板;
  2. L298N电机驱动模块*2;
  3. 纳姆轮小车;
  4. 减速电机*4;
  5. 车架;

实现过程介绍

L298N模块

网上资料较多,此处就不多赘述了。

只需要知道两个IO可以控制一个轮子的正反转和停止,还有一路可以接pwm实现输出电压控制进而实现速度控制就行。

纳姆轮

纳姆轮分A,B两种轮,安装时候需要注意;
安装好以后俯视图如下:

此时通过控制四个轮子不同的旋转方向即可达到控制小车前进,后退,左移,右移,左前,右前,左后,右后的移动,也可以控制小车左转,右转,自旋转等运动,比较好玩;

代码主要先实现对轮子的控制,然后通过封装一个小车结构体,调用轮子控制接口来实现小车运动。

成果视频

代码介绍

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控制;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/184260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一起自学SLAM算法:12.1 ros-navigation导航系统

连载文章&#xff0c;长期更新&#xff0c;欢迎关注&#xff1a; 可以说ros-navigation是ROS系统中最重要的组件之一&#xff0c;绝大部分自主移动机器人的导航功能都是基于ros-navigation导航系统实现的。下面将从原理分析、源码解读和安装与运行这3个方面展开讲解ros-navigat…

一篇五分生信临床模型预测文章代码复现——FIgure 9.列线图构建,ROC分析,DCA分析 (一)

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…

拉伯证券|2023年净利“超十倍潜力股”揭秘

本年成绩有望暴增的个股有哪些&#xff1f; 2022年各首要指数调整较大&#xff0c;但2023年开年以来A股体现继续强势&#xff0c;三大股指到目前涨幅均超5%&#xff0c;创业板指更是大涨超10%&#xff0c;医药、消费、科技等赛道轮番体现。 外资也对A股进行新一轮的加仓调仓&a…

Redis学习笔记:慢查询,Pipeline,事务,乐观锁

本文是自己的学习笔记。主要参考资料如下&#xff1a; 马士兵 1、Redis的慢查询1.1、慢查询的相关参数1.1.1、设置阈值1.1.2、慢查询日志存储长度1.1.2.1、慢查询日志解析1.2、生产环境下慢查询的配置2、Pipeline2.1、简单的pipeline代码示例2.2、使用Pipeline的注意事项3、事务…

自己写的功能简单的 http server 文件下载服务器 http服务器

最近在项目中遇到过 通过ssh登录到某台机器A &#xff0c;然后 又从A机器上ssh到机器B 而B机器是没有外网功能&#xff0c;这个时候如果想从B机器上传文件到A机器上就很不好办了 由于B机器没有外网 很多工具软件都没有 原来是是用python 起的http服务器 但是B机器没有安装py…

Black Basta 勒索软件利用 QakBot 进行分发

自 2022 年 4 月投入运营以来&#xff0c;Black Basta 对全球近 50 家组织发起了攻击。攻击者使用了“双重勒索”策略&#xff0c;如果受害者不交付赎金就会被公开数据。 勒索团伙会不断改进攻击方式&#xff0c;最近研究人员发现 Black Basta 与银行木马 QakBot 勾结在一起&a…

nginx+uwsgi部署django项目

1. python3.9环境安装 安装依赖 yum install zlib zlib-devel libffi-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make wget下载源码 官网地址 wget https://www.python.org/ftp/python/3.9.6/Python-3.9.6.tar.xz解压 &…

maven的下载与安装

前言 本篇文章是基于win11系统下载安装Maven的教程。 一、 Maven介绍 1. 什么是Maven&#xff1f; Maven是基于项目对象模型(POM project object model)&#xff0c;可以通过一小段描述信息&#xff08;配置&#xff09;来管理项目的构建&#xff0c;报告和文档的软件项目管…

【FreeRTOS】详细讲解FreeRTOS中任务管理并通过示例讲述其用法

任务状态 在FreeRTOS中一个任务经创建后会有多个状态&#xff0c;通常可分为以下几种状态&#xff1a; 就绪态&#xff1a;新创建的任务一般处于就绪态。处于就绪态的任务表明其已经存在于就绪列表中&#xff0c;其已经具备所有的任务执行需要条件&#xff0c;只等待调度器调度…

社科院杜兰大学金融管理硕士项目——美丽的风景,在你前行的路上

一个人的强大源于内心的坚定&#xff0c;内心强大的人&#xff0c;是平和的、自信的、乐观的。在工作中也是奋发图强、积极向上的&#xff0c;就像选择来社科院与杜兰大学金融管理硕士充电&#xff0c;为职场发展注入能量&#xff0c;为未来发展奠定基础。近些年来&#xff0c;…

Centos7离线安装MySQL

使用tar.gz文件安装MySQL 1、下载MySQL离线包 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 根据需要下载对应版本tar.gz文件&#xff0c;下载完成后上传到服务器 2、解压tar.gz文件 tar -zxvf mysql-5.7.37-linux-glibc2.12-x86_64.tar.gz等待解…

【计算机网络】TCP/UDP协议

传输层协议 负责数据能够从发送端传输接收端,这篇文章主要介绍TCP和UDP协议 UDP协议 学习UDP协议需要掌握&#xff0c;UDP协议如何做到封装和解包的&#xff0c;如何做到向上交付的&#xff08;分用问题&#xff09; UDP协议格式 封装&#xff1a;添加定长报头 解包&…

用Python掌握QQ群聊天记录数据分析

当你打开QQ群时,你是否想过如何用Python提取里面的数据呢?随着社交媒体的兴起,QQ群成为了人们交流的重要平台,而提取这些数据可以帮助我们了解用户喜好和行为。那么,如何使用Python提取QQ群数据呢? 这里做了一套脚本用于提取QQ群的消息并进行一些简单的处理。 其中包括…

IB、AP、A-LEVEL,哪种最适合自己呢?

刚开始了解新加坡留学的家长和学生&#xff0c;一定看到这些就觉得头大吧。当下国际学校里的课程可以说五花八门&#xff0c;在选择之前一定要弄清楚这些名词背后的含义…… IB是什么 IB&#xff08;International Baccalaureate&#xff09;全称为国际预科证书课程&#xff0c…

Linux下rabbitmq的集群搭建

1 修改 3 台机器的主机名称 在三台服务器分别执行 hostnamectl set-hostname master hostnamectl set-hostname node01 hostnamectl set-hostname node022 配置各个节点的 hosts 文件 vim /etc/hosts 192.168.5.6 master 192.168.5.7 node01 192.168.5.8 node023 确保各个节…

【工具】苏格拉底式诘问法解决工作问题

目录一、什么是苏格拉底式诘问法二、苏格拉底式诘问法的细分三、在实际工作中运用苏格拉底式诘问法解决问题一、什么是苏格拉底式诘问法 苏格拉底式诘问法&#xff08;Socratic Elenchus&#xff09;是苏格拉底式提问的一种&#xff0c;也叫做"诘问法"。它是由古希腊…

OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门

欢迎关注『OpenCV-PyQT项目实战 Youcans』系列&#xff0c;持续更新中 OpenCV-PyQT项目实战&#xff08;1&#xff09;安装与环境配置 OpenCV-PyQT项目实战&#xff08;2&#xff09;QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战&#xff08;3&#xff09;信号与槽机制 …

【Java】final的关键字和final的四种用法

final定义 final翻译成中文的意思是 “最终” &#xff0c; 它是java当中的一个关键字&#xff0c;使用final修饰的对象不允许修改或替换其原始值或定义。 假如当final修饰一个类的时候&#xff0c;是不能被其他类继承的。 final的四种用法 修饰类修饰方法修饰变量修饰参数 1.…

Oracle 里的优化器

对于关系型数据库而言&#xff0c;优化器是最核心的部分。主要是因为优化器负责解析SQL。而大家都是通过SQL来访问存储在数据库中的数据。故此&#xff0c;优化器的好坏直接决定该关系型数据库的强弱。 同时&#xff0c;想要做好SQL优化&#xff0c;就必须深入了解优化器。这是…

源表的基础知识

浅谈“源表”的定义、功能及应用 源表与传统电源的区别 源表速度更快&#xff1b; 源表电流、电压分辨率更高&#xff1b; 源表是四象限&#xff0c;可以正电压&#xff08;源表提供给外部&#xff09;负电流&#xff08;外部灌入源表&#xff09;或者负电压、正电流。 传统电…