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这块的通讯程序。
免费领,单片机入门到高级开挂学习攻略(附教程+工具)https://blog.csdn.net/HWdanpianji/article/details/121722883?spm=1001.2014.3001.5502
NB-Iot烟感06:烟雾检测软件实现及详解相关推荐
- nb iot 与java_NB-IoT物联网技术解析与案例详解 PDF 下载
相关截图: 资料简介: 以NB-IoT为典型应用的移动物联网技术正处于规模发展的关键期,各行各业都在思考如何把NB-IoT与行业应用有效结合起来.由于垂直行业普遍缺乏对通信技术和通信行业的认知,同时对 ...
- Sniff网络基础原理和软件实现技巧详解
Sniff网络基础原理和软件实现技巧详解 前言 SNIFF真是一个古老的话题,关于在网络上采用SNIFF来获取敏感信息已经不是什么新鲜事,也不乏很多成功的案例,那么,SNIFF究竟是什么呢? SNIF ...
- 目标检测模型YOLO-V1损失函数详解
❝ 上期我们一起学习了YOLOV1算法的原理框架,如下: 目标检测算法YOLO-V1算法详解 今天我们深入一步,一起学习下关于YOLO-V1算法的损失函数和优缺点. ❞ YOLO-V1损失函数 从上期 ...
- python画简单的图形的代码-Python实现画图软件功能方法详解
概述 虽然Python的强项在人工智能,数据处理方面,但是对于日常简单的应用,Python也提供了非常友好的支持(如:Tkinter),本文主要一个简单的画图小软件,简述Python在GUI(图形用户 ...
- python画图代码大全-Python实现画图软件功能方法详解
概述 虽然Python的强项在人工智能,数据处理方面,但是对于日常简单的应用,Python也提供了非常友好的支持(如:Tkinter),本文主要一个简单的画图小软件,简述Python在GUI(图形用户 ...
- 短信平台专业版软件客户端功能详解源码搭建|移讯云短信系统
国际短信平台专业版软件客户端功能详解|移讯云短信系统 首页显示 剩余条数 充值总数 提交总数 成功数量 失败数量 未知数量 代发数量 签名数量 最新提交 平台公告 API接口文档 短信发送 发送短信选 ...
- python画图软件是哪个_Python实现画图软件功能方法详解
Python实现画图软件功能方法详解,按钮,事件,绑定,快捷键,直线 Python实现画图软件功能方法详解 易采站长站,站长之家为您整理了Python实现画图软件功能方法详解的相关内容. 概述 虽然P ...
- 目标检测算法YOLO-V1算法详解
❝ 前面我们一起学了SSD算法的相关知识,如下: SSD目标检测算法必须知道的几个关键点 目标检测算法SSD结构详解 ❞ 今天我们学习另一系列目标检测算法YOLO(You Only Look Once ...
- hypersnap截图软件使用方法详解
hypersnap截图软件使用方法详解: 启动后屏幕出现HyperSnap窗口. HyperSnap的窗口界面包括File(文件).Edit(编辑).View(查看).Capture(抓取).Imag ...
最新文章
- 深入浅出Rust-Future-Part-5.md
- 01-iOS获取系统iTunes音乐
- c语言发牌思路,C语言发牌机程序求详细解析
- Linux 系统关于应该把程序安装在目录 /usr 还是目录 /usr/local 下的思考
- Android 后台线程Thread调用前台线程Handler,延时线程,runOnUiThread使用,Timer延时,定时循环,倒计时
- 客座编辑:武永卫,男,博士,清华大学计算机科学与技术系教授。
- STM32F103:一.(2)STLINK的配置
- 丁克是什么意思,丁克家庭是什么意思,丁克家庭为什么越来越多
- MySQL之语法入门与基础命令
- (转载)ARM的字对齐问题总结
- 节点本地范围和链路本地范围_微服务链路追踪——skywalking
- 英语常用九种时态记忆要点
- matlab开环传递函数 求单位负反馈的系统传递函数,已知负反馈控制系统的开环传递函数为...
- WinRAR压缩软件安装步骤
- Java多线程系列--“JUC集合”04之 ConcurrentHashMap
- 梅花雪MzTreeView2.0 的checkbox完全攻略
- 基于JSoup的网络爬虫爬取小说内容
- 身在北京,都有故事:九位北漂的心酸故事,只有经历过才有体会!
- opengl实现太阳系、地球系,并加上地球的贴图
- Dogfight :从无人机视频中检测无人机