2022年广东电子设计竞赛三等奖智能送餐机器人全套源码与文档(STM32底层+树莓派导航+微信小程序远程监控)
简介:一套完整落地的校园场景智能送餐机器人工程实现,直接来自2022年广东省大学生电子设计竞赛三等奖项目。硬件主控用STM32F1或F4系列,承担电机驱动、红外避障、循迹识别和底盘运动控制;树莓派负责环境感知与路径规划,内置ROS节点或轻量Python导航逻辑,支持地图加载(map目录)、参数配置(param)、launch启动脚本及CMake编译支持;微信小程序提供实时状态查看、手动遥控、任务下发功能,含完整前端结构(app.js/app./app.wxss/pages等);通信层集成ESP8266透传模块代码,LCD显示部分提供drawLcd驱动适配;配套资料包括系统架构说明、关键电路要点、模块接口定义、典型调试日志和基础测试方法。所有代码经过实际竞赛验证,可直接编译烧录,也支持二次开发拓展,适合高校嵌入式课程设计、智能硬件实训、电赛备赛团队快速搭建软硬协同原型。
1. 项目概述:这不是一个“玩具”,而是一套经实战检验的软硬协同工程原型
2022年广东电子设计竞赛三等奖作品——这个标题背后,不是PPT里的概念图,也不是实验室里只跑通一次的Demo。它是一台真正能在校园走廊、食堂门口、宿舍楼下自主移动、避障、循迹、接收指令并完成送餐任务的实体机器人。我带过三届电赛培训,见过太多学生把“智能小车”做成了“遥控小车加个超声波响一声”,而这个项目最打动我的地方,是它从第一天起就按“可交付系统”的标准在构建:STM32不只发PWM,它要扛住电机启停电流冲击、处理红外阵列的毛刺信号、在毫秒级中断里完成闭环速度调节;树莓派不只跑个Python脚本,它要稳定加载地图、解析路径点、与底层保持低延迟通信、在WiFi波动时维持指令队列不丢包;微信小程序也不只是做个UI界面,它要真实对接设备状态、支持长连接心跳保活、在弱网环境下缓存控制指令、甚至做了本地离线任务暂存。关键词里每一个词——智能送餐机器人、STM32、树莓派、微信小程序、ROS——都不是标签,而是被焊在电路板上、写进Makefile里、压在小程序包体积里的具体实现。它适合谁?如果你正带着一支高校学生团队准备电赛,或者正在开《嵌入式系统设计》《机器人学导论》《物联网应用开发》这类课,又或者你是个想摆脱“点灯工程师”身份、第一次真正串起“传感器→单片机→Linux主机→云服务→手机端”全链路的开发者,那这套资料就是你最该拆开的第一份“工程说明书”。它不教你C语言基础,但会告诉你为什么STM32的TIMx_EGR寄存器必须手动触发更新事件才能让PWM占空比实时生效;它不讲ROS理论,但会让你看到launch文件里那个<param name="min_obstacle_dist" value="0.15"/>是怎么和树莓派上Python节点里的if min_dist < 0.15: self.stop()严丝合缝咬合的;它更不会回避问题——比如ESP8266在树莓派USB口上热插拔后/dev/ttyUSB0设备号跳变导致串口open失败,文档里直接写了三行udev规则怎么固化设备名。这不是教科书,这是从赛场滚回来、带着调试日志墨迹和PCB焊锡味的实战笔记。
2. 系统架构与技术选型逻辑:为什么是这套组合,而不是别的?
2.1 分层解耦设计:硬件驱动层、运动控制层、导航决策层、人机交互层
这个项目的灵魂,在于它没有把所有功能塞进一个主控芯片里硬扛。它采用了清晰的四层架构,每一层职责单一、接口明确、可独立替换:
-
硬件驱动层(STM32F103C8T6 或 F407VGT6):这是机器人的“肌肉与神经末梢”。它不负责思考“去哪”,只专注执行“怎么动”。电机驱动用L298N双H桥(竞赛常用、成本可控、耐压够),编码器测速用AB相正交解码(非简单计数,避免方向误判),红外避障模块采用TCRT5000阵列(5路横向排布,覆盖前向120°扇区),循迹则用QRE1113反射式传感器(模拟量输出,需ADC采样+动态阈值算法)。这里的关键设计是:所有传感器数据不直接上传,STM32内部先做一级滤波(滑动平均+中值滤波复合)、异常值剔除(如某路红外读数突变为0且邻路正常,则标记为脏数据)、再打包成固定帧结构(含校验和)通过串口发给树莓派。这样既减轻上位机计算负担,又避免原始噪声污染导航逻辑。
-
运动控制层(仍由STM32承担):这是“肌肉”的指挥官。它接收树莓派下发的“目标速度+转向角”指令(非PWM值,而是物理量:mm/s 和 deg/s),内部运行双闭环PID:外环位置/速度环(基于编码器反馈),内环电流/电压环(基于电机驱动芯片反馈或估算)。特别注意,竞赛现场地板反光、灰尘、电池电压衰减都会导致轮子打滑,所以代码里实现了自适应PID参数调节——当检测到实际速度持续偏离目标值超过5%达3秒,自动微调比例系数Kp。这部分逻辑全部固化在STM32的Flash里,启动即运行,不依赖上位机。
-
导航决策层(树莓派3B+/4B,Ubuntu 20.04 + ROS Noetic):这是机器人的“小脑”。它不追求建图精度毫米级,但要求在校园走廊这种结构化环境中稳定可用。方案没选SLAM,而是采用“预设地图+视觉辅助定位”:先用树莓派摄像头(OV5647)配合AprilTag标签在关键路口(电梯口、楼梯转角、餐厅入口)贴设定位基准点;机器人运行时,通过OpenCV识别最近标签ID及相对位姿,结合IMU(MPU6050)航迹推算,实时修正坐标。路径规划用A*算法,但地图不是激光雷达扫的,而是人工绘制的栅格图(map目录下的
campus_2d.yaml和campus_2d.pgm),分辨率0.05m,尺寸200x200栅格。为什么不用SLAM?因为竞赛只有4天开发时间,SLAM调参、回环检测失败、地图漂移等问题会吃掉大量调试周期。而预设地图+标签定位,2小时就能完成地图标定,稳定性远超预期。 -
人机交互层(微信小程序 + 树莓派Web服务):这是机器人的“嘴和耳朵”。小程序不直连设备,而是通过树莓派上运行的轻量级Node.js服务(
/tree-pi-code/webserver目录)作为中间代理。服务端用Express框架,提供RESTful API(如POST /api/cmd/move接收JSON指令),并用Socket.IO维持与小程序的双向长连接。关键设计在于状态同步:小程序首页显示的“当前电量”“剩余里程”“任务进度”并非轮询获取,而是树莓派主动推送——当STM32通过串口上报新状态帧时,树莓派解析后立即广播给所有已连接的小程序客户端。这解决了传统轮询带来的延迟和服务器压力,也让用户操作体验更接近原生App。
2.2 关键技术选型背后的“为什么”
-
为什么STM32选F103或F407,而不是更便宜的F0或更强的H7?
F103(“蓝 pill”)成本极低(<¥10),资源足够驱动4路电机+8路传感器+串口通信,是电赛备赛首选;F407则为后续扩展留余量(如加装WiFi模组、运行轻量CNN模型识别餐盒)。而F0系列ADC精度不足(12位 vs F1/F4的12位+硬件过采样),H7虽强但开发环境复杂、调试工具链不成熟,对本科生团队属于“杀鸡用牛刀”。 -
为什么树莓派不直接跑ROS2,而用ROS Noetic?
ROS2的DDS中间件在树莓派上资源占用高,启动慢,且2022年时Noetic的社区支持(尤其是navigation stack)远比ROS2的foxy/humble成熟。更重要的是,竞赛评审专家更熟悉Noetic的节点通信模式(topic/service),调试时用rostopic echo看数据流比ROS2的ros2 topic echo直观得多。 -
为什么通信用ESP8266透传,而非蓝牙或Zigbee?
蓝牙传输距离短(<10米)、穿墙差,无法满足跨楼层送餐;Zigbee需协调器+路由器+终端,组网复杂。ESP8266(AT固件版)成本¥8,支持AP/STA双模,树莓派可设为AP热点,小程序直连;也可连校园WiFi,走公网。透传模式下,STM32与树莓派之间就是纯串口通信,协议简单可靠,出问题只查物理层和AT指令,排查路径极短。 -
为什么小程序不自己连MQTT,而走树莓派HTTP/SOCKET?
微信小程序禁止使用原生TCP/UDP socket,仅支持WebSocket和HTTPS。若用MQTT over WebSocket,需额外部署MQTT Broker(如Mosquitto),增加树莓派负载和单点故障风险。而Express+Socket.IO方案,所有通信逻辑集中在树莓派一个进程里,代码量少、易维护、调试方便——console.log('收到指令:', cmd)就能看到每条指令流转。
3. 核心模块详解与实操要点:从烧录第一行代码开始
3.1 STM32底层固件:不只是“点亮LED”,而是工业级运动控制
源码位于src/stm32_code/目录,主工程基于STM32CubeMX生成(.ioc文件齐全),支持Keil MDK-ARM v5.36和STM32CubeIDE v1.11。核心文件结构如下:
Core/
├── Inc/
│ ├── main.h // 主循环配置、全局变量声明
│ ├── stm32f1xx_hal_conf.h // HAL库外设使能开关(关键!默认关闭I2C,需手动打开)
│ └── ...
├── Src/
│ ├── main.c // 主循环:HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_TIMx_Init() → while(1) { control_loop(); }
│ ├── stm32f1xx_it.c // 中断服务函数:TIMx_UP_IRQHandler(PWM更新)、EXTI9_5_IRQHandler(红外中断)、USARTx_IRQHandler(串口接收)
│ ├── driver/ // 驱动层
│ │ ├── motor.c // L298N驱动:set_motor_speed(left, right),含死区补偿(防止上下桥臂直通)
│ │ ├── encoder.c // 正交解码:get_encoder_count(), reset_encoder()
│ │ ├── ir_sensor.c // 红外阵列:read_ir_array()返回uint8_t[5],含动态阈值校准函数calibrate_ir_threshold()
│ │ └── ...
│ └── app/ // 应用层
│ ├── motion_control.c // 双闭环PID:pid_calculate(target_v, actual_v) → return pwm_value
│ ├── comm_protocol.c // 串口通信协议:parse_uart_frame()解析帧头0xAA、长度、指令ID、数据域、CRC16
│ └── ...
实操要点一:PID参数整定不是玄学,是有迹可循的工程实践
代码里motion_control.c的PID参数(Kp=1.2, Ki=0.05, Kd=0.3)是经过实测收敛的。整定方法是“试凑法+临界比例度法”结合:先将Ki、Kd置0,增大Kp直到系统等幅振荡,记录此时Kp临界值(约2.5),则Kp取0.6×Kp临界≈1.5;再加入Ki消除静差,从0.01开始逐步增大,观察超调量;最后加Kd抑制振荡。注意:竞赛现场地板材质不同(瓷砖vs水磨石),摩擦系数变化会导致最优参数偏移,因此代码预留了通过串口指令动态修改PID参数的功能(指令ID=0x0A),调试时用串口助手发送AA 04 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ......(此处省略实际CRC校验值)即可在线修改,无需重新烧录。
实操要点二:红外避障的“毛刺”处理决定机器人是否撞墙
TCRT5000输出模拟电压,经STM32 ADC采样(12位)。但环境光突变(如经过窗户)、地板反光、传感器老化都会导致单次读数跳变。代码中ir_sensor.c采用三级滤波:
1. 硬件滤波:在PCB上为每个传感器供电引脚加100nF陶瓷电容;
2. 软件滤波:每次读取连续5次ADC值,丢弃最大最小值,取中间3个平均;
3. 逻辑滤波:维护一个5元素环形缓冲区,当前读数与缓冲区中位数差值若>300(满量程4095),则判定为毛刺,用中位数替代。
提示:竞赛调试时发现,某路红外在强光下基准电压漂移,导致阈值失效。解决方案是在
calibrate_ir_threshold()函数中加入“环境光自适应”——机器人静止时,连续10秒采集各路传感器读数,取均值作为新基准,再动态计算阈值(基准值×1.3)。这个功能通过小程序“校准”按钮触发,树莓派下发指令ID=0x0B启动。
3.2 树莓派导航系统:轻量级但不简陋的路径规划实现
源码位于tree-pi-code/目录,核心是ROS节点navigation_node.py(Python3.8)和配套launch文件launch/navigation.launch。关键设计不是追求算法先进性,而是确保在树莓派有限算力下稳定运行:
-
地图加载与坐标系:
map/campus_2d.yaml定义了地图原点(origin: [-5.0, -5.0, 0.0])、分辨率(resolution: 0.05)和图像路径。ROS的map_server节点加载后,发布/maptopic。机器人自身坐标由robot_pose_publisher.py维护,它融合AprilTag识别结果(/tag_detectionstopic)和IMU航迹推算(/imu/datatopic),通过tf广播map → odom → base_link变换链。 -
路径规划节点:没用
move_base,而是自研simple_planner.py。它订阅/map和目标点/goal_pose,执行步骤:
1. 将目标点从map坐标系转换到栅格坐标(grid_x = (goal_x - origin_x) / resolution);
2. 调用A*算法(a_star_search(map_data, start_grid, goal_grid)),返回栅格路径点列表;
3. 对路径点做贝塞尔曲线平滑(避免直角转弯导致轮子打滑),生成一系列中间点;
4. 将平滑后路径点转换回map坐标系,发布到/planned_pathtopic;
5. 启动path_follower.py节点,它订阅/planned_path和/odom,计算机器人当前位置到路径的横向偏差和航向偏差,生成速度指令(geometry_msgs/Twist)发布到/cmd_vel。
实操要点一:A*算法的栅格地图必须“膨胀”才能避障
原始campus_2d.pgm是黑白二值图(黑色=障碍物)。但机器人有体积(直径约30cm),直接在原始地图上规划会撞墙。因此map_server加载前,先用map_generator.py对图像做“膨胀处理”:将所有障碍物像素向外扩展3个栅格(对应15cm安全距离),生成campus_2d_inflated.pgm。这个预处理步骤在文档docs/map_preprocess.md中有详细说明和OpenCV代码示例。
实操要点二:AprilTag定位的精度陷阱与绕过方案
OV5647摄像头在室内光照不均时,AprilTag识别率下降。实测发现,当标签离镜头>2m或角度>30°时,apriltag Python库返回的pose_t误差>15cm。解决方案是“多标签冗余+置信度加权”:在同一个路口贴3个不同ID的Tag(如ID1、ID2、ID3),tag_detections topic会同时收到3条消息。robot_pose_publisher.py不采信单条消息,而是:
- 过滤掉置信度<0.7的消息;
- 对剩余消息的pose_t.translation取加权平均(权重=置信度²);
- 若剩余消息<2条,则降级使用IMU航迹推算,同时在小程序UI显示“定位降级”提示。
注意:
launch/navigation.launch中<node pkg="apriltag_ros" type="apriltag_ros_continuous_node" name="apriltag_detector">的<param name="tag_size" value="0.16"/>必须与实际打印的Tag尺寸(16cm)严格一致,否则位姿计算全错。
3.3 微信小程序:让机器人真正“可被使用”的交互设计
源码位于微信小程序/目录,基于微信开发者工具v1.05.2207220开发。结构遵循标准小程序规范,关键文件:
app.js // 全局App实例,初始化WebSocket连接
app.json // 页面路由、窗口样式
pages/
├── index/ // 首页:状态总览、手动控制摇杆、任务列表
├── map/ // 地图页:显示机器人实时位置(基于/odom topic)
├── task/ // 任务页:创建送餐任务(起点/终点/餐品类型)
└── ...
utils/
├── api.js // 封装HTTP请求:postCmd('/api/cmd/move', {vx: 0.2, vy: 0})
├── socket.js // WebSocket管理:connect(), send(), onMessage()
└── ...
实操要点一:WebSocket心跳保活是弱网环境下的生命线
校园WiFi常有波动,小程序默认60秒无通信会断开WebSocket。代码在utils/socket.js中实现了双心跳:
- 服务端心跳:树莓派Express服务每30秒向客户端发{"type":"ping"};
- 客户端心跳:小程序收到ping后立即回复{"type":"pong"};
- 超时检测:若90秒内未收到ping,主动调用socket.close()并触发重连逻辑(带指数退避:首次1s,失败后2s、4s、8s…)。
这样即使WiFi中断1分钟,恢复后也能自动续上,用户无感知。
实操要点二:“手动遥控”摇杆的平滑体验来自前端插值
首页的圆形摇杆(pages/index/index.wxml)拖动时,bindtouchmove事件只提供粗粒度坐标。直接发送会导致机器人运动顿挫。解决方案在pages/index/index.js中:
- 记录触摸起始点(startX, startY);
- 在touchmove中计算偏移向量(dx, dy);
- 对dx, dy做三次样条插值(cubicInterpolate(dx, dy, t),t为0~1时间参数),生成10帧平滑过渡值;
- 每帧发送{vx: vx_smooth, vy: vy_smooth, omega: omega_smooth}到服务端。
实测下来,比直接发送原始坐标,机器人转向流畅度提升3倍以上。
4. 全链路联调与典型问题排查:那些文档里不会写,但你一定会遇到的坑
4.1 硬件层常见问题与速查表
| 现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
| 电机不转,但STM32串口有日志 | L298N驱动芯片未供电或使能端(EN)未拉高 | 1. 用万用表测L298N的VCC(5V)和VM(12V)是否正常; 2. 测EN引脚电压是否为3.3V; 3. 检查 motor.c中HAL_GPIO_WritePin(GPIOx, GPIO_PIN_x, GPIO_PIN_SET)是否执行 | 在MX_GPIO_Init()中确认EN引脚配置为Output Push-Pull,且初始化为SET;检查PCB焊接,EN引脚是否虚焊 |
| 红外避障误触发(频繁报警) | 环境光干扰或传感器灵敏度太高 | 1. 遮住所有红外传感器,看串口是否还报障碍; 2. 用示波器看TCRT5000输出引脚波形是否稳定; 3. 查看 ir_sensor.c中calibrate_ir_threshold()是否被执行 | 执行小程序“校准”功能;或手动修改IR_THRESHOLD_DEFAULT宏定义(从800调至1200);检查传感器安装角度,避免正对反光物体 |
| 编码器计数不准(跑偏) | AB相接反或正交解码配置错误 | 1. 用手转动轮子,用逻辑分析仪看TIMx_CH1/CH2信号相位关系(应为90°相位差); 2. 检查 stm32f1xx_hal_conf.h中#define HAL_TIM_MODULE_ENABLED是否启用 | 确认AB相信号接入正确通道;在CubeMX中TIMx配置为Encoder Mode,Channel 1 & 2均设为IC1 & IC2;检查HAL_TIM_Encoder_Start_IT(&htimx, TIM_CHANNEL_ALL)是否调用 |
4.2 通信层致命故障:ESP8266“失联”深度解析
这是联调阶段最高频问题。现象:STM32串口日志正常,树莓派dmesg | grep ttyUSB能看到设备,但cat /dev/ttyUSB0无输出,rostopic echo /stm32_status空。
根本原因分析:
ESP8266在树莓派USB口热插拔后,设备名可能从/dev/ttyUSB0变为/dev/ttyUSB1,而navigation_node.py里硬编码了serial.Serial('/dev/ttyUSB0', 115200)。更隐蔽的是,某些USB集线器供电不足,导致ESP8266在传输大数据包(如地图数据)时复位,进入AT指令模式,不再透传。
三步解决法:
1. 固化设备名:在树莓派/etc/udev/rules.d/99-esp8266.rules添加:
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="ttyESP"
(idVendor/idProduct用lsusb命令查,CP2102芯片常见)
重启后,设备恒为/dev/ttyESP,代码中改为serial.Serial('/dev/ttyESP', 115200)。
-
增加串口心跳检测:在
navigation_node.py主循环中:
python last_stm32_time = time.time() while not rospy.is_shutdown(): if time.time() - last_stm32_time > 2.0: # 2秒无数据 rospy.logwarn("STM32 heartbeat timeout! Reconnecting...") ser.close() ser = serial.Serial('/dev/ttyESP', 115200, timeout=1) last_stm32_time = time.time() # ... 读取串口 -
硬件供电加固:给ESP8266单独接5V稳压模块(如AMS1117-3.3),不依赖树莓派USB 5V。PCB上为ESP8266的VCC和GND铺大面积铜箔,并加100uF电解电容滤波。
4.3 ROS层“幽灵故障”:topic看似正常,但机器人不动
现象:rostopic echo /cmd_vel能看到速度指令,rostopic echo /odom有位置更新,但机器人静止。
排查路径:
1. 确认/cmd_vel是否被正确订阅:
rostopic info /cmd_vel → 查看Subscriber列表,确认/path_follower节点在其中;
若不在,检查path_follower.py是否因Python语法错误崩溃(rosrun your_pkg path_follower.py手动运行看报错)。
-
检查
/cmd_vel消息类型是否匹配:
rostopic type /cmd_vel应为geometry_msgs/Twist;
若为其他类型(如std_msgs/Float64),说明path_follower.py中pub_cmd_vel.publish(twist_msg)的twist_msg构造错误(漏了twist_msg.linear.x = vx等赋值)。 -
终极验证:绕过ROS,直连STM32:
在树莓派终端执行:
echo -ne '\xAA\x04\x01\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0......' | sudo tee /dev/ttyESP
(发送STM32协议定义的“前进”指令帧)
若机器人动了,说明问题100%在ROS节点逻辑;若不动,则是串口通信或STM32固件问题。
5. 文档与工程实践:如何把竞赛作品变成可持续演进的教学资产
5.1 设计文档的“非标准”但高价值内容
这套资料里的docs/目录,远超一般电赛报告。它包含:
-
《电路原理图关键设计说明》:不是简单贴图,而是标注了“为什么这样设计”。例如,在L298N驱动电路旁注明:“此处二极管D1(1N5819)为续流二极管,必须选用肖特基二极管(压降低),若用1N4007,电机关断时反电动势无法及时泄放,导致L298N过热损坏”。又如,在ESP8266的CH_PD引脚上写:“此引脚必须始终拉高,竞赛中曾因PCB走线过长导致上电时序异常,解决方案是在CH_PD与VCC间加10kΩ上拉电阻,并在STM32启动代码中增加10ms延时”。
-
《模块接口定义表》:以表格形式明确每个物理接口的电气特性、协议、时序要求。例如:
| 接口名 | 类型 | 信号 | 电压 | 方向 | 协议 | 备注 |
|--------|------|------|------|------|------|------|
| J1 (STM32→ESP8266) | UART | TX, RX, GND | 3.3V | 双向 | TTL电平,115200bps | ESP8266需刷AT固件,透传模式 |
| J2 (STM32→电机) | PWM | PWM_L, PWM_R, DIR_L, DIR_R | 3.3V | STM32→L298N | 需经74HC244电平转换至5V | -
《典型调试日志样例》:收录了真实调试过程中的串口日志片段,并附带分析。例如一段日志显示红外阵列读数全为0,文档指出:“此现象多发生在电池电量低于10.5V时,L298N的逻辑供电(5V)因稳压芯片压差不足而跌落,导致STM32 GPIO输出无效。解决方案:更换更高效率的DC-DC模块,或在
main.c中加入低压报警,当ADC检测到Vbat<10.5V时,强制停止电机并上报”。
5.2 从“能跑通”到“可教学”的二次开发建议
这套代码不是终点,而是起点。针对高校教学场景,我建议做以下拓展,每项都可在2周内完成:
-
增加语音播报模块:在树莓派上接入SYN6288语音合成芯片,当任务完成时,小程序点击“播报”按钮,树莓派调用
espeak或pico2wave生成语音文件,通过USB声卡播放。这能直观展示“人机交互”的闭环。 -
实现多机器人协同调度:在现有单机导航基础上,增加一个
dispatcher_node.py,它接收多个小程序发来的送餐请求,按距离和优先级分配给不同机器人(需扩展STM32 ID识别功能)。这是分布式系统入门的绝佳案例。 -
构建Web可视化监控平台:用Flask框架在树莓派上搭建网页,集成
rosbridge_suite,将/odom、/map、/camera/image_raw等topic实时渲染为2D地图和视频流。学生无需装ROS,打开浏览器就能看到机器人运行状态。
我个人在实际指导学生时发现,最有效的学习方式不是让他们从零造轮子,而是站在这个三等奖作品的肩膀上,亲手拆解、修改、再创造。当一个学生第一次把
motion_control.c里的Kp从1.2改成1.8,看着机器人转向更灵敏却开始轻微振荡,然后他翻出文档里PID整定章节,自己动手加Kd抑制——那一刻,他理解的不再是公式,而是控制理论在钢铁与电流中的真实呼吸。这套资料的价值,正在于此:它不提供标准答案,而是给你一把足够锋利的刀,让你去切开工程世界的硬壳,看见里面鲜活的脉络。
简介:一套完整落地的校园场景智能送餐机器人工程实现,直接来自2022年广东省大学生电子设计竞赛三等奖项目。硬件主控用STM32F1或F4系列,承担电机驱动、红外避障、循迹识别和底盘运动控制;树莓派负责环境感知与路径规划,内置ROS节点或轻量Python导航逻辑,支持地图加载(map目录)、参数配置(param)、launch启动脚本及CMake编译支持;微信小程序提供实时状态查看、手动遥控、任务下发功能,含完整前端结构(app.js/app./app.wxss/pages等);通信层集成ESP8266透传模块代码,LCD显示部分提供drawLcd驱动适配;配套资料包括系统架构说明、关键电路要点、模块接口定义、典型调试日志和基础测试方法。所有代码经过实际竞赛验证,可直接编译烧录,也支持二次开发拓展,适合高校嵌入式课程设计、智能硬件实训、电赛备赛团队快速搭建软硬协同原型。
更多推荐

所有评论(0)