1. 项目缘起与整体设计思路
1.1 为什么会想到做鸽子驯养这件事
养鸽子这件事,外行看热闹,内行看门道。我接触赛鸽和观赏鸽前后差不多六年时间,最开始纯粹是个人爱好,后来帮朋友打理过一个小型鸽舍,才发现传统驯养方式里有一堆靠人力硬扛的痛点。喂食要定时定点,放飞训练要盯着时间,鸽舍温湿度靠手感判断,归巢记录靠人眼盯着数。一个人管二三十只还行,一旦上到上百只,光每天重复的体力活就能把人拖垮。
这个基于STM32的智能鸽子驯养系统,核心目标就是用一套低成本的嵌入式方案,把喂食、环境监测、归巢识别、远程查看这几件事自动化。它不是一个停留在仿真软件里的课设,而是有实物、有电路、有完整设计手册的可落地项目。适合谁参考?电子类专业做毕业设计的学生、想入门STM32又缺一个完整实战项目的开发者、以及真正养鸽子想搞点自动化改造的爱好者。哪怕你之前只点亮过一颗LED,跟着这套思路走也能把系统搭起来。
1.2 系统整体架构是怎么搭的
整套系统我采用的是“主控+多模块+双通道通信”的结构。主控选STM32F103C8T6,也就是大家常说的“蓝板”或最小系统板,原因很直接:价格便宜、资料多、外设够用、社区踩坑记录丰富。你遇到问题一搜基本都有人答过,这对个人项目来说太重要了。
系统分成四个功能层。第一层是感知层,包括DHT11温湿度传感器、HX711加称重传感器组成的料仓重量检测、红外对管或超声波测距做的归巢检测。第二层是执行层,包括五线四相步进电机驱动的下料机构、继电器控制的水泵或风扇。第三层是人机交互层,用ILI9341驱动的2.4寸TFT屏做本地显示,几个按键做参数设置。第四层是通信层,本地用RS485做多节点扩展,远程用巴法云做数据上报和手机端查看。
为什么这么分层?因为养鸽场景里,鸽舍往往离人住的地方有一段距离,你不可能天天守着。把感知和执行分开,通信独立出来,后面哪一块要升级或者坏了,替换起来不影响其他部分。这是我在实际维护中体会最深的一点,模块化不是为了好看,是为了你半夜发现某个功能挂了的时候能快速定位。
1.3 关键器件的选型逻辑
选型这块我踩过不少坑,这里把几个关键决策讲透。
主控选F103C8T6而不是F407或者G系列,是因为这个项目对算力要求不高,主要跑定时器、ADC、UART和GPIO,F103的72MHz主频绰绰有余。而且F103的标准库和HAL库资料最全,新手友好。你要是手上正好有别的STM32芯片,移植过去问题也不大,注意时钟树和引脚复用差异就行。
显示选ILI9341而不是OLED,是因为鸽舍环境光线复杂,OLED在强光下看不清,TFT屏可视角度和亮度更合适。ILI9341用SPI驱动,占用引脚少,刷屏速度也够。这里有个细节,很多人读ILI9341的ID读出来是0xA1A1,这其实是正常的,不同批次或者兼容芯片返回的ID就是不一样,别以为是坏的,只要初始化能点亮、能刷色块就没问题。
通信选RS485而不是直接TTL串口,是因为鸽舍里电机、继电器这些感性负载多,TTL电平抗干扰能力差,走几米线就可能丢包。RS485差分信号抗共模干扰强,配合TVS二极管保护电路,稳定性提升明显。远程用巴法云是因为它接入简单,MQTT协议,有现成的手机端,不用自己搭服务器。
2. 核心电路设计与实操要点
2.1 电源电路:别小看这一块
电源是整个系统最容易翻车的地方。我第一版直接用USB 5V供电,结果步进电机一转,屏幕就闪,单片机偶尔复位。后来老老实实做了电源分级。
系统需要三路电压:12V给步进电机,5V给继电器和部分传感器,3.3V给STM32和TFT屏。12V用适配器直接输入,5V用LM2596或MP1584这类Buck电路降压,3.3V用AMS1117-3.3从5V降下来。这里要注意,AMS1117压差要求至少1V以上,5V降到3.3V没问题,但如果你从12V直接降到3.3V,发热会很严重,必须用DCDC。
Buck电路的电感选型有讲究。以MP1584为例,开关频率1.5MHz,输入12V输出5V,电感选4.7uH到10uH之间比较合适。电感太小纹波大,太大响应慢。输出电容用22uF陶瓷电容并联一个100uF电解电容,兼顾高频和低频滤波。实测下来,加了这套滤波之后,电机启动时3.3V轨的波动从原来的300mV降到了50mV以内。
注意:Buck电路的续流二极管一定要选肖特基管,比如SS34,普通整流管反向恢复时间长,效率低还发热。
2.2 防倒灌与保护电路
鸽舍供电有时候会用太阳能加锂电池,这就涉及到防倒灌。我用PMOS管做了一个简单的防倒灌电路,原理是利用PMOS的体二极管方向,当输入电压消失时,PMOS截止,防止电池电流倒灌回输入端。具体接法是PMOS的源极接负载侧,漏极接输入侧,栅极通过电阻分压控制。这个电路比用二极管防倒灌的好处是压降小,二极管有0.3到0.7V压降,PMOS导通时压降只有几十毫伏。
TVS二极管保护电路也是必须的。RS485的A、B线对地各接一个SMBJ6.5CA,防止雷击或静电浪涌。电源输入端接一个SMBJ15CA。别省这几个元件,我有个朋友的鸽舍系统就是雷雨天没做保护,一个浪涌把主控和485芯片全带走了。
复位电路用经典的RC复位加按键复位。STM32的NRST引脚内部有上拉,外部接一个100nF电容到地,再并联一个复位按键。防抖电路就是在按键两端并联一个100nF电容,硬件消抖比软件消抖可靠,尤其是复位这种关键操作。
2.3 传感器电路细节
DHT11的电路很简单,数据线接一个4.7K到10K的上拉电阻到3.3V。但要注意,DHT11对时序敏感,如果你用RTOS或者中断频繁,读出来的数据可能出错。我的做法是读DHT11的时候关中断,读完再开。
HX711称重电路是料仓重量检测的核心。HX711的A通道接称重传感器的四根线,注意激励电压用5V还是3.3V要看传感器规格。我用的5kg量程传感器,激励5V,输出灵敏度1mV/V,满量程输出5mV。HX711内部增益128倍,ADC分辨率24位,理论上能分辨到微克级,但实际受机械结构和温漂影响,稳定精度在几克左右。电路上,HX711的AVDD和DVDD之间接一个0.1uF电容,REF和AGND之间接一个0.1uF电容,这些去耦电容不能省。
咪头差分电路用于声音检测,比如检测鸽子叫声或者异常响动。咪头输出信号很微弱,需要差分放大。我用的是两级放大,第一级用LM358做差分放大,增益100倍,第二级再做一次放大和滤波。差分放大的好处是抑制共模噪声,鸽舍里电机噪声大,单端放大很容易被干扰淹没。
2.4 电机驱动与隔离
五线四相步进电机用ULN2003驱动是最简单的方案。五线四相电机的五根线,一根是公共端接12V,另外四根是相线,分别接ULN2003的四个输出。ULN2003内部有续流二极管,驱动感性负载没问题。但要注意,ULN2003的输入是3.3V逻辑,STM32的GPIO直接驱动没问题,但如果你用5V单片机,要加电平转换。
电机和主控之间最好做光耦隔离。我用的是PC817,四路分别隔离四个相线控制信号。隔离之后,电机侧的噪声不会串到主控侧。实测不加隔离的时候,电机每走一步,ADC读数就跳一下;加了隔离之后,ADC读数稳定多了。
485自动收发电路也值得说一下。传统485收发需要一根DE/RE控制线,软件上要来回切换。自动收发电路利用三极管的开关特性,发送时自动拉高DE,发送完自动拉低。具体电路是TX线接三极管基极,集电极接DE和RE,发射极接地。这样软件上就当普通串口用,不用管方向控制。但要注意,自动收发电路在高速率下可能来不及切换,115200以上建议还是用带方向控制的方案。
3. 软件架构与核心功能实现
3.1 开发环境搭建
开发环境我用VSCode加PlatformIO,也试过Keil和STM32CubeIDE。VSCode的好处是编辑体验好,插件丰富,配合PlatformIO可以一键编译下载。如果你习惯Keil,用Keil 5加STM32芯片包也行,芯片包安装就是下载对应的DFP包,双击安装,然后在Keil里选对应的器件。
用VSCode搭建STM32开发环境,需要装Cortex-Debug插件和STM32的编译工具链。J-Link下载的话,在launch.json里配置好设备型号和接口速度。我一般设成SWD接口,速度4000kHz,稳定又够快。如果你用ST-Link,配置类似,把interface改成stlink就行。
有个坑要注意,STM32默认启用JTAG,会占用PB3、PB4、PA15这几个引脚。如果你这些引脚要当普通GPIO用,得先禁用JTAG。标准库里的做法是调用GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE),HAL库是在初始化时配置复用功能。禁用JTAG后SWD还能用,不影响下载调试。
3.2 定时器与喂食控制
喂食控制的核心是定时器。我用TIM3做喂食定时,配置成1ms中断一次,在中断里累加计数,到设定时间就触发下料。下料量通过步进电机转动的步数控制,比如转200步对应下料10克,这个比例要实际标定。
步进电机的驱动时序用定时器PWM或者GPIO翻转都行。我用TIM2的四个通道输出PWM,但步进电机需要的是脉冲序列而不是PWM波,所以实际上是用定时器中断翻转GPIO。八拍模式比四拍模式运行更平滑,但力矩稍小。五线四相电机用八拍驱动,顺序是A-AB-B-BC-C-CD-D-DA。
喂食逻辑里有个细节,料仓重量检测和电机下料要联动。我的做法是:先读HX711得到当前料仓重量,然后启动电机下料,同时持续读重量,当重量减少到目标值就停止电机。这样比单纯按步数下料更准,因为料仓的流动性会变化,同样的步数在不同料量下出的料不一样。
3.3 归巢检测与超声波测距
归巢检测我用了两种方案做冗余。一种是红外对管,装在入口两侧,鸽子进出遮挡光线就计数。另一种是超声波测距,装在鸽舍内部,检测特定位置有没有鸽子。STM32超声波测距用定时器捕获模式,HC-SR04的Trig引脚给10us高电平,Echo引脚返回高电平,高电平持续时间就是距离换算的依据。声速按340m/s算,距离等于高电平时间乘以340再除以2。
定时器捕获测频率也是类似原理。我用TIM4的输入捕获功能,配置成上升沿捕获,捕获到上升沿时读CCR值,两次捕获的差值就是周期,频率就是周期的倒数。这个功能可以用来检测鸽子的活动频率,或者配合咪头电路做声音频率分析。
提示:超声波测距要注意温度补偿,声速随温度变化,公式是v=331.4+0.6T,T是摄氏度。DHT11测到的温度可以直接用来修正。
3.4 巴法云接入与远程查看
巴法云接入用ESP8266或者ESP32做透传,STM32通过UART发AT指令控制。巴法云的MQTT协议,需要先在产品页面创建主题,然后设备用ClientID和用户名密码连接。STM32这边把温湿度、料仓重量、归巢次数这些数据打包成JSON,通过串口发给ESP8266,ESP8266再发到巴法云。
这里有个坑,STM32的UART和ESP8266通信,波特率要匹配,一般用115200。但有些ESP8266固件默认波特率是74880或者9600,要先发AT指令确认。另外,AT指令的响应有延迟,不能发一条等一条死等,要用状态机或者超时重试。我一开始用阻塞式发送,网络不好的时候整个系统卡死,后来改成非阻塞加超时,稳定多了。
手机端用巴法云自带的小程序或者APP,能看到实时数据,也能下发控制指令。比如远程启动喂食、开关风扇。指令下发到STM32后,STM32解析JSON,执行对应动作,再回传执行结果。
4. 常见问题与排查技巧实录
4.1 系统不稳定与复位问题
系统跑着跑着复位,这是嵌入式项目最常见的毛病。排查思路从电源开始。先用示波器看3.3V轨,如果电机启动时有明显跌落,那就是电源功率不够或者滤波不足。我的经验是,步进电机启动瞬间电流能到1A以上,如果你的5V电源只给500mA,肯定扛不住。换2A以上的电源,加大输出电容,问题基本能解决。
如果电源没问题,看复位引脚。NRST引脚如果走线太长,容易耦合噪声导致误复位。解决办法是在NRST靠近芯片的地方加100nF电容,走线尽量短。还有看门狗,如果开了独立看门狗但喂狗不及时,也会复位。调试阶段可以先关看门狗,稳定后再开。
4.2 通信丢包与CAN连不上
RS485丢包,先查终端电阻。485总线两端各接一个120欧姆终端电阻,中间节点不接。如果终端电阻没接或者接多了,信号反射严重,丢包率飙升。再查共地,485是差分信号,但两端设备如果不共地,共模电压可能超出收发器范围。用万用表量一下A、B线对地电压,正常应该在0到5V之间。
CAN通信突然连不上,常见原因是波特率不匹配或者终端电阻问题。CAN总线两端也要各接一个120欧姆电阻。另外,CAN_H和CAN_L接反了也连不上,这个低级错误我犯过,查了半天。还有,如果总线上有节点断电,可能拉低总线,导致整个网络瘫痪,所以最好用带隔离的CAN收发器。
4.3 传感器读数异常
DHT11读出来全是0或者全是1,先查上拉电阻。没有上拉电阻或者阻值太大,数据线拉不高。再查时序,DHT11对延时敏感,如果你用了系统滴答定时器做延时,注意别被其他中断打断。我的做法是读DHT11时关中断,用NOP做微秒延时。
HX711读数跳动大,先查机械结构。称重传感器安装要保证受力方向正确,不能有侧向力。再查屏蔽,传感器信号线要用屏蔽线,屏蔽层单端接地。软件上做滑动平均滤波,取10次读数的平均值,跳动能明显减小。如果还跳,检查HX711的供电,AVDD和DVDD要干净,加LC滤波。
4.4 屏幕显示与ILI9341初始化
ILI9341读ID是0xA1A1,前面说了这是正常的。但如果屏幕完全不亮,先查背光。背光引脚BLK要接高电平或者PWM调光,不接背光屏幕是黑的但实际在工作。再查SPI接线,SCK、MOSI、CS、DC、RST这几根线不能接错。RST复位引脚要先拉低再拉高,给屏幕一个复位脉冲。
刷屏慢的话,检查SPI时钟频率。ILI9341的SPI最高能到40MHz左右,但实际受走线影响,我一般设成18MHz或者9MHz。如果你用硬件SPI,配置好分频系数;用软件SPI的话,翻转GPIO的速度就是瓶颈,刷全屏会明显卡顿。
4.5 问题速查表
| 现象 | 可能原因 | 排查方法 | 解决措施 |
|---|---|---|---|
| 系统频繁复位 | 电源跌落、看门狗、NRST干扰 | 示波器看3.3V轨、查喂狗、查NRST电容 | 加大电源功率、及时喂狗、NRST加电容 |
| 485丢包 | 终端电阻、共地、波特率 | 量A/B对地电压、查电阻 | 两端接120欧、共地、匹配波特率 |
| 电机干扰ADC | 未隔离、滤波不足 | 电机转时看ADC读数 | 光耦隔离、加滤波电容 |
| DHT11读数错 | 上拉电阻、时序被打断 | 查上拉、关中断读 | 加4.7K上拉、读时关中断 |
| 屏幕不亮 | 背光、接线、复位 | 查BLK、查SPI线、查RST | 接背光、核对接线、给复位脉冲 |
| CAN连不上 | 波特率、终端电阻、接线 | 查波特率、查120欧、查H/L | 匹配波特率、接电阻、纠正接线 |
5. 设计手册与实物制作经验
5.1 设计手册该写什么
设计手册不是把代码贴一遍就完事。我写手册的习惯是分五部分:系统概述、硬件设计、软件设计、调试记录、物料清单。系统概述讲清楚做什么、为什么这么做。硬件设计放原理图和PCB布局要点,关键网络标号要标注。软件设计放流程图和核心代码片段,不用全贴,但关键算法要写清楚。调试记录是最有价值的部分,把你遇到的问题和解决方法记下来,别人少走弯路。物料清单列清楚型号、数量、购买渠道,方便复现。
PCB布局有几个原则。电源部分和信号部分分区,避免干扰。晶振靠近芯片,走线尽量短,下面不要走其他信号线。去耦电容靠近芯片电源引脚,每个电源引脚配一个100nF。电机驱动和主控之间留隔离带,或者干脆分两块板。
5.2 实物组装与调试顺序
组装不要一次全焊完再上电,要分步调试。第一步,只焊电源部分,上电测各路电压是否正常。第二步,焊主控和最小系统,烧录一个LED闪烁程序,确认主控能工作。第三步,焊显示部分,点亮屏幕。第四步,焊传感器,逐个读数据。第五步,焊执行机构,测试电机和继电器。第六步,联调通信。
这个顺序的好处是,每一步只引入一个新变量,出问题容易定位。我见过有人一次全焊完,上电不亮,查了两天发现是电源芯片焊反了。分步调试虽然慢一点,但总体效率高。
5.3 外壳与防护
鸽舍环境潮湿、有粉尘、有氨气,外壳防护不能马虎。我用的是防水接线盒,开孔处用防水接头。电路板喷三防漆,防潮防腐蚀。屏幕加一块亚克力面板,边缘打胶密封。传感器外露部分做防尘处理,DHT11加透气防尘罩,称重传感器做防潮涂层。
提示:鸽舍氨气浓度高,普通排针和插座容易氧化接触不良,建议用镀金排针或者直接焊接。
5.4 成本控制与替代方案
整套系统物料成本我控制在200元以内。主控15元,屏幕25元,DHT11五元,HX711加传感器20元,步进电机加驱动15元,485模块10元,ESP8266十五元,电源和外壳杂项50元左右。如果你预算更紧,屏幕可以换成LCD1602,几块钱,但显示信息少。远程通信可以用蓝牙模块替代,便宜但距离短。
替代方案要考虑兼容性。比如HX711可以用ADS1232替代,精度更高但价格贵。步进电机可以用舵机替代,控制简单但力矩小。选替代方案的时候,先确认软件驱动能不能复用,不然改代码的时间成本可能比省下的钱还多。
6. 后续扩展与个人体会
这套系统做完之后,我又陆续加了一些功能。比如用正交信号生成电路做电机编码器反馈,实现闭环控制,下料精度从正负5克提升到正负1克。还加了电流采样电路,监测电机电流,堵转时自动停机保护。电流采样用霍尔传感器或者采样电阻加运放,我用的采样电阻加差分放大,成本低,精度够用。
EMI滤波电路也值得加。鸽舍附近如果有大功率设备,电源线上会有高频噪声,加一个共模电感和X电容、Y电容组成的EMI滤波器,能明显改善系统稳定性。这个在工业环境里是标配,家用环境如果干扰不大可以省。
我个人在实际操作中的体会是,做这类项目,硬件是骨架,软件是血肉,但真正决定成败的是对应用场景的理解。你得知道鸽子什么时候吃食、什么时候归巢、鸽舍环境有什么特点,才能设计出好用的系统。纯技术堆砌做出来的东西,参数再漂亮,养鸽人用两天就不想用了。所以多跟实际使用者聊,比多看几篇论文管用。
最后分享一个小技巧:调试阶段在关键代码处加串口打印,把状态机每一步都打出来,出问题的时候看日志比单步调试快得多。但正式版要把打印关掉或者降级,不然串口输出会拖慢系统响应。这个度自己把握,我的做法是定义一个DEBUG宏,调试时打开,发布时注释掉。