一、产品开发功能简介

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


  1. #define LED_ctrl _pbc1 ///IO 输入输出口控制 = 0 输出
  2. #define LED _pb1 /// LED IO 控制脚
  3. #define LED_pbpu _pbpu1 ///PB 上拉控制脚 = 1
  4. 驱动代码
  5. void led_init(void)
  6. {
  7. LED_ctrl = 0; ///配置为输出
  8. LED_pbpu = 1; ///使能上拉
  9. LED = 0; ///LED关闭
  10. }
  11. void led_open(void)
  12. {
  13. LED =1; ///LED关闭
  14. }
  15. void led_close(void)
  16. {
  17. LED = 0; ///LED关闭
  18. }

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


  1. /************************maze_check**********************************/
  2. unsigned char maze_check(void)
  3. {
  4. Vopa1_ctrl = 0;
  5. Vopa1 =1; //set opa input DC bias source voltage
  6. _a2en =1;
  7. delay500us();
  8. _a1en =1;
  9. delay500us();
  10. delay500us();
  11. _emi =0;
  12. _adonb=0;
  13. GCC_NOP();
  14. GCC_NOP();
  15. _adcr=0b00000110;
  16. _start=0; //START ADC Converter ADCR.7
  17. _start=1; //(ADC START bit) 0 -> 1 -> 0
  18. _start=0;
  19. GCC_NOP();
  20. GCC_NOP(); //4 Tad for ADC Sampling Time
  21. GCC_NOP();
  22. GCC_NOP();
  23. _a2en=0;
  24. _a1en=0;
  25. Vopa1=0;
  26. while(_eocb);
  27. An7_AD_H=_adrh;
  28. An7_AD_L=_adrl;
  29. _adonb=1; //Disable ADC
  30. _c=0;
  31. _emi=1;
  32. GCC_RRC(An7_AD_H);
  33. GCC_RRC(An7_AD_L);
  34. GCC_RRC(An7_AD_H);
  35. GCC_RRC(An7_AD_L);
  36. GCC_RRC(An7_AD_H);
  37. GCC_RRC(An7_AD_L);
  38. Smoke_value_det=An7_AD_H;
  39. Smoke_value_det<<=8;
  40. Smoke_value_det=Smoke_value_det+An7_AD_L;
  41. //无IR发射AD值大于100,出现初始化错误
  42. if(Smoke_value_det> 2048)
  43. {
  44. return 0;
  45. }
  46. return 1;
  47. }

烟雾探测部分代码

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

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

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

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

程序代码逻辑:

第1步:红外发射

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

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

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

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

程序代码如下:


  1. /************************maze_smoke**********************************/
  2. unsigned int maze_smoke(void)
  3. {
  4. unsigned int smoke_data=0;
  5. Vopa1_ctrl = 0;
  6. Vopa1 =1; //set opa input DC bias source voltage
  7. Vopa1_ctrl =0;
  8. Vopa1 =1; //set opa input DC bias source voltage
  9. _a2en =1;
  10. delay500us();
  11. _a1en =1;
  12. delay500us();
  13. delay500us();
  14. _emi =0;
  15. IR_tx =1; //Set IR LED On
  16. delay90us();
  17. _adonb=0; //Read ADC
  18. GCC_NOP();
  19. GCC_NOP();
  20. _adcr=0b00000110;
  21. _start=0; //START ADC Converter ADCR.7
  22. _start=1; //(ADC START bit) 0 -> 1 -> 0
  23. _start=0;
  24. GCC_NOP();
  25. GCC_NOP(); //4 Tad for ADC Sampling Time
  26. GCC_NOP();
  27. GCC_NOP();
  28. IR_tx=0; //LED Off
  29. _a2en=0;
  30. _a1en=0;
  31. Vopa1=0;
  32. while(_eocb);
  33. GCC_CLRWDT();
  34. An7_AD_H=_adrh;
  35. An7_AD_L=_adrl;
  36. _adonb=1;
  37. _c=0;
  38. _emi=1;
  39. GCC_RRC(An7_AD_H);
  40. GCC_RRC(An7_AD_L);
  41. GCC_RRC(An7_AD_H);
  42. GCC_RRC(An7_AD_L);
  43. smoke_data=An7_AD_H;
  44. smoke_data<<=8;
  45. smoke_data=AN7_AD_data+An7_AD_L;
  46. return smoke_data;
  47. }

烟雾探测的算法(核心)

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

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

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

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

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

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

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


  1. unsigned int GetBackValue(void)
  2. {
  3. unsigned char i;
  4. unsigned int advalue;
  5. advalue = 0;
  6. for(i=0;i<10;i++)
  7. {
  8. advalue += maze_smoke();
  9. }
  10. return advalue/10;
  11. }
  12. BackVale = GetBackValue();

烟雾探测报警程序。

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

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

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


  1. unsigned char smokeAlarm_check(void)
  2. {
  3. if(maze_smoke() > (BackVale +1000))
  4. {///高浓度
  5. return 1;
  6. }
  7. else if(maze_smoke() > (BackVale + 500))
  8. {///中级浓度
  9. return 1;
  10. }
  11. return 0;
  12. }
  13. if(smokeAlarm_check() == 1)
  14. {
  15. ///打开蜂鸣器DI DI声
  16. ///LED指示灯 开始闪烁
  17. }
  18. else
  19. {
  20. ///关闭蜂鸣器DI DI声
  21. ///关闭LED指示灯
  22. }

更新ADC的背景值。

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

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

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

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


  1. void valueInit(void)
  2. {
  3. unsigned char i;
  4. unsigned int sumValue;
  5. sumValue = 0;
  6. for(i=0;i<10;i++)
  7. {
  8. adcValue[i] = maze_smoke();
  9. sumValue += adcValue[i];
  10. }
  11. BackValue = sumValue/10;
  12. }

