Arduino UNO智能小车全套例程:引脚映射与避障循迹调试指南 📅 发布时间:2026/9/14 20:29:15 👁 浏览次数: 简介面向毕业设计与课程设计的Arduino UNO三轮智能小车例程包覆盖蓝牙遥控、红外遥控、WiFi遥控、自动循迹、超声波避障、测速等常见实验适合自动化、电子信息、计算机等专业学生完成课设、毕设或大作业也方便初学者按例程进阶。资源共35个文件包括19个ino主程序、12个h头文件、1份智能小车Arduino平台IO分布图xlsx和1个使用说明txt压缩包整体仅59KB目录按实验场景拆分如超声波舵机自动避障、超声波红外自动跟踪、光电管避障、蓝牙遥控速度调节、自动循迹等便于对照运行与二次修改。代码均经过测试成功运行答辩评审平均分达到96分可放心作为项目原型已有194人学习/下载具备一定参考热度。项目还内置测速、舵机控制、红外接收等多类例程解压后可快速复现也能自行扩展传感器或功能。1. 一套 Arduino UNO 智能小车例程能节省你两周的调试时间拿到一款新的智能小车平台最耗时间的往往不是写代码而是搞清楚每个传感器该接哪个引脚、PWM 通道够不够用、舵机和电机驱动会不会互相抢占定时器。这套基于 Arduino UNO 的三轮小车例程把本科毕设里最常见的功能都做成了可直接烧录的实验工程红外遥控、蓝牙遥控、WiFi 遥控、超声波避障、光电管避障、黑线循迹、霍尔测速以及超声波加舵机的组合避障。每一份代码都带开关宏定义同一块板子通过#define切换功能不用每换一个实验就重新接线。资源包里的智能小车 arduino 平台 IO 分布图是第一个要看的文件它回答了引脚怎么分配这个最基础也最关键的问题。对做课设的在校生来说这套代码可以直接作为答辩演示基础对工程师来说它的模块划分思路——把传感器采集、运动控制、通信协议分层写——完全可以迁移到 STM32 或 ESP32 平台。下面从硬件映射开始逐个拆解这些例程的实现逻辑和参数配置。2. 硬件准备与引脚映射先看懂 IO 分布图再动手2.1 三轮小车的底盘结构选型常见的三轮智能小车有两种布局一种是两个驱动轮加一个万向轮另一种是两个驱动轮加一个舵机转向轮。这套例程用的是前者即两路直流减速电机分别驱动左右轮通过差速实现转向后部或前部有一个随动万向轮。这种结构的优势在于控制模型简单——左轮正转右轮反转就是原地旋转左轮慢右轮快就是弧线转弯。配合 L298N 或 TB6612 这类 H 桥驱动模块UNO 只需要输出两路 PWM 控制转速两路数字 IO 控制方向。比舵机转向的方案少一个闭环环节调试门槛低不少。2.2 引脚分配表与 Arduino UNO 的资源约束打开智能小车 arduino 平台 IO 分布图典型的分配方案如下表所示功能模块Arduino UNO 引脚说明左电机 PWMD5与右电机共用 Timer0左电机方向D4HIGH/LOW 切换正反转右电机 PWMD6与右电机共用 Timer0右电机方向D7HIGH/LOW 切换正反转超声波 Trig/EchoD2 / D3舵机安装于 D9舵机信号D9使用 Servo 库占用 Timer1光电对管左/右A0 / A1数字量读取阈值由电位器调节循迹传感器模块A2 / A3沿黑线输出高电平蓝牙模块 RX/TXD10 / D11SoftwareSerial 软串口霍尔测速中断D2 或 D3外部中断测速例程专用这里有一个关键点UNO 只有 Timer0、Timer1、Timer2 三个定时器。Timer0 被millis()占用Timer2 通常被 tone() 占用Servo 库只能用 Timer1。所以舵机和电机 PWM 不能同时依赖同一个定时器上面的分配方案中舵机接 D9、PWM 走 D5/D6恰好避开冲突。提示如果发现舵机抖动或电机转速异常先检查是不是某个库偷偷占用了 Timer1。Servo.h和IRremote.h在部分版本中存在冲突IRremote 库建议使用支持 Timer2 的版本或改用 D9 之外的引脚。2.3 从模板工程复制项目时的快速检查清单打开 AICar_sys 目录能看到每个实验都有独立的 .ino 文件。复制一份新工程时建议按以下顺序检查确认开发板型号是 Arduino/Genuino UNO处理器选 ATmega328P打开工具 - 端口确认串口号与设备管理器一致在代码头部查找#define开关比如#define USE_BLUETOOTH、#define USE_IR一次只打开一个功能检查 IRread 例程的接收引脚是否与IRrecvDemo中RECV_PIN定义一致。资源包内的 test 目录集中放了 servo、IRread、ultsound、bluetooth 等单项测试代码先用它们逐个验证硬件再跑组合实验能省掉大量排查时间。3. 传感器例程逐个拆解红外、超声波、光电对管3.1 红外遥控实验从 IRrecvDemo 到指令映射红外遥控是最容易出成果的实验因为只需要一个红外接收头和一个遥控器。IRrecvDemo例程的核心代码通常如下#include IRremote.h const int RECV_PIN 11; IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // 启动红外解码 } void loop() { if (irrecv.decode(results)) { Serial.println(results.value, HEX); irrecv.resume(); // 收到下一个编码 } }results.value是 NEC 协议解码后的 32 位数据常见的遥控器按键值形如FF00FF、FF30CF。不同遥控器编码不同所以 smartcar 例程里专门留了 IRread 目录先烧录它打开串口监视器按一遍遥控器按键把真实键值抄下来替换到宏定义里。逻辑说明irrecv.decode()返回 true 说明收到一帧完整数据results.value是编码值resume()必须调用否则接收器停在已解码状态无法继续接收。RECV_PIN定义为 11 而非 D2/D3是因为红外接收对时序要求高软串口和中断引脚都留给其他模块更稳妥。3.2 超声波 舵机避障测距转向一体化超声波避障例程把 HC-SR04 固定在舵机云台上舵机扫过 0 度到 180 度小车判断哪个方向距离最远就往哪个方向转弯。核心测距代码#define TRIG_PIN 2 #define ECHO_PIN 3 float getDistance() { digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIG_PIN, LOW); long duration pulseIn(ECHO_PIN, HIGH); return duration * 0.034 / 2; // 声速340m/s往返距离减半 }参数说明TRIG 高电平持续 10 微秒触发测距pulseIn等待 ECHO 引脚变为 HIGH 并测量持续时间返回的是微秒数。距离厘米等于声速34000 cm/s乘以时间再除以 2。实际使用中20 到 400 厘米范围内精度可接受超过这个范围要加滤波比如连续取五次去掉最大最小值再平均。舵机扫描策略上常见的做法是分三步先朝前方测一次再朝左 90 度测一次最后朝右 90 度测一次比较三组距离决定转向方向和角度。资源包里的超声波舵机光电对管自动避障实验在此基础上叠加了光电对管用于检测桌面边缘或台阶防止小车从高处跌落相当于防坠崖保护。3.3 光电对管避障与红外跟踪光电对管实验用的是 TCRT5000 模块它内部集成了红外发射管和接收管近距离检测反射红外线的强度。检测到障碍物时输出电平翻转。接线很简单VCC、GND、OUT 三根线OUT 接 A0 或 A1。int leftSensor analogRead(A0); int rightSensor analogRead(A1); if (leftSensor threshold rightSensor threshold) { // 两侧都有障碍后退 } else if (leftSensor threshold) { // 只有左侧有障碍右转 }threshold是判定阈值一般在 200 到 600 之间具体数值取决于环境光强度和障碍物表面反射率。模块上自带的电位器可以调节灵敏度调到指示灯刚熄灭的位置即可。光电对管组的参数用analogRead而非digitalRead是为了保留灵敏度调节的余量——环境光变化时模拟量读数会漂移纯数字量容易误触发。把读数直接打印到串口观察不同距离下的数值变化再设定阈值这样最可靠。4. 运动控制与测速从 PWM 调速到霍尔编码器闭环4.1 测速实验原理与中断计数测速实验用的是霍尔传感器配合磁钢。电机轴上贴一块小磁铁霍尔模块检测到磁场变化就输出一个脉冲。根据三轮车常用的减速电机参数——通常减速比 1:30 左右电机每转一圈霍尔输出一个脉冲轮子转一圈需要 30 个脉冲。测速代码volatile unsigned long pulseCount 0; void countPulse() { pulseCount; } void setup() { attachInterrupt(digitalPinToInterrupt(2), countPulse, RISING); Serial.begin(9600); } void loop() { pulseCount 0; delay(1000); float rps pulseCount / 30.0; // 每秒转数 float speed rps * 3.14159 * wheelDiameter; // cm/s Serial.print(Speed: ); Serial.print(speed); Serial.println( cm/s); }这里有两个细节值得注意volatile关键字必须加因为countPulse在中断上下文执行pulseCount被主循环读取不加 volatile 会被编译器优化掉更新RISING表示只在信号上升沿触发中断如果磁铁极性安装反了或霍尔模块输出是低电平有效要改成FALLING。4.2 测速数值与 PWM 占空比的关系实际测试时PWM 值从 0 到 255 线性增加但轮子转速并不完全线性。以普通 N20 减速电机为例PWM100 时转速约 60 转/分PWM200 时转速约 130 转/分曲线接近直线但有小幅下凹。原因是电机内部的摩擦阻力和反电动势非线性。如果需要做速度闭环光测脉冲不够还要加 PID。资源包里的蓝牙遥控速度调节例程在测速基础上增加了简单的比例控制目标速度和当前速度的差值乘以 Kp叠加到 PWM 上。Kp 一般从 2 到 5 开始试观察速度响应曲线再微调。4.3 循迹实验传感器布局与转向策略自动循迹实验是课设出现率最高的功能。典型的循迹模块包含 2 到 5 路红外对管沿黑线排列。两路版本的逻辑最简单左传感器在线上、右传感器压到白底说明车头偏右需要左转右传感器在线上、左传感器压到白底说明车头偏左需要右转两个传感器都在线上直行两个传感器都在白底可能冲出赛道按上一次方向继续前进或原地旋转寻找黑线。int leftTrack digitalRead(A2); int rightTrack digitalRead(A3); if (leftTrack LOW rightTrack HIGH) { // 左转左轮减速 analogWrite(PWM_LEFT, BASE_SPEED - 60); analogWrite(PWM_RIGHT, BASE_SPEED 60); } else if (leftTrack HIGH rightTrack LOW) { // 右转右轮减速 analogWrite(PWM_LEFT, BASE_SPEED 60); analogWrite(PWM_RIGHT, BASE_SPEED - 60); }BASE_SPEED建议设 120 到 150 之间差速 60 左右。速度太快会导致小车冲出弯道因为两路传感器只有两种组合检测不到线的曲率变化速度太慢则转向到位后回正不及时走 S 形。值得留意的是循迹例程普遍存在一个坑黑线在传感器正下方时输出 LOW在白底输出 HIGH这个电平逻辑因模块而异。接线之前先把模块悬空对着黑线实测一次确认逻辑再写判断条件。5. 无线控制链路蓝牙遥控、WiFi 遥控与 smartlink 配置5.1 蓝牙遥控SoftwareSerial 软串口收发蓝牙遥控例程用的是 HC-05 或 HC-06 模块通过 D10/D11 软串口与 UNO 通信。HC-05 默认波特率 96008N1 格式。代码结构#include SoftwareSerial.h SoftwareSerial btSerial(10, 11); // RX, TX char cmd; void setup() { Serial.begin(9600); btSerial.begin(9600); pinMode(LED_BUILTIN, OUTPUT); } void loop() { if (btSerial.available()) { cmd btSerial.read(); switch (cmd) { case F: moveForward(); break; case B: moveBackward(); break; case L: turnLeft(); break; case R: turnRight(); break; case S: stopCar(); break; } } }协议约定是单字符命令F/B/L/R/S分别是前进、后退、左转、右转、停止。手机端用一个串口蓝牙调试助手发送字符即可控制。参数说明btSerial.available()返回接收缓冲区字节数每次只读一个字节所以发送 F 就直接触发前进。软串口的局限要注意D10/D11 上不能用SoftwareSerial收发同时跑高速数据9600 波特率是稳定上限。如果想要手机实时回传传感器数据最好换硬件串口 D0/D1把调试串口改到软串口。5.2 WiFi 遥控与 smartlink 的两种接法WiFi 遥控例程通常是 UNO 外接 ESP8266 或 ESP-01 模块。ESP8266 跑 AT 固件UNO 通过串口发 AT 指令配置 WiFi 连接。smartlink 目录里放了手机 App 配网相关的代码核心逻辑是利用 ESP8266 的 SmartConfig 功能手机 App 广播 SSID 和密码模块自动抓取并连接。AT 指令序列一般是btSerial.println(ATCWMODE1); // Station 模式 delay(500); btSerial.println(ATCWJAP\SSID\,\password\); // 连接路由器 delay(3000); btSerial.println(ATCIPMUX1); // 开启多连接 delay(500); btSerial.println(ATCIPSERVER1,8080); // 启动 TCP Server每一条 AT 指令都要等待模块返回OK或ERROR再执行下一条否则 ESP8266 没就绪时下发指令会被丢弃。ATCIPSERVER1,8080启动端口 8080 的 TCP 服务端手机 App 连上同一个路由器后向模块 IP 的 8080 端口发送 TCP 报文UNO 从串口读到数据后解析出控制指令。WiFi 方案比蓝牙的优势是距离远、可以穿透一堵墙缺点是延迟稍高且依赖路由器。做毕设演示时如果现场网络环境不可控建议准备一条退路——用蓝牙方案保底。5.3 蓝牙遥控 速度调节的组合模式蓝牙遥控速度调节例程在遥控指令基础上增加了 PWM 占空比调节命令协议扩展为两位字符第一位是命令类型第二位是数值。比如V180表示设置速度为 180A100表示加速度到 100。解析用strtok或直接字符串比较String input btSerial.readStringUntil(\n); if (input.startsWith(V)) { int targetSpeed input.substring(1).toInt(); currentSpeed targetSpeed; analogWrite(PWM_LEFT, currentSpeed); analogWrite(PWM_RIGHT, currentSpeed); }这样遥控器上可以做两个滑动条一个管速度一个管方向。手机 App 端发送频率建议限制在每秒 10 帧以内UNO 的串口缓冲区只有 64 字节发太频繁会丢命令。6. 进阶调试技巧IO 分布图之外的实战经验6.1 用 Wokwi 模拟器做代码先行验证接线前先验证逻辑用 Wokwi 仿真平台可以省大量时间。Wokwi 支持 Arduino UNO 的电路仿真在浏览器里添加 UNO、HC-SR04、舵机和电机驱动模块烧录同一份代码即可跑通逻辑。注意模拟环境里 HC-SR04 的返回时间和真实硬件有差异只能验证程序流程不能验证时序精度。6.2 电机 PWM 共地的坑L298N 或 TB6612 驱动模块和 UNO 必须共地否则控制信号没有参考电平电机要么不转要么乱转。很多同学第一次上电发现电机不动第一反应是代码问题实际上只是少了根 GND 线。检查顺序先看电源指示灯再看信号线是否共地最后才怀疑代码。6.3 串口打印与波形观测结合定位问题如果测速数值异常先打印原始脉冲计数而不算速度确认中断是否触发。如果循迹反应迟钝把传感器模拟值直接打到串口放到黑线上看读数变化。遇到舵机抖动用示波器看 PWM 波形频率Servo 库默认 50Hz低于标准会抖动。// 调试用直接打印原始值 Serial.print(L:); Serial.print(analogRead(A2)); Serial.print( R:); Serial.println(analogRead(A3)); delay(100);这套例程包拿到的第一件事是烧录 test 目录下的单项测试每一项通过后再组合跑完整流程。把红外键值表、传感器阈值、PWM 基础速度记录在代码注释里后面做参数调优会省很多事。答辩演示前至少连续跑 30 分钟确认电池电量稳定下电机不会过热降速。本文还有配套的精品资源点击获取