ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于STM32的智能鸽子驯养系统:从电路设计到代码实现的完整指南

基于STM32的智能鸽子驯养系统:从电路设计到代码实现的完整指南 1. 项目缘起与整体设计思路1.1 为什么会想到做鸽子驯养系统养鸽子这件事外行看热闹内行看门道。我接触信鸽驯养差不多有六七年时间从最开始在阳台搭个简易棚到后来帮朋友做鸽舍环境改造踩过的坑真不少。传统养鸽最大的问题就是“凭感觉”——什么时候喂、喂多少、鸽舍温湿度怎么样、光照够不够、鸽子归巢有没有记录全靠人盯着。一旦养的数量上到几十只或者白天要上班根本顾不过来。这个基于STM32的智能鸽子驯养系统核心目标就是把“凭感觉”变成“看数据”。它要解决的具体问题有这么几个第一定时定量投喂避免鸽子过胖或者抢食不均第二鸽舍环境监测温度、湿度、光照、氨气浓度这些指标实时掌握第三归巢检测通过红外或者RFID方式记录鸽子进出第四远程告警环境异常或者设备故障时能及时知道。整套系统是实物级别的包含电路设计、PCB打样、程序开发和一份完整的设计手册适合电子类专业学生做毕业设计也适合有一定动手能力的养鸽爱好者自己复现。从技术选型上说STM32是绕不开的选择。原因很直接外设资源丰富、资料多、成本低、生态成熟。你要做定时器PWM控制电机、要做ADC采集传感器、要做USART串口通信、要做RTC实时时钟STM32F103系列一颗芯片全搞定价格还不到十块钱。相比之下用51单片机做同样的事情外设不够用定时器精度也吃紧用树莓派或者ESP32成本上去了而且对于纯控制类任务来说有点杀鸡用牛刀。所以这个项目的主控就定在STM32F103C8T6也就是大家常说的“最小系统板”那颗芯片。1.2 系统整体架构拆解整个系统我把它分成四个层次来设计这样思路清晰后面调试也好定位问题。感知层负责采集环境数据和鸽子活动信息。包括DHT22温湿度传感器、光敏电阻模块、MQ-135氨气传感器、红外对射传感器装在鸽舍入口用于归巢检测。这些传感器输出的信号有数字的也有模拟的数字的走GPIO模拟的走ADC。控制层STM32主控负责所有逻辑判断和决策。它要读传感器数据、驱动执行机构、管理时间任务、处理串口通信。这里我用的是标准库开发因为对于初学者来说标准库比HAL库更直观寄存器操作一目了然而且网上资料多遇到问题好查。执行层包括舵机控制的投喂机构、继电器控制的补光灯和排风扇、无源蜂鸣器做的声光告警。投喂机构我用的是SG90舵机加一个旋转料盘舵机转一个角度就放出一份饲料结构简单可靠。交互层一块0.96寸OLED显示屏做本地数据显示一个EC11旋转编码器做参数设置另外通过HC-05蓝牙模块或者CH340 USB转串口和上位机通信把数据传到电脑或者手机上看。这个架构的好处是模块化程度高每个层之间通过明确的接口通信调试的时候可以一层一层单独验证。比如你先单独测传感器读数对不对再测舵机转动角度准不准最后再联调。不要一上来就全部焊好写完整程序那样出了问题你根本不知道是哪里的毛病。1.3 关键设计决策与取舍在方案设计阶段有几个地方我反复权衡过这里把思考过程分享出来供大家参考。第一个决策投喂机构用舵机还是步进电机舵机便宜、控制简单、扭矩够用缺点是角度范围有限一般0到180度而且长时间堵转容易烧。步进电机精度高、可以连续旋转但需要驱动器成本和复杂度都上去了。考虑到投喂动作其实就是一个“转一个固定角度放料”的简单动作舵机完全够用所以选了舵机。实际用下来SG90在5V供电下扭矩大约1.8kg·cm带动一个直径8cm的塑料料盘毫无压力。第二个决策归巢检测用红外还是RFID红外对射便宜一对才几块钱但只能检测“有东西经过”不能区分是哪只鸽子。RFID可以给每只鸽子戴脚环实现个体识别但成本高而且读写距离和方向性需要仔细调。这个项目定位是“驯养系统”而不是“赛鸽计时系统”所以红外对射够用了。如果你要做赛鸽归巢计时那必须上RFID这是另一个量级的项目。第三个决策通信方式用蓝牙还是WiFi蓝牙模块HC-05便宜、配对简单、手机APP开发也容易缺点是传输距离短10米左右穿墙能力差。WiFi模块比如ESP8266可以联网、可以远程访问但需要配置路由器对不熟悉网络的人有门槛。考虑到鸽舍一般就在家里阳台或者楼顶蓝牙距离够用所以选了蓝牙。如果你鸽舍在郊区院子里那还是上WiFi或者4G模块更靠谱。第四个决策电源方案怎么定整个系统需要5V舵机、传感器、3.3VSTM32、OLED两种电压。我用的是12V直流适配器输入然后通过LM2596降压到5V再用AMS1117-3.3降到3.3V。这里要注意舵机启动瞬间电流可能冲到1A以上所以5V这一路的电容要够大我用了两个470uF电解电容并联实测舵机动作时电压波动控制在0.2V以内。另外STM32的ADC参考电压用的是VDDA如果3.3V不稳ADC读数就会跳所以AMS1117输出端也加了100uF和0.1uF的滤波电容。2. 核心电路设计与关键细节2.1 STM32最小系统电路最小系统是整个板子的心脏这部分如果画错了后面全白搭。STM32F103C8T6最小系统包含这几个部分电源、复位、晶振、启动模式选择、调试接口。电源部分VDD和VSS引脚每一对都要加0.1uF去耦电容这个不能省。我见过有人为了省事只在整板放一个104电容结果ADC采集出来的数据跳得跟心电图一样。正确的做法是每个电源引脚旁边就近放一个0.1uF然后整板再放一个10uF的钽电容做储能。复位电路用经典的RC复位10k电阻上拉到3.3V100nF电容下拉到地再加一个复位按键。这里有个细节复位按键两端最好并联一个0.1uF电容做硬件消抖虽然STM32内部有复位滤波但外部加一个更稳妥。晶振电路用8MHz无源晶振加两个20pF负载电容。负载电容的值不是随便选的要根据晶振规格书上的负载电容CL来算。公式是CL (C1 * C2) / (C1 C2) Cstray其中Cstray是PCB走线寄生电容一般取3到5pF。如果晶振规格书要求CL12pF那么C1和C2大约取18到20pF。晶振尽量靠近芯片放置走线尽量短下面不要走其他信号线。启动模式选择BOOT0通过10k电阻下拉到地BOOT1也就是PB2也下拉到地这样默认从主闪存启动。如果你要串口下载程序把BOOT0跳到3.3V复位后进入系统存储器启动模式。调试接口我留了SWD四针接口3.3V、GND、SWDIO、SWCLK。SWD比JTAG省引脚而且速度够用。这里注意如果你在程序里禁用了JTAG但保留了SWD需要调用GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)这样PA15、PB3、PB4可以当普通GPIO用同时SWD还能正常下载。2.2 传感器接口电路设计DHT22温湿度传感器是单总线协议数据线需要接一个4.7k到10k的上拉电阻到3.3V。这个上拉电阻不能省否则信号上升沿太慢STM32读出来的数据全是错的。我一开始用10k读数据偶尔失败换成4.7k之后稳定了。另外DHT22的供电电压是3.3V到5V我直接接3.3V这样数据线电平匹配不需要电平转换。光敏电阻模块我用的是GL5528加一个10k分压电阻输出模拟电压接到STM32的ADC引脚。这里有个坑光敏电阻的阻值范围很大暗电阻可能到1M欧亮电阻只有几k欧所以分压电阻选10k的话暗光下ADC读数接近0亮光下接近4095动态范围还行。但如果你想要更线性的响应可以用对数放大电路不过对于“判断白天还是晚上”这个需求来说简单的分压就够了。MQ-135氨气传感器输出也是模拟电压但它的输出阻抗比较高直接接ADC引脚会导致采样不准。正确做法是加一个电压跟随器用LM358运放搭一个同相放大器增益设为1起到阻抗匹配的作用。LM358便宜好买但注意它的输出摆幅不能到轨到轨所以供电要给5V输出经过分压后再进ADC或者直接用轨到轨运放比如MCP6002。红外对射传感器我用的是E18-D80NK输出是数字信号检测到遮挡输出低电平。这个传感器内部是集电极开路输出所以需要接一个10k上拉电阻到3.3V。安装的时候要注意发射端和接收端要对准间距不要超过80cm否则灵敏度不够。鸽舍入口一般也就20到30cm宽完全够用。2.3 执行机构驱动电路舵机驱动看起来简单其实有讲究。SG90舵机有三根线棕色地、红色5V、橙色信号。信号线直接接STM32的PWM输出引脚就行但要注意舵机的工作电流。空载的时候大概100mA堵转的时候能到1A以上。如果你用STM32板子上的3.3V稳压器给舵机供电大概率会烧掉稳压器。所以舵机的5V必须从独立的5V电源取而且STM32和舵机要共地。继电器模块我用的是光耦隔离的继电器板输入控制信号接STM32的GPIO输出控制220V的补光灯和排风扇。这里安全第一强电和弱电必须物理隔离PCB上强电走线和弱电走线间距至少3mm而且强电部分要加绝缘漆或者灌封。如果你没有强电操作经验建议补光灯和排风扇直接用12V直流的风扇和LED灯带这样整个系统都是安全电压调试起来也放心。无源蜂鸣器驱动电路很多人直接用GPIO推结果声音小得跟蚊子叫一样。无源蜂鸣器需要方波驱动而且驱动电流可能超过GPIO的20mA上限。正确做法是用一个NPN三极管做开关比如S8050基极通过1k电阻接GPIO集电极接蜂鸣器负极蜂鸣器正极接5V发射极接地。同时蜂鸣器两端要反向并联一个续流二极管比如1N4148防止关断时反向电动势打坏三极管。PWM频率一般设在2kHz到4kHz之间人耳最敏感声音最响。2.4 电源电路与抗干扰设计电源部分我前面提了LM2596和AMS1117的组合这里展开说细节。LM2596是降压型开关电源芯片输入12V输出5V效率大概80%左右。它的外围需要一个33uH的电感和一个肖特基二极管比如SS34输出电容建议用低ESR的电解电容或者钽电容。反馈引脚FB的电阻分压比决定了输出电压Vout 1.23 * (1 R2/R1)。要输出5VR1取1kR2取3.06k实际用3k和1k组合输出大约4.92V可以接受。AMS1117-3.3是线性稳压器输入5V输出3.3V压差1.7V在500mA负载下功耗大约0.85W不加散热片的话芯片温度会到60度左右有点烫但还能用。如果你带的负载比较重比如OLED加蓝牙加传感器全开电流可能到200mA那功耗就是0.34W温度还好。建议在AMS1117的输入输出端各加一个10uF钽电容和一个0.1uF陶瓷电容抑制高频噪声。抗干扰方面STM32的ADC采集最容易受干扰。除了前面说的去耦电容还可以在ADC输入引脚加一个RC低通滤波比如1k电阻加0.1uF电容截止频率大约1.6kHz对于温湿度、光照这些慢变信号完全够用。另外模拟地和数字地最好分开走最后在电源入口处单点共地。如果PCB空间允许模拟部分下面铺铜做屏蔽。还有一个容易被忽略的地方STM32的BOOT0引脚和NRST引脚如果走线太长容易引入干扰导致误复位。这两个引脚尽量靠近芯片走线短而粗。如果实在要走长线加一个100pF电容到地做滤波。3. 软件架构与核心代码实现3.1 开发环境搭建与工程配置开发环境我用的是Keil MDK5配合STM32F1的器件支持包。安装的时候有个坑Keil5默认不包含STM32的器件包需要单独下载安装。你可以从Keil官网下载STM32F1xx_DFP双击安装就行。另外如果你电脑上同时装了Keil C51和Keil MDK它们可以共存但要注意安装顺序——先装C51再装MDK否则C51的注册信息会被覆盖。如果已经装反了卸载重装或者手动合并TOOLS.INI文件也可以解决。工程配置里几个关键设置第一在Options for Target的Target标签页勾选Use MicroLIB这样printf函数才能重定向到串口。第二在C/C标签页的Define里加上USE_STDPERIPH_DRIVER这样标准库的外设驱动才会被编译。第三在Debug标签页选ST-Link Debugger然后点Settings在Flash Download里勾选Reset and Run这样下载完程序自动运行不用手动按复位键。如果你习惯用VSCode开发也可以配置STM32的开发环境。需要安装Cortex-Debug插件和ARM GCC工具链然后写一个Makefile或者用STM32CubeMX生成工程。VSCode的好处是代码补全和跳转比Keil强但调试体验还是Keil更顺手。我一般是Keil写代码和调试VSCode用来看代码和搜索。3.2 定时器与PWM驱动舵机STM32F103C8T6有四个通用定时器TIM2、TIM3、TIM4、TIM5每个都有四个独立通道。我用TIM3的通道1PA6来输出PWM驱动舵机。舵机的控制信号是周期20ms、脉宽0.5ms到2.5ms的方波对应角度0到180度。计算过程STM32系统时钟72MHzTIM3挂载在APB1总线上APB1预分频系数为2所以TIM3时钟是36MHz。要得到20ms周期预分频系数PSC和自动重装载值ARR满足(PSC1)*(ARR1)/36MHz 20ms。取PSC71则计数频率为36MHz/72500kHz周期2us。ARR取9999则周期为(99991)*2us20ms。这样PWM分辨率是2us对应角度分辨率是180/20000.09度完全够用。脉宽设置CCR值等于脉宽除以2us。0.5ms对应CCR2502.5ms对应CCR1250。所以角度0到180度对应CCR从250到1250线性变化。代码里写一个函数SetServoAngle(uint8_t angle)内部计算CCR 250 angle * (1000/180)然后调用TIM_SetCompare1(TIM3, CCR)就行。这里有个注意事项舵机上电瞬间可能会抖动因为PWM还没稳定。解决办法是在初始化的时候先把GPIO拉低等定时器配置好了再使能PWM输出。另外舵机不要频繁大角度来回转SG90的塑料齿轮很容易扫齿。投喂动作一天也就几次问题不大。3.3 ADC多通道采集与滤波STM32F103C8T6有两个ADC12位精度最多18个通道。我用ADC1的通道0PA0接光敏电阻通道1PA1接MQ-135通道2PA2接一个电位器用于手动调节阈值。ADC配置步骤第一使能ADC1和GPIOA时钟。第二配置PA0、PA1、PA2为模拟输入模式。第三配置ADC为独立模式、连续转换、扫描模式使能DMA。第四配置DMA通道1从ADC数据寄存器搬到内存数组。第五使能ADC的DMA请求启动ADC。为什么要用DMA因为如果你用轮询方式读ADC每次转换都要等EOC标志CPU占用率高而且多通道切换的时候容易读到旧数据。用DMA自动搬运CPU只需要在需要的时候读内存数组就行效率高很多。滤波方面硬件上我已经加了RC低通软件上再用滑动平均滤波。具体做法是开一个长度为10的数组每次新数据进来就替换最旧的数据然后求平均值。这样既能平滑数据又不会引入太大延迟。对于温湿度这种慢变信号还可以用一阶滞后滤波Y(n) α*X(n) (1-α)*Y(n-1)α取0.1到0.3之间。我实测下来滑动平均加一阶滞后组合使用ADC读数波动从±20降到±3以内。3.4 定时任务调度与看门狗整个系统需要同时处理多个任务读传感器、刷新OLED、检测按键、控制投喂、串口通信。如果全部塞在while(1)里顺序执行 timing会乱而且某个任务卡住整个系统就死了。所以我用了一个简单的时间片轮询调度器。具体做法用SysTick定时器产生1ms中断在中断里给每个任务计数器加1。主循环里判断计数器是否达到设定值到了就执行对应任务然后清零计数器。比如传感器任务每500ms执行一次OLED刷新每200ms一次按键扫描每20ms一次投喂检查每1秒一次。这样每个任务都能按时执行互不干扰。看门狗用独立看门狗IWDG时钟源是内部40kHz的LSI。预分频系数取64重装载值取625则溢出时间 (64 * 625) / 40kHz 1秒。主循环里每500ms喂一次狗如果程序跑飞了1秒后看门狗复位。这里注意喂狗不要放在定时器中断里否则中断还在跑但主循环卡死了看门狗照样被喂就失去保护意义了。喂狗必须放在主循环里确保主循环正常运行。3.5 串口通信与数据上报串口我用USART1波特率115200接CH340模块到电脑或者接HC-05蓝牙模块到手机。数据上报格式我设计成简单的文本协议每行一条数据字段用逗号分隔方便解析。比如$DATA,25.6,68.2,45,120,1,0#分别表示温度、湿度、光照ADC值、氨气ADC值、归巢状态、投喂状态。上位机收到后按逗号分割就能解析。printf重定向在标准库工程里需要重写fputc函数把字符输出到USART1。代码很简单int fputc(int ch, FILE *f) { USART_SendData(USART1, (uint8_t)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TC) RESET); return ch; }注意要勾选Use MicroLIB否则fputc不会被正确链接。另外如果你同时用了半主机模式需要注释掉#pragma import(__use_no_semihosting)相关的代码否则程序会卡在BKPT指令。蓝牙模块HC-05的配置默认波特率是9600需要发AT指令改成115200。接线的时候HC-05的TXD接STM32的PA10USART1_RXRXD接PA9USART1_TXVCC接5VGND共地。注意HC-05的RXD是3.3V电平STM32的TX输出是3.3V可以直接连不用电平转换。4. 实物组装与调试实录4.1 PCB打样与焊接注意事项PCB我用的是嘉立创打样双面板尺寸10cm x 8cm绿色阻焊白色丝印。画板的时候有几个地方要特别注意第一电源走线要粗12V和5V的主干走线至少40mil3.3V至少20mil。第二晶振下面不要走任何信号线最好铺地铜。第三SWD接口放在板子边缘方便插调试器。第四舵机和继电器的接口用大间距的端子比如KF301-2P方便接粗线。焊接顺序先焊矮的元件再焊高的。具体是先焊STM32芯片如果用贴片的话再焊电阻电容再焊晶振、复位按键再焊排针、端子最后焊OLED和蓝牙模块。STM32F103C8T6是LQFP48封装引脚间距0.5mm手焊有点难度。我的经验是先用烙铁在焊盘上上一点锡然后用镊子把芯片放正再用烙铁把引脚一个一个压焊。如果连锡了用吸锡带清理。助焊剂要多用好的助焊剂能让焊接轻松很多。焊接完成后先不要上电用万用表测一下3.3V和5V对地有没有短路。确认没有短路再上电上电后先测电压对不对3.3V应该在3.2到3.4之间5V在4.8到5.2之间。然后用ST-Link连接看能不能识别到芯片。如果识别不到检查SWD接线和BOOT0电平。4.2 分模块调试与联调调试一定要分模块来不要一上来就全部联调。我的调试顺序是这样的第一步最小系统验证。写一个最简单的LED闪烁程序下载进去看LED有没有闪。如果闪了说明最小系统、下载电路、时钟配置都没问题。第二步串口验证。写一个串口发送程序电脑上用串口助手看能不能收到数据。如果收不到检查波特率、接线TX和RX有没有接反、串口助手有没有打开对应端口。第三步传感器验证。单独读DHT22看温湿度数据对不对。如果读出来是0或者255检查上拉电阻和时序。DHT22的时序对延时很敏感如果STM32的延时函数不准读数据会失败。我建议用SysTick做微秒级延时不要用for循环空跑因为编译器优化等级不同for循环的延时时间会变。第四步执行机构验证。单独控制舵机转0度、90度、180度看动作是否到位。如果舵机抖动或者不动检查PWM频率和脉宽以及5V供电是否足够。第五步联调。把所有模块接上跑完整程序观察OLED显示、串口输出、舵机动作是否正常。联调的时候最容易出现的问题是电源不够比如舵机一动OLED就闪一下这是5V被拉低了。解决办法是给5V加更大的电容或者给舵机单独供电。4.3 常见问题与排查技巧调试过程中我遇到不少问题这里整理成速查表方便大家对照排查。问题现象可能原因排查方法解决办法程序下载失败BOOT0电平不对测BOOT0对地电压BOOT0接3.3V进入下载模式OLED不显示I2C地址错误用I2C扫描程序找地址修改代码中的从机地址DHT22读数失败上拉电阻太大测数据线空闲电平换成4.7k上拉舵机抖动电源电流不足示波器看5V纹波加470uF电容或独立供电ADC读数跳动参考电压不稳测VDDA电压加去耦电容软件滤波串口乱码波特率不匹配检查两边波特率统一设为115200看门狗误复位喂狗间隔太长计算溢出时间缩短喂狗周期或加大重装载值蓝牙连接不上波特率不对发AT指令测试用ATUART改波特率还有一个坑STM32的PA15、PB3、PB4默认是JTAG引脚如果你要用它们做普通GPIO必须禁用JTAG。但禁用JTAG后SWD还能用所以下载程序不受影响。代码里加一句GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)就行。我一开始不知道这个PB3接蜂鸣器死活不响查了半天才发现是JTAG占用了。4.4 投喂机构机械结构优化投喂机构我前后改了三个版本。第一版用舵机直接带一个挡板挡板打开饲料就掉下来。问题是饲料容易卡住而且每次掉落的量不稳定。第二版改成旋转料盘舵机转一个角度料盘上的孔对准出料口饲料掉下去。这个方案好一些但孔的大小和数量需要根据饲料颗粒大小调整。我用的鸽子饲料颗粒直径大约3到4mm所以料盘上的孔直径取8mm深度10mm每次转60度放一份大约15克。第三版在料盘下面加了一个振动马达每次放料前振动2秒防止饲料结拱。振动马达用手机里的那种扁平马达3V供电通过一个NPN三极管驱动基极接STM32的GPIO。实测下来加振动之后放料成功率从80%提升到98%以上。料盘和舵机的连接用的是一个3D打印的联轴器如果你没有3D打印机也可以用热熔胶把舵机臂和料盘粘死但那样就不能调角度了。我建议还是画个简单的STL文件找打印店打一个成本也就几块钱。5. 设计手册编写与项目扩展5.1 设计手册应该包含哪些内容一份完整的设计手册不是把代码和原理图堆上去就完事了它应该让一个完全不懂的人也能照着做出来。我写的手册包含这几个章节第一章是项目概述讲清楚这个系统是干什么的、有哪些功能、适合什么场景。第二章是系统框图用方块图展示各个模块之间的关系。第三章是硬件设计包括原理图、PCB布局图、元器件清单BOM表。BOM表要写清楚每个元件的型号、封装、数量、购买链接或者替代型号。第四章是软件设计包括程序流程图、关键代码解析、通信协议说明。第五章是组装调试按步骤说明怎么焊接、怎么烧录、怎么测试。第六章是常见问题就是我前面整理的那个速查表。写手册的时候要注意截图要清晰标注要明确。比如原理图上每个网络标号都要看得清PCB图要标出元件位置。代码解析不要贴大段代码只贴关键部分然后配上注释和说明。我见过一些毕业设计手册代码贴了五十页结果关键的中断服务函数反而没讲清楚这就本末倒置了。5.2 从驯养系统到赛鸽计时系统的升级路径这个项目做完了如果你还想继续折腾可以往赛鸽计时系统方向升级。核心改动是把红外对射换成RFID读写器给每只鸽子戴一个125kHz或者13.56MHz的电子脚环。当鸽子归巢经过读写器天线时系统记录脚环ID和时间戳然后通过蓝牙或者WiFi上传到手机APP。RFID读写器我推荐用MFRC522模块便宜、资料多、SPI接口。天线可以用PCB印刷天线或者铜线绕制。读写距离一般5到10cm所以要把天线装在鸽舍入口的通道两侧鸽子经过时刚好能读到。这里有个难点多只鸽子同时经过时可能冲突需要做防碰撞处理。MFRC522支持防冲突算法但需要仔细调参数。另外赛鸽计时对时间精度要求高STM32的RTC用外部32.768kHz晶振的话精度可以做到每天误差几秒以内。如果要更高精度可以加一个GPS模块做时间同步但成本就上去了。对于业余比赛来说RTC精度够用了。5.3 低功耗设计与电池供电方案如果鸽舍没有市电或者你想做一个便携版本那就需要考虑低功耗设计。STM32F103本身功耗不算低运行模式大概30mA睡眠模式可以降到几mA待机模式只有几uA。但传感器和舵机才是耗电大户DHT22每次测量大概1mA舵机动作瞬间1A这些都没法省。所以低功耗设计的思路是用大容量锂电池或者铅酸电池配合太阳能板充电。电池容量按每天耗电量算假设平均电流50mA一天24小时就是1200mAh考虑阴雨天备用电池至少选10Ah以上。太阳能板选10W到20W晴天一天能发40到80Wh够用了。软件上可以让STM32在不干活的时候进入睡眠模式用RTC闹钟或者外部中断唤醒。比如每10分钟醒来一次读传感器读完继续睡。舵机只在投喂时间动作其他时间断电。这样平均电流可以降到10mA以下电池续航能到一个月以上。5.4 上位机与手机APP的简单实现上位机我用Python写了一个简单的串口数据接收和可视化程序用pySerial读串口用matplotlib画实时曲线。代码不长大概一百行左右。核心逻辑就是开一个串口线程不断读数据解析后存到环形缓冲区然后定时刷新图表。手机APP可以用MIT App Inventor做拖拖拽拽就能搭一个蓝牙接收界面。或者用微信小程序通过蓝牙API连接HC-05显示数据和控制投喂。如果你不想写APP也可以用现成的蓝牙串口助手比如“蓝牙串口助手”或者“Serial Bluetooth Terminal”直接看数据就行。数据存储方面可以在电脑上把接收到的数据存成CSV文件然后用Excel或者Python做进一步分析。比如统计一周的温度变化曲线看看鸽舍环境是否稳定。这些数据对于优化驯养策略很有价值。5.5 我踩过的几个典型坑最后分享几个我在这个项目里踩过的坑希望大家能避开。第一个坑STM32的延时函数delay卡死。我一开始用for循环做微秒延时在默认的8MHz时钟下调好了后来把时钟改成72MHz延时就不准了DHT22直接读不出数据。后来改用SysTick做延时不管时钟怎么变延时都准确。所以延时函数一定要用硬件定时器不要用软件循环。第二个坑看门狗电路设计。我一开始把看门狗喂狗放在定时器中断里结果主循环卡死了中断还在跑看门狗一直被喂系统就不复位。后来把喂狗放到主循环问题解决。另外独立看门狗的时钟是内部LSI精度不高溢出时间会有偏差所以喂狗周期要留足余量比如溢出时间1秒喂狗周期设500ms。第三个坑485电路和串口3.3V转1.8V电平转换。这个项目其实没用到485但如果你要扩展成多鸽舍联网485是常用方案。SN65HVD230是3.3V的485收发器典型电路很简单但要注意终端电阻。总线两端各接一个120欧姆电阻中间节点不要接。另外485的A和B线要双绞最好加屏蔽层否则长距离通信误码率很高。第四个坑无源蜂鸣器驱动电路。我一开始直接用GPIO推蜂鸣器声音小得几乎听不见。后来加了S8050三极管和1N4148续流二极管声音立刻大了很多。PWM频率也很关键我试过1kHz、2kHz、4kHz最后发现2.7kHz左右声音最响。这个频率不是固定的不同蜂鸣器的谐振频率不一样你可以写个程序从1kHz扫到5kHz找到最响的那个频率。第五个坑STM32的ADC参考电压。我一开始用VDDA做参考但VDDA是从AMS1117出来的3.3V精度只有2%左右ADC读数误差比较大。后来改用外部基准芯片比如REF3033精度0.2%ADC读数就准多了。当然对于这个项目来说2%的误差也能接受但如果你要做精确测量外部基准是必须的。这个项目从画板子到写代码到组装调试前后花了大概三周时间中间断断续续改了很多版。现在系统跑得很稳每天定时投喂三次环境数据实时上传鸽子养得比以前好多了。如果你也在做类似的项目希望这些经验能帮你少走点弯路。
返回列表