ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Arduino UNO超声波避障小车:接线、决策状态机与实验数据

Arduino UNO超声波避障小车:接线、决策状态机与实验数据 简介这份资源是一篇本科毕业设计论文文档以基于Arduino单片机的超声波避障小车为研究对象适合电子信息、自动化、计算机等专业需要完成毕业论文或课程设计的学生参考。论文围绕行为设计思路完整展开移动机器人从机械结构搭建到软件控制逻辑的实现过程硬件上以Arduino单片机为控制核心配合超声波传感器检测前方障碍物距离通过L298N驱动两个直流电机并用PWM调速控制行进速度软件上采用Arduino语言编程实现前进、后退、转向等动作当探测到约25厘米内有障碍物时自动转向避让。文中还涉及机器人机械设计、传感器检测与试验结果分析等内容可作为超声波测距、电机驱动与嵌入式编程的综合实践参考。资源包共1个文件为docx格式的毕业论文压缩包大小12.69MB结构完整目录与摘要、绪论、硬件设计、软件编程及测试章节齐备。目前已有248人学习。1. 答辩前一周小车跑不起来才是这个题目真正的难点选题表上写下「基于Arduino单片机避障小车机器人」的那一刻多数人以为难点在论文实际卡住的是车。实验室里最常见的一幕代码编译通过串口能打印距离电机就是不转或者原地打转撞上桌角答辩前一天还在换驱动模块。这个题目的技术骨架其实很窄——一块Arduino UNO、一个超声波模块、一块电机驱动、两个直流减速电机加几十行决策代码但要把这几样凑成一辆每次都能绕开障碍的小车牵涉供电、共地、定时器冲突、测距滤波和参数整定五件事任何一件没处理好演示就会翻车。下面按硬件、代码、实验数据、进阶调试的顺序走一遍目标是让车先动起来、再让论文里的数据站得住。2. Arduino UNO 避障小车的硬件选型与接线2.1 主控与驱动选型为什么 UNO 加 L298N 最不容易翻车毕设现场比拼的不是算力而是「一次点亮」。主控的选择直接决定了你需要花多少时间在底层而不是在算法和论文上。方案资源与特点上手门槛适合的题目方向Arduino UNO R314 路数字 IO、6 路 PWM、5V 电平Servo、NewPing 等库现成低接线即用功能单一的避障小车课设、本科毕设STM32F103定时器多能同时跑编码器、PWM、串口3.3V 需考虑电平中HAL 配置耗时stm32 循迹避障小车、需要测速与闭环51 / STC 单片机成本低、寄存器直观IO 与定时器偏紧中多数驱动要自己写教学演示、偏硬件设计的题目我一般会按「论文里要写几个功能」倒推主控只做避障UNO 足够要同时做避障、测速、循迹、串口上报STM32 或 Arduino 加扩展板更省事。Arduino 生态里Servo.h、NewPing.h这类库把超声波和舵机的时序细节都封好了答辩演示最怕的时序抖动问题能少一大半。驱动模块是第二个分水岭。L298N 是双 H 桥输入 7 到 12V单路持续 2A 左右缺点是内部压降约 1.4 到 2V两节 18650 串成 7.4V 时电机实际只拿到 5.5V 上下速度偏慢TB6612FNG 压降小、效率高但对 PWM 频率和逻辑电平更挑DRV8833 适合小功率空心杯。常见做法是 UNO 加 L298N 打底如果论文里要写「不同驱动方案对能耗的影响」正好把 TB6612 作为对照组实验章节立刻有内容。2.2 引脚分配表超声波、舵机与 L298N 怎么接不打架接线冲突里最隐蔽的一条是定时器。UNO 上Servo.h默认占用 Timer1一旦调用attach()9 号和 10 号引脚就失去analogWrite()的 PWM 能力——编译不会报错表现是电机调速失灵或舵机抖动。模块模块引脚UNO 引脚说明HC-SR04VCC / GND5V / GND工作电流约 15mAHC-SR04TrigD3触发端需要 10µs 高电平HC-SR04EchoD4回波高电平时长即往返时间SG90 舵机信号D9占用 Timer1D9/D10 失去 PWMSG90 舵机VCC外部 5V 优先堵转电流可达 700mAL298NENAD5左轮 PWMTimer0L298NIN1 / IN2D7 / D8左轮方向L298NENBD6右轮 PWMTimer0L298NIN3 / IN4D12 / D13右轮方向L298NGNDGND必须与 UNO 共地这套分配把两路 PWM 留给 Timer0 的 D5、D6舵机单独用 D9Trig 和 Echo 放在不冲突的 D3、D4。后面如果要加编码器测速D2、D3 是外部中断引脚TrIG 需要挪到 D11这一点在做扩展实验之前就要规划好不然后期改板子很痛苦。2.3 供电与共地小车一上电就复位的原因新手最常见的现象是接上电池UNO 反复重启串口不断打印启动信息。九成是电源问题。电机启动瞬间的浪涌电流能到 1A 以上如果 UNO 和电机共用一路供电电压被拉低到复位阈值以下主控就会重启。# 推荐的供电拓扑文字描述接线时对照 # 电池组 7.4V ── L298N 的 12V 输入端子同时给电机供电 # L298N 板载 5V 输出 ── 舵机 VCC拔掉 5V 使能跳帽后引出 # UNO 单独用 USB 或 9V 电池供电 # 三者的 GND 必须短接在一起参数上要盯三个点。第一L298N 的 5V 使能跳帽插上时板载稳压给内部逻辑供电同时也从 5V 端子输出如果要用它给 UNO 的 5V 引脚反供电就必须拔掉 USB否则两路电源互顶。第二电机两端并一个 0.1µF 陶瓷电容能明显减少对主控的干扰。第三舵机和电机尽量分开取电或者在 5V 母线并一只 470µF 到 1000µF 的电解电容做储能。提示所有模块的 GND 必须连到同一点。只接了信号线没接共地是最难查的一类故障——串口有数据电机纹丝不动。3. 避障决策的最小可跑通代码与参数整定3.1 HC-SR04 测距函数与超时保护先把测距做扎实后面所有逻辑都建立在这个数字上。下面这段是所有避障小车的地基重点是超时保护否则前方无遮挡、回波丢失时pulseIn会一直等下去整辆车卡死。#include Servo.h Servo scanServo; const uint8_t PIN_TRIG 3; const uint8_t PIN_ECHO 4; const uint8_t PIN_SERVO 9; const uint8_t ENA 5, IN1 7, IN2 8; // 左轮 const uint8_t ENB 6, IN3 12, IN4 13; // 右轮 // 返回厘米-1 表示本次没有收到回波 float readDistanceCM() { digitalWrite(PIN_TRIG, LOW); delayMicroseconds(4); // 拉低一小段保证触发沿干净 digitalWrite(PIN_TRIG, HIGH); delayMicroseconds(10); // 规格书要求的 10µs 触发脉冲 digitalWrite(PIN_TRIG, LOW); // 25000µs 超时约等于 4.3m超出量程直接放弃本次采样 unsigned long dur pulseIn(PIN_ECHO, HIGH, 25000UL); if (dur 0) return -1.0f; // 声速取 20℃ 下的 343m/s即 0.0343cm/µs除以 2 是往返距离 return dur * 0.0343f / 2.0f; }pulseIn的第三个参数是超时微秒数这个值必须给。返回 0 代表超时业务层把它当成「无限远」还是「无效值」要写清楚否则决策逻辑会出现「因为读不到就往前冲」这种危险分支。3.1.1 中值滤波与温度补偿单次采样跳变很大尤其是地面反射和软质障碍物。取三次中值是最省 CPU 的做法代码只有几行int medianOf3(float a, float b, float c) { if (a b) { float t a; a b; b t; } if (b c) { float t b; b c; c t; } if (a b) { float t a; a b; b t; } return (int)b; // 排序后取中间值 }如果论文里要做误差分析温度补偿是个加分项声速 v 331.4 0.6 × TT 为摄氏度加一个 DHT11 或者 DS18B20 就能把 0.0343 换成实时计算值。需要注意的是室温下这个修正量只有百分之几测距误差的主要来源其实是障碍物表面材质和安装高度别把精力全押在温度上。3.2 三向扫描舵机的决策状态机只靠一个前置超声波小车只能在正前方做出反应遇到直角墙角会来回犹豫。加一个舵机做三向扫描决策空间立刻变清晰左 150°、正前 90°、右 30°。const int ANG_LEFT 150, ANG_MID 90, ANG_RIGHT 30; const int DIST_STOP 22; // 厘米小于此值触发避障 // 转到指定角度后取三次中值320ms 是 SG90 走完 60° 的经验值 int scanAt(int angle) { scanServo.write(angle); delay(320); float a readDistanceCM(); float b readDistanceCM(); float c readDistanceCM(); return medianOf3(a, b, c); } void setMotor(int l, int r) { digitalWrite(IN1, l 0 ? HIGH : LOW); digitalWrite(IN2, l 0 ? LOW : HIGH); analogWrite(ENA, constrain(abs(l), 0, 255)); digitalWrite(IN3, r 0 ? HIGH : LOW); digitalWrite(IN4, r 0 ? LOW : HIGH); analogWrite(ENB, constrain(abs(r), 0, 255)); }setMotor传入正负值表示方向负数就是反转这样决策层只需要关心「左轮给多少、右轮给多少」不用再关心电平组合。注意constrain把 PWM 夹在 0 到 255负值在取绝对值之前不能直接喂给analogWrite。决策表是论文里最值得画的一张图实际代码就是它的直译左侧距离正前距离右侧距离动作远近远后退 200ms向更远一侧转远近近左转 380ms近近远右转 380ms近近近后退 300ms原地掉头远远远直行「远」和「近」用同一个 DIST_STOP 阈值判定即可简单可靠。真正影响体验的是转向时长转太少下一轮扫描还是「近」转太多车会在走廊里左右画龙。这个值必须实测。3.3 速度 PWM 与转向时间的参数表参数不是拍脑袋定的每个都对应一个物理量改的时候要知道自己在改什么。参数建议初值可调范围影响SPEED_RUN165120–220直行速度过高会冲过障碍SPEED_TURN130100–180转向速度过高容易打滑PWM_DEADZONE8560–100TT 电机起步的最小占空比TURN_MS380250–500单次转向时长决定转弯角度DIST_STOP2215–35触发避障的距离阈值SCAN_DELAY320250–450舵机到位等待时间整定顺序建议这样走先把 DIST_STOP 设成 40cm让车在安全距离外就停下来确认避障分支能触发再固定 TURN_MS 为 380ms在瓷砖地面上量一次转弯的实际角度按比例修正最后把 DIST_STOP 逐步降到 20cm 左右找到既不撞、又不会因为太保守而频繁停车的位置。PWM 死区也要单独测一遍占空比低于某个值时电机只会嗡嗡响不转这个值写进论文的「电机特性测试」小节正好。注意L298N 的 ENA、ENB 跳帽必须拔掉PWM 才受控。跳帽插着的时候电机全速运转analogWrite完全无效这个坑每年都有人踩。4. 论文实验数据怎么采测距误差、避障成功率与路径对比4.1 串口输出 CSV把每次避障记录成可分析的数据论文里的表格不能用「大概」「基本可以」这种词得有一行行原始记录。最省事的方式是让 Arduino 直接吐 CSV按固定周期输出后处理交给 Excel 或 Python。const unsigned long LOG_INTERVAL 200; // 每 200ms 记一行 unsigned long lastLog 0; void logRow(unsigned long t, int c, int l, int r, const char* action) { Serial.print(t); Serial.print(,); Serial.print(c); Serial.print(,); Serial.print(l); Serial.print(,); Serial.print(r); Serial.print(,); Serial.println(action); }字段顺序是时间戳、前方距离、左侧距离、右侧距离、当前动作。采集时把 Arduino IDE 串口监视器的波特率设成 115200关掉「显示时间戳」选项否则打印出来的时间戳会混进 CSV后期要多写一刀清洗脚本。数据量大或者要脱离电脑跑可以加 SPI 的 TF 卡模块CS 接 D10每写一行flush()一次避免断电丢数据。这套记录方式还有个附带好处答辩演示翻车时串口日志能直接说明是测距异常还是决策分支没走到排查速度比盯着车看快得多。4.2 实验分组与数据表设计数据要有对照才有说服力。每组障碍物重复 30 次记录成功次数和响应时间取平均值和标准差。实验组前方障碍物距离设置测试次数成功次数平均响应时间A硬质纸箱50cm30290.42sB布质靠垫50cm30240.51sC直径 3cm 细杆50cm30190.47sD移动障碍手持50cm30210.55s布质和细杆的失败率明显高原因是回波散射或反射面太小这一条正好写进「测距误差分析」移动障碍那一组失败率高说明当前决策周期偏长可以推给「动态避障小车路径规划」作为后续改进方向。踩坑记录也是数据pulseIn返回 0 的次数单独统计一列比笼统说「偶尔失灵」有价值得多。4.3 Arduino IDE 上传报错与常见故障排查演示前一周的报错基本都集中在这几类按表逐条对现象常见原因处理方式avrdude: stk500_recv(): programmer is not responding板子型号选错、串口被占用确认开发板选 UNO关掉串口监视器再上传工具菜单里端口灰色数据线只供电不传数据或 CH340 驱动未装换一根数据线装完驱动重插编译通过但电机不转ENA/ENB 跳帽未拔、未共地、PWM 占空比低于死区拔跳帽、短接 GND、把速度提到 100 以上舵机抖动、主控重启舵机与电机抢电流分开供电母线并 470µF 以上电容距离恒为 0 或跳变剧烈Trig/Echo 接反、采样间隔过短交换引脚两次采样间隔留 60ms 以上如果用的是第三方库从 Arduino IDE 的库管理器安装版本尽量选最近一两个大版本老版本对pulseIn超时参数的支持不一致。想在没硬件的情况下先验证逻辑Wokwi 仿真平台能省掉大量插拔时间。5. 从能演示到能复现仿真、测速与论文落笔5.1 用 Wokwi 仿真平台先验证决策逻辑接线还没到货的时候把 UNO、HC-SR04、Servo、两个 LED 拖进 Wokwi 的电路画布LED 分别代表左右轮正转和反转串口打印决策过程。仿真里可以拖动障碍物距离滑块把「远、中、近」三种输入都跑一遍确认状态机没有死角分支——比如左右都近的时候是否真的进了掉头逻辑。需要注意的是Wokwi 的舵机是瞬时到位的没有真实的 320ms 延时所以scanAt里的等待时间必须到真车上再调仿真只能验证逻辑正确性验证不了时序。5.2 加编码器做单片机小车测速与 PID 直行校正两轮小车用同样 PWM 直行走三米之后必然偏原因是两个电机的减速箱阻力不一致。要写「单片机小车测速」相关内容就得加霍尔编码器A 相接 D2、B 相接 D3用外部中断计数。volatile long pulseL 0, pulseR 0; void countL() { pulseL; } // D2 上升沿计数 void countR() { pulseR; } // D3 上升沿计数 float speedOf(long pulses, float wheelCM, int ppr, float dt) { return (pulses / (float)ppr) * wheelCM / dt; // cm/s } // 主循环里每 100ms 校正一次 float err speedL - speedR; int corr (int)(Kp * err); // Kp 从 1.0 开始试 setMotor(baseSpeed corr, baseSpeed - corr);ppr是每圈脉冲数11 线编码器配 1:48 减速箱要乘上去别直接填 11。Kp 从 1.0 起步观察车头是否左右大幅摆动摆就减半反应迟钝就加大。加编码器后 Trig 要从 D3 挪到 D11 或 D12把 D2、D3 这两个外部中断引脚让出来。5.3 论文图表与代码附录的整理技巧图表规范上图题写在图下方、表题写在表上方编号连续正文里每一张都至少引用一次。数据图建议从 Excel 导出矢量图或者用 Origin 画截图放进去打印会糊答辩投影更明显。参数表要给出测试条件和取值依据只列数字不写条件评阅人会直接打问号。代码附录里保留测距、决策、电机控制三个核心函数调试用的串口打印全部删掉行数控制在三到五页。查重方面方法章节的表述尽量用自己的话重写尤其是从数据手册翻译过来的模块介绍那部分重复率通常最高。答辩被问到阈值和 PID 参数怎么定的把原始测速数据和整定过程的记录一起翻出来比背一句「经过多次调试」有用得多——把每次改参后的速度曲线留在附录临界值就有据可查。本文还有配套的精品资源点击获取
返回列表