NB-Iot烟感06:烟雾检测软件实现及详解

一、产品开发功能简介

1.开机自检

LED灯快闪5次,自检迷宫是否漏光,感烟部分的硬件是否正常,异常蜂鸣器长鸣,LED快闪。

2.工作模式

烟雾探测大概4秒左右感应1次烟感。检测是否有 烟雾火灾发生,4秒中检测一次电池是否低压。

LED灯大概48秒左右闪烁一次。

3.烟感报警

测到烟雾报警,LED快闪 蜂鸣器嘀嘀 鸣叫,声音要求 90DB(正向一米远)。

二、程序开发

1.单片机IO 口驱动

HT45F23A的IO 寄存器列表:

PAWUn:PA 唤醒功能控制位

0:除能

1:使能

PAPUn/PBPUn/PCPUn:上拉电阻控制位

0:除能

1:使能

PACn/PBCn/PCCn:输入 / 输出控制位

0:输出

1:输入

PA/PB/PC  IO口控制器

LED闪烁驱动程序。

IO 的初始化 和定义: 通过原理图我们可以查看到LED 连接到PB1

#define    LED_ctrl                  _pbc1        ///IO 输入输出口控制 = 0 输出
#define    LED                         _pb1         /// LED  IO 控制脚
#define    LED_pbpu	        _pbpu1    ///PB 上拉控制脚       = 1

驱动代码
void led_init(void)
{
LED_ctrl = 0;    ///配置为输出
LED_pbpu = 1;  ///使能上拉
      LED   = 0;   ///LED关闭                    
}
void led_open(void)
{
LED   =1;   ///LED关闭      
}
void led_close(void)
{
LED   = 0;   ///LED关闭      
}

2. 按键驱动代码、蜂鸣器控制、数据通讯部分代码

这部分代码都是编程的基础代码,在这里给大家不介绍了,如果不懂可以找我们无际单片机编程获取支持,直接度娘就能搜到。

3. 烟雾探测器部分程序逻辑,代码及烟雾探测器的算法介绍:

烟雾探测红外发射。

迷宫的红外发射管,不能常打开,常打开会导致烟感的待机电流过大。

从原理图可以看出。迷宫的红外发射管是有单片机的PC2控制的。 PC2为单片机红外发射管控制脚。

PC2 需要配置成  输出 /上拉使能。

烟雾探测红外接收部分逻辑分析。

单片机内部的运算放大器2的结构和对应寄存器的配置方式

下表内容为 OPA2 控制寄存器设置与开关状态的关系。

下表内容为 OPA2 I/O 设置及状态。

单片机内部运算放大器1 的内部结构及IO 表格说明。

下表内容为 OPA1 控制寄存器设置与开关状态的关系:

下表内容为 OPA1 I/O 设置及状态。

单片机的内部ADC:

单片机含有一组 12 位的 A/D 转换器,它们转换的最大值可达 FFFH。由于模拟

输入最大值等于 VDD 或 VREF 的电压值,因此每一位可表示 VDD 或 VREF/4096 的

模拟输入值。

1 LSB=(VDD 或 VREF)÷4096.

A/D 转换器的所有工作由五个寄存器控制。

下三个控制寄存器设置 A/D 转换器的操作和控制功能,一对只读寄存器来存放 12 位 ADC

数据的值。

源于OPA1、OPA2、ADC 的底层驱动我就在这里不和大家探讨了。我们直接看一下烟感感应的驱动逻辑和代码:

4.程序开发

检测迷宫是否漏光。

迷宫探测器是一个密闭的环境,如果迷宫的结构有问题,自然光漏进迷宫中,就会造成迷宫工作异常。

因为自然光中包含我们红外接收管的波长光线,如果接收自然光,红外接收管会收到电压量信号。

程序处理办法:上电关闭红外发射管,打开红外接收管,检测红外接收的电压量,如果有电压量,或电压量还偏大,则说明迷宫漏光,探测器异常。

程序代码逻辑:

第1步:关闭红外发射

第2步:OPA1 OPA2 配置打开启动红外接收

第3步:单片机ADC启动,转换OPA1 接收的电压量

第4步:如果ADC转换的值小于2048,表示设备正常,否则异常报警

第5步:单片机的ADC是12位,FFFH 十进制:4096,ADC 的参考电压选择为单片机工作电压3V,则2048对应的电压值为1.5V.

4096 / 2048 = 3/1.5

对应代码如下:   如果返回为1 表示  返回0 表示OK

