一、項(xiàng)目介紹
煤氣泄漏是一種常見的危險(xiǎn)情況,可能導(dǎo)致火災(zāi)、爆炸和人員傷亡。為了及時(shí)發(fā)現(xiàn)煤氣泄漏并采取相應(yīng)的安全措施,設(shè)計(jì)了一種基于單片機(jī)的煤氣泄漏檢測(cè)報(bào)警裝置。
主控芯片采用STM32F103C8T6作為主控芯片,具有強(qiáng)大的計(jì)算和控制能力。煤氣檢測(cè)傳感器選擇了MQ-5,它能夠檢測(cè)到環(huán)境中的煤氣濃度,并將其轉(zhuǎn)換為電信號(hào)輸出。裝置通過讀取傳感器輸出的模擬信號(hào),并經(jīng)過ADC轉(zhuǎn)換獲得相應(yīng)的數(shù)字值,實(shí)時(shí)監(jiān)測(cè)煤氣濃度。
當(dāng)檢測(cè)到煤氣濃度超過設(shè)定的安全閾值時(shí),裝置會(huì)觸發(fā)報(bào)警機(jī)制。通過控制蜂鳴器發(fā)出高頻報(bào)警聲,吸引人的注意并提醒危險(xiǎn)情況。同時(shí),裝置會(huì)控制LED燈光閃爍,以視覺方式提醒用戶。這樣的多重報(bào)警方式可以在不同環(huán)境中有效地引起人們的警覺。
為了進(jìn)一步提高報(bào)警的及時(shí)性和可靠性,還集成了SIM800C模塊,用于發(fā)送報(bào)警短信給指定的聯(lián)系人。當(dāng)煤氣濃度超標(biāo)時(shí),裝置會(huì)通過SIM800C模塊發(fā)送預(yù)先設(shè)定的報(bào)警短信,通知相關(guān)人員及時(shí)采取措施。
通過以上設(shè)計(jì),基于單片機(jī)的煤氣泄漏檢測(cè)報(bào)警裝置能夠?qū)崟r(shí)監(jiān)測(cè)環(huán)境中的煤氣濃度,并在檢測(cè)到異常情況時(shí)通過聲光報(bào)警和短信通知提醒用戶。這樣的裝置可以廣泛應(yīng)用于家庭、工業(yè)和商業(yè)環(huán)境中,為人們的生命財(cái)產(chǎn)安全提供有效的保障。
二、硬件選型
在這個(gè)設(shè)計(jì)中,選擇了下面的硬件來實(shí)現(xiàn)煤氣泄漏檢測(cè)報(bào)警裝置。
【1】主控芯片:STM32F103C8T6。該芯片是一款強(qiáng)大的低功耗微控制器,具有豐富的外設(shè)和良好的性能。它集成了多個(gè)通用輸入輸出引腳、模數(shù)轉(zhuǎn)換器 (ADC)、定時(shí)器和串行接口等功能,適合用于各種嵌入式應(yīng)用。
【2】煤氣檢測(cè)傳感器:MQ-5。MQ-5是一種常見的煤氣傳感器,可檢測(cè)到液化石油氣(LPG)、天然氣和甲烷等可燃?xì)怏w。它基于半導(dǎo)體氣敏材料,當(dāng)檢測(cè)到目標(biāo)氣體濃度超過設(shè)定閾值時(shí),其電阻值發(fā)生變化。通過測(cè)量電阻值的變化,可以判斷煤氣的濃度是否超標(biāo)。
【3】蜂鳴器:用于發(fā)出報(bào)警聲音,提醒人們注意。選擇合適的蜂鳴器需要考慮其音量大小、工作電壓和驅(qū)動(dòng)方式等因素。
【4】LED燈:用于提醒人們注意并指示報(bào)警狀態(tài)。選擇合適的LED需要考慮其亮度、工作電壓和顏色等因素。
【5】SIM800C模塊:用于發(fā)送報(bào)警短信。SIM800C是一款支持GSM/GPRS通信的模塊,可以通過AT指令與主控芯片進(jìn)行通信。它具有較小的體積、低功耗和穩(wěn)定的性能,適合物聯(lián)網(wǎng)應(yīng)用中的短信通信需求。
三、系統(tǒng)設(shè)計(jì)思路
軟件設(shè)計(jì)思路:
【1】初始化:對(duì)STM32F103C8T6單片機(jī)和外設(shè)進(jìn)行初始化設(shè)置,包括引腳配置、時(shí)鐘設(shè)置等。
【2】煤氣檢測(cè):使用ADC模塊讀取MQ-5傳感器的模擬信號(hào),并轉(zhuǎn)換為相應(yīng)的數(shù)字值。
【3】煤氣濃度判斷:根據(jù)傳感器的特性曲線,將讀取到的數(shù)字值轉(zhuǎn)換為實(shí)際的煤氣濃度。
【4】報(bào)警判斷:判斷煤氣濃度是否超過設(shè)定的安全閾值。
【5】報(bào)警處理:
- 控制蜂鳴器發(fā)出報(bào)警聲。
- 控制LED燈光閃爍。
- 使用SIM800C模塊發(fā)送報(bào)警短信給指定的聯(lián)系人。
【6】主循環(huán):在主循環(huán)中不斷進(jìn)行煤氣檢測(cè)和報(bào)警判斷,保持系統(tǒng)的實(shí)時(shí)監(jiān)測(cè)和報(bào)警功能。
偽代碼示例:
初始化:
初始化STM32F103C8T6單片機(jī)和外設(shè)設(shè)置
主循環(huán):
while (true) {
煤氣檢測(cè)();
煤氣濃度判斷();
報(bào)警判斷();
延時(shí)一段時(shí)間;
}
煤氣檢測(cè):
讀取MQ-5傳感器的模擬信號(hào);
將模擬信號(hào)轉(zhuǎn)換為數(shù)字值;
煤氣濃度判斷:
根據(jù)傳感器的特性曲線,將數(shù)字值轉(zhuǎn)換為實(shí)際的煤氣濃度;
報(bào)警判斷:
if (煤氣濃度超過安全閾值) {
報(bào)警處理();
}
報(bào)警處理:
控制蜂鳴器發(fā)出報(bào)警聲;
控制LED燈光閃爍;
使用SIM800C模塊發(fā)送報(bào)警短信給指定的聯(lián)系人;
四、代碼實(shí)現(xiàn)
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模塊的發(fā)送引腳
#define SIM800C_SEND_PIN GPIO_Pin_3
#define SIM800C_SEND_PORT GPIOA
// 定義報(bào)警閾值
#define THRESHOLD 1000
// 聲明函數(shù)原型
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)
{
// 進(jìn)行煤氣濃度檢測(cè)
u16 gasValue = ADC_GetConversionValue(ADC1);
// 如果煤氣濃度超過閾值,則觸發(fā)報(bào)警
if (gasValue > THRESHOLD)
{
Buzzer_Alarm();
LED_Flash();
Send_SMS();
}
}
}
// GPIO初始化函數(shù)
void GPIO_Init(void)
{
// 打開GPIO時(shí)鐘
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模塊的發(fā)送引腳為推挽輸出
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初始化函數(shù)
void ADC_Init(void)
{
// 打開ADC時(shí)鐘
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轉(zhuǎn)換
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
// 觸發(fā)蜂鳴器報(bào)警
void Buzzer_Alarm(void)
{
GPIO_SetBits(BUZZER_PORT, BUZZER_PIN); // 打開蜂鳴器
Delay(1000); // 延時(shí)一段時(shí)間
GPIO_ResetBits(BUZZER_PORT, BUZZER_PIN); // 關(guān)閉蜂鳴器
}
// LED閃爍提醒
void LED_Flash(void)
{
for (int i = 0; i < 10; i++)
{
GPIO_SetBits(LED_PORT, LED_PIN); // 打開LED
Delay(500); // 延時(shí)一段時(shí)間
GPIO_ResetBits(LED_PORT, LED_PIN); // 關(guān)閉LED
Delay(500); // 延時(shí)一段時(shí)間
}
}
// 發(fā)送報(bào)警短信
void Send_SMS(void)
{
// 這里編寫與SIM800C模塊通信的代碼,發(fā)送報(bào)警短信
}
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
// 定義發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小
#define TX_BUFFER_SIZE 128
#define RX_BUFFER_SIZE 128
// 聲明全局變量
char tx_buffer[TX_BUFFER_SIZE]; // 發(fā)送緩沖區(qū)
char rx_buffer[RX_BUFFER_SIZE]; // 接收緩沖區(qū)
uint8_t rx_index = 0; // 接收緩沖區(qū)索引
// 函數(shù)原型
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)
{
// 在主循環(huán)中調(diào)用Send_SMS函數(shù)即可觸發(fā)發(fā)送短信
}
}
// 初始化USART2
void USART2_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); // 打開GPIOA和AFIO時(shí)鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 打開USART2時(shí)鐘
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);
// 啟動(dòng)USART2接收中斷
USART_ITConfig(SIM800C_USART, USART_IT_RXNE, ENABLE);
// 啟動(dòng)USART2
USART_Cmd(SIM800C_USART, ENABLE);
}
// 發(fā)送字符串到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中斷處理函數(shù)
void USART2_IRQHandler(void)
{
if (USART_GetITStatus(SIM800C_USART, USART_IT_RXNE) != RESET)
{
char receivedData = USART_ReceiveData(SIM800C_USART);
rx_buffer[rx_index++] = receivedData;
// 處理接收到的數(shù)據(jù)
// ...
USART_ClearITPendingBit(SIM800C_USART, USART_IT_RXNE);
}
}
// 發(fā)送AT指令
void Send_AT_Command(const char* at_command)
{
memset(rx_buffer, 0, RX_BUFFER_SIZE); // 清空接收緩沖區(qū)
rx_index = 0;
USART2_SendString(at_command);
// 等待模塊返回?cái)?shù)據(jù)
while (strncmp(rx_buffer, "OK", 2) != 0 && strncmp(rx_buffer, "ERROR", 5) != 0)
{
// 延時(shí)一段時(shí)間
Delay(10);
}
// 處理模塊返回的數(shù)據(jù)
// ...
}
// 發(fā)送短信
void Send_SMS(void)
{
// 發(fā)送AT指令設(shè)置短信模式
Send_AT_Command("AT+CMGF=1rn");
// 發(fā)送AT指令設(shè)置短信收件人和內(nèi)容
Send_AT_Command("AT+CMGS="+861**********"rn");
Send_AT_Command("Hello, this is a test message.rn");
// 發(fā)送短信結(jié)束標(biāo)志(Ctrl+Z)
USART2_SendString("x1A");
}
五、總結(jié)
本項(xiàng)目設(shè)計(jì)了一個(gè)基于單片機(jī)的煤氣泄漏檢測(cè)報(bào)警裝置,通過使用STM32F103C8T6作為主控芯片和MQ-5煤氣傳感器進(jìn)行煤氣檢測(cè),有效地提醒用戶煤氣泄漏的危險(xiǎn)。通過控制蜂鳴器和LED燈的報(bào)警機(jī)制,以及使用SIM800C模塊發(fā)送報(bào)警短信,用戶可以及時(shí)采取措施來避免潛在的危險(xiǎn)。這個(gè)項(xiàng)目結(jié)合了硬件設(shè)計(jì)和嵌入式軟件開發(fā)的知識(shí),為用戶提供了一個(gè)可靠的煤氣泄漏檢測(cè)報(bào)警解決方案。