
1. 这个项目解决的痛点图书馆环境为什么需要“被监测”先说个我自己的观察。很多做嵌入式开源项目的朋友一上来就奔着炫技去——屏幕要大的传感器要多的协议要新的结果做完发现除了发朋友圈啥用没有。但图书馆环境监测这个方向不一样它是个典型的“小需求、真场景、可落地”的选题特别适合拿来练手也特别适合改造成实际能部署的东西。我这套方案的核心硬件是STM32F103C8T6也就是大家常说的“STM32最小系统板”配上DHT11温湿度传感器、光敏电阻模块、烟雾或火焰传感器可选再加一个OLED屏或LCD1602做本地显示。数据采集之后一方面在本地屏幕上实时刷新另一方面通过串口或模拟的I2C/SPI总线上报给上位机或者直接接ESP8266走Wi-Fi上报到云端。整个系统用Keil MDK开发配合Proteus做仿真验证。图书馆环境监测到底要解决什么问题说白了就是三个维度温湿度纸质书籍最怕潮湿和高温。湿度超过60%RH纸张容易发霉、变形温度长期超过30°C胶装书脊会加速老化。所以图书馆的恒温恒湿不只是“人舒服”更是“书保命”。光照强度紫外线是纸张发黄变脆的头号杀手。阳光直射的书架书脊褪色速度肉眼可见。监测光照强度一方面是为了智能控制窗帘或补光灯另一方面也是提醒管理员调整书架位置。烟雾/火灾隐患图书馆是典型的人员密集易燃物聚集场所烟雾传感器的价值不用多说。就算不做完整的消防联动至少能在无人值守时段发出本地声光报警或者通过Wi-Fi推送到管理员手机。这套东西的妙处在于它把传感器采集、信号调理、MCU逻辑控制、显示输出、报警联动、通信上报这一个完整的嵌入式数据链路全部串起来了。你做完它基本就等于把STM32最常见的几种外设GPIO、ADC、定时器、UART、I2C/SPI都过了一遍。而这几个外设恰恰是后面做任何正经项目的底子。2. 硬件选型思路为什么是F103C8T6各传感器怎么挑2.1 主控选择STM32F103C8T6凭什么当“万金油”F103C8T6这颗芯片现在几乎是国产嵌入式教学和开源项目的事实标准。它属于STM32F1系列的主流型号Cortex-M3内核主频72MHzFlash 64KBSRAM 20KB。从参数上看平平无奇但它有几个特性让它在“环境监测”这种中低复杂度项目里格外顺手外设资源够用但不过剩3个USART、2个I2C、2个SPI、1个USB、2个ADC12位最多10个通道。环境监测需要的UART接ESP8266或上位机、I2C/SPI接OLED、ADC接光敏和烟雾传感器、GPIO接DHT11和蜂鸣器它全都有。3.3V供电功耗可控整板功耗在几十mA级别用USB供电或者18650电池都能跑这对长期无人值守的环境监测场景特别重要。固件库和例程生态极成熟标准外设库SPL和HAL库的例程一抓一大把遇到问题搜一下基本都有答案。别小看这一点对新手来说“能搜到答案”比“性能强”重要得多。如果你手头没有F103C8T6用STM32F103RCT6大容量版或者STM32F407系列也完全能改但代码逻辑不用动只改引脚配置和启动文件即可。2.2 传感器怎么挑DHT11、光敏电阻、烟雾传感器的选型要点DHT11温湿度传感器这是最入门级的数字温湿度传感器单总线协议一条数据线搞定通信。测量范围温度0-50°C、湿度20%-90%RH精度温度±2°C、湿度±5%RH。说实话精度不高但图书馆环境监测要的不是“实验室级的精准”而是“趋势监控超限报警”DHT11完全够用而且价格便宜、程序好写。想做得更专业一点可以换成DHT22AM2302精度提升到±0.5°C和±2%RH通信协议和DHT11几乎一样代码只需要改时序参数。或者用SHT30走I2C总线精度更高但代码量会多一截。这个决策取决于你的目标如果是学习为主DHT11是最佳选择如果是要真正部署到图书馆建议DHT22起步。光敏电阻模块市面上常见的“光敏电阻传感器模块”一般是一个分压电路LM393比较器输出数字量和模拟量两路信号。数字量输出可以调阈值电位器模拟量输出直接接MCU的ADC引脚读取。我这里推荐用模拟量输出因为你不仅要判断“亮不亮”还要知道“到底多亮”这样才能做出“光照过强报警”或“光照过低自动开灯”的差异化逻辑。实测下来光敏电阻在暗处阻值几百kΩ亮处几kΩ分压后的电压变化范围大概0.2V-3.3V完全在STM32 ADC的可测范围内。烟雾传感器常见的有MQ-2可燃气体/烟雾和MQ-135空气质量。MQ系列本质是气敏电阻加热电阻丝到一定温度后表面电阻随气体浓度变化。它的输出也是模拟量需要一个分压电阻转成电压信号。注意MQ-2需要预热几分钟而且功耗比较大加热丝大约150mW-800mW如果电池供电要考虑电源余量。在图书馆这种场景我建议烟雾传感器做成“辅助监测项”主监测还是温湿度和光照因为烟雾传感器误报率相对偏高容易“狼来了”。2.3 显示与报警OLED屏和蜂鸣器的组合逻辑显示部分我用的是0.96寸I2C接口的OLEDSSD1306驱动四根线VCC、GND、SCL、SDA直接接MCU极其省事。为什么不推荐LCD1602因为LCD1602需要8根数据线或4根线控制线而且带背光功耗大接口占用的引脚多对后面扩展通信模块不友好。OLED在信息密度上也更胜一筹可以一屏同时显示温度、湿度、光照强度、报警状态四行数据。报警部分用一个有源蜂鸣器接在GPIO上高电平触发。有源蜂鸣器内部自带振荡源只要给电平就响不需要MCU输出PWM驱动软件实现最简单。如果嫌蜂鸣器太吵可以改成LED灯蜂鸣器双通道或者直接通过串口向上位机发报警指令。2.4 供电和通信整板电源设计要点整个系统的供电我建议分两级USB 5V输入经过AMS1117-3.3稳压到3.3V给MCU和传感器供电。注意DHT11的供电范围是3.3V-5VOLED模块一般是3.3V-5VMQ-2传感器模块一般需要5V内部加热丝对电压敏感5V供电时加热功率才是额定值所以如果是3.3V单电源系统MQ-2模块要单独5V供电。这一点最容易翻车后面细讲。通信模块如果有ESP8266它需要3.3V供电但峰值电流可以达到300mA直接从AMS1117后面取电会导致压降系统可能不稳定最好用独立的3.3V稳压芯片或者5V转3.3V的DC-DC模块。如果只是本地串口通信用CH340G USB转串口模块就够同时还能给整个系统供电一箭双雕。3. 软件架构与核心代码逻辑从初始化到业务闭环3.1 整体程序框架轮询为主中断为辅这套系统软件上不需要上RTOS实时操作系统裸机轮询就够了。我的程序结构是一个大循环里依次跑四个任务DHT11采集、ADC采集光照烟雾、数据显示刷新、报警判断与处理。伪代码逻辑如下int main(void) { // 初始化 SystemClock_Config(); // 系统时钟72MHz GPIO_Init(); // LED、蜂鸣器、按键引脚 ADC_Init(); // 光敏、烟雾传感器ADC通道 DHT11_Init(); // DHT11数据引脚 OLED_Init(); // SSD1306初始化 USART_Init(115200); // 串口调试/上报 while (1) { DHT11_ReadData(temp, humi); // 读取温湿度 light_value ADC_Read(CH_LIGHT); // 读取光照ADC值 smoke_value ADC_Read(CH_SMOKE); // 读取烟雾ADC值可选 OLED_Refresh(); // 刷新显示 CheckAlarm(temp, humi, light, smoke); // 报警判断 delay_ms(100); // 控制刷新周期 } }核心思路就是“上电初始化 → 循环执行任务 → 串口/FMQ上报”。整个循环周期控制在100ms左右对这几个传感器来说完全够用——DHT11本身最快的采样周期就是1-2秒你读再快也没意义反而浪费时间。3.2 DHT11时序解析最容易踩坑的地方DHT11的单总线协议看起来简单实际写起来有几个细节特别容易翻车。我一个一个说。起始信号主机拉低数据线至少18ms然后释放。DHT11检测到起始信号后会回一个80us的低电平响应信号再拉高80us然后开始发送40位数据8位湿度整数8位湿度小数8位温度整数8位温度小数8位校验和。数据位读取每一位都是“50us低电平高电平”高电平持续时间26-28us代表“0”高电平持续70us代表“1”。所以读位的核心就是“等低电平结束后测量高电平持续时间超过40us判为1否则判为0”。这里最容易出问题的是GPIO模式切换。DHT11的数据线是开漏的主机必须先配置为输出模式发送起始信号然后立刻切换为输入模式读取数据。很多新手忘了切换或者切换时机不对导致读出来的数据全是0xFF或者随机跳变。我封装了一个读取函数核心代码如下uint8_t DHT11_ReadBit(void) { uint8_t count 0; // 等待低电平结束50us while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) RESET); // 低电平结束后计时高电平持续时间 while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) SET) { count; delay_us(1); if (count 100) return 0xFF; // 超时保护 } // 高电平持续约70us为1约26-28us为0临界值设40us if (count 40) return 1; else return 0; }注意这个40us的临界值实际测试中高温高湿环境下高电平时间会有波动我见过有项目把临界值设为30us导致误判的。这个值设成40-45us之间比较稳但前提是delay_us(1)的延时精度要够。如果你用HAL库的HAL_Delay它的最小粒度是1ms完全不能用在这里必须自己用SysTick或者空循环写一个us级的延时函数。3.3 ADC多通道采集光敏和烟雾信号的数字化STM32F103C8T6内部有两个12位ADC我一般用ADC1的通道0PA0和通道1PA1分别接光敏模块和烟雾模块的模拟量输出。ADC的配置要点打开GPIOA时钟和ADC1时钟。将PA0、PA1配置为模拟输入模式。配置ADC为独立模式、单次转换、右对齐、扫描模式关闭。校准ADCADC_SoftwareStartConvCmd之前做一次ADC_ResetCalibration和ADC_StartCalibration。读取时切换通道启动转换等待EOC标志位。代码片段uint16_t ADC_ReadChannel(uint8_t channel) { ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) RESET); return ADC_GetConversionValue(ADC1); }采样时间我用的是239.5个周期也就是最慢档。为什么不用最快的1.5周期因为光敏电阻和烟雾传感器的输出阻抗都比较高信号源驱动能力弱采样时间短会导致ADC内部采样电容来不及充电到稳定值转换结果会偏小。这是很多新手容易忽略的点。对于高阻抗信号源慢速采样反而更准。读回来的ADC值是0-4095对应0-3.3V。光照强度我用反向映射——ADC值越大说明光照越强光敏电阻阻值小分压电压高。烟雾浓度同理ADC值越大说明气体浓度越高。这两个原始值要不要换算成实际物理量我的建议是不需要。因为光敏电阻的非线性太强不同厂家的模块差异也大标定成本高工程上直接用阈值判断就够了。比如光照ADC值大于3500判定为“光照过强”低于500判定为“光照不足”这两个阈值可以在OLED菜单里通过按键调整做成“可配置”比“精准换算”实用得多。3.4 OLED显示与菜单逻辑不写点阵字库也能优雅显示SSD1306 OLED的驱动市面上有现成的库比如U8g2功能强大但你未必用得上。我更喜欢用极简的底层驱动只实现以下几个函数OLED_Init()初始化SSD1306OLED_Clear()清屏OLED_ShowString(line, col, str)显示字符串OLED_ShowNum(line, col, num, len)显示数字字库方面我直接把ASCII字符的8x16点阵数据做到一个常量数组里只包含数字、字母和几个常用符号%、C、:、空格等Flash占用非常小。菜单逻辑参考“状态机”模型每次按键触发一个事件状态根据当前状态和事件切换到下一个状态。状态有主界面实时数据、报警阈值设置-温度、报警阈值设置-湿度、报警阈值设置-光照。长按按键可以进入菜单短按切换/调整逻辑清晰扩展也方便。显示效果上主界面我习惯做成这样的布局Temp: 25.3 C Humi: 56.0 % Light: 2350 [I] Smoke: 1024 [N]第四行的[I]表示光照状态IIntense强光NNormal正常DDark过暗[N]表示烟雾状态NNormal正常AAlarm报警。一屏四行信息密度刚刚好。3.5 报警判断阈值回差避免“临界抖动”这是很多项目做得糙的地方。直接写成“温度大于30就报警小于30就解除”结果就是温度在29.9和30.1之间反复横跳蜂鸣器响一下停一下能把管理员逼疯。正确的做法是加回差滞回控制。比如设定上限30°C回差2°C温度升到30.1°C时触发报警之后必须降到28°C以下才解除报警。这样即使温度在30°C附近波动报警状态也不会频繁翻转。同样逻辑适用于湿度下限。比如湿度低于35%RH时报警太干燥回差设5%那么必须回升到40%才解除。光照过强同理。代码实现也不复杂typedef struct { float upper_limit; float lower_limit; float hysteresis; uint8_t alarm_active; } AlarmParam; uint8_t AlarmJudge(AlarmParam *param, float value) { if (param-alarm_active) { // 已经处于报警状态判断是否低于回差值 if (value param-lower_limit param-hysteresis value param-upper_limit - param-hysteresis) { // 仍在回差带内维持报警 return 1; } if (value param-lower_limit || value param-upper_limit) { return 1; // 仍然超限 } param-alarm_active 0; // 回到安全区解除报警 return 0; } else { // 未报警判断是否越限 if (value param-lower_limit || value param-upper_limit) { param-alarm_active 1; return 1; } return 0; } }这段逻辑胜在通用性。温湿度、光照、烟雾全都可以用同一个函数只要各自实例化一个AlarmParam结构体设置不同的阈值就行。4. 上位机通信与模块联动让数据“活”起来4.1 串口协议设计简单可靠的帧格式数据采集上来只存在本地屏幕上是远远不够的。我做了一个非常简单的串口帧协议方便上位机C#写的简易监测面板或串口调试助手解析帧头(0xAA) 帧头(0x55) 数据长度(1字节) 命令字(1字节) 数据区(N字节) 校验和(1字节)比如周期上报当前数据AA 55 06 01 19 01 38 02 00 3F拆解一下AA 55帧头06是数据长度命令字5字节数据01是命令字周期上报19 01是温度0x0119281除以10就是28.1°C38 02是湿度0x0238568除以10就是56.8%00是光照状态标志3F是校验和前面所有字节累加取低字节。校验和算法用最简单的累加和但一定要加上否则串口误码会让上位机显示乱码。上位机收到一帧后先验证帧头和校验和再解析数据这样抗干扰能力大大增强。有朋友问为什么不用JSON或者ModbusJSON在嵌入式上解析开销太大Modbus对图书馆这种点对点串口场景来说规则偏重。自定义轻量协议足够而且你能顺便学会“协议设计”的思路这在后面做任何物联网项目都是必背技能。4.2 ESP8266扩展从本地监测升级到远程告警如果想让系统具备远程告警能力加一个ESP8266模块是最便宜的方案。ESP8266通过UART和STM32通信用AT指令控制Wi-Fi连接和MQTT发布。典型流程是上电后STM32发送AT指令配置ESP8266连接Wi-FiATCWMODE1Station模式ATCWJAPSSID,password连接路由ATMQTTUSERCFG0,1,client_id,username,password,0,0,配置MQTTATMQTTCONN0,broker地址,1883,1连接MQTT服务器每采集一轮数据通过MQTT发布到主题library/env消息体用JSON格式{temp:28.1,humi:56.8,light:2350,smoke:1024,alarm:1}。上位机或手机App订阅这个主题实现远程监控。ESP8266的AT指令解析其实是个比较头疼的点因为模块返回的OK、ERROR、MQTTSUBRECV等字符串是不可预测的。我的经验是不要用阻塞式的sprintf和delay而是用串口接收中断状态机来解析AT响应。如果只是低速上报数据也可以用最简单的延时判断法发送指令后延时200ms读取串口缓存判断是否包含“OK”但稳定性会差一些。MQTT broker我用的是公共服务比如EMQX的免费broker部署简单适合演示和开发。真要商用到图书馆建议本地部署一个broker或者用带鉴权的云服务避免数据裸奔。4.3 与Proteus仿真的对应关系纯软件也能验证逻辑这个项目的开源包里包含了Proteus仿真文件这点我要专门说一下。Proteus的仿真是很有价值的尤其是当你的硬件板子还没打样、或者不想反复烧录调试的时候先用仿真把逻辑链路跑通能省下大量时间。仿真里我搭了以下模块STM32F103C8T6DHT11模型Proteus自带光敏电阻传感器模型用可变电阻分压电路模拟LM016L液晶LCD1602或者直接接一个虚拟终端按键、LED、蜂鸣器虚拟串口终端Proteus仿真有个坑它自带的DHT11模型时序和真实芯片略有差异如果你用“读高电平计数”的方式判断数据位仿真可能能过但烧到真机上就翻车。反过来有些代码在真机上稳定运行仿真却卡死。所以我的建议是仿真只用来验证逻辑最终一定要在真机上跑一遍。开源包里我同时提供仿真文件和真机代码目的就在这里。设计原理图时我也踩过一个坑光敏电阻的ADC输入引脚直接接3.3V结果在强光下读数饱和到4095无法区分“强光”和“超强光”。后来在光敏电阻模块的输出和ADC引脚之间串了一个10kΩ电阻并对地接一个100nF电容做低通滤波信号稳定了很多读数也拉开梯度了。这个细节在原理图里标注出来了大家抄的时候留意一下。5. 实测效果与故障排查那些我踩过的坑5.1 实测数据与系统表现我在办公室里用这套系统跑了大约两周放在一个靠窗的书架旁边。实测下来温湿度读数在早上和下午有明显波动早上8点室内温度大约24°C湿度58%下午2点太阳直射时温度能升到29°C湿度降到45%左右。光照ADC值的变化最剧烈太阳直射时接近3900傍晚拉上窗帘后直接跌到200以下。烟雾传感器因为办公室没有真实烟雾源我用打火机的气体测试了一下ADC值能从1024飙升到2800报警触发灵敏。整个系统的功耗用USB供电时实测电流约120mA含OLED和蜂鸣器待机如果改成电池供电休眠策略每次采集完进入STOP模式用RTC定时唤醒平均功耗可以压到10mA以下。对图书馆这种有市电的场景直接用电源适配器就好但如果你要部署在没有插座的临时展区低功耗模式值得做。5.2 典型故障一DHT11读回固定值85或空白这个现象非常经典。原因基本只有一个DHT11起始信号的总线占用时间太短或者GPIO方向切换失败。具体表现是读回来的湿度永远是85%这是DHT11的无效上电值温度永远是0。排查链路用示波器或逻辑分析仪看数据线波形如果起始信号之后没有看到DHT11的80us响应低电平说明起始信号不满足要求。检查GPIO模式配置。F103的GPIO在输入模式下要用GPIO_Mode_IPU上拉输入DHT11数据线空闲状态是高电平如果没配上拉读到的永远是0。检查延时函数。我见过用了HAL_Delay(18)来拉低18ms的HAL_Delay单位是ms没问题但读bit时用了HAL_Delay(1)那就全毁了。必须用us级延时。5.3 典型故障二ADC读数在强光下饱和如果你用的光敏电阻模块输出直接接ADC引脚而且模块上没有滤波电容大概率会遇到读数跳变或者饱和。我上面提到的“串10kΩ电阻并联100nF电容”方案是通用的解决办法几乎不增加成本。另外ADC采样时间一定要设置成慢速档这能显著降低读数波动。5.4 典型故障三板载3.3V给ESP8266供电Wi-Fi模块反复重启ESP8266的峰值电流可达300mASTM32最小系统板上的AMS1117是低压差线性稳压器最大输出电流一般是800mA看似够用但AMS1117在压差较大5V转3.3V有1.7V压差时发热明显输出电流能力会降额。再加上板载LED、OLED和传感器都在同一路3.3V上总电流接近300mA时AMS1117的输出电压已经跌到3.2V以下ESP8266在电压跌落时就重启。解决办法最省事的是ESP8266用独立的3.3V供电比如从USB 5V经过一片单独的AMS1117或DC-DC降压模块和MCU的3.3V在电源端隔离共地即可。或者直接用5V版的ESP-01S模块需要确认模块支持5V输入一般ESP8266核心板都有板载稳压可以直接5V供电。6. 开源包里有什么从抄作业到改作业开源包的结构我整理如下LibraryEnvMonitor/ ├── README.md # 项目说明和硬件清单 ├── Hardware/ │ ├── LibraryEnvMonitor_SCH.pdf # 原理图PDF版 │ ├── LibraryEnvMonitor_SCH.dws # 立创EDA源文件 │ └── LibraryEnvMonitor_PCB.dws # PCB工程可选 ├── Firmware/ │ ├── Core/ │ │ ├── Inc/ # 头文件 │ │ └── Src/ # 主程序、中断、传感器驱动、OLED驱动、报警逻辑 │ ├── Drivers/ # STM32标准外设库 │ └── MDK-ARM/ # Keil工程文件 ├── Simulation/ │ └── LibraryEnvMonitor.pdsprj # Proteus仿真工程 └── Docs/ ├── 接线说明.md └── 上位机协议.md拿到这个包之后我建议按这个顺序操作别一上来就编译第一步看README确认硬件清单。F103C8T6最小系统板、0.96寸OLED、DHT11、光敏模块、MQ-2模块、蜂鸣器、按键、AMS1117模块、面包板杜邦线。大概80-100元能拿下全套不含开发板调试器的话。第二步打开原理图PDF对照接线表先把真实硬件搭起来。这里我强烈建议先只接MCU最小系统和OLED跑一个“点灯显示”的Demo确认开发板本身是好的再逐步接入传感器。一次性把所有外设都接好出了问题反而难排查。第三步打开Keil工程先编译一次。如果报错检查芯片型号是否选成F103C8有些工程默认是RCT6以及是否安装了对应的器件支持包。第四步烧录后先用串口调试助手以115200波特率连接看数据。串口数据正常了再打开OLED和报警功能。这个“先通信后显示”的顺序能避免“不知道是传感器坏了还是显示坏了”的窘境。第五步跑通真机后再去玩Proteus仿真。仿真里我将DHT11的时序调慢了一些方便观察总线波形但真机代码是标准时序两者不要混用。7. 后续扩展方向别让项目止步于“做完”这个项目做完之后等于把嵌入式开发的主线流程走了一遍。如果想继续往下深入我建议在这几个方向里挑一个方向一低功耗化改造。把采集周期从100ms拉长到5分钟采集完进入STOP模式用RTC定时唤醒再配合LoRa或NB-IoT模块做一个真正能部署的“图书馆角落传感器节点”。这里面涉及的STM32低功耗模式Sleep、Stop、Standby切换、唤醒源配置、电源树设计都是后面做电池供电产品必考的题目。方向二多节点组网。单点监测只是“点”多个传感器节点组成“面”才有意义。可以加一个ESP8266或CC2530Zigbee做无线组网把每个书架的温湿度数据汇总到中心节点再由中心节点统一上报。这涉及无线协议选型、数据冲突规避、断线重连策略复杂度会上一个台阶。方向三数据可视化平台。把MQTT上报的数据接到Home Assistant、Node-RED或者自建一个Web面板画曲线、做历史趋势、设告警规则。这个方向偏软件但能逼你把嵌入式端的协议设计得更健壮——比如需要补包机制、时间戳设计、数据压缩等。方向四执行机构联动。监测的目的是控制。接一个继电器控制除湿机、加湿器、空调或者自动窗帘做成“环境闭环控制系统”。这里面会涉及PID控制恒温恒湿但先不用那么高深一个简单的开关控制湿度大于60%开除湿机小于50%关就够你练很久的。我个人做完这个项目最大的体会是嵌入式项目最重要的不是芯片多高级、外设多复杂而是你能否把一个“真实世界的物理量”准确采集上来经过逻辑判断再转化为“有用的动作输出”。图书馆环境监测刚好是这条完整链路的典型代表。只要你能独立把DHT11、ADC、OLED、串口、报警这几件事打通后面再遇到什么传感器模块基本都是一通百通。最后补一个使用建议这套系统的报警阈值参数千万不要随便用我在代码里的默认值。每个图书馆的温湿度基线和书籍存放要求都不一样一定要根据实际环境先采集一周数据看正常波动范围在哪再把阈值设在波动范围之外、防护要求之内。这样既能保证报警有效又不会因为阈值设置太激进导致天天误报。