/************************maze_check**********************************/	
unsigned char maze_check(void)
{
	Vopa1_ctrl	 = 0;                              
	Vopa1 		=1;				//set opa input DC bias source voltage
	_a2en		=1;
	delay500us();
	_a1en		=1;
	delay500us();
	delay500us();
	_emi		=0;
	_adonb=0;	
	GCC_NOP();
	GCC_NOP();
	_adcr=0b00000110;
	_start=0;					//START ADC Converter ADCR.7 								
	_start=1;					//(ADC START bit) 0 -> 1 -> 0
	_start=0;
	GCC_NOP();
	GCC_NOP();					//4 Tad for ADC Sampling Time
	GCC_NOP();
	GCC_NOP();
	_a2en=0;
	_a1en=0;
	Vopa1=0;
	while(_eocb);
	An7_AD_H=_adrh;
	An7_AD_L=_adrl;
	_adonb=1;					//Disable ADC
	_c=0;
	_emi=1;
	GCC_RRC(An7_AD_H);
	GCC_RRC(An7_AD_L);	
	GCC_RRC(An7_AD_H);
	GCC_RRC(An7_AD_L);
	GCC_RRC(An7_AD_H);
	GCC_RRC(An7_AD_L);
	Smoke_value_det=An7_AD_H;
	Smoke_value_det<<=8;
	Smoke_value_det=Smoke_value_det+An7_AD_L;
	//无IR发射AD值大于100,出现初始化错误	
	if(Smoke_value_det> 2048)		
	{
return 0;
	}
        return 1;
}

烟雾探测部分代码

我们先研究一下烟感探测部分的代码。

烟感探测的过程就是 红外发射管发射红外信号,经过烟感离职散射,接收管收到光的过程。

所有程序处理,需要先打开红外发射,产出红外光,打开红外接收管(使能OPA1 OPA2),将红外接收管的微弱信号放大让单片机可以识别判定,经放大OPA1输出的电压信号,通过ADC转换成数字信号。

烟感粒子越多,ADC 转换的值越大。

程序代码逻辑:

第1步:红外发射

第2步:OPA1 OPA2 配置打开启动红外接收

第3步:单片机ADC启动,转换OPA1 接收的电压量

第4步:关闭红外发射OPA1 OPA2 取消使能

第5步:输出ADC的转化值。

程序代码如下:

/************************maze_smoke**********************************/
unsigned int maze_smoke(void)
{
 unsigned int  smoke_data=0;	
	Vopa1_ctrl	= 0;
	Vopa1 		=1;				//set opa input DC bias source voltage
	Vopa1_ctrl	=0;
	Vopa1 		=1;				//set opa input DC bias source voltage
	_a2en		=1;
	delay500us();
	_a1en		=1;
	delay500us();
	delay500us();
	_emi		=0;
	IR_tx		=1;					//Set IR LED On
	delay90us();
	_adonb=0;	                                               //Read ADC	
	GCC_NOP();
	GCC_NOP();
	_adcr=0b00000110;
	_start=0;					                  //START ADC Converter ADCR.7 								
	_start=1;					                   //(ADC START bit) 0 -> 1 -> 0
	_start=0;
	GCC_NOP();
	GCC_NOP();				                	//4 Tad for ADC Sampling Time
	GCC_NOP();
	GCC_NOP();
	IR_tx=0;					//LED Off
	_a2en=0;
	_a1en=0;
	Vopa1=0;
	while(_eocb);
	GCC_CLRWDT();
	An7_AD_H=_adrh;
	An7_AD_L=_adrl;
	_adonb=1;					
	_c=0;
	_emi=1;
	GCC_RRC(An7_AD_H);
	GCC_RRC(An7_AD_L);
	GCC_RRC(An7_AD_H);
	GCC_RRC(An7_AD_L);
smoke_data=An7_AD_H;
smoke_data<<=8;
smoke_data=AN7_AD_data+An7_AD_L;
return smoke_data; 	 
}	

烟雾探测的算法(核心)

对于经验不足的工程师来说,可以检测到烟感的ADC值,有烟雾的时候的AD值要比无烟雾的时候的大很多,这样就可以起到烟雾探测的功能了,不错,上面的程序已经可以满足烟感探测的基本需求了。

但以上的还远远的不能满足探测器产品化,还需要注意以下细节:

  • 迷宫的结构,和红外接收和发射有一定的误差
  • 红外发射和接收管同一批次,或不同批次的精度有误差
  • 烟感长期工作,一些灰尘进入迷宫会导致 迷宫参数发生变化

为了处理以上的问题,我们就需要增加一些算法,让我们的产品工作的更加稳定。

烟感启动需要产生一个烟感的背景值。

原理:烟感开机后,再无烟的情况下,连续检测10次ADC的转化值。 

我们定义烟感的背景值BackVale;