更新背景值

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


  1. void updaterBackvalue(void)
  2. {
  3. unsigned char i;
  4. unsigned int sumValue;
  5. sumValue = 0;
  6. for(i=0;i<9;i++)
  7. {
  8. adcValue[i] = adcValue[i+1];
  9. sumValue += adcValue[i];
  10. }
  11. adcValue[9] = maze_smoke();
  12. sumValue += adcValue[9];
  13. BackValue = sumValue/10;
  14. }

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

三、数据的传输程序开发

我们先看一下硬件接口:

和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:烟雾检测软件实现及详解相关推荐

  1. nb iot 与java_NB-IoT物联网技术解析与案例详解 PDF 下载

    相关截图: 资料简介: 以NB-IoT为典型应用的移动物联网技术正处于规模发展的关键期,各行各业都在思考如何把NB-IoT与行业应用有效结合起来.由于垂直行业普遍缺乏对通信技术和通信行业的认知,同时对 ...

  2. Sniff网络基础原理和软件实现技巧详解

    Sniff网络基础原理和软件实现技巧详解 前言 SNIFF真是一个古老的话题,关于在网络上采用SNIFF来获取敏感信息已经不是什么新鲜事,也不乏很多成功的案例,那么,SNIFF究竟是什么呢? SNIF ...

  3. 目标检测模型YOLO-V1损失函数详解

    ❝ 上期我们一起学习了YOLOV1算法的原理框架,如下: 目标检测算法YOLO-V1算法详解 今天我们深入一步,一起学习下关于YOLO-V1算法的损失函数和优缺点. ❞ YOLO-V1损失函数 从上期 ...

  4. python画简单的图形的代码-Python实现画图软件功能方法详解

    概述 虽然Python的强项在人工智能,数据处理方面,但是对于日常简单的应用,Python也提供了非常友好的支持(如:Tkinter),本文主要一个简单的画图小软件,简述Python在GUI(图形用户 ...

  5. python画图代码大全-Python实现画图软件功能方法详解

    概述 虽然Python的强项在人工智能,数据处理方面,但是对于日常简单的应用,Python也提供了非常友好的支持(如:Tkinter),本文主要一个简单的画图小软件,简述Python在GUI(图形用户 ...

  6. 短信平台专业版软件客户端功能详解源码搭建|移讯云短信系统

    国际短信平台专业版软件客户端功能详解|移讯云短信系统 首页显示 剩余条数 充值总数 提交总数 成功数量 失败数量 未知数量 代发数量 签名数量 最新提交 平台公告 API接口文档 短信发送 发送短信选 ...

  7. python画图软件是哪个_Python实现画图软件功能方法详解

    Python实现画图软件功能方法详解,按钮,事件,绑定,快捷键,直线 Python实现画图软件功能方法详解 易采站长站,站长之家为您整理了Python实现画图软件功能方法详解的相关内容. 概述 虽然P ...

  8. 目标检测算法YOLO-V1算法详解

    ❝ 前面我们一起学了SSD算法的相关知识,如下: SSD目标检测算法必须知道的几个关键点 目标检测算法SSD结构详解 ❞ 今天我们学习另一系列目标检测算法YOLO(You Only Look Once ...

  9. hypersnap截图软件使用方法详解

    hypersnap截图软件使用方法详解: 启动后屏幕出现HyperSnap窗口. HyperSnap的窗口界面包括File(文件).Edit(编辑).View(查看).Capture(抓取).Imag ...

最新文章

  1. 深入浅出Rust-Future-Part-5.md
  2. 01-iOS获取系统iTunes音乐
  3. c语言发牌思路,C语言发牌机程序求详细解析
  4. Linux 系统关于应该把程序安装在目录 /usr 还是目录 /usr/local 下的思考
  5. Android 后台线程Thread调用前台线程Handler,延时线程,runOnUiThread使用,Timer延时,定时循环,倒计时
  6. 客座编辑:武永卫,男,博士,清华大学计算机科学与技术系教授。
  7. STM32F103:一.(2)STLINK的配置
  8. 丁克是什么意思,丁克家庭是什么意思,丁克家庭为什么越来越多
  9. MySQL之语法入门与基础命令
  10. (转载)ARM的字对齐问题总结
  11. 节点本地范围和链路本地范围_微服务链路追踪——skywalking
  12. 英语常用九种时态记忆要点
  13. matlab开环传递函数 求单位负反馈的系统传递函数,已知负反馈控制系统的开环传递函数为...
  14. WinRAR压缩软件安装步骤
  15. Java多线程系列--“JUC集合”04之 ConcurrentHashMap
  16. 梅花雪MzTreeView2.0 的checkbox完全攻略
  17. 基于JSoup的网络爬虫爬取小说内容
  18. 身在北京,都有故事:九位北漂的心酸故事,只有经历过才有体会!
  19. opengl实现太阳系、地球系,并加上地球的贴图
  20. Dogfight :从无人机视频中检测无人机

热门文章

  1. 为什么我的Linux ls命令不能用了?
  2. android手机各大分区详解
  3. 如何在Keil uVision5建立飞思卡尔K60开发板的工程
  4. 大疆OSMO POCKET(大疆灵眸)使用无线模块连接手机后瞬间断开连接的解决办法
  5. android apk 提取,android APK提取内置软件odex转dex
  6. input框中的背景文字
  7. linux 分区 物理卷 逻辑卷
  8. 2019阿里系电子书合集来了,免费下载
  9. Android联网报错:Cleartext HTTP traffic to XXXXX not permitted的解决方法
  10. 拼多多按关键词搜索示例