自己做农业物联网相关项目有一阵子了手头这个基于STM32单片机的大棚温湿度环境参数监测无线蓝牙APP控制方案是帮一个朋友园区改造时沉淀下来的完整思路。标题看着长实际拆开就是三件事传感器采集环境数据、单片机做逻辑处理、蓝牙和APP负责无线交互与控制。这套东西做完后园区里的大棚湿度超标或者温度过高人不用再跑现场手机上一看就知道该不该掀膜、该不该启动风机。先说说这套方案适合谁。如果你是要做毕业设计的学生、想搞农业智能化的嵌入式开发者、或者只是想在老家大棚里低成本实现远程监测的实操派都可以直接参考。硬件成本控制在百元级别全程不需要接网线和路由器供电就靠一块电源适配器或者电池组部署起来比较灵活。文章后面我会把原理图设计思路、每个模块为什么这么选、单片机程序怎么一个个功能拆开写、以及APP调通的完整过程都捋一遍踩过的坑也会列出来方便你少走弯路。1. 整体方案设计与选型思路1.1 需求拆解这套系统到底解决什么问题农业大棚最大的痛点就是环境不可控。温度高了薄膜内壁全是水珠作物容易烂叶湿度太大又容易爆发灰霉病但是单纯开风口降温又可能让温度波动太大影响生长。人工管理靠经验看天吃饭稍微一疏忽就是成片的损失。基于这个背景系统需要四个核心能力第一实时采集大棚内的空气温湿度和土壤湿度第二把数据显示在本地屏幕上方便现场巡视的人一眼看到第三通过蓝牙把这些数据同步到手机APP上人不在棚里也能看第四APP上可以远程控制风机、水泵、补光灯这些执行设备不用跑回配电箱手动操作。既然是蓝牙方案而不是WiFi方案就要接受一个客观限制蓝牙的有效通信距离一般在10米到20米之间隔着一栋房子就没信号了。所以这套系统适合大棚管理房或者值班室离棚区不远、巡检半径不大的场景。对于这个前提蓝牙的价值就很突出——功耗低、配对快、不需要网络基础设施、手机自带蓝牙功能基本上零学习成本。1.2 系统拓扑与数据流向设计整个系统可以分成三段链路。第一段是感知层温湿度传感器挂在棚内离地面1.2米左右的位置这个高度基本是作物冠层所在区域数据最有代表性。土壤湿度传感器插在滴灌区边缘的根系密集区注意不要贴着滴灌头不然测出来永远都是过饱和状态。第二段是控制层STM32单片机作为核心它干的事情是定期轮询传感器、处理数据、刷新OLED屏幕同时管理蓝牙模块的收发状态。单片机是这套系统的调度室所有外部设备的动作都必须经过它来决定。第三段是交互层手机APP通过蓝牙模块和单片机通信。我把通信内容拆成两类一类是单向上报的环境数据帧以字符串形式发给APP另一类是双向的命令帧——APP下发控制指令给单片机单片机执行完再把设备状态回传确认。数据流的方向很明确传感器 - STM32 - 本地屏幕/蓝牙 - 手机APP手机APP - 蓝牙 - STM32 - 继电器 - 执行设备。这个闭环一旦建立人在办公室喝着茶就能掌握大棚里的一切。注意设计通信协议时不管是上行数据还是下行指令都要带帧头和校验位。后面程序部分我会用具体的例子说明为什么必须这么做做嵌入式通信最忌讳的就是裸发裸收。2. 硬件电路设计的核心要点2.1 主控芯片选型为什么是STM32而不是51单片机标题里直接点名STM32那就要说说为什么它不是51单片机。虽然51单片机做LED流水灯够用但做带通信协议、多传感器管理、实时控制的系统时51的短板很明显——没有硬件I2C和SPI串口只有一个中断资源紧张主频也低。我选的是STM32F103C8T6也就是大家俗称的蓝板。这芯片最大优势是性价比和生态。它的资源对于一个农业监测系统来说属于算力富裕的状态64引脚封装里有足够多的GPIO、3个串口、2个I2C、2个SPI、还有多个定时器。最关键是网上资料极多哪怕遇到疑难杂症基本都能找到前人填过的坑。如果开发者预算实在紧张可以考虑用STM32F030或者国产替代芯片但我的建议是别为了省那一两块钱折腾自己。F103的库函数和HAL库资料是最全的遇到问题排查起来效率高好几倍。评估一个项目的整体成本不能只算物料也要把调试时间算进去。2.2 传感器选型与接线细节DHT11还是SHT30需要认真对比大棚环境监测最基础的两个参数就是温度和湿度。市面上常用的传感器有DHT11、DHT22、SHT30这三种。传感器温度精度湿度精度通信方式单价区间实测评价DHT11±2℃±5%RH单总线2-4元便宜但湿度误差偏大DHT22±0.5℃±2%RH单总线8-12元性价比高推荐首选SHT30±0.3℃±2%RHI2C10-15元精度高但需要库支持这里有个很多新手会忽视的点DHT11的湿度精度是±5%RH大棚里如果湿度已经达到80%RH误差跨度可以到75%和85%的区别。这个误差在判断是否触发除湿逻辑时会导致系统频繁误动作。所以我强烈建议至少用DHT22起步不差钱直接上SHT30。DHT22的接线非常简单三根线VCC接3.3V或5VGND接地DATA接单片机任意一个GPIO引脚比如PB6。注意数据线需要接一个4.7kΩ到10kΩ的上拉电阻到VCC因为它是单总线开漏输出没有上拉电阻直接不干活。土壤湿度传感器我用的是电容式型号不敏感市面上几十块钱的都行。它输出的是模拟电压信号范围大概在0到3.3V之间接STM32的ADC输入引脚比如PA1。具体数值通过ADC转换后映射到0-100%的湿度百分比数值越大说明越湿润。2.3 执行设备控制电路继电器隔离与驱动设计执行设备是220V的风机和水泵让单片机的3.3V GPIO直接去控制220V交流电是绝对不行的。铁一般的安全红线数字地、模拟地、强电地必须隔离。我采用的方案是低电平触发的继电器模块控制信号经过光耦隔离再驱动继电器线圈。STM32的引脚输出高电平时光耦不导通继电器不动作输出低电平时光耦导通继电器吸合。这里有个容易理解错的地方很多人看继电器模块的低电平触发字样就以为要一直给低电平才能保持吸合实际上模块上的跳线帽选择HIGH模式还是LOW模式决定的是信号极性而已。继电器选型要看负载功率。一个1.5kW的轴流风机额定电流接近7A至少选10A规格的继电器模块才安全。水泵、风机、补光灯可以各用一个独立继电器分别接在PC13、PC14、PC15这些引脚上避免共用一个通道导致电流过载。接线时还有一个小细节继电器输出端的公共端COM接火线常开端NO接负载。这样当继电器吸合时负载得电工作。如果接成常闭端NC上电瞬间设备就会误动作这在现场很危险。2.4 电源系统与OLED显示模块整个系统的供电链路我设计成12V电源适配器 - 降压模块 - 5V - 板载稳压到3.3V给STM32。如果用的是普通USB供电电流可能不够因为继电器模块的线圈和OLED背光都要吃电流再加上蓝牙模块峰值电流可能到300mA左右。所以我建议用外部电源供电而不是从开发板的USB口取电。显示模块用的0.96寸OLEDSSD1306驱动芯片I2C接口。OLED功耗低、响应快、在室外阳光下也看得清比LCD1602少占4个GPIO。接线就是VCC接3.3V、GND接地、SCL接PB8、SDA接PB9。I2C地址默认0x78或者0x7A如果屏幕不显示第一件事就是检查I2C地址对不对。3. 程序设计框架与核心代码实现3.1 单片机程序的结构用一个定时器把任务调度起来这套程序的复杂度决定了不能把所有逻辑都塞在main函数里循环。我的设计思路是系统上电后先初始化各模块然后进入一个由定时器中断驱动的调度循环每100ms处理一次事件队列。具体拆分系统心跳是100ms每1秒采集一次DHT22数据每200ms刷新一次OLED屏幕每500ms检查一次蓝牙缓冲区是否有新数据需要解析。每个任务的执行周期不一样这在嵌入式设计里叫“时间片轮询”。在写代码时我建议用STM32标准外设库或者HAL库但不建议把整个工程搞成阻塞式。DHT22的读取时序刚好是个典型的时序敏感操作单片机发完起始信号后DHT22会拉低总线然后拉高之后按高低电平宽度表示0和1。整个过程微秒级如果用系统滴答去阻塞等待就会拖累其他任务。所以DHT22的读取我放在了定时器回调之外用一个专门的延时函数去处理读取完后立刻恢复到轮询主循环。核心代码逻辑大概这样void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) ! RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); tick_100ms; if (tick_100ms % 10 0) // 每秒 { sensor_read_flag 1; } if (tick_100ms % 2 0) // 每200ms { oled_refresh_flag 1; } if (tick_100ms % 5 0) // 每500ms { ble_poll_flag 1; } } }标志位在main循环里对应的函数来处理这样程序永远不会因为某个外设的等待时间而卡死。3.2 DHT22传感器读取时序要求与代码封装DHT22的单总线协议是这套硬件里最娇气的部分。读取过程每一步都有严格的时间窗口主机拉低18ms以上作为起始信号然后释放总线传感器回应一个80us的低电平信号再拉高80us之后就是40bit的数据每一位由50us的低电平开始后续高电平持续26-28us表示070us表示1。我写了一个读取函数核心在于微秒延时和读引脚电平uint8_t DHT22_ReadData(float *temp, float *humi) { uint8_t data[5] {0, 0, 0, 0, 0}; GPIO_SetBits(GPIOB, GPIO_Pin_6); delay_ms(500); // 传感器上电稳定 GPIO_ResetBits(GPIOB, GPIO_Pin_6); delay_us(18000); // 起始信号大于18ms GPIO_SetBits(GPIOB, GPIO_Pin_6); delay_us(30); // 等待应答 if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) RESET) { while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) RESET); // 等待80us低电平结束 while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) SET); // 等待80us高电平结束 // 开始读40bit数据 for (int i 0; i 40; i) { while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) RESET); delay_us(40); if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) SET) data[i / 8] (data[i / 8] 1) | 1; else data[i / 8] (data[i / 8] 1); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) SET); } } else { return 1; // 传感器未应答 } uint8_t checksum data[0] data[1] data[2] data[3]; if (checksum ! data[4]) return 2; // 校验失败 *humi ((data[0] 8) | data[1]) * 0.1; *temp ((data[2] 8) | data[3]) * 0.1; return 0; }读取时间窗口写不对最容易出现的现象就是数据跳变或者偶发读不到数据。我的经验是等待40us是在读到低电平结束后再等待这个40us误差尽量控制在±5us否则在临界点判断会把0判成1或者反过来。3.3 蓝牙通信协议设计串口如何传输结构化数据蓝牙模块和单片机之间是串口通信本质上就是一根TX和一根RX交叉接线。但通信内容要结构化不能裸发包。我给这套系统设计了两个协议帧。上行数据帧单片机 - 手机APP采用JSON格式文本方便APP直接解析{t:25.6,h:78.4,s:45.2,fan:0,pump:1}字段含义是温度25.6度湿度78.4%RH土壤湿度45.2%风机状态关水泵状态开。每个字段用逗号分隔长度不超过200字节。单片机把数据拼成字符串后通过串口发送到蓝牙模块手机APP接收到字符串后JSON解析即可。下行指令帧手机APP - 单片机采用自定义的短指令格式CMD:FAN,ON# CMD:PUMP,OFF# CMD:ALL,ON#帧头关键字CMD命令类型是FAN或者PUMPON或者OFF是目标状态帧尾#表示结束。单片机在串口接收中断里把字节拼进缓冲区检测到#就认为一条指令完整了然后交给解析函数处理。协议帧头和帧尾的作用就是分割指令校验时再判断关键字段是否合理。为什么不用JSON做下行因为受控设备的指令格式越短出错概率越低解析开销也小。手机端接收JSON是为了可视化展示丰富而单片机端解析短指令是为了减少代码复杂度。两端通信协议不一定非要统一功能上能对上就行。3.4 控制逻辑与阈值报警的实现控制逻辑是这套系统的灵魂。我的设计方案里有两种模式手动模式和自动模式通过APP切换。手动模式很简单APP下发什么指令单片机就执行什么。自动模式下单片机会判断阈值温度高于32℃自动开启风机低于20℃自动停止湿度高于85%RH自动开启除湿风机低于70%关闭土壤湿度低于30%时自动打开水泵滴灌高于60%停止灌水。这个自动逻辑不能用简单的if-else嵌套因为大棚控制不是纯线性关系。比如夏天中午高温高湿同时存在如果按优先级来处理先降温还是先除湿我的做法是设置一个状态机每个设备有独立的使能标志位只要温度超过高温阈值或湿度超过高湿阈值风机就打开水泵只由土壤湿度控制补光灯由光照强度和时序决定这部分可以做定时开关。另外我加了一个防抖机制设备状态切换之后至少保持60秒不变。否则传感器的小幅波动会导致继电器频繁通断一天下来继电器就废了而且这种操作对电网冲击也大。实现方法就是在切换状态时记录时间戳下次检查阈值时先看距离上次切换有没有超过60秒。4. 手机APP端设计与无线控制4.1 先跑通蓝牙串口调试通道再谈界面很多新手一上来就写APP界面结果手机连不上蓝牙模块各种挫败。我的建议是先下载一个蓝牙串口调试助手比如蓝牙调试器这类的工具手机和HC-05配对后用它来发AT指令、收数据。等硬件链路完全稳定了再动手写APP。HC-05蓝牙模块的默认参数是波特率9600密码1234模块名HC-05。第一次使用前最好先通过AT指令配置一下。把蓝牙模块的KEY引脚拉高再接电源然后通过USB转TTL接到电脑串口助手发送ATNAMEGreenhouse改名ATPSWD8888改密码ATUART115200,0,0把波特率改到115200。如果不改波特率用9600和手机通信也没问题但处理大量JSON数据时115200更快。4.2 安卓上位机开发的框架选择APP这部分我用的是Android Studio原生Java写的没有用繁琐的跨平台框架。开发蓝牙应用需要几个核心权限Android 6.0以上需要动态申请定位权限蓝牙经典扫描需要Android 12以上蓝牙相关权限更细化。蓝牙通信的核心流程分四步蓝牙适配器初始化、搜索设备、建立socket连接、启动收发线程。搜索蓝牙设备用startDiscovery()方法连接用BluetoothSocket的connect()方法默认RFCOMM通道UUID是00001101-0000-1000-8000-00805F9B34FB。我封装了一个蓝牙连接类核心收发逻辑如下public class BluetoothService { private BluetoothAdapter mAdapter; private BluetoothSocket mSocket; private InputStream mInputStream; private OutputStream mOutputStream; private Handler mHandler; public void connect(BluetoothDevice device) throws IOException { mSocket device.createRfcommSocketToServiceRecord(MY_UUID); mSocket.connect(); mInputStream mSocket.getInputStream(); mOutputStream mSocket.getOutputStream(); } public void sendCommand(String command) { try { mOutputStream.write(command.getBytes(UTF-8)); mOutputStream.flush(); } catch (IOException e) { e.printStackTrace(); } } }收数据时需要注意蓝牙串口是流式数据数据到达是不定时的而且可能一次达到一串。所以接收线程必须持续读InputStream把字节累积到缓冲区检测到换行符或者特定的EOF标记我这里是}就截断出来当成一帧完整数据交给JSON解析器。4.3 APP界面布局与数据展示APP界面我分三个区域顶部是环境数据实时卡片温度、湿度、土壤湿度三个数值配一个简明图表中间是设备控制区风机、水泵、补光灯各一个开关按钮底部是通信状态指示灯显示蓝牙连接状态。界面用LinearLayout嵌套或ConstraintLayout都行核心是数据刷新用HandlerThread的模式UI主线程不能直接做蓝牙读写。我开一条循环线程读串口解析完数据后通过runOnUiThread把结果扔回UI线程更新界面。控制按钮的事件绑定也很直接点击按钮时把对应的指令字符串通过蓝牙发送比如开风机就发CMD:FAN,ON#关水泵就发CMD:PUMP,OFF#。发送后会收到单片机的回传确认如果500ms内没收到APP弹Toast提示通信失败。注意APP里所有通信操作必须在子线程中执行绝对不能直接在UI线程里调mOutputStream.write()否则当蓝牙断开或数据量大会直接导致ANR崩溃。4.4 蓝牙通信异常时的提示与重连策略蓝牙设备的本质问题是连接状态不稳定尤其大棚现场可能有金属棚架、电机干扰等信号容易波动。我在APP里做了三层容错第一层是通信超时重试发指令后2秒内没收到回应自动重发一次第二层是断线自动重连抛出IOException后把蓝牙状态标记为断开弹窗提示用户检查设备第三层是连接失败时给出诊断信息区分是设备未配对还是服务发现失败还是IO错误这块调试起来很省心。如果你用的是HC-05模块还有一个冷知识模块进入AT模式时是不能和手机连接通信的所以接线和供电时一定要把KEY引脚的处理逻辑弄清楚。很多人的蓝牙模块连不上多半就是这个原因。5. 原理图设计与PCB制作注意点5.1 原理图模块划分与信号流向原理图我画的时候分了两层结构。第一层是最小系统板直接用现成的STM32F103C8T6核心板省去画晶振电路、复位电路、Boot配置电路的麻烦。第二层是传感器接口、继电器驱动、蓝牙模块接口、电源接口的扩展底板。这样做的好处是核心板坏了可以单独换扩展板可以复用。原理图设计的重点在电源网络12V输入经过LM2596降压模块变成5V5V分两路一路直接给继电器模块供电另一路经过AMS1117-3.3变成3.3V给STM32、OLED、蓝牙模块供电。千万不要把5V直接灌进STM32的3.3V引脚STM32不是所有引脚都容忍5V输入的ADC引脚尤其脆弱。5.2 PCB布局与走线的几条硬性约束画PCB时我总结了几条必须遵守的规则。第一电源线和地线加粗至少1mm宽继电器控制板的强电侧走线要保证足够电流承载。第二蓝牙模块的天线区域下方不要铺铜天线净空区要保持干净否则蓝牙信号直接衰减到通信距离只有几米。第三继电器模块和主控板之间用光耦隔离如果光耦集成在继电器模块内部就无所谓外接时一定加。继电器切换感性负载时会产生反向电动势必须在继电器线圈两端并联一个续流二极管1N4007否则关断瞬间的高压尖峰容易打坏光耦或者单片机引脚。这个细节在原理图上看不出来但在实际运行中差异巨大。我有一个板子之前没加续流二极管测试时偶尔死机加了一个二极管后再也没有复现过。5.3 结构设计与防潮处理农业大棚环境最大的敌人就是潮气。裸PCB板在棚里放一个礼拜插针和走线就开始氧化发绿。我建议把电路板装进防水接线盒引线接口用电缆防水接头板子和盒底之间垫一层绝缘珍珠棉。接线盒内部放一小包干燥剂定期更换。传感器的防水也要注意DHT22本身不防水裸奔测湿度时间久了会被水汽渗透读数漂移。可以套一个透气防水膜或者买那种带金属网罩的传感器保护壳既能透气又不进液滴。6. 常见问题与排查技巧实录6.1 快速定位问题的检查顺序表我做过的项目排障经验显示这类系统八成的问题集中在硬件连线和通信配置上真正程序逻辑出bug的概率反而没那么高。整理了一个排查顺序按这个顺序查最快故障现象优先检查项具体检查方法OLED不显示I2C地址与接线先用I2C扫描程序确认地址检查SCL/SDA是否接错传感器数据全为0上拉电阻用万用表量DATA线对VCC电压应该约有3.3V手机搜不到蓝牙模块电源与KEY脚HC-05的KEY脚不能悬空进入AT模式电源电流需足够蓝牙能连但收不到数据波特率匹配检查单片机串口波特率和蓝牙模块AT配置是否一致继电器不动作触发极性确认模块跳线是LOW触发还是HIGH触发和代码输出极性是否匹配数据时断时续电源稳定性示波器看3.3V纹波继电器吸合瞬间电压跌落是否超0.3V6.2 几个实践中才会明白的坑第一个坑是HC-05蓝牙模块供电不足。它正常工作峰值电流能到50mA左右如果直接从单片机3.3V引脚取电在继电器吸合瞬间电流波动会导致蓝牙模块掉线。解决方式蓝牙模块独立用AMS1117供电甚至单独用一个小电容储能。第二个坑是DHT22连续读取失败的问题。很多人的解决思路是重试三次再报故障但实际原因往往是传感器上电后需要至少2秒稳定时间而程序初始化后立即读取就会失败。我的做法是在上电后延时500ms再读第一次之后每隔1秒读一次连续5次失败才在屏幕上报传感器异常。第三个坑是蓝牙模块和手机配对后手机却显示已配对但未连接。这大概率是模块处于AT模式KEY脚接高电平或者串口波特率被改成115200但手机端软件还是9600。所以每次蓝牙模块出问题先确认是不是进了AT模式再确认波特率基本能解决八成问题。6.3 大数据量传输时的串口缓冲与丢帧处理STC或者STM32的串口接收缓冲区默认不大F103的USART1接收缓冲区是1字节硬件FIFO加上我们自己设置的软件缓冲区。如果蓝牙模块发送的JSON字符串超过缓冲区长度数据会被截断APP端解析自然报错。我的做法是把接收缓冲区设成256字节并采用环形队列。串口中断每收到一个字节就写入环形队列主循环里定期从队列取数据拼接成完整帧。判断是否完整帧的依据就是开头是否有{结尾是否有}。如果缓冲区里出现了多个帧粘连的情况用状态机切分而不是用简单的indexOf这样可以避免半包错位的问题。uint8_t ble_buffer[256]; uint16_t ble_index 0; uint8_t frame_ready 0; void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { uint8_t ch USART_ReceiveData(USART1); if (ch ) ble_index 0; // 新帧开始 if (ble_index sizeof(ble_buffer)) ble_buffer[ble_index] ch; if (ch #) { ble_buffer[ble_index] \0; frame_ready 1; ble_index 0; } } }用作为帧头#作为帧尾任何情况下接收状态都能快速复位不会出现因为历史残留数据导致的解析错乱。7. 现场部署与实测数据评估7.1 传感器安装位置与数据可靠性现场实测时我特意对比了不同安装位置的温差把传感器挂在薄膜下沿和挂在作物冠层上方读出的温度差了接近6度。这是因为薄膜附近聚集了大量热气传感器如果离膜太近测出的温度对作物管理没有参考价值。正确的位置应该是在作物冠层或者吊挂在顶棚1/3处同时避开风机直吹的区域。土壤湿度传感器也有讲究插太浅测的是表面干湿状态插太深测的是底层水分。实践中最合理的是插在10-15cm深度这也是多数作物根系密集区。另外要横插而不是竖插因为横插可以获得整个土层横截面的平均湿润度。7.2 连续运行7天的数据稳定性我在某园区一个黄瓜大棚连续跑了7天测试数据整体表现稳定。白天温度在28-35℃之间波动凌晨湿度可以升到90%以上这些极端值都能被系统准确捕捉并同步到APP。继电器自动控制风机水泵时OLED屏幕和手机端显示状态完全同步没有出现一次状态错乱。蓝牙通信的稳定性也经受住了考验。测试的距离在10米左右隔一层塑料膜数据基本无损隔一堵砖墙时信号骤降但还在通信范围内。如果实际部署时管理房距离太远可以把蓝牙模块换成带外置天线的版本或者改用BLE低功耗蓝牙来延长通信距离。7.3 APP远程控制延迟实测实测了APP下发指令到继电器动作的端到端延迟从手机点击按钮到听到继电器哒声吸合大概在170毫秒左右。这个延迟对于手动控制完全可以接受因为人在APP上操作本身就是有意识的慢动作。控制回传的确认信息也在300ms内就能显示到界面上。不过还是要说清楚蓝牙方案天然不适合超远距离控制如果你需要人在几公里外远程监控那正确的技术路线是用WiFi模块接路由器或者直接用4G DTU。这套蓝牙系统适合的是人在园区附近但不想走路去大棚的场景定位要清晰。最后再聊两句我个人做这套系统最大的感受是STM32单片机的资源对于这种程度的项目是绰绰有余的真正决定项目成败的不是芯片性能而是传感器数据可靠性和通信链路的稳定性。一个数据可信的监测系统比一个界面花哨但数据漂移的系统有价值得多。如果你后续想扩展可以在相同硬件基础上加CO2传感器、光照传感器或者把蓝牙换成WiFi模块接入云端底层的I2C和串口驱动代码基本可以复用。这套方案做成型的最终效果现场用下来反馈不错希望你也顺利调通。
阅读完成 · 觉得有帮助?