基于单片机的煤气泄漏检测报警装置设计

一、项目介绍

煤气泄漏是一种常见的危险情况,可能导致火灾、爆炸和人员伤亡。为了及时发现煤气泄漏并采取相应的安全措施,设计了一种基于单片机的煤气泄漏检测报警装置。

主控芯片采用STM32F103C8T6作为主控芯片,具有强大的计算和控制能力。煤气检测传感器选择了MQ-5,它能够检测到环境中的煤气浓度,并将其转换为电信号输出。装置通过读取传感器输出的模拟信号,并经过ADC转换获得相应的数字值,实时监测煤气浓度。

当检测到煤气浓度超过设定的安全阈值时,装置会触发报警机制。通过控制蜂鸣器发出高频报警声,吸引人的注意并提醒危险情况。同时,装置会控制LED灯光闪烁,以视觉方式提醒用户。这样的多重报警方式可以在不同环境中有效地引起人们的警觉。

为了进一步提高报警的及时性和可靠性,还集成了SIM800C模块,用于发送报警短信给指定的联系人。当煤气浓度超标时,装置会通过SIM800C模块发送预先设定的报警短信,通知相关人员及时采取措施。

通过以上设计,基于单片机的煤气泄漏检测报警装置能够实时监测环境中的煤气浓度,并在检测到异常情况时通过声光报警和短信通知提醒用户。这样的装置可以广泛应用于家庭、工业和商业环境中,为人们的生命财产安全提供有效的保障。

image-20230802163612836

image-20230802163555635

二、硬件选型

在这个设计中,选择了下面的硬件来实现煤气泄漏检测报警装置。

【1】主控芯片:STM32F103C8T6。该芯片是一款强大的低功耗微控制器,具有丰富的外设和良好的性能。它集成了多个通用输入输出引脚、模数转换器 (ADC)、定时器和串行接口等功能,适合用于各种嵌入式应用。

【2】煤气检测传感器:MQ-5。MQ-5是一种常见的煤气传感器,可检测到液化石油气(LPG)、天然气和甲烷等可燃气体。它基于半导体气敏材料,当检测到目标气体浓度超过设定阈值时,其电阻值发生变化。通过测量电阻值的变化,可以判断煤气的浓度是否超标。

【3】蜂鸣器:用于发出报警声音,提醒人们注意。选择合适的蜂鸣器需要考虑其音量大小、工作电压和驱动方式等因素。

【4】LED灯:用于提醒人们注意并指示报警状态。选择合适的LED需要考虑其亮度、工作电压和颜色等因素。

【5】SIM800C模块:用于发送报警短信。SIM800C是一款支持GSM/GPRS通信的模块,可以通过AT指令与主控芯片进行通信。它具有较小的体积、低功耗和稳定的性能,适合物联网应用中的短信通信需求。

三、系统设计思路

软件设计思路:

【1】初始化:对STM32F103C8T6单片机和外设进行初始化设置,包括引脚配置、时钟设置等。

【2】煤气检测:使用ADC模块读取MQ-5传感器的模拟信号,并转换为相应的数字值。

【3】煤气浓度判断:根据传感器的特性曲线,将读取到的数字值转换为实际的煤气浓度。

【4】报警判断:判断煤气浓度是否超过设定的安全阈值。

【5】报警处理:

  • 控制蜂鸣器发出报警声。
  • 控制LED灯光闪烁。
  • 使用SIM800C模块发送报警短信给指定的联系人。

【6】主循环:在主循环中不断进行煤气检测和报警判断,保持系统的实时监测和报警功能。

伪代码示例:

初始化:
    初始化STM32F103C8T6单片机和外设设置
    
主循环:
    while (true) {
        煤气检测();
        煤气浓度判断();
        报警判断();
        延时一段时间;
    }

煤气检测:
    读取MQ-5传感器的模拟信号;
    将模拟信号转换为数字值;

煤气浓度判断:
    根据传感器的特性曲线,将数字值转换为实际的煤气浓度;

报警判断:
    if (煤气浓度超过安全阈值) {
        报警处理();
    }

报警处理:
    控制蜂鸣器发出报警声;
    控制LED灯光闪烁;
    使用SIM800C模块发送报警短信给指定的联系人;

四、代码实现

4.1 主程序

#include "stm32f10x.h"

// 定义蜂鸣器控制引脚和LED控制引脚
#define BUZZER_PIN      GPIO_Pin_0
#define BUZZER_PORT     GPIOA

