
1. 项目缘起与整体设计思路1.1 为什么会想到做鸽子驯养系统养鸽子这件事外行看热闹内行看门道。赛鸽驯养的核心痛点其实就三个字规律性。鸽子是极度依赖生物钟的动物喂食时间、放飞时间、归巢训练、光照周期每一项的偏差都会直接影响归巢率和体能状态。传统养鸽人靠的是经验和闹钟但人总有疏忽的时候——出差一趟回来鸽子的状态就掉了。我最初做这个项目的动机很朴素能不能用一块STM32把喂食、环境监测、训练记录这几件事自动化管起来市面上确实有商用鸽舍控制器但要么功能单一就是个定时喂食器要么价格离谱动辄大几千而且没法按自己的驯养节奏定制。既然自己懂嵌入式那就动手做一套。这套系统最终实现的功能包括定时定量自动喂食、鸽舍温湿度与光照监测、自动补光控制、归巢检测与记录、异常报警温度过高/过低、断粮、以及通过串口屏做本地交互。主控选的是STM32F103C8T6也就是大家常说的“蓝板子”性价比高、资料全、外设够用。1.2 方案选型的几个关键决策主控为什么选F103而不是F4或G系列这个项目的外设需求是3路定时器喂食电机PWM、补光灯PWM、系统时基、2路ADC光敏电阻、电池电压检测、2路UART串口屏、调试输出、若干GPIO继电器、限位开关、蜂鸣器、1路I2C温湿度传感器。F103C8T6有3个通用定时器、2个ADC、3个USART、2个I2C资源刚好卡在够用的线上。F4当然更充裕但价格翻了几倍对这个项目来说属于浪费。G系列供货不稳定不考虑。喂食机构为什么用步进电机而不是舵机或直流电机喂食需要精确控制下料量舵机角度控制虽然简单但扭矩小、长时间往复运动容易扫齿直流电机加编码器成本上去了而且低速扭矩差。最终选了28BYJ-48五线四相步进电机配ULN2003驱动板便宜、扭矩够、控制简单配合减速比每步出料量可以精确到克级别。温湿度传感器为什么选SHT30而不是DHT11DHT11便宜但精度太差温度±2℃湿度±5%而且响应慢鸽舍环境湿度变化大DHT11根本跟不上。SHT30是I2C接口温度精度±0.3℃湿度±2%而且有加热功能可以防凝露适合鸽舍这种高湿环境。价格也就贵几块钱完全值得。显示交互为什么用串口屏而不是OLEDOLED做多级菜单开发量大而且养鸽人年龄偏大小屏幕看不清。串口屏淘晶驰TJC系列用上位机拖控件就能做界面开发快3.5寸屏显示清晰触摸操作直观。代价是要占用一个UART但F103有3个USART够用。1.3 系统整体架构整个系统按功能划分为四个模块主控模块STM32F103C8T6最小系统板负责所有逻辑调度执行模块步进电机ULN2003喂食、继电器LED灯带补光、有源蜂鸣器报警感知模块SHT30温湿度、光敏电阻分压电路光照强度、限位开关料仓余量检测交互模块串口屏本地操作、ESP-01S可选用于远程数据上报供电方面整机用12V/2A适配器输入经过LM2596降压到5V给步进电机和继电器再经过AMS1117-3.3降到3.3V给STM32和传感器。这里要注意步进电机启动瞬间电流冲击比较大5V和3.3V的电源走线要分开否则MCU容易被拉复位。提示如果你也打算做类似项目电源部分千万别省。我第一版用USB供电步进电机一转MCU就重启查了半天以为是看门狗问题最后发现是电源塌陷。2. 硬件电路核心细节与实操要点2.1 最小系统与复位、防抖电路STM32F103C8T6最小系统的核心就三块电源、晶振、复位。电源部分前面说了3.3V用AMS1117输入输出各加10uF和0.1uF电容。晶振用8MHz无源晶振配两个20pF电容负载电容要根据晶振规格书选一般20pF是安全的。复位电路很多人随便搞个10K上拉加0.1uF电容就完事了但实际用下来按键复位如果不加防抖偶尔会出现按一下复位多次的情况。我的做法是在NRST引脚和按键之间串一个100Ω电阻再并一个0.1uF电容到地形成RC防抖。另外NRST引脚内部有上拉外部10K上拉可以保留也可以省掉但建议保留抗干扰更好。看门狗电路这里要说明一下STM32内部有独立看门狗IWDG和窗口看门狗WWDG一般应用用IWDG就够了。我在项目里开了IWDG超时设成2秒主循环里喂狗。但要注意如果用了串口屏屏幕初始化可能耗时较长喂狗要及时否则一上电就复位。我的做法是在屏幕初始化循环里也插入喂狗操作。2.2 步进电机驱动与喂食机构28BYJ-48是五线四相减速步进电机减速比1:64步距角5.625°/64。ULN2003是达林顿管阵列用来放大STM32的GPIO信号驱动电机绕组。接线很简单IN1-IN4接STM32的PB0-PB3电机五根线插ULN2003板子上的插座。驱动方式用八拍模式比四拍模式运行更平滑。八拍时序是A-AB-B-BC-C-CD-D-DA。每步延时1ms左右太快了电机会失步太慢了出料效率低。实测下来1.2ms比较稳。喂食机构我用的是一种“转盘式”结构步进电机带动一个带凹槽的转盘转盘每转一格就有一小撮饲料从料仓落到食槽。转盘用3D打印的凹槽容积经过标定每格大约2克。要喂50克就转25格。这里有个细节转盘和电机轴之间要用D型轴配合不能用圆轴加顶丝否则打滑后计量就不准了。限位开关装在料仓底部当饲料快用完时弹簧片被释放触发开关MCU检测到后通过串口屏提示“料仓不足”。限位开关的接线要注意防抖我在GPIO口加了10K上拉和0.1uF电容到地软件里再做20ms延时确认。2.3 温湿度采集与光照检测SHT30用I2C接口接STM32的PB6SCL和PB7SDA上拉电阻用4.7K。SHT30的I2C地址是0x44ADDR接地或0x45ADDR接VCC我用的0x44。读取流程是发送测量命令0x2C06高重复性无时钟拉伸延时15ms然后读6个字节前两个是温度中间两个是湿度最后两个是CRC校验。CRC校验建议做鸽舍环境电磁干扰不小I2C偶尔会读出错数据。CRC多项式是0x31初始值0xFF。如果校验失败就丢弃这次数据用上一次的有效值。光照检测用光敏电阻GL5528和10K电阻分压接到STM32的PA0ADC1_IN0。光敏电阻的阻值随光照增强而减小所以分压点电压随光照增强而升高。ADC采样12位参考电压3.3V。实际使用中我设定了两个阈值低于800暗开启补光灯高于2000亮关闭补光灯。阈值需要根据鸽舍实际采光情况标定不能照搬。补光灯用12V LED灯带通过继电器控制。继电器线圈两端要并一个续流二极管1N4148否则断电瞬间的反向电动势会干扰MCU。继电器触点侧如果控制的是220V交流灯那必须做好绝缘隔离强电部分和弱电部分在PCB上要拉开至少3mm间距。我用的是12V直流灯带安全很多。2.4 电源管理与抗干扰设计整机电源树是这样的12V输入 → LM2596降压到5V → AMS1117降压到3.3V。LM2596的反馈电阻我用的是10K和3.3K输出约5V。电感用33uH输出电容用220uF低阻电容。这里要注意LM2596的开关频率是150KHz布局时电感和续流二极管要靠近芯片反馈走线要远离电感。步进电机和继电器是主要的干扰源。我的做法是电机电源和MCU电源在LM2596输出端就分开走线各自加磁珠和电容滤波。电机驱动板附近并一个100uF电解电容和一个0.1uF陶瓷电容。继电器线圈并续流二极管触点并RC吸收电路100Ω0.1uF。TVS二极管保护也是必要的我在12V输入端并了一个SMBJ15A防止电源浪涌。虽然适配器输出一般比较干净但鸽舍环境可能有电网波动加一个不亏。注意PCB布局时晶振要尽量靠近MCU底下不要走线。复位电路靠近NRST引脚。去耦电容每个电源引脚都要有不能省。3. 软件架构与核心功能实现3.1 开发环境搭建与工程配置开发环境我用的是VSCode STM32CubeMX arm-none-eabi-gcc OpenOCD。这套组合免费、跨平台、插件生态好。具体步骤安装STM32CubeMX配置时钟树HSE 8MHzPLL倍频到72MHzAHB 72MHzAPB1 36MHzAPB2 72MHz。配置外设USART1调试115200、USART2串口屏9600、I2C1SHT30100KHz、TIM2系统时基1ms、TIM3步进电机PWM、TIM4补光灯PWM、ADC1光照和电池电压。生成Makefile工程用VSCode打开。配置launch.json和tasks.json用OpenOCD ST-Link下载调试。这里有个坑STM32CubeMX生成的Makefile默认优化等级是-Og调试够用但代码效率一般。如果对性能有要求可以改成-O2但要注意有些延时函数可能被优化掉需要加volatile。另外STM32芯片包安装有时候会卡住可以手动下载pack包放到CubeMX的仓库目录里。VSCode的Cortex-Debug插件配置launch.json时svd文件路径要写对否则看不到寄存器。3.2 定时器与任务调度系统时基用TIM2配置成1ms中断在中断里维护一个全局tick计数器。主循环里用tick做软定时比如每500ms读一次SHT30每100ms检测一次限位开关每1s更新一次屏幕显示。步进电机控制用TIM3配置成PWM输出模式但实际驱动步进电机用的是GPIO翻转PWM只是用来产生稳定的步进脉冲。具体做法是TIM3配置成1KHz PWM更新中断里切换GPIO状态按八拍时序输出。这样步进电机的转速就由PWM频率决定改频率就改转速。补光灯用TIM4的PWM输出频率1KHz占空比可调。不过我用的是继电器控制所以PWM其实没用上直接GPIO开关。如果以后换成MOS管调光PWM就派上用场了。任务调度没有用RTOS因为任务不多前后台架构够了。主循环里依次执行喂狗、读传感器、更新状态机、刷新屏幕、处理串口命令。每个任务都是非阻塞的用tick判断是否到了执行时间。3.3 喂食逻辑与步进电机控制喂食逻辑的核心是一个状态机IDLE空闲状态等待喂食时间到达FEEDING正在喂食步进电机按设定步数转动ERROR异常状态比如限位开关触发或电机堵转喂食时间表存在Flash里可以掉电保存。默认设置是每天三次早上7点、中午12点、下午5点每次50克。时间到达后进入FEEDING状态计算需要转的步数50克 ÷ 2克/格 × 每格步数。28BYJ-48八拍模式每转一圈是4096步转盘每格对应1/20圈所以每格约205步。50克就是25格共5120步。步进电机控制代码用查表法输出八拍时序const uint8_t step_table[8] {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09};每次更新中断里输出step_table[step_index]然后step_index到8归零。步进延时用TIM3的更新中断实现频率设成800Hz左右对应每步1.25ms。喂食过程中要监测限位开关如果料仓空了立即停止并报警。另外电机堵转检测可以通过电流采样实现但ULN2003没有电流反馈所以只能靠限位开关和超时判断。我设了最大喂食时间30秒超时就报错。3.4 串口屏交互与数据记录串口屏用的是淘晶驰TJC3224T035_0113.5寸电阻触摸屏。开发用官方USART HMI软件拖控件、设属性、写事件代码。屏幕和STM32之间用USART2通信波特率9600协议是简单的帧格式0x55 0xAA 指令 数据 0xFF 0xFF 0xFF。屏幕主界面显示当前温度、湿度、光照强度、料仓状态、下次喂食时间。设置界面可以修改喂食时间和喂食量。数据记录界面显示最近7天的喂食记录。STM32这边要解析屏幕发来的指令比如“修改喂食时间”指令包含小时和分钟两个字节。解析后更新Flash里的时间表并回传确认。屏幕发来的数据可能粘包所以要用状态机解析不能简单用延时。数据记录存在STM32的内部Flash里F103C8T6有64KB Flash划出最后4KB做数据存储。每条记录8字节时间戳4字节、喂食量2字节、状态2字节。4KB可以存512条记录够用很久了。Flash写入前要先擦除扇区擦除时CPU会停顿所以要在喂食完成后、系统空闲时再写。4. 常见问题与排查技巧实录4.1 步进电机失步与喂食不准这是最常见的问题。表现是设定喂50克实际出来只有30多克。原因通常有三个电源功率不足。28BYJ-48额定电流约200mA但启动瞬间可能到400mA。如果5V电源只能给300mA电机就会失步。用万用表测电机转动时5V电压如果掉到4.5V以下就是电源问题。换2A以上的适配器。步进延时太短。八拍模式下每步延时低于1ms电机响应不过来。把TIM3频率降到800Hz以下试试。转盘卡涩。3D打印的转盘如果公差没控制好转动阻力大电机扭矩不够就会丢步。用砂纸打磨转盘边缘或者加一点润滑脂。排查步骤先空载测试电机能否正常转一圈再装上转盘测试最后加饲料测试。逐步排除。4.2 SHT30读数据失败或CRC错误I2C通信失败的原因比较多按概率排序问题现象可能原因排查方法完全读不到数据接线错误或地址不对用逻辑分析仪抓I2C波形确认地址是0x44偶尔CRC错误上拉电阻太大或走线太长上拉换成2.2K缩短走线数据固定不变传感器未初始化或命令错误检查测量命令是否为0x2C06温度正常湿度异常传感器凝露开启SHT30加热功能或加防凝露膜我遇到过一次CRC频繁错误最后发现是I2C走线太长15cm而且和电机线捆在一起。分开走线后问题消失。所以I2C线尽量短远离干扰源。4.3 看门狗误复位看门狗复位表现为系统每隔几秒重启一次。原因通常是喂狗不及时。检查以下几点主循环里是否有阻塞操作比如串口屏初始化用了delay_ms(2000)这期间没喂狗。Flash擦除时CPU停顿如果擦除时间超过看门狗超时也会复位。中断里如果有死循环主循环喂不了狗。解决方法把看门狗超时设长一点比如4秒在阻塞操作里插入喂狗或者用窗口看门狗在中断里喂狗。我最终把IWDG超时设成4秒并在屏幕初始化循环里加了喂狗。4.4 串口屏通信不稳定串口屏偶尔不响应或显示乱码通常是波特率不匹配或地线没接好。检查屏幕和STM32的波特率是否一致我用的9600。TX和RX是否交叉连接。地线是否共地。如果不共地通信会时好时坏。电源是否足够。屏幕背光耗电较大如果和电机共用5V电机一转屏幕就可能复位。我的做法是屏幕单独用一个5V电源和电机电源分开。通信线用屏蔽线屏蔽层接地。4.5 常见问题速查表现象优先排查解决方案MCU频繁复位电源、看门狗加大电容延长看门狗超时电机不转驱动板供电、GPIO测ULN2003输入输出检查GPIO配置温度读数偏高传感器自热降低采样频率增加间隔屏幕触摸不准校准重新做触摸校准Flash数据丢失擦除未完成就断电写入后延时加掉电检测继电器吸合干扰MCU续流二极管、布局加二极管继电器远离MCU5. 外壳设计与整机装配5.1 外壳结构设计要点外壳用SolidWorks设计3D打印。分上下两层下层放电源和电机驱动板上层放主控板和屏幕。层间隔板开孔走线。设计时要注意屏幕开孔尺寸要精确大了屏幕会晃小了装不进去。我一般留0.2mm间隙。散热孔要开LM2596和AMS1117都会发热密闭空间温度会累积。料仓要设计成可拆卸的方便清洗和加料。电机轴和转盘的连接处要留检修口。5.2 装配顺序与注意事项装配顺序建议先装电源模块测各路电压正常再装主控板烧录测试程序确认能跑起来然后装传感器和屏幕测试通信最后装电机和机械结构测试喂食。每一步都要测试不要全装好了再上电。我第一版就是全装完才上电结果电机一转就复位拆开查了半天。接线用杜邦线临时测试确认没问题后再焊接。焊接时注意不要虚焊特别是电源线。电机线电流大用粗一点的线。5.3 成本清单与物料选型物料型号数量单价约主控板STM32F103C8T6最小系统115元步进电机28BYJ-48 ULN2003112元温湿度传感器SHT30模块115元串口屏TJC3224T035165元电源模块LM2596 AMS111718元继电器模块5V单路15元光敏电阻GL552811元限位开关微动开关12元蜂鸣器有源5V12元12V电源2A适配器120元外壳3D打印130元其他线材、电阻、电容-20元合计约195元这个成本比商用产品便宜很多而且功能可以自己定制。如果去掉串口屏用OLED成本还能降40元左右但操作体验会差一些。6. 功能扩展与驯养数据应用6.1 归巢检测与训练记录归巢检测用RFID方案鸽子脚环上贴RFID标签鸽舍入口装读卡器。鸽子归巢时读卡器读到标签STM32记录时间。这样就能统计每只鸽子的归巢时间、训练成绩。RFID读卡器用RC522SPI接口接STM32的SPI1。标签用 Mifare S50脚环上贴圆形标签。读卡器天线要放在入口通道两侧确保鸽子经过时能读到。数据记录格式鸽子ID4字节、归巢时间4字节、日期4字节。存在Flash里可以通过串口屏查看也可以导出到电脑分析。6.2 远程数据上报如果需要远程查看鸽舍状态可以加ESP-01S模块通过AT指令连接云平台。STM32通过UART发AT指令ESP-01S负责网络通信。数据上报用MQTT协议每5分钟上报一次温湿度和料仓状态。这里要注意ESP-01S供电要稳定峰值电流可能到300mA不能和MCU共用LDO。我用一个独立的AMS1117给它供电并在电源脚并100uF电容。6.3 驯养数据分析收集到的数据可以做一些简单分析归巢时间趋势如果某只鸽子归巢时间逐渐变长可能状态下滑。温湿度与归巢率的关系高温高湿天气归巢率是否下降。喂食量与体重的关联需要额外称重数据。这些分析可以在电脑上用Python做STM32只负责采集和存储。数据导出用串口格式是CSV方便导入Excel或Python。7. 实操心得与避坑总结7.1 调试顺序很重要不要想着一次把所有功能都调通。我的调试顺序是电源→最小系统→串口输出→传感器→屏幕→电机→整机联调。每一步确认没问题再进下一步。这样出问题时排查范围小容易定位。7.2 电源是万恶之源嵌入式项目80%的奇怪问题都和电源有关。电机一转就复位、屏幕闪烁、传感器读数跳变先查电源。示波器看电源纹波万用表看电压跌落。电源搞定了问题少一半。7.3 代码要留调试接口我习惯留一个UART专门做调试输出用printf打印关键变量。出问题时看串口输出比猜快得多。另外留一个GPIO做状态指示不同闪烁频率代表不同状态一眼就能看出系统跑到哪一步了。7.4 机械结构不能凑合软件可以改机械改起来麻烦。转盘、料仓、电机支架这些结构件设计时多留余量装配时多测试。3D打印的零件强度有限受力大的地方加厚或者用金属件。7.5 现场测试不可省略实验室里跑得好好的到鸽舍可能就出问题。温度、湿度、灰尘、震动都会影响系统稳定性。我第一版在实验室跑了一周没问题装到鸽舍第二天就死机了最后发现是鸽舍湿度大屏幕排线氧化接触不良。所以一定要在实际环境里测试至少一周。7.6 关于设计手册的编写设计手册不是把代码和电路图堆上去就完事了。好的设计手册应该包含系统框图、各模块原理说明、关键参数计算过程、调试步骤、常见问题排查、物料清单、PCB布局建议。这样别人拿到手册能复现自己以后维护也有据可查。我写手册的习惯是每完成一个模块就写对应的章节不要等全部做完再补。当时记得最清楚过后就忘了。手册里的参数要写清楚是怎么算出来的比如步进电机步数计算、分压电阻选型、滤波电容取值这些计算过程比结果更重要。7.7 后续可以怎么玩这套系统的基础框架搭好后扩展空间很大。比如加一个称重模块HX711压力传感器监测鸽子体重加一个摄像头做行为分析加一个CO2传感器监测空气质量。软件上可以加PID控制鸽舍温度或者用历史数据做喂食量自适应调整。我个人觉得最有价值的扩展是归巢检测和数据分析因为这直接关系到驯养效果。硬件成本增加不多但数据积累起来后对驯养策略的优化很有帮助。最后分享一个小技巧STM32的Flash写入寿命是1万次左右如果频繁记录数据建议加一个铁电存储器FM24C02或者SD卡避免Flash写坏。我一开始没注意每天写几十条记录半年后Flash就出坏块了。后来换成FM24C02I2C接口写入次数几乎无限问题解决。