基于Arduino UNO的智能摇头避障小车

简介: 基于Arduino UNO的智能摇头避障小车

1.首先介绍两个基本函数

void setup() { 
// put your setup code here, to run once: 把你的设置代码放在这里,运行一次
}
void loop() {
// put your main code here, to run repeatedly: 把你的主代码放在这里,重复运行
}

2.L298N控制逻辑

根据我们的接线:

左电机由引脚2,3控制,右电机由4,5控制。正反转导致前进后退需要根据输出端子那边的电机接线实际验证 测试。


接线说明:


左电机安装朝向是接杜邦线的那侧朝外(朝轮子) 左轮上,接左端子的OUT2口, 左轮下,接左端子的OUT1口, IN1由2控制,IN2为3控制 右电机安装朝向是接杜邦线的那侧朝内(背对轮子) 右轮上,接右端子的OUT3口, 右轮下,接右端子的OUT4口, IN3由4控制,IN4为5控制


3.让小车实现前后左右轮子动代码示例:

void setup() {
// put your setup code here, to run once:
//左轮信号方向初始化
pinMode(2,OUTPUT);// 配置2口为输出引脚
pinMode(3,OUTPUT);// 配置3口为输出引脚
//右轮信号方向初始化
pinMode(4,OUTPUT);// 配置4口为输出引脚
pinMode(5,OUTPUT);// 配置5口为输出引脚
}
void loop() {
// put your main code here, to run repeatedly:
//小车前进
digitalWrite(2,LOW);
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
delay(1000);
//小车后退
digitalWrite(2,HIGH);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
delay(1000);
//小车左转,右轮前,左轮后
digitalWrite(2,HIGH);
digitalWrite(3,LOW);
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
delay(1000);
//小车右转,左轮前,右轮后
digitalWrite(2,LOW);
digitalWrite(3,HIGH);
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
delay(1000);
}
可以用函数封装,代码示例:
void qianJin() {
// 小车前进的功能
digitalWrite(2,LOW);
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
}
void houTui() {//函数的封装
// 小车后退的功能
digitalWrite(2,HIGH);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
}
void zuoZhuan(){
digitalWrite(2,HIGH);
digitalWrite(3,LOW);
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
}
void youZhuan(){
digitalWrite(2,LOW);
digitalWrite(3,HIGH);
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
}
void carInit()
{
// put your setup code here, to run once:
pinMode(2,OUTPUT);// 配置2口为输出引脚
pinMode(3,OUTPUT);// 配置3口为输出引脚
//右轮信号方向初始化
pinMode(4,OUTPUT);// 配置4口为输出引脚
pinMode(5,OUTPUT);// 配置5口为输出引脚
}
void setup() {
carInit();
}
void loop() {
qianJin();//函数的调用
delay(1000);
houTui();
delay(1000);
zuoZhuan();
delay(1000);
youZhuan();
delay(1000);
}

4.串口介绍

我们把程序通过电脑下载到WemosD1上的时候,就是通过串口通信


在程序中,我们也可以通过函数调用实现串口通信


串口的初始化函数:


描述:开启串口,通常置于setup()函数中。 Serial.begin(speed)


参数: speed:波特率,一般取值9600,115200等。


ArduinoUno通过串口发送一个消息给电脑


Serial.print(“test message,这里是消息,喜欢发什么消息,就写什么消息”)


Serial.println(“test message,这里是消息,喜欢发什么消息,就写什么消息”), 比上面多了ln,代表换行


代码示例:

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("zglnb");
Serial.println("zglnb");
}
 

打开测试

5.跟随小车开发

主要用到超声波模块,型号:HC-SR04

原理图:

超声波代码通过串口测验:

