智能消防栓压力监测终端

举报
DS小龙哥 发表于 2025/03/30 19:20:42 2025/03/30
【摘要】 当前消防栓压力监测主要依赖人工巡检,这种方式存在周期长、成本高、数据不连续等缺陷。特别是在极端天气或紧急情况下,人工巡检难以满足实时性要求。同时,消防栓长期处于户外恶劣环境,对设备的防水性、耐用性和低功耗特性提出了极高要求。

#

项目开发背景

随着智慧城市建设的不断推进,城市基础设施的智能化改造已成为重要发展方向。消防系统作为城市安全的重要组成部分,其智能化水平直接关系到公共安全。传统消防栓普遍存在压力监测手段落后、维护效率低下等问题,无法实时掌握消防栓工作状态,导致在紧急情况下可能出现水压不足、设备故障等安全隐患。

当前消防栓压力监测主要依赖人工巡检,这种方式存在周期长、成本高、数据不连续等缺陷。特别是在极端天气或紧急情况下,人工巡检难以满足实时性要求。同时,消防栓长期处于户外恶劣环境,对设备的防水性、耐用性和低功耗特性提出了极高要求。

物联网技术的发展为解决这一问题提供了新的思路。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,配合铁氧体磁片增强耦合效率。线圈整体用环氧树脂封装,既保证机械强度又实现防水防潮。

预期成果

完成后的智能消防栓压力监测终端将实现以下技术指标:

  1. 压力测量范围0~2.5MPa,综合精度±0.5%FS,采样间隔可配置(默认10s)

  2. 无线充电距离≤5mm,充电效率≥75%,完整充电周期<4小时

  3. NB-IoT通信成功率≥99%,市区环境下平均功耗<200μA

  4. 防护等级IP68,可在1米水深持续工作,适应-20℃~+60℃环境温度

  5. 内置2000mAh锂电池,无外部供电情况下可连续工作≥3年

  6. 支持远程固件升级(FOTA),便于后期功能扩展和维护

系统将形成完整的消防栓压力监测解决方案,包括终端设备、云平台和移动应用。预计可降低消防栓维护成本60%以上,提高故障响应速度90%,为城市消防系统提供实时、可靠的压力监测数据。

总结

本设计针对传统消防栓监测手段的不足,提出了一种基于物联网技术的智能解决方案。系统整合了高精度压力传感、无线充电和NB-IoT通信等先进技术,在保证测量精度的同时,解决了户外设备供电和通信难题。

创新点主要体现在三个方面:一是采用磁吸式无线充电设计,彻底解决了防水与充电的矛盾;二是改进的滑动窗口滤波算法,有效区分真实压力变化与干扰信号;三是超低功耗设计,使设备在无外部供电情况下可工作多年。

该终端不仅适用于新建智慧城市项目,也可对现有消防栓进行低成本改造。随着国家智慧消防建设的推进,此类智能化终端具有广阔的应用前景。下一步可考虑增加流量监测、防撞报警等功能,进一步丰富系统应用场景。


整体代码设计思路

本主控代码采用模块化、事件驱动架构设计,主要实现以下核心功能:

  1. 多任务调度管理:通过状态机实现各功能模块的协同工作,避免阻塞式编程

  2. 低功耗优化:充分利用STM32的睡眠模式和PVD功能,最大限度降低系统功耗

  3. 传感器数据处理:实现压力信号的采集、滤波和异常检测算法

  4. 无线充电管理:监控充电状态,管理电池供电

  5. NB-IoT通信控制:处理数据上报和报警触发

  6. 故障自诊断:定期检查系统健康状态

代码采用分层结构:

  • 硬件抽象层:直接操作外设的底层驱动

  • 服务层:提供传感器、通信等模块的中间件服务

  • 应用层:实现业务逻辑和系统调度

完整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;
        }
    }
}

代码设计说明

  1. 低功耗管理

    • 采用STM32的停止模式(STOP)实现低功耗

    • 通过PVD监控电池电压,提前预警低电量状态

    • NB-IoT模块按需供电,发送完成后立即断电

  2. 压力数据处理

    • 采用滑动窗口均值滤波消除瞬时干扰

    • 动态阈值检测实现异常压力判断

    • 支持高压(>2.3MPa)和低压(<0.2MPa)双阈值报警

  3. 无线充电管理

    • 实时监测充电状态

    • 充电时LED指示灯慢闪提示

    • 充电状态下禁用低功耗模式

  4. 通信机制

    • 异常事件立即上报

    • 定期状态上报(默认5分钟)

    • 采用精简数据格式减少通信开销

  5. 可靠性设计

    • 传感器数据范围检查

    • 重要参数备份到备份寄存器

    • 看门狗定时器(未展示)防止程序跑飞

  6. 扩展性考虑

    • 模块化设计便于功能扩展

    • 关键参数宏定义方便调整

    • 预留FOTA升级接口

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。