unsigned int GetBackValue(void)
{
unsigned char i;
unsigned int advalue;
advalue = 0;
for(i=0;i<10;i++)
{
advalue += maze_smoke();
}
return advalue/10;
}
BackVale = GetBackValue();

烟雾探测报警程序。

原理:我们每隔4秒探测一次烟雾报警,如果烟雾报警的值比背景值大 1000,则烟雾报警;

备注:烟雾报警的值比背景值大1000,只是一个参考值,具体请结合实际情况判定

返回值   1 有烟雾 系统报警  蜂鸣器鸣叫 LED指示灯闪烁

unsigned char smokeAlarm_check(void)
{
if(maze_smoke() > (BackVale +1000))
{///高浓度
return 1;
}
else if(maze_smoke() > (BackVale + 500))
{///中级浓度
return 1;
}
return 0;
}
if(smokeAlarm_check() == 1)
{
///打开蜂鸣器DI DI声
///LED指示灯 开始闪烁
}
else
{
///关闭蜂鸣器DI DI声
///关闭LED指示灯  
}

更新ADC的背景值。

我们通过求取最近的10次AD转换的值的平均值来更新背景值。

共定义一个数组来保存最新的ADC转换的值。

获取adcValue[10]的值和BackValue的值。

开机获取somke[10]的初始值。

void valueInit(void)
{
unsigned char i;
unsigned int sumValue;
sumValue = 0;
for(i=0;i<10;i++)
{
adcValue[i] = maze_smoke();
sumValue += adcValue[i];
}
BackValue = sumValue/10;
}

更新背景值

更新somke[10]的值,将最早的ADC去掉。增加最新的ADC转化值。程序如下:

void updaterBackvalue(void)
{
unsigned char i;
unsigned int sumValue;
sumValue = 0;
for(i=0;i<9;i++)
{
adcValue[i] = adcValue[i+1];
sumValue += adcValue[i];
}
adcValue[9]  = maze_smoke();
sumValue += adcValue[9];
BackValue = sumValue/10;
}

以上便是 烟雾探测的程序逻辑及代码,其他部分还需要大家自己去完善。

三、数据的传输程序开发

我们先看一下硬件接口:

和NB-Iot通讯模块的接口模块:

本产品的感烟探测和 NB-IOT没有在同一块PCB上,是有6P的2.0的插针链接。接口图如上。

PIN1-2 是电池的电源和GND

PIN3:  是烟感控制单片机的上行数据接口,采用的时单线通讯方式

PIN4:  是烟感控制单片机的下行数据接口,采用的时单线通讯方式

PIN5:  是唤醒脚是单片机唤醒NB-IOT,启动数据传输的作用

PIN6:  预留

从上可以看到。通讯接口共有三个,包括: MCU_DAT_UP、 MCU_DAT_DOWM、MCU_WAKEUP

1. 数据上行数据 通讯接口

2. 数据下行数据  通讯接口

3. 唤醒   NB-Iot平时处于休眠状态,感烟探测主板有数据需要上传时,需要先唤醒NB-Iot模块,再发送数据。

主要传输的数据

上行:

烟雾报警、按键测试、电池低压、自检异常、按键消音、防拆按钮(预留)

下行:报警消音

上行通讯方式

本通讯方式是自定义的一个数据传输方式。数据通讯方式如下:

数据帧头+4位数据。

4为数据可以传输16中数据,我们只使用其中5个

0 0 0 1 —— 烟雾报警

0 0 1 0 —— 按键测试

0 0 1 1 —— 电池低压

0 1 0 0 ——自检异常

0 1 0 1 —— 按键消音

其他保留

帧头: 10毫秒高电平

数据部分:   

Bit1:4毫秒低电平 2毫秒的高电平 

Bit0:2毫秒低电平 4毫秒的高电平 

举例:数据传输平时为低电平。

如果传输烟雾报警则:

10毫秒高电平 +  2毫秒低电平 4毫秒的高电平  +  2毫秒低电平 4毫秒的高电平  +  2毫秒低电平 4毫秒的高电平  + 4毫秒低电平 2毫秒的高电平。

程序逻辑:

MCU_WAKEUP 唤醒NB-IOT模块,然后传输数据  3次。

下行通讯方式

因下行只有一种信号传输,所有我们只需要将MCU_DAT_DOWM拉高1秒 即可实现数据功能的传输。

本节课就先讲到这里,下篇文章无际单片机编程为大家讲解BC26这块的通讯程序

原创干货

NB-Iot烟感05:合泰HT45F23A开发环境搭建

2021-6-30 15:37:53

原创干货

NB-Iot烟感07:NB-IOT 无线通讯程序开发

2021-6-30 18:07:33

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索