文章目录

前言介绍一、硬件结构1.整体结构展示2.材料选型3.洞洞板拖锡4.3D打印零件

二、软件思路1.控制思路2.代码烧录4.资源下载

三、经验教训总结

前言

大二时,我羡慕学长们在比赛中拿奖,于是跟着学点知识,报名参加吉林省人工智能创新大赛全地形赛道,想锻炼自己并加学分。无论结果如何,我都想总结这次经历分享给学弟学妹,让他们少走弯路。

另外,我也是个新手小白,要是有啥说错的地方,大家尽管提,我虚心接受!

介绍

本项目小车的核心是用的Arduino Uno R3控制板,然后用L298N作为驱动模块。它主要是靠激光寻迹模块来感知地形的。激光寻迹模块会传回不同的信号,小车根据这些信号判断出不同的地形,然后做出相应的决策。

主要是完成如下赛道:

在比赛时候,大部分人都用的是履带小车,我做的是四轮小车。我的小车没有上中间的高台,不过最后还是拿到了省一等奖,还挺惊喜的!😁

全地形小车运行视频

一、硬件结构

1.整体结构展示

2.材料选型

主控:Arduino UNO R3 一个 激光寻迹模块 五个 分线端子 两个

减速直流电机 四个

2P 一个(多买点)

洞洞板 一个(多买点)

降压模块 一个(多买点)

L298N驱动模块 一个(多买点)

导向轮 两个

12V锂电池 一个

小车底板 一个

排母若干

排针若干

铜线若干

轮胎和联轴器

开关

除了主要部件,还用了铜柱、热缩管、标签贴纸、杜邦线、尼龙扎带、螺丝螺母等辅助材料。

3.洞洞板拖锡

为什么要用洞洞板拖锡? 因为作者不太熟练用嘉立创EDA😢,再加上时间特别紧张,等不及电路板寄到学校,所以只能选择拖锡了。好在之前买了好多洞洞板,刚好派上用场。

可以提前准备好下载好程序的备用主控板。这样在赛场上,如果哪个模块或者主板烧毁或者故障了,就不用再根据代码一点点重新连线了。直接用排针排母拔插的方式,快速替换掉有问题的模块就行。这样一来,引脚之间的连接会更稳定,不会出现接触不良的情况。而且在小车比赛行进或者被搬运的时候,也能减少因为飞线不稳导致的故障。

万用板焊接教学视频

在纸上把主控板和各个功能模块的引脚分配规划好

L298N 引脚Arduino Uno R3 引脚ENA11IN112IN213IN38IN49ENB10

Arduino Uno R3 中带波浪线标注的引脚才具有PWM输出功能

激光寻迹模块 引脚Arduino Uno R3 引脚L12L23ME4R25R16

把每个模块的电源供电安排好

模块种类电压Arduino Uno R35V(Vin)L298N12V激光寻迹模块5V

锂电池的12V直接接给L298N。尽量别用L298N输出的5V给主控芯片供电,因为那个电压不太稳。可以把锂电池的12V接到降压模块上,让降压模块输出5V,专门给单片机和5个激光寻迹模块供电(激光寻迹模块不能用单片机输出的电压供电哦)。激光寻迹模块单独供电的同时,要和Arduino Uno R3的信号口连接,并且所有模块要共地。L298N也得和Arduino Uno R3共地

4.3D打印零件

五路激光寻迹模块支架

因为激光寻迹模块得倾斜摆放,才能发挥出最好的效果。不过,激光的具体倾斜角度要根据不同的小车模型来调整。

导向轮支架

轻松过弯道,就算有时候激光寻迹模块识别不到亚克力板下面的黑线,它也能碰运气通过😴

二、软件思路

1.控制思路

根据寻迹模块检测到黑线的次数,调用对应的障碍子函数,每种障碍都有自己的处理逻辑。

首先得确定小车的行走路线,然后根据路线里障碍的顺序来写代码。 我的思路是先写好小车前进、后退、左转、右转这些基本动作的子函数。在速度控制方面,我设计了低速、中速、高速三种前进模式,还有小速度和大速度下的左右转。此外,还写了后退、停止的子函数,以及针对特定地形的速度函数,比如上台阶和通过U型管道的速度肯定是不一样的。

速度子函数代码示例:

void W() //正常速度模式

{

digitalWrite(IN1, 1);

digitalWrite(IN2, 0);

analogWrite(ENA, 140);//PWM值根据不同转速而定

digitalWrite(IN3, 1);

digitalWrite(IN4, 0);

analogWrite(ENB, 140);

}

设置变量n来进行不同状态之间的转换。 像是通过小台阶,我将通过小台阶的方法,写成了两个部分分别是小台阶上和小台阶下两个子函数,之后再小台阶上下的子函数里面,进行速度的配置,其他障碍依次类推,越复杂的障碍对应的子函数越多配置速度更加详细。 使用多个变量(如 n、j、t、Q 等)作为计时器或状态转换的条件,用于控制模式的切换和特定动作的执行。

Serial.println(“在调试过程中,最好加上输出语句或者设置断点,这样能清楚地了解代码的执行情况");

U型管模块代码示例:

void U()

{

int L1_V = digitalRead(L1);

int L2_V = digitalRead(L2);

int ME_V = digitalRead(ME);

int R2_V = digitalRead(R2);

int R1_V = digitalRead(R1);

if (L1_V == 1 && L2_V == 1 && ME_V == 1 && R2_V == 1 && R1_V == 1) //1 1 1 1 1

{

LW();

n=6;

} else if (L1_V == 0 && L2_V == 0 && ME_V == 1 && R2_V == 0 && R1_V == 0) //0 0 1 0 0

{

LW();

} else if (L1_V == 0 && L2_V == 1 && ME_V == 0 && R2_V == 0 && R1_V == 0) //0 1 0 0 0

{

XZ();

} else if (L1_V == 0 && L2_V == 0 && ME_V == 0 && R2_V == 1 && R1_V == 0) //0 0 0 1 0

{

XY();

} else if (L1_V == 0 && L2_V == 0 && ME_V == 0 && R2_V == 0 && R1_V == 0) //0 0 0 0 0

{

LW();

}

}

状态机代码示例:

switch (n) {

case 0:

{

while (1) {

jiansudai();

Serial.println("减速带");

if (n >= 4) {

n = 3;

Serial.println("改变的n");

Serial.println(n);

break;

}

}

}

break;

case 3:

{

while (1) {

caodi();

Serial.println("草地");

Serial.println(n);

if (n >= 7) {

Serial.println(">=8");

Serial.println(n);

n = 4;

break;

}

}

}

break;

default:

Serial.println("未知状态");

break;

}

2.代码烧录

下载Arduino IDE,安装后连接开发板,选择对应的开发板和端口,编写代码并上传

4.资源下载

资料包内容如下:

三、经验教训

小车的结构一定要稳定,速度再快也得稳!重要的事情说三遍:稳定、稳定、稳定!轮子最好换成窄一点的,这样通过U型管道和方形隧道会更方便。比赛情况千变万化,可能会有大灯干扰,地形也可能和在学校模拟的时候不一样,所以一定要做好十足的准备!

总结

如果需要资料,可以通过上面的视频链接找到我的主页私信我,也可以直接私信我哦! 最后祝大家比赛顺利,小车一路畅通无阻!😁 视频主页