基于ZIGBEE烟雾报警系统
目录:
1、任务书
2、设计思路
3、实现代码
4、上位机页面
1、任务书
1)检测地点的温度、湿度及烟雾浓度
2)前端服务平台实时反应显示监测地点的监测数据,若有异常及时反馈。根据设定的数据阈值和定时时间,判断温度、湿度、烟雾浓度数据是否达到报警要求(根据温湿度、烟雾浓度决定报警状态,不同浓度有不同报警状态),报警则发出光、声报警,并向手机/119 发送报警短信。
2、设计思路
主控采用STM32F103C8系列单片机,采用DHT11采集温湿度;MQ-2烟雾气敏模块采集烟雾浓度;zigbee无限串口收发作为通信模块;蜂鸣器作为报警方式;SIM800A作为通信模块;OLED作为显示屏幕。
通过单片机采集温湿度,烟雾浓度等信息,zigbee串口可以发送信息(该模块通过基础配置即可通信,配置成单对单),当出现烟雾浓度过高等或者温湿度异常,即发送报警信息,同时将报警信息发送到上位机(QT页面),上位机具备取消报警功能。
3、实现代码
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "oled.h"
#include <DHT11.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define HUMstade 20
#define Temstade 20
#define Smokestade 30
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
uint8_t temperature = 1; //温度
uint8_t humidity = 1; //湿度
u8 buzz_stat=0; //蜂鸣器状态
u8 TIM2_i=0;
u32 GAS_VALUE;
u32 DIS_GAS=0;
u32 oled_GAS;
u8 buff;
u8 Send_buff[13]="C9H30T22S69A0";
u8 KEY_state = 0; //上位机是否取消报警 0:未处理 1:上位机取消报警
u8 str1[]= "AT+CSCS=\"GSM\"\r\n"; //发送短息基础指令
u8 str2[]="AT+CMGF=1\r\n";
u8 str3[]="AT+CMGS=\"1********3\"\r\n"; //电话号码
u8 str4[]="Alarm:Have fire at home\r\n"; //发送内容
u8 str5 =0x1a; //结束发送指令
u8 alarm_new_state=0; //发送报警信息状态
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void Alarm_Buzz(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
GAS_VALUE=HAL_ADC_GetValue(&hadc1); //获取ADC的值 12位ADC,0-4095
GAS_VALUE=GAS_VALUE*100/(4095); //将采集到的数据归一化,转化成百分制
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //中断服务函数
{
if(htim->Instance == TIM2) //500ms
{
//Send_state=0;
HAL_ADC_Start_IT(&hadc1); //打开ADC中断
DIS_GAS+=GAS_VALUE; //累加气体数据的值,为后边均值做准备
TIM2_i++; //一个计数变量累加
OLED_ShowString(0,0,(u8*)"T=",16,1);
OLED_ShowNum(16,0,temperature,2,16,1); //显示温度
OLED_ShowString(0,16,(u8*)"H=",16,1);
OLED_ShowNum(16,16,humidity,2,16,1); //显示湿度
Send_buff[3]=humidity/10 +0X30; //52 0x30---'0'
Send_buff[4]=humidity%10 +0X30;
Send_buff[6]=temperature/10 +0X30;
Send_buff[7]=temperature%10 +0X30;
OLED_Refresh(); //刷新下屏幕
if((oled_GAS>=30)&&KEY_state==0){
buzz_stat=1; //报警状态
}
else if((oled_GAS<30)||KEY_state==1){
buzz_stat=0; //正常状态
}
Alarm_Buzz();
if(TIM2_i%4==0) //没四次进入一次执行
{
oled_GAS=DIS_GAS/4; //滤波 烟雾浓度气体
OLED_ShowString(48,0,(u8*)"G=",16,1);
OLED_ShowNum(64,0,oled_GAS,2,16,1); //气体采样数值 均值滤波
Send_buff[9]=(oled_GAS)/10 +0X30;
Send_buff[10]=(oled_GAS)%10 +0X30;
if((oled_GAS>=30)&&KEY_state==0) buzz_stat=1; //报警状态 如果烟雾浓度高于30,并且没有按下取消按键
else if(KEY_state==1) buzz_stat=0; //正常状态 低电平蜂鸣器会叫
Send_buff[12]=buzz_stat +0X30; //把报警状态发送到上位机
OLED_Refresh(); //更新显示
HAL_UART_Transmit(&huart1,Send_buff,13,0xfff); //发送到上位机的数据包
//发送 阻塞发送
DIS_GAS=0; //归零 重新累加
}
if(TIM2_i>127) TIM2_i=0; //计数清零
}
}
void Alarm_Buzz() //报警信息
{
if(buzz_stat==1) { //报警
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); //低电平 蜂鸣器报警
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); //低电平 LED亮
if(alarm_new_state>0) alarm_new_state=2; //发送报警信息 //2
alarm_new_state++; //1->3->3 数据溢出
}
else {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); //高电平,蜂鸣器不叫
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); //高电平 LED亮
alarm_new_state=0; //发送状态清零
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口中断服务函数
{
if(huart->Instance==USART1) //上位机用的是串口1
{
if(buff=='A') //取消
{
KEY_state=1; //取消报警状态
buff=' ';
}
}
}
void NewAlarn() //手机短信报警信息
{
if(alarm_new_state==1) //开始发送报警信息
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
HAL_UART_Transmit(&huart2,str1,15,0xfff);
HAL_Delay(500);
HAL_UART_Transmit(&huart2,str2,11,0xfff);
HAL_Delay(500);
HAL_UART_Transmit(&huart2,str3,23,0xfff);
HAL_Delay(500);
HAL_UART_Transmit(&huart2,str4,25,0xfff);
HAL_Delay(500);
HAL_UART_Transmit(&huart2,&str5,1,0xfff);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM2_Init();
MX_USART1_UART_Init();
MX_ADC1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_Delay(500); //防止oled花屏
DHT11_Strat(); //DHT11初始化
OLED_Init(); //OLED初始化
OLED_DisPlay_On(); //打开屏幕
HAL_TIM_Base_Start_IT(&htim2); //打开定时器2
HAL_UART_Transmit(&huart1,(u8*)"C9H35T22S10A0",13,0xfff);//一开机给我们上位机发送初始化的数据
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
OLED_ShowNum(48,16,KEY_state,1,16,1); //按键状态
OLED_Refresh(); //更新OLED显示
if(((oled_GAS)<30) )KEY_state=0; //
DHT11_Read_Data(&temperature,&humidity); //不断读取DHT11温湿度 采集速度比较慢 放中断卡死
HAL_UART_Receive_IT(&huart1,&buff,1);
//Alarm_Buzz();
NewAlarn();
}
//printf("公主号:三颗金子");//获取完整工程
/* USER CODE END 3 */
}
4、上位机界面