我去年给一位养信鸽的朋友做了套驯养系统,核心板子用的就是STM32,前后折腾了将近两个月,从需求对接到画板、写代码、现场调试,最终交付的是一套能定时开关鸽舍门、自动定量喂食、统计鸽子进出数量、记录棚内温湿度的实物,外加一整套完整的设计手册。这篇文章就是把整个项目的来龙去脉、选型逻辑、电路设计、代码状态机、实测踩坑和手册整理思路全部拆开来讲,文章按一名嵌入式开发者的实操视角来写,适合正在做STM32方向课程设计、毕业设计,或者单纯想用单片机做一套小型物联网系统的读者参考。
1. 养鸽子的人需要什么:先把需求账算清楚再立项
很多做嵌入式项目的同学一上来就画原理图、写代码,做到一半才发现“这个功能其实根本用不上”或者“核心需求被做成了配角”。我在做这套系统之前,先跟朋友蹲了一个星期的鸽棚,把驯养流程完整看了一遍,才敢动手。
1.1 驯养场景里的三个核心痛点
信鸽驯养不是简单的“把鸽子关笼子里”,它有一套固定节奏:每天早上开笼放飞、傍晚吹哨唤回、归巢后要记录哪些鸽子回来了、回来多少只、有没有迟迟不回的情况,然后还要定量补食、换水。这些事靠人工做,一是时间卡得死,人必须守在鸽棚,二是记录全靠脑子或本子,长期下来数据难追溯,三是一旦出差或者临时有事,整个驯养节奏就乱了。
所以系统应该优先解决三件事:定时控制鸽舍门开合来配合放飞和归巢,按预设时间定量喂食喂水来保证营养节律,自动统计进出鸽子的数量并连温度湿度一起上报,让人不用天天守在棚里也能掌握情况。
1.2 功能表与硬性指标
我把系统功能拆成了下面这张表,每一条都对应明确的量化指标,这些指标后期直接写进设计手册的“性能要求”章节。
| 功能模块 | 实现方式 | 关键指标 |
|---|---|---|
| 鸽舍门控制 | 五线四相步进电机驱动卷帘门机构 | 单次开关门时间不超过12秒,支持手动/自动切换 |
| 定时喂食 | 步进电机带动螺旋给料器 | 投料误差控制在±5克,支持每天多时段设定 |
| 进出计数 | 入口红外对射传感器 | 计数误差不大于5%,能区分进/出方向 |
| 环境监测 | DHT11温湿度传感器、光敏电阻/照度模块 | 温度采集范围0-50℃,湿度20%-90%RH |
| 数据展示 | 0.96寸OLED屏幕、串口/ESP8266上报 | 本地实时显示,云端可查历史趋势 |
| 应急操作 | 实体按键、遥控切换 | 断电或异常时可按手动开关代替 |
1.3 明确“不做”的部分
做项目很容易陷入“什么功能都想加”的怪圈。这套系统里我也明确砍掉了两个方向:一是视频识别鸽子个体,二是语音控制。原因很直接:鸽舍环境复杂,光线变化大,灰尘多,视频识别对主控算力要求高,STM32F103C8T6跑起来会很吃力,单独上K210或树莓派又会把成本和功耗拉高;语音控制在鸽舍嘈杂环境下实用性很低。最终方案只保留一个“以后可以扩展”的口子,给主控留了一组USART和一组空闲GPIO,后面想接K210做更聪明的个体识别,直接串口对接就能跑,不需要改动现有电路板。这种“留扩展但不做进去”的思路,在实际项目中比堆功能更实用。
2. 器件选型:主控、传感器、执行机构逐个定下来的过程
选型这件事没有绝对的最优,只有最合适。我做这套系统时定了几个硬约束:满足功能、成本可控、采购容易、资料多好调试。在这个前提下,每一项选型都经过了比较。
2.1 主控为什么定在STM32F103C8T6
如果只是做个能跑的小玩具,用51单片机也能勉强应付,但一旦涉及步进电机控制、多路传感器采集、定时器输入捕获、定时器产生PWM,51的处理能力和外设数量都会很紧张。我最后选的是STM32F103C8T6,原因可以列得很直白:
- 内核是Cortex-M3,72MHz主频,跑这套逻辑绰绰有余;
- 片上带USART、I2C、SPI、ADC、多个定时器,几乎不需要外扩芯片;
- 生态成熟,从标准库到HAL库再到各种开源例程,遇到问题搜得到答案;
- 价格便宜,蓝板子十块钱上下,烧了也不心疼;
- 3.3V供电,整板功耗低,适合长期通电运行。
有人会问为什么不上ESP32,自带WiFi还便宜。我承认ESP32确实方便,但项目要求的是“稳定控制”和“现场可维护”,ESP32在WiFi协议栈占资源、以及长期在金属鸽棚环境下射频稳定性方面,都不如STM32加独立WiFi模块来得清晰可控。最终分工是:STM32负责实时控制和本地逻辑,通信交给ESP8266,两者通过串口通信。如果电源和信号都正常,这组方案能长期稳定跑。
开发环境我用的STM32CubeMX生成初始化代码加HAL库,配合Keil MDK编译下载。网上下载芯片支持包的时候注意跟Keil版本匹配,不然安装不上。如果不想用Keil,也可以考虑VSCode加PlatformIO或EIDE插件,配合J-Link或ST-Link下载,这套组合现在也很成熟,不过调试习惯不同的人上手成本会略高。
2.2 传感器的“够用”与“好用”之争
这是最容易纠结的地方。比如温湿度,DHT11精度一般,DHT22(AM2302)精度更高,但价格贵好几倍。对鸽子驯养这个场景,棚内温湿度只要趋势准确、误差不超过2℃和5%RH就够用了,所以选DHT11是完全合理的。反过来如果你做的是实验室级别的恒温控制,那DHT11肯定不行,得换SHT30这类数字传感器。
距离检测我用的HC-SR04超声波模块。这套模块在鸽舍里有个天然优势——它对静止的鸽子羽毛、木屑、灰尘没那么敏感,比红外更不容易误触。但超声波在狭小空间里容易收到多径反射,后面实测阶段我专门做了对策,这点放到第5章详细说。
进出门计数用的是红外对射传感器,E3F-DS30C4这类NPN常开输出,穿过门口时红外束被挡一次就产生一个下降沿。它比超声波更适合做计数,因为边界非常干净,而且响应速度快。
光照检测我直接用光敏电阻分压电路接ADC,不单独用BH1750数字光照模块。原因只有一个:鸽舍只需要区分“天亮/天黑”来辅助判断放飞时间,光敏电阻的分辨率已经足够,省一个I2C外设就少一条I2C总线上的干扰风险。
OLED屏选的是0.96寸、I2C接口的SSD1306,显示温湿度、计数、门状态和系统时间。选I2C版本而不是SPI版本,是为了省引脚,四根线就能搞定显示。
| 传感器/模块 | 接口方式 | 选型理由 | 替代方案 |
|---|---|---|---|
| DHT11 | 单总线GPIO | 成本低、够用 | DHT22/SHT30(精度更高) |
| HC-SR04 | GPIO触发+输入捕获 | 非接触、抗羽毛干扰 | 红外测距(精度更高但怕光干扰) |
| 红外对射E3F-DS30C4 | GPIO外部中断 | 边界干净、响应快 | 激光对射(成本高) |
| 光敏电阻电路 | ADC | 只需判断明暗 | BH1750(数字量、更精确) |
| OLED SSD1306 | I2C | 引脚少、显示直观 | SPI版(刷新更快但多占引脚) |
2.3 鸽舍门控制:五线四相步进电机 vs 舵机
鸽舍门是个既需要力矩又需要位置可控的东西。一开始我朋友提议用大扭矩舵机,但我算了一下:舵机角度范围一般在180度左右,要驱动卷帘门结构得加连杆机构,安装精度要求高,而且堵转时容易烧舵机。五线四相步进电机配合ULN2003驱动板就简单得多——它转的是圈,不是角度,通过控制脉冲数量可以精确控制门帘升降高度,断电时线圈有一定自锁力,不会让门帘自己滑下来。
步进电机型号我选了常见的28BYJ-48,12V或5V供电都能跑,驱动板就是ULN2003。它单步转角大约5.625度,四相八拍方式下步距角可以到0.0875度左右,配合减速齿轮能做到比较平稳的启停。缺陷是转速不能太高,否则会丢步,所以开门动作不要图快,控制在10到12秒跑完全行程比较稳。
2.4 通信和云端:ESP8266与巴法云
本地显示用OLED就够了,但朋友希望在外出时也能看数据,所以加了ESP8266模块做串口透传,把温湿度和计数数据通过WiFi上报到巴法云,手机上看一眼就行。这套方案没有用STM32直接跑TCP协议栈,而是让ESP8266用AT指令完成网络连接,STM32只负责通过串口发JSON格式的字符串,职责分离,出问题也好排查。
需要提一下的是,巴法云这类物联网平台的接入原理都差不多:设备通过MQTT或HTTP上报主题数据,手机端订阅同一个主题就能收到。ESP8266部分配置好WiFi账号、设备和密钥之后,稳定性取决于网络环境,鸽舍如果是铁皮棚,信号衰减会很严重,最好把天线引到棚外或者加一个信号中继。
2.5 电源分配:容易被低估的坑
整个系统里最容易被初学者忽视的就是电源。STM32需要3.3V,传感器和步进电机驱动需要5V,某些型号的超声波模块还要求5V供电但IO电平可以兼容3.3V,我用的HC-SR04是5V供电、回波引脚输出5V高电平,直接接STM32是有风险的,最好在回波引脚上加一颗10K电阻分压或者用电阻串联限幅。
电源树我设计成:12V适配器输入,一路经DC-DC降压到5V给传感器、OLED、ESP8266、电机驱动板和STM32的5V脚供电,另一路经AMS1117-3.3稳压给STM32核心供电。步进电机启动瞬间电流在200mA以上,四个相同时通电时峰值可能更高,所以要单独用一个大容量电解电容在电机供电处滤波,避免瞬间压降导致STM32复位。这个“复位-重启”问题是我实测中遇到的最典型的电源坑,后面会专门讲。
3. 电路设计:从最小系统到实物焊接的关键决策点
电路设计这部分,我按模块来讲,每一块都是画板时真正纠结过的点。
3.1 STM32最小系统与启动配置
STM32F103C8T6最小系统看起来简单,但有几个新手特别容易踩的细节。
第一,BOOT0引脚必须通过10K电阻下拉到地,不然上电可能进入ISP模式,程序跑不起来。如果板子预留了BOOT0跳线,设计手册里一定要写清楚“跳线短接是烧录模式,断开是正常启动模式”。
第二,8MHz晶振的两个负载电容通常用20pF,但实际影响不大,我一般都在18pF到22pF之间选取,关键是匹配,而不是绝对精确。如果不用外部晶振,用内部HSI也可以跑,但USART波特率会偏移,通讯容易乱码,所以有串口的项目还是老老实实焊外部晶振。
第三,复位引脚NRST接10K上拉电阻和100nF电容到地,这属于标准套路,抄官方最小系统即可,不需要发挥。
第四,关于STM32芯片第一脚怎么确认,这个我在实际焊接时反复提醒自己:看芯片丝印,圆点或凹槽标记一侧是第1脚,然后按逆时针方向数,不是按顺时针。用贴片封装时,如果方向焊反了,上电后芯片会发烫,基本就废了。焊接完用万用表蜂鸣档量相邻两个电源脚有没有短路,这个检查动作必须做,不能省。
3.2 电源树与去耦电容布局
整体电源路径是:12V适配器 -> DC-DC降压模块(LM2596或MP1584)输出5V -> AMS1117-3.3输出3.3V。
画板时要特别注意三点:
- STM32每个电源脚旁边放一个100nF去耦电容,尽量贴着芯片引脚放,否则高频噪声滤不掉;
- 主电源入口放一个470uF的大电解电容,稳住电机启动时的瞬时电流;
- 模拟地和数字地在STM32的底部单点连接,避免传感器信号被电机开关噪声干扰。
如果你是在洞洞板上飞线搭电路,做不到铺地,那就尽量用粗线走电源,信号线短、绕开电机线,这个经验对稳定运行非常关键。
3.3 步进电机驱动电路与隔离
步进电机用的ULN2003驱动板是现成的,内部是达林顿管阵列,输入接STM32的四个GPIO(这里我用的PA0、PA1、PA2、PA3),输出接电机的四相线。ULN2003输入端最好串一个1K电阻,虽然它本身耐压够,但串电阻能减少GPIO口电流负载。电机电源不要和STM32共用同一路5V,应该由主5V分支供电,并且电机地线单独回到电源负端,不要跟STM32地线走成一个大环。
加光耦隔离不是必须的,但我在实际系统里做了。原因是鸽舍环境潮湿,电机与门体之间的开关偶合会把一些尖峰脉冲串进主控板。用PC817光耦在STM32 GPIO和ULN2003之间做一次隔离,虽然多花几个元件钱,但稳定性的提升非常明显。光耦输入侧用STM32的3.3V驱动,输出侧用电机电源的5V,两边电源不共地,这可能是整套系统最值得的投资。
3.4 红外对射计数电路和I2C上拉
红外对射传感器是NPN常开输出,检测到遮挡时输出低电平,我把它接到STM32的外部中断引脚(PA4),上升沿和下降沿都可以作为触发信号,再配合第二个对射传感器安装位置一前一后,就能判断鸽子是进还是出。
这里有个电路细节:传感器输出是开漏,需要接一个上拉电阻到3.3V,否则输出电平不确定。通常我用10K上拉,如果线上干扰明显可以降到4.7K。
OLED的I2C总线SDA和SCL需要接上拉电阻,STM32的I2C外设本身有弱上拉但不够稳定,我在板上放了两颗4.7K电阻到3.3V,实测波形干净很多。
3.5 画板、打样和实物焊接记录
PCB我是在Altium Designer里画的,画完导出Gerber发给嘉立创打样。板子是双面,尺寸大概8cm x 10cm,尽量把接口全部引出:SWD下载口、串口调试口、传感器接口、电机驱动接口、电源输入口。
焊接顺序有讲究:先焊电源部分,再焊STM32最小系统,然后焊传感器接口和OLED接口,最后焊电机驱动和光耦。焊完最小系统先别急着焊其他模块,先把ST-Link插上试试能不能识别芯片,确认芯片活着再继续。这个“分段上电测试”的习惯能帮你把问题隔离在最小范围内,避免满板子找故障。
焊接时最好用排针加端子座连接传感器模块,不要直接焊死,因为现场调试时经常要换模块、改方向,焊死了就是灾难。
4. 软件状态机:驯养流程到底是怎么在代码里跑起来的
硬件只是骨骼,驯养逻辑才是灵魂。我把软件设计成了一套状态机,状态之间可以自动切换,也可以在必要时被手动按键打断。
4.1 基于HAL库的工程搭建
工程用STM32CubeMX生成,选好芯片后配置时钟树:外部8MHz晶振,PLL倍频到72MHz。外设初始化涉及GPIO、USART1(调试)、USART2(ESP8266)、I2C1(OLED)、ADC1(光照)、TIM2(PWM/延时)、TIM3(输入捕获或外部计数)、以及若干外部中断。HAL库代码比较啰嗦,但胜在逻辑清晰,出了问题好查。
如果你更习惯标准库,也没问题,这套项目的逻辑跟库没太大关系,只要中断、延时、GPIO读写是同一套约定,状态机照样跑。需要注意的只有一点:不要混合使用HAL库和标准库的延时函数,SysTick会被搞乱。
4.2 DHT11和OLED:最容易卡住的两段时序
DHT11是单总线协议,数据脚需要先在GPIO输出模式下拉18ms作为启动信号,然后切换为输入模式读取40位数据。每一位的“0”或“1”是靠高电平持续时长区分的,26到28微秒左右是0,70微秒左右是1,这个时序对主频要求敏感,务必使用微秒级延时函数。
如果用HAL库的HAL_Delay,它只支持毫秒级,而且会占用SysTick中断,写DHT11驱动时必须改成自己用定时器实现的delay_us。很多人的DHT11读出来永远是0或者固定值,八成就是这里出了问题。正确的思路是:
// 用TIM2实现us延时,以72MHz为例,计数器每次递增1就是1us void delay_us(uint32_t us) { __HAL_TIM_SET_COUNTER(&htim2, 0); while (__HAL_TIM_GET_COUNTER(&htim2) < us); }OLED那边我用的是I2C,SSD1306芯片的初始化序列是固定的,网上例程很多,但要注意一点:如果用了CubeMX自动生成的I2C初始化,不要再手动去配置GPIO开漏,否则总线时序会乱。常见的一个问题是用软件I2C读取设备ID得到0xA1A1之类的异常值,这个现象我在第5章会详细讲。
4.3 超声波测距与红外计数:数据处理比传感器本身更重要
HC-SR04的驱动逻辑其实不复杂:给Trig引脚一个10us以上的高电平,模块自动发出8个40kHz超声波脉冲,然后Echo引脚输出一个宽度跟距离成正比的高电平。用定时器输入捕获或者直接用HAL_GetTick()测高电平时间,距离 = 时间 × 声速 / 2。
但实际用在鸽舍时,单一测量数据根本不靠谱,鸽子扇动翅膀、风吹动杂物都会产生瞬时跳变。我的处理方法是:连续测5次,去掉最大值和最小值,取中间3次的平均值。同时对“距离突变”做了逻辑限制,某次测量值跟前一次相差超过30cm,且连续三次都这样,才认为状态真的变了,否则视为干扰。
红外计数相对简单,但同样存在抖动问题,尤其是鸽子贴着传感器经过时会来回遮挡。我在中断服务函数里加了软件消抖:记录触发时间,距离上次有效触发小于80ms的脉冲直接忽略。这样计数逻辑就稳了。
计数部分如果用定时器输入捕获做频率测量,可以把红外脉冲当成外部时钟源的计数信号,统计单位时间内脉冲数量来估算鸽子飞行经过的频率,这是“STM32定时器捕获测频率”和“STM32定时器模式”这两个热搜点里涉及的核心思路,完全可以复用到别的项目里。
4.4 五线四相步进电机的八拍控制
28BYJ-48步进电机是五线四相(也有叫四相五线的),ULN2003驱动板上标识为A、B、C、D四相。四相八拍的励磁顺序是:A -> AB -> B -> BC -> C -> CD -> D -> DA,如此循环。我用的驱动代码如下:
const uint8_t StepTable[8] = { 0x08, 0x0C, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09 }; // 对应 OUT1=A OUT2=B OUT3=C OUT4=D // 0x08=1000 D相导通,0x0C=1100 C+D导通,依此类推 void Stepper_Run(uint16_t steps, uint8_t direction) { for (uint16_t i = 0; i < steps; i++) { uint8_t idx = (direction ? (i % 8) : (7 - (i % 8))); HAL_GPIO_WritePin(MOTOR_A_GPIO_Port, MOTOR_A_Pin, (StepTable[idx] & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(MOTOR_B_GPIO_Port, MOTOR_B_Pin, (StepTable[idx] & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(MOTOR_C_GPIO_Port, MOTOR_C_Pin, (StepTable[idx] & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(MOTOR_D_GPIO_Port, MOTOR_D_Pin, (StepTable[idx] & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET); delay_us(2000); // 速度约200步/秒,太快容易丢步 } }开门时,程序先读限位开关,如果门不在完全关闭状态,就先执行“关门复位”动作,再按设定脉冲数开门,这样每次门的位置都绝对准确,不会因为偶尔的丢步越跑越偏。
4.5 驯养状态机:把驯养流程翻译成程序逻辑
整个系统我设计了6个核心状态:STANDBY(待机)、FEEDING(喂食)、DOOR_OPEN(开门)、DOOR_CLOSE(关门)、COUNT_UPDATE(计数更新)、UPLOAD(上报)。状态切换由定时器和中断共同驱动。
每天的时间表是预设的,比如早晨6:30开门,6:35开始喂食;傍晚17:30关门,17:40再喂一次。到了时间点,RTC或定时器触发,状态机从STANDBY进入DOOR_OPEN,开完门后判断是否需要喂食。每次有鸽子经过红外对射,中断服务函数里更新计数变量,同时触发COUNT_UPDATE状态刷新OLED显示。
异常处理也做了一套:如果开门后超过30分钟没有任何鸽子进入,说明鸽子可能没回来,状态机会在OLED上显示提醒,并通过ESP8266发一条消息到手机端。这套逻辑并不复杂,但对朋友来说非常实用,他说以前只顾着忙别的,经常忘了鸽子回没回齐。
5. 实测中的故障排查:那些让我在鸽棚蹲了半天的坑
这部分可能对多数读者最有价值。很多问题不是原理看不懂,而是现象诡异。
5.1 延时函数卡死:SysTick冲突是万恶之源
现象是程序运行到某个位置突然“死了”,代码逻辑看着没问题,最后定位到是延时函数卡死。原因是工程里既用了HAL_Delay(),又用了自己基于SysTick或TIM写的delay_ms(),两个函数都在操作同一个定时器,结果就产生了“你的延时还没走完,SysTick中断已经把计数器改了”的冲突。
解决方法是统一延时源,毫秒级延时统一用HAL_GetTick()做比较,微秒级延时单独用一个定时器。这个经验在调试任何STM32项目时都适用,先确认你的延时函数是不是唯一入口,再检查是不是有中断服务函数里调用了耗时操作。
5.2 超声波在鸽舍里疯狂误报
HC-SR04在空旷环境测得很准,一进鸽舍就乱跳。鸽子在栖架上活动,翅膀扇动会产生大量杂波;另外鸽舍地面和铁网会对超声波形成多径反射,导致测出来忽远忽近。我蹲在现场观察波形,发现只要鸽子从传感器前方飞过,Echo脚的波形就乱成一团。
对策分三层:第一,把传感器朝向从水平改为略微向下,避开正对鸽子的飞行路径;第二,软件上做中值滤波和连续一致性判断,前面代码里已经实现了;第三,给传感器加了一个半开放式的亚克力挡板,让发射和接收的方向性更集中。三层下来,误报率基本降到可忽略的程度。这就是“原理上能用”和“现场真正能用”的区别。
5.3 OLED或I2C设备读ID读到0xA1A1:先查电平再查接线
网上关于ILI9341读ID读到0xA1A1的讨论很多,实际意思是“总线上的设备没有正常响应,主控读到的是漂移电平或空数据”。我的OLED在使用软件I2C时也出现过类似现象,刚开始以为屏坏了,换了一块还是老样子。最后用逻辑分析仪看波形,发现问题出在I2C上拉电阻缺失上。
STM32内部的上拉较弱,加上杜邦线比较长,总线电容偏大,SDA和SCL的上升沿变得很缓,OLED端的逻辑判断就出错了。解决方法是外加4.7K上拉电阻,并且把杜邦线长度控制在20cm以内。如果你遇到任何I2C设备读ID异常,不要急着怀疑设备本身,先用万用表确认SDA和SCL上有没有稳定的3.3V上拉电平,再看地址是否正确,最后再用示波器或逻辑分析仪看波形时序。
5.4 步进电机丢步和堵转
门帘机构有时候会被卡住,步进电机还在拼命输出,时间长了就会丢步,门的实际位置和程序记录的脉冲数对不上。堵转时我测到ULN2003输入端的电流明显偏大,但电机不动,这就是典型的驱动能力不足或者机构卡死。
我的处理是:每次开关门动作前,先执行“复位找零”程序,让门先关到限位开关触发的位置,以这个位置为绝对零点,再按固定脉冲数走。这样即便某次动作中丢了步,下一次动作时也会自动清零误差,不会越走越偏。同时给门体机构加装了一个微动限位开关,作为程序上的物理保险。
5.5 禁用JTAG之后程序烧不进去了
调试过程中,有段时间为了省引脚,我把JTAG功能禁用,只留SWD,结果后来一次手滑把SWD也禁用或者配置错了,芯片直接无法识别,ST-Link都连不上。这个坑在聊STM32禁JTAG时是高频话题。
解决办法是使用ST-Link的“connect under reset”模式,让芯片在复位状态时被强制连接,趁程序还没跑起来就把FLASH擦掉。如果手上没有支持这个功能的下载器,应急办法是把BOOT0拉高,让芯片上电进ISP模式,再用串口把FLASH清空。从此之后我养成了一个习惯:凡是有调试需求的板子,必定保留SWD接口,并且代码里绝不轻易禁用SWD引脚。
5.6 巴法云上报偶尔断线
WiFi模块偶尔会断线,服务器连接会掉。STM32如果只发一次连接请求,断线后就不会自动恢复。我在代码里加了一个“看门狗式”的重连机制:每隔30秒检查一次ESP8266和云端服务器的连接状态,发现未连接就自动重新AT握手,重新订阅主题。这个思路是所有单片机做物联网上报的通用做法,不要假设网络永远稳定,要把断线重连当成必须实现的功能而不是可选项。
6. 设计手册怎么组织:从实物到完整交付的文档经验
项目标题里写明了“实物+电路+设计手册”,说明这套系统不是装完就完事的,文档同样是交付物。尤其如果是毕业设计,设计手册(也就是说明书)的分数占比往往比实物还高。
6.1 手册的整体框架
我整理手册时的章节结构是:需求分析、总体方案设计、硬件设计、软件设计、系统测试与误差分析、成本估算、总结与展望。每一章都不要写空话,比如“系统稳定可靠”这种话要换成“连续运行7天,计数误差在3%以内”这种可验证的描述。
在总体方案章节里,画系统结构图时,不要画那种每个模块只是简单连线的框图,最好能把数据流向、控制流向、电源流向一并标出来,让读者一眼看出系统是“感知-决策-执行-反馈”的闭环。
6.2 测试记录与误差分析
我实测的数据可以作为参考模板:
| 测试项 | 测试条件 | 结果 |
|---|---|---|
| 温湿度采集 | 鸽舍内放置,对比水银温度计 | 温度误差±1℃,湿度误差±4%RH |
| 超声波测距 | 距离10cm-200cm,每20cm测一次 | 最大误差2cm,平均误差1cm以内 |
| 进出计数 | 人为赶鸽子通过,连续10次 | 识别9次,漏计1次,准确率90% |
| 开门时间 | 全行程从关闭到完全打开 | 平均11.6秒,重复10次误差小于0.5秒 |
| 云端上报 | 手机端查看延迟 | 平均延迟1-2秒,偶尔丢包后自动重传 |
这份测试表是设计手册最有力的部分,因为它的每一行都对应真实实验环境,不是从别人论文里抄的。
6.3 物料成本与替代空间
整套系统的物料成本大概如下:
| 物料 | 数量 | 参考单价 |
|---|---|---|
| STM32F103C8T6最小系统板 | 1 | 约10元 |
| 0.96寸OLED(I2C) | 1 | 约12元 |
| DHT11模块 | 1 | 约5元 |
| HC-SR04模块 | 1 | 约6元 |
| 红外对射传感器 | 2 | 约20元 |
| ESP8266模块 | 1 | 约10元 |
| 28BYJ-48+ULN2003 | 1 | 约15元 |
| 降压模块、AMS1117、阻容等 | 若干 | 约20元 |
| PCB打样 | 5片 | 约25元 |
合计大约120元左右,如果把PCB和结构件再压缩,还能更低。毕业设计里写明成本构成和替代空间,比简单列价格更能体现工程思维。
6.4 给想复刻这套系统的人几条建议
如果你打算复刻或者改造这个项目,我给几条具体的建议:
- 先把“需求表”写清楚再动手,宁可少做功能,也别做出一堆没用的功能;
- 电路上电源是大头,先把电源调稳再谈传感器,10个项目里有6个问题都出在电源上;
- 步进电机一定要加限位开关和复位流程,没有绝对值位置控制的机械结构都是不合格的;
- 超声波和红外这种易受环境干扰的传感器,一定要在软件里做滤波,不能直接裸读;
- 云端上报必须做断线重连,这是嵌入式联网的基本素养;
- 文档和代码同步更新,不要等做完了再补手册,否则细节早就忘光了。
这套系统的本质是一个“传感器+执行器+主控+通信”的标准物联网架构,把鸽舍门换成鱼缸加热棒,把红外对射换成水位传感器,就变成了智能鱼缸;把喂食电机换成台灯调光电路,就变成了智能台灯。当初设计时我对朋友说,我帮你做的不是一套只能养鸽子的设备,而是一个什么都能接的控制盒子。实际上也确实是这么用起来的——后来他又让我把同样的板子改成了鸽舍照明自动控制。个人体会是,嵌入式项目里最有价值的部分不是某个器件多贵,而是面对复杂环境时你作的那些判断和取舍。希望这篇文章能帮你在自己的项目上少走几个弯路。