传入预警信息, 应急处理
引言
之前我们是直接在while循环里面, 直接访问全局变量环境温度temp和温度阈值temp_th , 然后直接做出判断.
但是我们如果代码器件一多, 就会显得非常臃肿, 所以我们就相当于找一个功能函数, 我们只需要传入环境信息和阈值信息, 应急系统根据对应的数据,做出相应的措施就可以了.
我们举出一个最简单的例子
定义所有器件情况
int deal_mode;
调用函数 (monitor 监控)
deal_mode = ararm_monitor(温度,湿度,温度阈值,湿度阈值);
然后, 我们根据操作函数, 返回的数据, 从而进行对应的器件处理
我们在 ararm_deal(温度,湿度,温度阈值,湿度阈值); 操作函数里面, 进行处理判断, 我们提前对所有情况进行预演判断, 从而根据这些情况, 返回对应的数字.后续我们再根据对应的器件处理数字, 进行对应的处理
情况预演举例
(1)温度异常 , temp >= temp_th
红灯亮, 返回 1
(2)湿度异常 , humi >= humi_th
蓝灯亮, 返回 2
(3)一切正常, 返回 0
器件处理
我们根据 返回的 deal_mode 进行处理操作
我们再定义一个函数, 传入刚才处理过的 ararm_deal(deal_mode);
(1) 如果 deal_mode == 0 , 则 把应急器件关闭
(2) 如果 deal_mode == 1 , 则打开红灯
(3) 如果 deal_mode == 2 , 则打开蓝灯
代码实操:
我们先直接开始写, 然后把这些代码复制黏贴过去, 我们这个工程 是在预警器件控制思考的基础上构建的, 基础工程链接如下(ctrl加鼠标左键跳转):
基础上修改:
本博客修改完的:
https://ww0.lanzoul.com/iYb1d273fdgh
失效联系qq2958360390, 回复关键词:传入预警信息应急处理
(1)定义预警模式变量
定义 deal_mode 变量, 代表我们预警判断后, 应该处于哪种模式
int deal_mode;
(2)定义传入预警检测函数
ararm_monitor(temp, humi, temp_th, humi_th);
具体函数定义处理:
int ararm_monitor(uint8_t temp,uint8_t humi,uint8_t temp_th, uint8_t humi_th);
分析相关变量:
传入了温度,湿度,以及相关阈值,我们通过判断,和之前预演的情况,进行对应的处理。
① 先注释 我们之前的代码
② 我们虽然没有写好那个预警判断函数, 但是我们先传入数据, 后面根据这些数据进行构建, 这些是没问题的,来跟我走
main函数调用:
deal_mode = ararm_monitor(temp,humi,temp_th,humi_th);
③ 我们先一切从简, 去main.c函数里面定义子函数,等后面我们器件越来越多的时候, 我们再去把他们择出来构建子文件.
先在main函数之前声明一下 预警检测函数
int ararm_monitor(uint8_t temp,uint8_t humi,uint8_t temp_th, uint8_t humi_th);
④ 有了这个声明, 我们在main.c里面任何地方去构建此子函数都可以
⑤ 下面我们根据提前定义的三种情况, 通过判断, 然后return对应的数字, 方便后续器件处理, 所以我们现在函数的功能就是 环境正常, 就返回0 , 温度异常就返回 1, 湿度异常就返回 0 ,
解耦处理原因:
我们不必立即处理器件, 因为后续功能复杂后, 立即处理, 会把预警信息和器件处理混为一谈, 导致安全不能到位,排查不能清晰。
编写代码遇到问题
环境正常情况下,是 temp < temp_th 和 humi < humi_th
但是, 我们是同时预警的温度和湿度, 存在一种情况, 是温湿度同时报警, 如果并且判断, 因为只有一个result变量承接预警信息, 并且就会把上一个环境预警信号覆盖了, 所以 我们要把所有情况都包含考虑 , 然后分序号标注:
<1>温度正常, 湿度异常 返回 1
<2>温度异常,湿度正常 返回 2
<3>温度,湿度都异常 返回 3
<4>温度湿度都正常 返回 0
所以我们再次进行构建相关代码, 这次我们所有预警信息, 只会出现上面的这一种情况, 所以我们就可以用 if else, 把他们组合起来了,
代码如下:
int ararm_monitor(uint8_t temp,uint8_t humi,uint8_t temp_th, uint8_t humi_th)
{
int result;
//(1)温度正常, 湿度异常
if(temp < temp_th && humi >= humi_th)
{
result = 1;
}
else //(2)温度异常,湿度正常
if(temp >= temp_th && humi < humi_th)
{
result = 2;
}
else //(3)温度,湿度都异常
if(temp >= temp_th && humi >= humi_th)
{
result = 3;
}
else //(4)温度,湿度都正常
if(temp < temp_th && humi < humi_th)
{
result = 0;
}
return result;
}
(3)根据返回的数值 , 进行对应的器件应急处理
函数情况分析:
因为情况比较多, 我们使用switch函数
① 返回值 1:温度正常, 湿度异常 ,打开蓝灯, 关闭红灯
humi_led_Set(blue_led_ON);
temp_led_Set(red_led_OFF);
② 返回值 2:温度异常, 湿度正常 ,打开红灯, 关闭蓝灯
temp_led_Set(red_led_ON);
humi_led_Set(blue_led_OFF);
③ 返回值 3:温度,湿度都异常 , 打开蓝灯和红灯
humi_led_Set(blue_led_ON);
temp_led_Set(red_led_ON);
④ 返回值 0: 温度,湿度都正常, 关闭蓝灯和红灯
humi_led_Set(blue_led_OFF);
temp_led_Set(red_led_OFF);
声明子函数:
void ararm_deal(int alarm_mode);
函数调用:
ararm_deal(deal_mode);
子函数实现:
void ararm_deal(int alarm_mode)
{
switch(alarm_mode)
{
case 0:
humi_led_Set(blue_led_OFF);
temp_led_Set(red_led_OFF);
break;
case 1: humi_led_Set(blue_led_ON);
temp_led_Set(red_led_OFF);
break;
case 2: humi_led_Set(blue_led_OFF);
temp_led_Set(red_led_ON);
break;
case 3:
humi_led_Set(blue_led_ON);
temp_led_Set(red_led_ON);
break;
default:break;
}
}
具体main函数调用:
//(3)每时每刻判断环境信息是否异常
//判断预警处理
deal_mode = ararm_monitor(temp,humi,temp_th,humi_th);
//根据器件预警信息, 进行应急操作
ararm_deal(deal_mode);
现象调试:
通过调整阈值 , 来进行判断, 其实我们也可以通过更改oled显示的数值, 来显示, 我们是否设置成功
(4)main.c 函数的源代码(在原有基础上, 其他的文件没变,就动了main.c)
#include "stm32f10x.h" // Device header
#include "sys.h"
#include "delay.h"
#include "dht11.h"
#include "OLED.h"
#include "humi_led.h"
#include "temp_led.h"
uint8_t temp; //读取的环境温度
uint8_t humi; //读取的环境湿度
uint8_t temp_th; //设置的温度阈值
uint8_t humi_th; //设置的湿度阈值
_Bool red_led; //(温度指示灯)
_Bool blue_led; //(湿度指示灯)
_Bool set_limit; //管理员是否设置阈值
led小灯初始化
//void led_init(void);
int deal_mode;
int ararm_monitor(uint8_t temp,uint8_t humi,uint8_t temp_th, uint8_t humi_th);
void ararm_deal(int alarm_mode);
int main()
{
unsigned short timeCount = 0; //发送间隔变量
//手动设置环境温度(模拟上帝)
temp = 66; //温度是28度
humi = 60; //湿度是60%
//手动设置阈值(代替远程)
temp_th = 30; //温度阈值是30度
humi_th = 60; //湿度阈值是60%
//小灯状态初始化
red_led = 0;
blue_led = 0;
//测试变量: 管理设置阈值符号位
set_limit = 1;
// //小灯初始化
// led_init();
//滴答定时器
Delay_Init();
//dht11初始化
DHT11_Init();
// while(DHT11_Init())
// {
printf("DHT11 Error \r\n");
// OLED_ShowString(0,48, "DHT11 Error", 8);
// OLED_Update();
// DelayMs(2000);
// }
//oled初始化
OLED_Init();
humi_led_Init();
temp_led_Init();
while(1)
{
//(1)设置环境信息阈值(手动输入代替远程控制)
if(set_limit == 1)
{
temp_th = 10;
humi_th = 22;
//设置完阈值就清零,下次不设置了, 直到set_limit被管理员置1
//然后再次进入此功能函数里,进行设置阈值
set_limit = 0;
}
//(2)读取环境信息 (手动输入代替器件读取)
//if(过了100毫秒) 每隔100毫秒,读取一次, 保证实时性,减轻负担
if(++timeCount >= 10)
{
DHT11_Read_Data(&temp,&humi);
// temp = 99; //人手输入,代替器件,忽略底层,重视逻辑
// humi = 99;
OLED_Clear();
OLED_ShowChinese(0, 0, "温度");
OLED_ShowChinese(0, 24, "湿度:");
OLED_Printf(48,0,OLED_8X16,"%2d",temp);
OLED_Printf(48,16,OLED_8X16,"%2d",humi);
OLED_Printf(48,32,OLED_8X16,"%2d",temp_th);
OLED_Printf(48,48,OLED_8X16,"%2d",humi_th);
OLED_ShowChinese(80,0 , "℃");
OLED_ShowChinese(80,24 , "%");
OLED_Update();
timeCount = 0; //从新计时`
}
DelayXms(10); //10*10 = 100ms
//后面跟 1ms的延时, 我们一切从简,先留着
//(3)每时每刻判断环境信息是否异常
//判断预警处理
deal_mode = ararm_monitor(temp,humi,temp_th,humi_th);
//根据器件预警信息, 进行应急操作
ararm_deal(deal_mode);
// if(temp >= temp_th)
// {
// //启动器件
// temp_led_Set(red_led_ON);
//
// }
// else //同理,环境正常时候
// {
// temp_led_Set(red_led_OFF);
// }
// //判断湿度是否报警
// //每时每刻判断环境信息是否异常
// if(humi >= humi_th)
// {
// humi_led_Set(blue_led_ON);
//
if(blue_led == 0) //如果是关闭状态则启动,开启则无操作
{
blue_led = 1;
PBout(4) = 1;
}
// }
// else //同理,环境正常时候
// {
// humi_led_Set(blue_led_OFF);
if(blue_led == 1) //如果是开启状态则启动,关闭则无操作
{
blue_led = 0;
PBout(4) = 0;
}
// }
}
}
///**************************************************
//函数名: led_init
//功 能: 温湿度,烟雾浓度小灯初始化
//参 数: 无
//配置参数: PB3(温度) PB4(湿度) PB5(烟雾浓度)
// 推挽输出
// 小灯正极接io口, 负极接地
//返回值: 无
//**************************************************/
//void led_init(void)
//{
// //初始化小灯 , PB3(温度) PB4(湿度) PB5(烟雾浓度)
// GPIO_InitTypeDef GPIO_InitStructure;
// //开启硬件时钟 PB5
// /* GPIOD Periph clock enable */
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// //开启AFIO时钟
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// //禁用JTAGD端口
// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
// //配置 pB 3 4 5 GPIO工作模式(推挽输出)
// /* Configure PD0 and PD2 in output pushpull mode */
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_Init(GPIOB, &GPIO_InitStructure); //配置端口
// //控制端口寄存器GPIO输出电平
// PBout(3) = 0;//temp_led
// PBout(4) = 0; //humi_led
PBout(5) = 0; //mq2_led
//
//}
int ararm_monitor(uint8_t temp,uint8_t humi,uint8_t temp_th, uint8_t humi_th)
{
int result;
//(1)温度正常, 湿度异常
if(temp < temp_th && humi >= humi_th)
{
result = 1;
}
else //(2)温度异常,湿度正常
if(temp >= temp_th && humi < humi_th)
{
result = 2;
}
else //(3)温度,湿度都异常
if(temp >= temp_th && humi >= humi_th)
{
result = 3;
}
else //(4)温度,湿度都正常
if(temp < temp_th && humi < humi_th)
{
result = 0;
}
return result;
}
void ararm_deal(int alarm_mode)
{
switch(alarm_mode)
{
case 0:
humi_led_Set(blue_led_OFF);
temp_led_Set(red_led_OFF);
break;
case 1: humi_led_Set(blue_led_ON);
temp_led_Set(red_led_OFF);
break;
case 2: humi_led_Set(blue_led_OFF);
temp_led_Set(red_led_ON);
break;
case 3:
humi_led_Set(blue_led_ON);
temp_led_Set(red_led_ON);
break;
default:break;
}
}