void setup() {
// put your setup code here, to run once:
// Trig 接 9,通过9发送一个触发信号给超声波
pinMode(9,OUTPUT);
// Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
pinMode(8,INPUT);
Serial.begin(9600);
}
void loop() {
long shijian;
long juli;
// put your main code here, to run repeatedly:
// 发送一个10us的信号给超声波,9Trig
digitalWrite(9, LOW);
delayMicroseconds(2);
digitalWrite(9, HIGH);
delayMicroseconds(10);
digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
// 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
shijian = pulseIn(8,HIGH);
// 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
juli = shijian * 0.017;
Serial.print(juli);
Serial.println("cm");
}
//封装测距代码
//函数:名 参数 返回值
long getDis() {
// 测距函数
long shijian;
long juli;
// put your main code here, to run repeatedly:
// 发送一个10us的信号给超声波,9Trig
digitalWrite(9, LOW);
delayMicroseconds(2);
digitalWrite(9, HIGH);
delayMicroseconds(10);
digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
// 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
shijian = pulseIn(8,HIGH);
// 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
juli = shijian * 0.017;
return juli;
}
void setup() {
// put your setup code here, to run once:
// put your setup code here, to run once:
// Trig 接 9,通过9发送一个触发信号给超声波
pinMode(9,OUTPUT);
// Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
pinMode(8,INPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
long juli;
juli = getDis();
Serial.print(juli);
Serial.println("cm");
}

跟随小车代码:

//前进
void qianJin() {
// 小车前进的功能
digitalWrite(2,LOW);
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
}
//后退
void houTui() {//函数的封装
// 小车后退的功能
digitalWrite(2,HIGH);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
}
//ting
void ting() {//函数的封装
// 小车后退的功能
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
}
//测距
//函数:名 参数 返回值
long getDis() {
// 测距函数
long shijian;
long juli;
// put your main code here, to run repeatedly:
// 发送一个10us的信号给超声波,9Trig
digitalWrite(9, LOW);
delayMicroseconds(2);
digitalWrite(9, HIGH);
delayMicroseconds(10);
digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
// 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
shijian = pulseIn(8,HIGH);
// 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
juli = shijian * 0.017;
return juli;
}
void carInit()
{
// put your setup code here, to run once:
pinMode(2,OUTPUT);// 配置2口为输出引脚
pinMode(3,OUTPUT);// 配置3口为输出引脚
//右轮信号方向初始化
pinMode(4,OUTPUT);// 配置4口为输出引脚
pinMode(5,OUTPUT);// 配置5口为输出引脚
}
void setup() {
// put your setup code here, to run once:
carInit();
// Trig 接 9,通过9发送一个触发信号给超声波
pinMode(9,OUTPUT);
// Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
 
pinMode(8,INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
delay(50);//为了放缓超声波交互的速度,交互过快,得出距离后会卡顿,影响效果体验
long juli;
juli = getDis();
//如果距离大于3且小于13,后退
if( 3 < juli && juli < 15){
houTui();
}
//如果距离大于14且小于40,前进
if( 14 < juli && juli < 40){
qianJin();
}
if(juli > 50){
ting();
}
}

6.摇头避障小车开发

需要舵机模块

如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制用处:垃圾桶项目开盖 用、智能小车的全比例转向、摄像头云台、机械臂等 常见的有0-90°、0-180°、0-360°

Arduino官方提供Servo类来支持舵机操作

//舵机的初始化
Servo myServo; //定义一个Servo变量
myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10
myServo.write(0);//转到某角度,根据实际执行观看
myServo.write(90);//转到某角度,根据实际执行观看

摇头避障小车代码:

#include <Servo.h>
Servo myServo;//因为很多子函数要用这个变量,所以把servo定义成全局变量,作用域是整个代码文件
void ting() {
// 小车前进的功能
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
void qianJin() {
// 小车前进的功能
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
}
void houTui() {//函数的封装
// 小车后退的功能
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, HIGH);
}
void zuoZhuan() {
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
}
void youZhuan() {
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
digitalWrite(5, HIGH);
}
void carInit()
{
// put your setup code here, to run once:
pinMode(2, OUTPUT); // 配置2口为输出引脚
pinMode(3, OUTPUT); // 配置3口为输出引脚
//右轮信号方向初始化
pinMode(4, OUTPUT); // 配置4口为输出引脚
pinMode(5, OUTPUT); // 配置5口为输出引脚
}
long getDis() {
// 测距函数
long shijian;
long juli;
// put your main code here, to run repeatedly:
// 发送一个10us的信号给超声波,9Trig
digitalWrite(9, LOW);
delayMicroseconds(2);
digitalWrite(9, HIGH);
delayMicroseconds(10);
digitalWrite(9, LOW);//超声波内部开始震荡,准备发送波
// 关注Echo高电平维持的时间,代表超声波发送到返回的时间,微秒
shijian = pulseIn(8, HIGH);
// 距离(cm) = 时间(s) * 速度340m/s 34000cm/s = cm
juli = shijian * 0.017;
return juli;
}
void setup() {
// put your setup code here, to run once:
//定义一个Servo变量
carInit();
myServo.attach(10);//把舵机黄色信号线插在arduino的引脚10
// Trig 接 9,通过9发送一个触发信号给超声波
pinMode(9, OUTPUT);
// Echo 接 8,通过读取8高电平维持的时间,确认超声波在空气中传播的时间
pinMode(8, INPUT);
Serial.begin(9600);
}
void loop() {
long youjuli;
long zhongjuli;
long zuojuli;
//如果前面没有障碍物,我让小车往前走
myServo.write(100);//中间方向
delay(500);
zhongjuli = getDis();
Serial.print("中间距离是:");
Serial.println(zhongjuli);
if (zhongjuli < 35) {
ting();//检测到前方右障碍物
//往右边摇头,并测距
myServo.write(30);//右方向
delay(500);
youjuli = getDis();
Serial.print("右边距离是:");
Serial.println(youjuli);
myServo.write(100);//测完右边距离,再回到中间,此时可以不测距
delay(500);
//往左边摇头,测左边距离
myServo.write(170);//左边方向
delay(500);
zuojuli = getDis();
Serial.print("左边距离是:");
Serial.println(zuojuli);
myServo.write(100);//测完右边距离,再回到中间,此时可以不测距
delay(500);
if(zuojuli > youjuli){
Serial.println("左转");
zuoZhuan();
delay(100);
ting();
}
if(zuojuli < youjuli){
Serial.println("右转");
youZhuan();
delay(100);
ting();
}
} else { //前方无障碍物,小车前进
qianJin();
}
}

7.实物展示

相关文章
|
3月前
|
人工智能 Linux API
【OpenClaw保姆级图文教程】阿里云/本地部署、免费大模型配置、Skills接入与常见问题解答
2026年初,开源AI智能体框架OpenClaw(昵称“小龙虾”)在GitHub平台实现指数级增长,短短数周斩获15万+星标,成为全球增速最快的AI开源项目之一。这款工具打破了传统AI的被动交互壁垒,实现7×24小时无间断自主运行,能自主操控浏览器、编写调试代码、解析各类文件、执行系统命令,即使用户休息,也能按预设目标完成全流程任务。开发者EthanMoore更是凭借OpenClaw在30天内实现月均被动收入突破1.2万美元,印证了这款工具的自动化生产力价值。
1608 4
|
人工智能 弹性计算 自然语言处理
专属个人主页助你在求职季脱引而出
AI时代是时候告别传统的“纸片简历”了!你需要一个能动态展示、深度链接、真正代表你的“云端名片”——专属个人主页! 本方案介绍如何通过自然语言,5分钟快速在云端搭建一个可对外提供访问的个人主页。
2592 6
|
传感器 存储 开发者
Arduino 中用于从传感器读取模拟和数字数据的函数
Arduino 提供了多种函数,用于从传感器读取模拟和数字数据。模拟数据通过 `analogRead()` 函数读取,数字数据则使用 `digitalRead()` 函数。这些函数简单易用,适用于各种传感器,帮助开发者轻松获取环境信息。
1240 2
|
传感器 存储 网络协议
Arduino 中的常见的库
Arduino 中的常见库包括:Wire(I2C通信)、SPI(串行外设接口)、Servo(伺服电机控制)、EEPROM(数据存储)、LiquidCrystal(液晶显示)等,这些库简化了硬件编程,提高了开发效率。
1769 3
|
JavaScript 数据安全/隐私保护 Python
python爬取m3u8实战!!
本文详细介绍了如何抓取和处理m3u8视频文件,包括从网页源代码中提取m3u8文件地址、下载m3u8文件及其对应的ts片段、处理加密的ts文件以及使用ffmpeg合并视频片段。通过多线程下载和文件路径处理,确保了高效和准确的视频抓取与合并。文中还提供了具体的Python代码示例,帮助读者理解和实现整个过程。
3479 1
西门子S7-1200组态网络连接,组态HMI连接
西门子S7-1200在图形化的网络视图工作区中,可以很方便地将具有联网能力的设备进行组网,下面我们就简单介绍如何组态网络连接及如何组态HMI连接。
西门子S7-1200组态网络连接,组态HMI连接
|
存储 Ubuntu
关于实体机安装Ubuntu 22.04.3-desktop-amd64遇见的一些问题
【10月更文挑战第2天】本文详细介绍了在使用 Ubuntu 过程中常见的五个问题及其解决方案:下载镜像文件速度慢或损坏,可更换镜像源或验证哈希值;制作启动盘失败,需检查 U 盘及设置;安装过程中的分区问题,需合理规划分区;安装后的驱动问题,可通过安装官方驱动解决;软件安装和更新问题,需检查仓库配置及依赖关系。
1547 4