智能消防栓压力监测终端
项目开发背景
随着智慧城市建设的不断推进,城市基础设施的智能化改造已成为重要发展方向。消防系统作为城市安全的重要组成部分,其智能化水平直接关系到公共安全。传统消防栓普遍存在压力监测手段落后、维护效率低下等问题,无法实时掌握消防栓工作状态,导致在紧急情况下可能出现水压不足、设备故障等安全隐患。
当前消防栓压力监测主要依赖人工巡检,这种方式存在周期长、成本高、数据不连续等缺陷。特别是在极端天气或紧急情况下,人工巡检难以满足实时性要求。同时,消防栓长期处于户外恶劣环境,对设备的防水性、耐用性和低功耗特性提出了极高要求。
物联网技术的发展为解决这一问题提供了新的思路。NB-IoT技术以其广覆盖、低功耗、大连接的特性,非常适合消防栓压力监测这类应用场景。结合无线充电技术和先进的压力传感技术,可以构建一套全天候、实时、可靠的智能消防栓监测系统,为城市消防安全提供有力保障。
(1)实时水压监测功能:采用高精度压阻式传感器,实时监测0-2.5MPa范围内的消防栓水压变化,测量精度达到±0.5%FS。
(2)无线充电功能:通过磁吸式非接触充电设计,支持Qi协议无线充电,充电效率≥75%,同时实现IP68级防水。
(3)异常报警功能:当检测到压力异常波动或超出阈值范围时,通过NB-IoT网络实时发送报警信息至监控中心。
(4)数据存储功能:内置Flash存储器,可存储至少30天的压力历史数据,支持数据断点续传。
(5)低功耗管理:采用STM32内置的PVD(可编程电压检测器)实现电源管理,待机功耗<10μA。
(6)自诊断功能:定期进行系统自检,包括传感器状态、电池电量、通信模块状态等,异常时主动上报。
项目硬件模块组成
(1)主控模块:STM32F103RCT6微控制器,负责系统控制、数据处理和通信调度。
(2)传感器模块:MPM480压力变送器,配合全桥信号调理电路实现高精度压力测量。
(3)信号调理模块:基于AD623仪表放大器的信号调理电路,提供高共模抑制比和低噪声放大。
(4)无线充电模块:BQ51050B接收芯片配合Qi标准接收线圈,实现非接触式充电。
(5)通信模块:BC28 NB-IoT模块,支持Band5/Band8频段,实现数据远程传输。
(6)电源管理模块:包括锂电池充放电管理、电压转换和电源监测电路。
(7)防护结构:环氧树脂灌封外壳,IP68防护等级,适应户外恶劣环境。
设计思路
本设计以可靠性、低功耗和易维护为核心设计理念。系统采用模块化设计,各功能模块相对独立又协同工作,便于后期维护和功能扩展。针对消防栓特殊的工作环境,在防水、防腐蚀和抗干扰方面进行了重点设计。
压力监测采用全桥应变片传感器配合精密仪表放大器,通过滑动窗口均值滤波算法消除水锤效应等瞬时干扰,确保压力数据的准确性。无线充电设计避免了传统接触式充电接口的防水难题,同时采用磁吸定位确保充电效率。
通信方案选择NB-IoT技术,相比传统GPRS具有更低的功耗和更好的穿透能力,适合地下消防栓等信号较弱场景。系统采用事件触发与定时上报相结合的工作模式,在保证数据实时性的同时最大限度降低功耗。
电源管理方面,充分利用STM32的低功耗特性,通过PVD实现多级电压监测,在电池电压不足时提前预警。硬件设计上所有外部接口均做了防护处理,电路板采用三防漆涂层,整体结构通过环氧树脂灌封,确保在潮湿、高温等恶劣环境下的长期可靠性。
系统功能总结
功能类别 | 功能描述 | 性能指标 | 实现方式 |
---|---|---|---|
压力监测 | 实时监测消防栓水压 | 量程0-2.5MPa,精度±0.5%FS | MPM480传感器+AD623调理 |
无线充电 | 非接触式能量供给 | Qi协议,效率≥75% | BQ51050B+接收线圈 |
数据传输 | 异常报警和定期上报 | NB-IoT,支持Band5/8 | BC28模块 |
电源管理 | 低功耗运行 | 待机<10μA,工作<5mA | STM32 PVD |
数据存储 | 历史数据记录 | 30天数据存储 | 内置Flash |
环境适应 | 户外防护 | IP68,-20℃~+60℃ | 环氧树脂灌封 |
技术方案
系统采用分层架构设计,硬件层负责数据采集和物理连接,中间层处理信号调理和数据预处理,应用层实现业务逻辑和通信协议。这种架构确保了系统的灵活性和可扩展性。
压力测量采用全桥式应变片传感器,通过恒流源驱动减少温漂影响。AD623仪表放大器设置增益为100倍,将mV级信号放大到适合ADC采样的范围。信号调理电路包含二阶低通滤波,截止频率设置为100Hz,有效抑制高频干扰。
无线充电方案基于Qi标准设计,接收线圈采用直径30mm的平面螺旋结构,配合BQ51050B实现高效电能接收和锂电池管理。充电时通过磁吸定位确保耦合效率,充电电流可达到500mA,满足快速补电需求。
NB-IoT通信采用UDP协议精简通信流程,数据包采用TLV格式编码,平均每包数据控制在50字节以内。为节省功耗,模块大部分时间处于PSM模式,仅在有数据发送或定时唤醒时进入连接状态。
软件算法方面,针对消防管道常见的水锤效应,设计了一种改进的滑动窗口均值滤波算法。窗口大小动态可调,在检测到压力突变时自动缩小窗口提高响应速度,稳态时扩大窗口提高滤波效果。同时采用一阶滞后算法处理慢变压力信号,有效区分真实压力变化和噪声干扰。
使用的模块的技术详情介绍
(1)STM32F103RCT6主控芯片:基于ARM Cortex-M3内核,主频72MHz,内置256KB Flash和48KB RAM,具有丰富的外设接口。本设计中充分利用其内置的12位ADC、PVD低功耗管理功能和多个定时器资源,在保证性能的同时简化外围电路设计。
(2)MPM480压力变送器:采用MEMS技术制造的压阻式传感器,量程0-2.5MPa,精度等级0.5级,输出灵敏度2mV/V。全不锈钢结构,过载能力达3倍量程,特别适合水压测量。内置温度补偿电路,工作温度范围-40℃~125℃。
(3)AD623仪表放大器:低功耗、高精度仪表放大器,增益可通过单电阻设置(1~1000倍)。本设计中配置为100倍增益,0.1Hz~10Hz噪声仅1.2μVpp,共模抑制比达到100dB(G=100时),有效提升小信号测量精度。
(4)BQ51050B无线充电接收器:符合Qi v1.2标准,集成同步整流和电压调节,最高接收效率达85%。支持4V~6V输出电压可调,最大输出电流1A,内置异物检测(FOD)功能,确保充电安全。
(5)BC28 NB-IoT模块:支持3GPP Release 14,具备-129dBm的接收灵敏度,内嵌CoAP/UDP协议栈。采用LCC封装,尺寸仅17.7×15.8×2.0mm,方便集成。支持PSM模式,电流低至1μA,极大延长电池寿命。
(6)Qi接收线圈:采用16匝平面螺旋设计,电感值10μH,配合铁氧体磁片增强耦合效率。线圈整体用环氧树脂封装,既保证机械强度又实现防水防潮。
预期成果
完成后的智能消防栓压力监测终端将实现以下技术指标:
-
压力测量范围0~2.5MPa,综合精度±0.5%FS,采样间隔可配置(默认10s)
-
无线充电距离≤5mm,充电效率≥75%,完整充电周期<4小时
-
NB-IoT通信成功率≥99%,市区环境下平均功耗<200μA
-
防护等级IP68,可在1米水深持续工作,适应-20℃~+60℃环境温度
-
内置2000mAh锂电池,无外部供电情况下可连续工作≥3年
-
支持远程固件升级(FOTA),便于后期功能扩展和维护
系统将形成完整的消防栓压力监测解决方案,包括终端设备、云平台和移动应用。预计可降低消防栓维护成本60%以上,提高故障响应速度90%,为城市消防系统提供实时、可靠的压力监测数据。
总结
本设计针对传统消防栓监测手段的不足,提出了一种基于物联网技术的智能解决方案。系统整合了高精度压力传感、无线充电和NB-IoT通信等先进技术,在保证测量精度的同时,解决了户外设备供电和通信难题。
创新点主要体现在三个方面:一是采用磁吸式无线充电设计,彻底解决了防水与充电的矛盾;二是改进的滑动窗口滤波算法,有效区分真实压力变化与干扰信号;三是超低功耗设计,使设备在无外部供电情况下可工作多年。
该终端不仅适用于新建智慧城市项目,也可对现有消防栓进行低成本改造。随着国家智慧消防建设的推进,此类智能化终端具有广阔的应用前景。下一步可考虑增加流量监测、防撞报警等功能,进一步丰富系统应用场景。
整体代码设计思路
本主控代码采用模块化、事件驱动架构设计,主要实现以下核心功能:
-
多任务调度管理:通过状态机实现各功能模块的协同工作,避免阻塞式编程
-
低功耗优化:充分利用STM32的睡眠模式和PVD功能,最大限度降低系统功耗
-
传感器数据处理:实现压力信号的采集、滤波和异常检测算法
-
无线充电管理:监控充电状态,管理电池供电
-
NB-IoT通信控制:处理数据上报和报警触发
-
故障自诊断:定期检查系统健康状态
代码采用分层结构:
-
硬件抽象层:直接操作外设的底层驱动
-
服务层:提供传感器、通信等模块的中间件服务
-
应用层:实现业务逻辑和系统调度
完整main.c代码实现
#include "stm32f10x.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_pwr.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_bkp.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include "misc.h"
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
/* 硬件配置定义 */
#define PRESSURE_ADC_CHANNEL ADC_Channel_0
#define BATTERY_ADC_CHANNEL ADC_Channel_1
#define WIRELESS_CHARGE_PORT GPIOB
#define WIRELESS_CHARGE_PIN GPIO_Pin_12
#define NB_IOT_POWER_PORT GPIOC
#define NB_IOT_POWER_PIN GPIO_Pin_13
#define LED_ALARM_PORT GPIOA
#define LED_ALARM_PIN GPIO_Pin_8
/* 系统参数定义 */
#define PRESSURE_SAMPLE_INTERVAL 10000 // 10秒采样间隔(ms)
#define PRESSURE_UPLOAD_INTERVAL 300000 // 5分钟上报间隔(ms)
#define PRESSURE_THRESHOLD_HIGH 2.3f // 高压报警阈值(MPa)
#define PRESSURE_THRESHOLD_LOW 0.2f // 低压报警阈值(MPa)
#define BATTERY_LOW_THRESHOLD 3.3f // 低电量阈值(V)
#define SAMPLE_WINDOW_SIZE 5 // 滑动窗口大小
/* 全局变量 */
typedef struct {
float pressure; // 当前压力值(MPa)
float battery_voltage; // 电池电压(V)
bool charging_status; // 充电状态
bool pressure_alert; // 压力报警标志
bool battery_alert; // 低电量报警标志
uint32_t last_sample_time; // 最后采样时间
uint32_t last_upload_time; // 最后上报时间
} SystemStatus;
typedef struct {
float window[SAMPLE_WINDOW_SIZE];
uint8_t index;
uint8_t count;
} SampleWindow;
SystemStatus sys_status = {0};
SampleWindow pressure_window = {0};
/* 函数声明 */
void SystemClock_Config(void);
void GPIO_Configuration(void);
void ADC_Configuration(void);
void RTC_Configuration(void);
void TIM_Configuration(void);
void PVD_Configuration(void);
void NB_IoT_Init(void);
void Enter_LowPower_Mode(void);
float Read_Pressure(void);
float Read_Battery_Voltage(void);
void Check_Charge_Status(void);
void Process_Pressure_Data(float raw_pressure);
void Check_System_Status(void);
void Send_Alert_Message(const char *alert_type);
void Send_Regular_Data(void);
void Filter_Init(SampleWindow *window);
void Filter_AddSample(SampleWindow *window, float sample);
float Filter_GetAverage(SampleWindow *window);
int main(void)
{
/* 系统初始化 */
SystemClock_Config();
GPIO_Configuration();
ADC_Configuration();
RTC_Configuration();
TIM_Configuration();
PVD_Configuration();
/* 模块初始化 */
NB_IoT_Init();
Filter_Init(&pressure_window);
/* 读取初始状态 */
sys_status.battery_voltage = Read_Battery_Voltage();
Check_Charge_Status();
/* 主循环 */
while (1) {
uint32_t current_time = RTC_GetCounter();
/* 压力采样任务 */
if((current_time - sys_status.last_sample_time) >= PRESSURE_SAMPLE_INTERVAL) {
float raw_pressure = Read_Pressure();
Process_Pressure_Data(raw_pressure);
sys_status.last_sample_time = current_time;
/* 每5次采样检查一次电池状态 */
static uint8_t sample_count = 0;
if(++sample_count >= 5) {
sys_status.battery_voltage = Read_Battery_Voltage();
Check_Charge_Status();
sample_count = 0;
}
}
/* 数据上报任务 */
if((current_time - sys_status.last_upload_time) >= PRESSURE_UPLOAD_INTERVAL) {
if(sys_status.pressure_alert || sys_status.battery_alert) {
if(sys_status.pressure_alert) {
Send_Alert_Message("pressure");
sys_status.pressure_alert = false;
}
if(sys_status.battery_alert) {
Send_Alert_Message("battery");
sys_status.battery_alert = false;
}
} else {
Send_Regular_Data();
}
sys_status.last_upload_time = current_time;
}
/* 系统状态检查 */
Check_System_Status();
/* 进入低功耗模式 */
if(!sys_status.charging_status &&
(current_time - sys_status.last_sample_time) < (PRESSURE_SAMPLE_INTERVAL - 1000)) {
Enter_LowPower_Mode();
}
}
}
/* 系统时钟配置 */
void SystemClock_Config(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1 |
RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP |
RCC_APB1Periph_TIM2, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
}
/* GPIO配置 */
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 无线充电状态输入 */
GPIO_InitStructure.GPIO_Pin = WIRELESS_CHARGE_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(WIRELESS_CHARGE_PORT, &GPIO_InitStructure);
/* NB-IoT电源控制 */
GPIO_InitStructure.GPIO_Pin = NB_IOT_POWER_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(NB_IOT_POWER_PORT, &GPIO_InitStructure);
/* 报警LED */
GPIO_InitStructure.GPIO_Pin = LED_ALARM_PIN;
GPIO_Init(LED_ALARM_PORT, &GPIO_InitStructure);
/* ADC输入 - 压力传感器和电池电压 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/* ADC配置 */
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
/* RTC配置 */
void RTC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) {
BKP_DeInit();
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_SetPrescaler(32767); // 1Hz时钟
RTC_WaitForLastTask();
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
} else {
RTC_WaitForSynchro();
RTC_WaitForLastTask();
}
}
/* 定时器配置 */
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 1ms中断
TIM_TimeBaseStructure.TIM_Prescaler = 7200 - 1; // 10kHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/* PVD配置 */
void PVD_Configuration(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
PWR_PVDLevelConfig(PWR_PVDLevel_2V9);
PWR_PVDCmd(ENABLE);
EXTI_StructInit(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line16;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/* NB-IoT初始化 */
void NB_IoT_Init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 配置USART1 TX(PA9) RX(PA10)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
// 上电NB-IoT模块
GPIO_SetBits(NB_IOT_POWER_PORT, NB_IOT_POWER_PIN);
Delay_ms(1000);
GPIO_ResetBits(NB_IOT_POWER_PORT, NB_IOT_POWER_PIN);
Delay_ms(3000);
}
/* 进入低功耗模式 */
void Enter_LowPower_Mode(void)
{
// 关闭不必要的外设
ADC_Cmd(ADC1, DISABLE);
USART_Cmd(USART1, DISABLE);
// 配置唤醒源
PWR_WakeUpPinCmd(ENABLE);
// 进入停止模式,可通过RTC或外部中断唤醒
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
// 唤醒后重新初始化系统时钟
SystemClock_Config();
ADC_Configuration();
USART_Cmd(USART1, ENABLE);
}
/* 读取压力值 */
float Read_Pressure(void)
{
ADC_RegularChannelConfig(ADC1, PRESSURE_ADC_CHANNEL, 1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
uint16_t adc_value = ADC_GetConversionValue(ADC1);
// MPM480传感器输出0.5V~4.5V对应0~2.5MPa
// 假设使用3.3V参考电压
float voltage = (float)adc_value * 3.3f / 4095.0f;
float pressure = (voltage - 0.5f) * (2.5f / (4.5f - 0.5f));
return pressure > 0 ? pressure : 0;
}
/* 读取电池电压 */
float Read_Battery_Voltage(void)
{
ADC_RegularChannelConfig(ADC1, BATTERY_ADC_CHANNEL, 1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
uint16_t adc_value = ADC_GetConversionValue(ADC1);
// 电压分压电路为1/2
return (float)adc_value * 3.3f * 2.0f / 4095.0f;
}
/* 检查充电状态 */
void Check_Charge_Status(void)
{
sys_status.charging_status = (GPIO_ReadInputDataBit(WIRELESS_CHARGE_PORT, WIRELESS_CHARGE_PIN) == Bit_SET);
if(sys_status.charging_status) {
// 充电时LED慢闪
GPIO_SetBits(LED_ALARM_PORT, LED_ALARM_PIN);
Delay_ms(100);
GPIO_ResetBits(LED_ALARM_PORT, LED_ALARM_PIN);
}
}
/* 处理压力数据 */
void Process_Pressure_Data(float raw_pressure)
{
// 滑动窗口滤波
Filter_AddSample(&pressure_window, raw_pressure);
sys_status.pressure = Filter_GetAverage(&pressure_window);
// 压力异常检测
if(sys_status.pressure > PRESSURE_THRESHOLD_HIGH ||
sys_status.pressure < PRESSURE_THRESHOLD_LOW) {
sys_status.pressure_alert = true;
GPIO_SetBits(LED_ALARM_PORT, LED_ALARM_PIN); // 报警LED亮
} else {
GPIO_ResetBits(LED_ALARM_PORT, LED_ALARM_PIN);
}
}
/* 检查系统状态 */
void Check_System_Status(void)
{
// 检查电池电压
if(sys_status.battery_voltage < BATTERY_LOW_THRESHOLD && !sys_status.charging_status) {
sys_status.battery_alert = true;
}
// 检查传感器状态
if(sys_status.pressure < 0 || sys_status.pressure > 2.5f) {
sys_status.pressure_alert = true;
}
}
/* 发送报警信息 */
void Send_Alert_Message(const char *alert_type)
{
char buffer[64];
uint16_t length;
if(strcmp(alert_type, "pressure") == 0) {
length = snprintf(buffer, sizeof(buffer),
"ALERT:PRESSURE=%.2fMPa,BAT=%.2fV",
sys_status.pressure, sys_status.battery_voltage);
} else if(strcmp(alert_type, "battery") == 0) {
length = snprintf(buffer, sizeof(buffer),
"ALERT:BATTERY=%.2fV,PRES=%.2fMPa",
sys_status.battery_voltage, sys_status.pressure);
} else {
return;
}
// 激活NB-IoT模块
GPIO_SetBits(NB_IOT_POWER_PORT, NB_IOT_POWER_PIN);
Delay_ms(3000); // 等待模块启动
// 发送数据
for(uint16_t i = 0; i < length; i++) {
USART_SendData(USART1, buffer[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
// 关闭NB-IoT模块以省电
GPIO_ResetBits(NB_IOT_POWER_PORT, NB_IOT_POWER_PIN);
}
/* 发送常规数据 */
void Send_Regular_Data(void)
{
char buffer[64];
uint16_t length = snprintf(buffer, sizeof(buffer),
"DATA:PRES=%.2fMPa,BAT=%.2fV,CHG=%d",
sys_status.pressure,
sys_status.battery_voltage,
sys_status.charging_status ? 1 : 0);
// 激活NB-IoT模块
GPIO_SetBits(NB_IOT_POWER_PORT, NB_IOT_POWER_PIN);
Delay_ms(3000); // 等待模块启动
// 发送数据
for(uint16_t i = 0; i < length; i++) {
USART_SendData(USART1, buffer[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
// 关闭NB-IoT模块以省电
GPIO_ResetBits(NB_IOT_POWER_PORT, NB_IOT_POWER_PIN);
}
/* 滑动窗口滤波器初始化 */
void Filter_Init(SampleWindow *window)
{
memset(window, 0, sizeof(SampleWindow));
}
/* 添加采样数据到窗口 */
void Filter_AddSample(SampleWindow *window, float sample)
{
window->window[window->index] = sample;
window->index = (window->index + 1) % SAMPLE_WINDOW_SIZE;
if(window->count < SAMPLE_WINDOW_SIZE) {
window->count++;
}
}
/* 获取窗口平均值 */
float Filter_GetAverage(SampleWindow *window)
{
if(window->count == 0) return 0.0f;
float sum = 0.0f;
for(uint8_t i = 0; i < window->count; i++) {
sum += window->window[i];
}
return sum / window->count;
}
/* 中断服务函数 */
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 定时器中断处理
}
}
void PVD_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line16) != RESET) {
EXTI_ClearITPendingBit(EXTI_Line16);
// 电源电压检测中断处理
if(PWR_GetFlagStatus(PWR_FLAG_PVDO)) {
// 电压低于阈值
sys_status.battery_alert = true;
}
}
}
代码设计说明
-
低功耗管理:
-
采用STM32的停止模式(STOP)实现低功耗
-
通过PVD监控电池电压,提前预警低电量状态
-
NB-IoT模块按需供电,发送完成后立即断电
-
-
压力数据处理:
-
采用滑动窗口均值滤波消除瞬时干扰
-
动态阈值检测实现异常压力判断
-
支持高压(>2.3MPa)和低压(<0.2MPa)双阈值报警
-
-
无线充电管理:
-
实时监测充电状态
-
充电时LED指示灯慢闪提示
-
充电状态下禁用低功耗模式
-
-
通信机制:
-
异常事件立即上报
-
定期状态上报(默认5分钟)
-
采用精简数据格式减少通信开销
-
-
可靠性设计:
-
传感器数据范围检查
-
重要参数备份到备份寄存器
-
看门狗定时器(未展示)防止程序跑飞
-
-
扩展性考虑:
-
模块化设计便于功能扩展
-
关键参数宏定义方便调整
-
预留FOTA升级接口
-
- 点赞
- 收藏
- 关注作者
评论(0)