
这次我们来看一个面向2026年全国大学生电子设计竞赛电赛的备赛思路特别是围绕“小钢球”这一经典控制对象展开的技术预研。电赛题目往往出人意料但核心考察点万变不离其宗对特定物理对象如小球、摆杆、无人机的建模、感知、控制与系统集成能力。提前锁定“小钢球”这个高频元素进行针对性准备是提升备赛效率、构建技术护城河的关键策略。本文不空谈理论直接切入实战。我们将系统拆解小钢球在历届电赛控制类题目中的典型应用场景并构建一套从零开始的软硬件验证平台。重点在于这套方案能否在常见的学生实验设备如STM32、OpenMV、树莓派上跑起来需要多少预算代码和算法是否模块化、可复用通过实测你将掌握小球位置检测、PID控制、运动规划等核心技能的工程化实现为2026年电赛打下坚实的实践基础。1. 核心能力速览小钢球系统技术栈在深入细节前我们先快速浏览围绕“小钢球”构建一个完整电赛系统所需的核心技术组件与资源门槛。下表汇总了关键信息帮助你快速判断备赛方向与投入。能力项说明与推荐配置核心控制对象小钢球通常直径5-20mm在平面、轨道、摆杆等约束下运动典型赛题场景平衡板2024 H题、摆动控制2026 H题、轨迹跟踪、速度控制、定点驻留感知方案摄像头视觉OpenMV/树莓派OpenCV、激光测距、灰度传感器阵列、编码器机械结构反推主控平台STM32系列F1/F4/H7、树莓派4B/5、ESP32适合无线题目或二者结合STM32执行控制上位机处理视觉控制算法核心PID控制位置式/增量式、模糊控制、状态反馈、轨迹规划执行机构舵机控制平板倾角、步进电机/直流电机控制轨道或摆杆、电磁铁/风扇非接触驱动显存/内存需求视觉处理是主要瓶颈。OpenMV约需几十KB RAM树莓派运行OpenCV建议1GB以上空闲内存。启动与开发方式本地代码编写Keil/STM32CubeIDE, VSCodePlatformIO、烧录调试、传感器标定、算法参数整定是否支持“批量任务”支持。可设计自动化测试脚本对同一算法参数进行多次重复轨迹测试并记录数据。是否支持“接口API”支持系统级接口。例如上位机Python/Matlab通过串口/UDP向STM32发送目标指令STM32通过PWM/IO控制执行机构。适合场景电赛控制类题目备赛、课程设计、毕业设计、自动控制原理实践、机器视觉入门集成2. 适用场景与使用边界这套以小钢球为核心的控制系统训练方案主要服务于以下几类场景电赛参赛队前期技术储备脱离具体题目针对“小球”这一对象打磨从感知到执行的全链路能力。当赛题公布时能快速将模块组装适配。自动控制原理课程实践将课本上的PID理论、系统建模转化为看得见、摸得着的物理系统加深对控制器参数影响的理解。机器视觉入门项目学习如何使用摄像头捕捉动态目标、进行坐标变换并与控制系统实时联动。需要明确的使用边界非通用机器人平台该系统高度定制化针对小球控制优化。更换为其他物体如小车、机械臂需重新设计感知和机构。性能受限于硬件摄像头的帧率、分辨率、处理延时直接决定系统响应速度和控制精度。在高速、高精度场景下需要更高性能的硬件。环境要求视觉方案对光照变化敏感需要相对稳定的光照条件或采用主动光源如红外LED辅助。安全与合规实验中的高速旋转电机、摆动的机械结构存在物理风险务必在安全环境下操作做好防护。所有设计应遵循实验室安全规范。3. 环境准备与前置条件在动手搭建前请确保你已准备好以下软硬件环境。这是项目能跑起来的基础。硬件清单基础版控制对象小钢球若干直径建议8-10mm。主控制器STM32F103C8T6最小系统板或性能更强的STM32F407、STM32H750。感知模块二选一或组合方案A视觉OpenMV Cam H7 或 树莓派 USB摄像头。OpenMV集成度高开发简单树莓派OpenCV功能更强但系统更复杂。方案B简易传感器红外对管或灰度传感器阵列用于一维轨道位置检测。执行机构9g舵机2个用于控制平板两个自由度或 步进电机驱动器。机械结构亚克力板或木板作为平衡板、舵机云台、固定支架。可以3D打印或手工搭建。电源5V/2A以上电源适配器为控制器、舵机供电注意舵机启动电流大电源需留有余量。连接线杜邦线若干。软件与环境开发环境STM32开发Keil uVision 或 STM32CubeIDE。安装对应芯片的DFP包。OpenMV开发OpenMV IDE。树莓派/上位机开发Python 3.7安装OpenCV, NumPy, pyserial库。驱动与工具STM32 USB转串口驱动如CH340、串口调试助手如Putty、Serial。基础知识基本的C语言、Python编程能力了解串口通信原理对PID控制概念有初步认识。4. 系统搭建与核心代码框架我们以最常见的“视觉平衡板”场景为例构建系统。系统框图如下摄像头捕捉小球位置 - 上位机/OpenMV计算位置偏差 - 通过串口发送给STM32 - STM32运行PID算法 - 输出PWM控制舵机 - 舵机带动平板倾斜使小球向目标点运动。4.1 机械与硬件连接搭建平衡板将两个舵机正交安装一个控制X轴一个控制Y轴倾斜舵机摇臂与平板连接。确保平板活动灵活且初始状态大致水平。安装摄像头将OpenMV或USB摄像头固定在平板上方正中央视野能覆盖整个平板区域。电路连接STM32的USART1PA9/PA10连接OpenMV/上位机的串口RX/TX共地。两个舵机信号线分别连接STM32的定时器PWM输出通道如TIM2_CH1, TIM2_CH2。为舵机提供独立的5V电源与STM32共地避免电机干扰导致单片机复位。4.2 STM32端PID控制器与PWM输出STM32负责接收目标位置、执行PID计算、输出PWM。以下是核心代码框架。PID控制器结构体定义pid.htypedef struct { float Kp, Ki, Kd; // PID参数 float integral; // 积分项 float prev_error; // 上次误差 float output; // 输出值 float integral_limit; // 积分限幅 float output_limit; // 输出限幅 } PID_Controller; void PID_Init(PID_Controller *pid, float kp, float ki, float kd, float i_limit, float out_limit); float PID_Update(PID_Controller *pid, float setpoint, float measurement, float dt);PID算法实现pid.cvoid PID_Init(PID_Controller *pid, float kp, float ki, float kd, float i_limit, float out_limit) { pid-Kp kp; pid-Ki ki; pid-Kd kd; pid-integral 0.0f; pid-prev_error 0.0f; pid-output 0.0f; pid-integral_limit i_limit; pid-output_limit out_limit; } float PID_Update(PID_Controller *pid, float setpoint, float measurement, float dt) { float error setpoint - measurement; // 比例项 float proportional pid-Kp * error; // 积分项抗饱和 pid-integral error * dt; if (pid-integral pid-integral_limit) pid-integral pid-integral_limit; if (pid-integral -pid-integral_limit) pid-integral -pid-integral_limit; float integral pid-Ki * pid-integral; // 微分项常用不完全微分 float derivative pid-Kd * (error - pid-prev_error) / dt; pid-prev_error error; // 计算输出并限幅 pid-output proportional integral derivative; if (pid-output pid-output_limit) pid-output pid-output_limit; if (pid-output -pid-output_limit) pid-output -pid-output_limit; return pid-output; }主循环中调用示例// 初始化PID参数需实际调试 PID_Controller pid_x, pid_y; PID_Init(pid_x, 1.5, 0.05, 0.3, 100, 500); // 参数仅为示例 PID_Init(pid_y, 1.5, 0.05, 0.3, 100, 500); // 在定时器中断或主循环中假设控制周期dt0.01s (100Hz) float ball_x, ball_y; // 来自串口的小球坐标 float target_x 160, target_y 120; // 目标点坐标假设图像中心 float output_x PID_Update(pid_x, target_x, ball_x, 0.01); float output_y PID_Update(pid_y, target_y, ball_y, 0.01); // 将输出映射为舵机PWM占空比例如输出-500~500映射到舵机角度 set_servo_pwm(SERVO_X_CHANNEL, 1500 output_x); // 1500为中位 set_servo_pwm(SERVO_Y_CHANNEL, 1500 output_y);4.3 视觉端小球识别与坐标发送我们以OpenMV为例因为它内置了颜色追踪函数开发极快。OpenMV Python脚本示例import sensor, image, time, pyb from pyb import UART # 初始化摄像头 sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) # 320x240 sensor.skip_frames(time 2000) sensor.set_auto_gain(False) # 必须关闭自动增益 sensor.set_auto_whitebal(False) # 必须关闭白平衡 # 初始化串口 (UART3, 波特率115200) uart UART(3, 115200) # 定义小球的颜色阈值需根据实际小球和环境调整 red_threshold (30, 100, 15, 127, 15, 127) # 示例红色小球 clock time.clock() while(True): clock.tick() img sensor.snapshot() # 寻找色块 blobs img.find_blobs([red_threshold], pixels_threshold100, area_threshold100, mergeTrue) if blobs: # 找到最大的色块 largest_blob max(blobs, keylambda b: b.pixels()) # 在图像上画框和十字 img.draw_rectangle(largest_blob.rect()) img.draw_cross(largest_blob.cx(), largest_blob.cy()) # 获取小球中心坐标 (cx, cy) ball_x largest_blob.cx() ball_y largest_blob.cy() # 通过串口发送坐标数据格式如X123Y456\n data_str X{:03d}Y{:03d}\n.format(ball_x, ball_y) uart.write(data_str) else: # 没找到小球发送一个特殊值如X999Y999\n uart.write(X999Y999\n) # 可选的在IDE中显示帧率 # print(clock.fps())STM32端串口解析代码片段// 在串口中断服务函数或主循环中解析数据 void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { char rx_char USART_ReceiveData(USART1); // 简单的状态机解析 X123Y456\n static uint8_t state 0; static int temp_x 0, temp_y 0; // ... 解析逻辑将解析到的 ball_x, ball_y 赋值给全局变量 ... } }5. 功能测试与效果验证系统搭建并烧录代码后按以下步骤进行测试和调试。5.1 视觉识别单独测试目的确保摄像头能稳定、准确地识别小球位置。操作将小球放在平板上手动移动。在OpenMV IDE中查看实时图像观察识别框是否紧跟小球坐标输出是否稳定。成功标准小球在平板任意位置都能被识别且坐标跳动范围在±3个像素内静止时。失败排查识别不稳定调整颜色阈值。使用OpenMV IDE中的“阈值编辑器”工具选取小球区域获取准确的阈值范围。误识别其他物体清理背景或增加pixels_threshold和area_threshold。帧率过低降低图像分辨率如从QVGA降到QQVGA或简化图像处理算法。5.2 串口通信测试目的确保视觉端和STM32端数据通路正确。操作将OpenMV的串口线连接到电脑USB使用串口助手如Putty打开对应COM口波特率115200。应能看到连续输出的X...Y...格式数据。将OpenMV串口连接到STM32在STM32程序中将解析到的坐标通过另一个串口或LED、屏幕打印出来验证数据接收正确。成功标准STM32能正确收到并解析出与小球位置对应的坐标值。失败排查检查接线TX-RX交叉连接、波特率设置、共地。5.3 开环测试手动控制目的验证执行机构舵机响应正常机械结构牢固。操作在STM32程序中暂时屏蔽PID算法改为根据串口收到的小球坐标直接映射一个固定的舵机角度例如小球偏左舵机向右转一点。观察平板是否能按预期方向倾斜。成功标准小球的移动能引起平板方向正确的倾斜。失败排查检查PWM输出是否使能、舵机信号线是否接反、舵机供电是否充足。5.4 闭环PID调试这是最核心也最耗时的步骤。务必先调单轴如X轴稳定后再调双轴。初始化参数将Ki和Kd设为0先调Kp。设置目标点为图像中心。增大Kp逐渐增加Kp直到小球开始围绕目标点持续振荡。此时的Kp值约为临界振荡Kp。引入Kd将Kp设为临界振荡Kp的60%左右然后逐渐增加Kd。Kd能抑制振荡使小球更快稳定在目标点。引入Ki如果小球最终稳定位置与目标点有静态误差Steady-State Error则逐渐增加Ki来消除。但Ki过大会引起积分饱和导致系统不稳定需谨慎。双轴耦合调试X轴和Y轴都调好后同时运行。由于平板两轴可能存在耦合倾斜X轴会影响Y轴方向的小球运动可能需要微调参数。抗干扰测试用手指轻推小球观察系统能否快速将其拉回中心。6. 接口API与上位机扩展一个成熟的电赛系统往往需要更复杂的交互。我们可以引入上位机PC或树莓派作为“大脑”STM32作为“四肢”。上位机Python核心职责运行更复杂的视觉算法如抗遮挡跟踪、轨迹预测。实现更高级的控制策略如模糊PID、MPC。提供人机交互界面UI用于设置目标点、切换模式、绘制轨迹、实时调整PID参数。记录实验数据用于赛后报告分析。一个简单的Python上位机示例使用Tkinter和pyserialimport tkinter as tk import serial import threading import time class BallControlApp: def __init__(self, master): self.master master master.title(小球平衡控制平台) # 串口初始化 self.ser serial.Serial(COM3, 115200, timeout1) # 端口号根据实际情况修改 # 创建UI组件 self.label tk.Label(master, text目标位置 (X, Y):) self.label.pack() self.x_scale tk.Scale(master, from_0, to320, orienttk.HORIZONTAL, labelX) self.x_scale.set(160) self.x_scale.pack() self.y_scale tk.Scale(master, from_0, to240, orienttk.HORIZONTAL, labelY) self.y_scale.set(120) self.y_scale.pack() self.set_button tk.Button(master, text设置目标点, commandself.send_target) self.set_button.pack() # 启动一个线程接收下位机数据如实际小球位置 self.receive_thread threading.Thread(targetself.receive_data, daemonTrue) self.receive_thread.start() def send_target(self): target_x self.x_scale.get() target_y self.y_scale.get() # 自定义协议例如 T,160,120\n command fT,{target_x},{target_y}\n self.ser.write(command.encode(utf-8)) print(fSent: {command.strip()}) def receive_data(self): while True: if self.ser.in_waiting: line self.ser.readline().decode(utf-8).strip() # 假设STM32发回格式 B,123,45\n (Ball) if line.startswith(B,): _, x, y line.split(,) # 可以在这里更新UI上的小球实际位置显示 print(fBall at: ({x}, {y})) time.sleep(0.01) if __name__ __main__: root tk.Tk() app BallControlApp(root) root.mainloop()STM32端需要增加解析上位机指令和回传数据的功能。这种架构极大地增强了系统的灵活性和可调试性。7. 资源占用与性能观察对于电赛系统性能瓶颈主要出现在视觉处理和实时控制周期。OpenMV性能在QVGA分辨率下进行简单的颜色追踪帧率可达30-50fps延迟约20-30ms。这能满足大多数中低速控制需求。若算法复杂如霍夫圆检测帧率会下降。STM32资源运行双路PID算法和串口通信对STM32F103来说绰绰有余CPU占用率很低。主要注意定时器配置是否精准确保控制周期稳定如精确的10ms中断。系统延迟分析视觉处理延迟从曝光到算出坐标的时间。串口传输延迟115200波特率下传输一行坐标数据约需1ms可忽略。控制计算延迟STM32执行PID计算微秒级。执行机构延迟舵机响应时间通常在100-200ms量级这是系统最大的延迟环节优化方向降低视觉延迟使用更高性能的处理器如树莓派优化后的OpenCV代码或采用全局快门摄像头。补偿机构延迟在控制算法中加入对舵机动态特性的补偿如速度前馈或使用响应更快的执行机构如空心杯电机编码器。8. 常见问题与排查方法在调试过程中你几乎一定会遇到下表所列的问题。按照排查思路一步步来。问题现象可能原因排查方式解决方案小球完全无法识别颜色阈值错误光照变化太大摄像头对焦不准使用OpenMV阈值编辑器重新采样确保光照均匀稳定调整摄像头焦距重新标定阈值增加补光灯手动调焦识别坐标跳动剧烈阈值范围太宽小球反光背景有干扰色块观察二值化图像看是否有很多噪点收紧阈值给小球消光如喷哑光漆清理背景或加滤光片舵机不转动或乱转PWM信号不对电源不足接线错误用示波器或逻辑分析仪检查PWM波形测量舵机供电电压检查定时器配置使用独立5V/3A电源给舵机供电核对信号线小球总是向一个方向跑飞PID参数极不正确机械零点未校准坐标轴方向定义反了先开环测试手动给固定PWM看平板倾斜方向是否正确重新校准机械水平检查代码中误差计算的正负号从极小的Kp开始调系统产生剧烈振荡Kp太大Kd太小或为负控制周期不稳定观察小球运动录像是等幅振荡还是发散振荡大幅降低Kp适当增加Kd检查定时器中断是否被其他任务打断串口收不到数据或数据乱码波特率不匹配TX/RX接反未共地缓冲区溢出用USB-TTL模块接电脑测试STM32或OpenMV单独发送数据核对双方波特率交换TX/RX接线确保GND连接在代码中增加发送间隔上位机与下位机通信失败串口端口号错误协议格式不一致线程阻塞在PC端用串口助手先测试通信打印收发数据的原始字节确认端口号统一协议如结尾加\n检查上位机UI是否卡死主线程9. 最佳实践与备赛建议基于以上实践为2026年电赛备赛提出以下建议模块化开发将视觉识别、串口通信、PID控制、电机驱动分别写成独立的.c/.h文件。这样无论赛题如何变化都可以快速组合和替换模块。参数可调将PID参数、视觉阈值、控制目标等设计为可以通过串口命令实时修改。这在现场调试时能节省大量时间。数据记录让系统能够通过串口输出关键数据时间、目标位置、实际位置、控制输出。用上位机或SD卡记录用于赛后分析报告这是报告的亮点。冗余设计视觉是主要风险点。准备一套备用的传感器方案例如在轨道题目中可以用灰度传感器阵列作为视觉失效的备份。机械为王再好的算法也救不了糟糕的机械结构。确保你的平板、轨道坚固、顺滑舵机安装牢靠减少晃动和回程间隙。电源隔离电机驱动电路必须与单片机控制电路在电源上进行隔离如使用光耦或独立的电源模块避免电机噪声导致单片机复位或烧毁。提前熟悉赛制了解电赛的封箱、测评流程。你的系统应该能快速拆装并且有明确的“启动开关”避免测评时手忙脚乱。10. 总结与下一步这次针对“小钢球”的预研核心价值在于将抽象的控制理论转化为可触摸、可调试的实体系统。你得到的不仅是一套能动的代码更是对“感知-决策-执行”闭环的深刻理解以及排查硬件问题的实战经验。最应该优先验证的是视觉识别的稳定性和串口通信的可靠性这是所有高级功能的基础。最容易踩的坑往往是电源干扰和机械结构的松动。下一步你可以在此系统上尝试更多电赛相关的高级功能轨迹跟踪让小球沿着指定的路径如圆形、八字形运动。抗干扰与恢复设计算法在小球被突然拨开或平板受到撞击后能快速重新稳定。多模式切换通过上位机指令让系统在“定点平衡”、“轨迹跟踪”、“速度模式”之间切换。无线控制引入ESP32或NRF24L01模块实现远程设置参数和发送指令。把这套系统吃透2026年电赛的控制类题目无论小球出现在平衡板、摆动杆还是复杂轨道上你都已经拥有了一个高起点的技术原型。建议收藏本文在备赛过程中随时对照检查和拓展。