#define LED_PIN         GPIO_Pin_1
#define LED_PORT        GPIOA

// 定义煤气传感器控制引脚
#define GAS_SENSOR_PIN  GPIO_Pin_2
#define GAS_SENSOR_PORT GPIOA

// 定义SIM800C模块的发送引脚
#define SIM800C_SEND_PIN    GPIO_Pin_3
#define SIM800C_SEND_PORT   GPIOA

// 定义报警阈值
#define THRESHOLD           1000

// 声明函数原型
void GPIO_Init(void);
void ADC_Init(void);
void Buzzer_Alarm(void);
void LED_Flash(void);
void Send_SMS(void);

int main(void)
{
    
    
    // 初始化GPIO和ADC
    GPIO_Init();
    ADC_Init();

    while (1)
    {
    
    
        // 进行煤气浓度检测
        u16 gasValue = ADC_GetConversionValue(ADC1);

        // 如果煤气浓度超过阈值,则触发报警
        if (gasValue > THRESHOLD)
        {
    
    
            Buzzer_Alarm();
            LED_Flash();
            Send_SMS();
        }
    }
}

// GPIO初始化函数
void GPIO_Init(void)
{
    
    
    // 打开GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitTypeDef gpioInitStruct;

    // 配置蜂鸣器引脚为推挽输出
    gpioInitStruct.GPIO_Pin = BUZZER_PIN;
    gpioInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(BUZZER_PORT, &gpioInitStruct);

    // 配置LED引脚为推挽输出
    gpioInitStruct.GPIO_Pin = LED_PIN;
    gpioInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_PORT, &gpioInitStruct);

    // 配置煤气传感器引脚为模拟输入
    gpioInitStruct.GPIO_Pin = GAS_SENSOR_PIN;
    gpioInitStruct.GPIO_Mode = GPIO_Mode_AIN;
    gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GAS_SENSOR_PORT, &gpioInitStruct);

    // 配置SIM800C模块的发送引脚为推挽输出
    gpioInitStruct.GPIO_Pin = SIM800C_SEND_PIN;
    gpioInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SIM800C_SEND_PORT, &gpioInitStruct);
}

// ADC初始化函数
void ADC_Init(void)
{
    
    
    // 打开ADC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    ADC_InitTypeDef adcInitStruct;

    // ADC配置
    adcInitStruct.ADC_Mode = ADC_Mode_Independent;
    adcInitStruct.ADC_ScanConvMode = DISABLE;
    adcInitStruct.ADC_ContinuousConvMode = ENABLE;
    adcInitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    adcInitStruct.ADC_DataAlign = ADC_DataAlign_Right;
    adcInitStruct.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &adcInitStruct);

    // 配置ADC通道
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_55Cycles5);

    // 打开ADC
    ADC_Cmd(ADC1, ENABLE);

    // 开始ADC转换
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

// 触发蜂鸣器报警
void Buzzer_Alarm(void)
{
    
    
    GPIO_SetBits(BUZZER_PORT, BUZZER_PIN);   // 打开蜂鸣器
    Delay(1000);                            // 延时一段时间
    GPIO_ResetBits(BUZZER_PORT, BUZZER_PIN); // 关闭蜂鸣器
}

// LED闪烁提醒
void LED_Flash(void)
{
    
    
    for (int i = 0; i < 10; i++)
    {
    
    
        GPIO_SetBits(LED_PORT, LED_PIN);     // 打开LED
        Delay(500);                          // 延时一段时间
        GPIO_ResetBits(LED_PORT, LED_PIN);   // 关闭LED
        Delay(500);                          // 延时一段时间
    }
}

// 发送报警短信
void Send_SMS(void)
{
    
    
    // 这里编写与SIM800C模块通信的代码,发送报警短信
}

4.2 SIM800C代码

#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>

// 定义SIM800C模块的串口引脚
#define SIM800C_USART           USART2
#define SIM800C_USART_GPIO      GPIOA
#define SIM800C_USART_TX_PIN    GPIO_Pin_2
#define SIM800C_USART_RX_PIN    GPIO_Pin_3

// 定义发送缓冲区和接收缓冲区的大小
#define TX_BUFFER_SIZE  128
#define RX_BUFFER_SIZE  128

// 声明全局变量
char tx_buffer[TX_BUFFER_SIZE]; // 发送缓冲区
char rx_buffer[RX_BUFFER_SIZE]; // 接收缓冲区
uint8_t rx_index = 0;           // 接收缓冲区索引

// 函数原型
void USART2_Init(void);
void USART2_SendString(const char* string);
void USART2_IRQHandler(void);
void Send_AT_Command(const char* at_command);
void Send_SMS(void);

int main(void)
{
    
    
    USART2_Init();
    
    while (1)
    {
    
    
        // 在主循环中调用Send_SMS函数即可触发发送短信
    }
}

// 初始化USART2
void USART2_Init(void)
{
    
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);    // 打开GPIOA和AFIO时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);                          // 打开USART2时钟

    GPIO_InitTypeDef gpioInitStruct;
    USART_InitTypeDef usartInitStruct;
    NVIC_InitTypeDef nvicInitStruct;

    // 配置USART2的GPIO引脚
    gpioInitStruct.GPIO_Pin = SIM800C_USART_TX_PIN;
    gpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SIM800C_USART_GPIO, &gpioInitStruct);

    gpioInitStruct.GPIO_Pin = SIM800C_USART_RX_PIN;
    gpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(SIM800C_USART_GPIO, &gpioInitStruct);

    // 配置USART2
    usartInitStruct.USART_BaudRate = 115200;
    usartInitStruct.USART_WordLength = USART_WordLength_8b;
    usartInitStruct.USART_StopBits = USART_StopBits_1;
    usartInitStruct.USART_Parity = USART_Parity_No;
    usartInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    usartInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(SIM800C_USART, &usartInitStruct);

    // 配置USART2中断
    nvicInitStruct.NVIC_IRQChannel = USART2_IRQn;
    nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    nvicInitStruct.NVIC_IRQChannelSubPriority = 0;
    nvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvicInitStruct);

    // 启动USART2接收中断
    USART_ITConfig(SIM800C_USART, USART_IT_RXNE, ENABLE);

    // 启动USART2
    USART_Cmd(SIM800C_USART, ENABLE);
}

// 发送字符串到USART2
void USART2_SendString(const char* string)
{
    
    
    uint16_t length = strlen(string);
    for (uint16_t i = 0; i < length; i++)
    {
    
    
        USART_SendData(SIM800C_USART, string[i]);
        while (USART_GetFlagStatus(SIM800C_USART, USART_FLAG_TXE) == RESET);
    }
}

// USART2中断处理函数
void USART2_IRQHandler(void)
{
    
    
    if (USART_GetITStatus(SIM800C_USART, USART_IT_RXNE) != RESET)
    {
    
    
        char receivedData = USART_ReceiveData(SIM800C_USART);
        rx_buffer[rx_index++] = receivedData;

        // 处理接收到的数据
        // ...

        USART_ClearITPendingBit(SIM800C_USART, USART_IT_RXNE);
    }
}

// 发送AT指令
void Send_AT_Command(const char* at_command)
{
    
    
    memset(rx_buffer, 0, RX_BUFFER_SIZE); // 清空接收缓冲区
    rx_index = 0;

    USART2_SendString(at_command);

    // 等待模块返回数据
    while (strncmp(rx_buffer, "OK", 2) != 0 && strncmp(rx_buffer, "ERROR", 5) != 0)
    {
    
    
        // 延时一段时间
        Delay(10);
    }

    // 处理模块返回的数据
    // ...
}

// 发送短信
void Send_SMS(void)
{
    
    
    // 发送AT指令设置短信模式
    Send_AT_Command("AT+CMGF=1\r\n");

    // 发送AT指令设置短信收件人和内容
    Send_AT_Command("AT+CMGS=\"+861**********\"\r\n");
    Send_AT_Command("Hello, this is a test message.\r\n");

    // 发送短信结束标志(Ctrl+Z)
    USART2_SendString("\x1A");
}

五、总结

本项目设计了一个基于单片机的煤气泄漏检测报警装置,通过使用STM32F103C8T6作为主控芯片和MQ-5煤气传感器进行煤气检测,有效地提醒用户煤气泄漏的危险。通过控制蜂鸣器和LED灯的报警机制,以及使用SIM800C模块发送报警短信,用户可以及时采取措施来避免潜在的危险。这个项目结合了硬件设计和嵌入式软件开发的知识,为用户提供了一个可靠的煤气泄漏检测报警解决方案。

猜你喜欢

转载自blog.csdn.net/xiaolong1126626497/article/details/133266468