基于单片机设计的防煤气泄漏装置

一、前言

煤气泄漏是一个严重的安全隐患,可能导致火灾、爆炸以及对人体健康的威胁。为了提高家庭和工业环境中煤气泄漏的检测和预防能力,设计了一种基于单片机的防煤气泄漏装置。

单片机选择STC89C52作为主控芯片。为了检测煤气泄漏,采用了MQ4传感器,能够快速、准确地检测煤气浓度。通过采集MQ4传感器的模拟信号,使用PCF8591模数转换芯片将模拟信号转换为数字信号。采用IIC接口的OLED显示屏,将采集到的数据显示出来,方便用户获取检测结果。用户可以通过两个独立按键设置煤气泄漏的报警阈值,以适应不同环境的需求。

当检测到煤气泄漏超过设定的阈值时,装置会触发蜂鸣器进行报警,并同时打开换气扇进行通风换气,以迅速排除煤气并降低安全风险。

这种基于单片机设计的防煤气泄漏装置具有以下优点:高效可靠的煤气泄漏检测能力、灵活的报警阈值设置、直观清晰的数据显示以及及时的安全响应措施。可以广泛应用于家庭、工业和商业场所,提供有效的煤气泄漏监测和安全保护。

image-20230823165237872

image-20230823165325193

二、硬件选型

在设计基于单片机的防煤气泄漏装置时,硬件选型是非常关键的。以下是详细介绍硬件选型的相关内容:

【1】主控芯片选择:STC89C52 STC89C52是一款8051架构的单片机,具有丰富的接口资源、较高的性能和稳定可靠的工作特性,广泛应用于各种嵌入式系统中。具有8位数据总线、16位地址总线和4KB的内部存储器。STC89C52具备多个通用I/O口、定时器/计数器、串口等功能,非常适合本项目需求。

【2】煤气传感器选择:MQ4 MQ4传感器是一种能够检测多种可燃气体,如天然气、甲烷等的传感器。具有高灵敏度和快速响应的特点,能够准确地检测煤气泄漏情况。MQ4传感器的输出为模拟信号,需要通过模数转换器将其转换为数字信号供主控芯片处理。

【3】模数转换器选择:PCF8591 PCF8591是一款集成了8位模数/数模转换和4个模拟输入通道的模数转换器。采用IIC总线通讯接口,能够将模拟信号转换为数字信号,并通过IIC协议发送给主控芯片。本项目中,PCF8591用于采集MQ4传感器输出的模拟信号,并将其转换为数字信号供STC89C52处理。

【4】显示屏选择:0.96寸OLED显示屏(IIC接口) 本设计采用基于IIC接口的OLED显示屏,具有高亮度、对比度和快速响应的特点。通过简单的通讯方式,可以将煤气浓度信息实时显示在屏幕上。OLED显示屏使用面积小、功耗低,在嵌入式系统中应用广泛。

【5】按键选择:独立按键 本设计采用两个独立按键来设置报警的阀值。一个按键用于递增阀值,另一个按键用于递减阀值。独立按键具有简单可靠、使用方便等特点,适合本项目需求。

【6】报警装置选择:蜂鸣器和换气扇 当检测到煤气泄漏超过设定的报警阀值时,蜂鸣器将发出警报,用于提醒周围人员。同时,为了降低煤气浓度,需要启动换气扇进行通风换气。具体的报警和换气扇电路可以根据实际需求设计。

三、设计思路

软件设计思路如下:

【1】初始化:在程序开始时,进行主控芯片STC89C52的初始化设置,包括引脚配置、定时器设置等。同时,初始化PCF8591和OLED显示屏,确保它们可以正常工作。

【2】传感器检测:通过MQ4传感器检测煤气是否泄漏。将MQ4传感器与STC89C52的模拟输入引脚连接,通过读取该引脚的模拟电压值,获取煤气浓度数据。

【3】数据采集与处理:使用PCF8591模数转换芯片,将MQ4传感器的模拟输出信号转换为数字信号,并通过STC89C52的IIC接口与PCF8591进行通信,获取转换后的数字数据。

【4】数据显示:将采集到的煤气浓度数据通过IIC接口的OLED显示屏进行显示。使用STC89C52的IIC通信功能,将数据发送给OLED显示屏,通过显示屏将数据以可读的方式展示给用户。

【5】阈值设置:通过两个独立按键实现报警阈值的设置。将按键与STC89C52的GPIO引脚连接,通过读取按键状态来判断用户是否进行阈值设置操作。当按键按下时,进入设置模式,用户可以通过按键的不同组合来调整报警阈值,并将设置的值保存在相应的变量中。

【6】报警与通风控制:根据当前采集到的煤气浓度数据和用户设置的报警阈值进行比较。如果煤气浓度超过设定的阈值,触发蜂鸣器进行报警,并控制换气扇打开进行通风换气。反之,当煤气浓度低于或等于设定的阈值时,停止报警并关闭换气扇。

【7】循环监测:使用主循环结构,不断进行煤气泄漏检测、数据采集、数据显示和阈值比较等操作,以实现持续的监测和反馈。

四、项目模块代码

4.1 PCF8591采集代码

下面是使用STC89C52单片机通过PCF8591读取MQ4传感器的ADC数据的代码。使用IIC总线进行PCF8591之间的通信,使用了自定义的IIC总线函数。通过readADC()函数实现了读取MQ4传感器模拟量的ADC转换结果。

#include <reg52.h>#define uchar unsigned char
#define uint unsigned intsbit SDA = P2^0;    // IIC总线数据线
sbit SCL = P2^1;    // IIC总线时钟线sbit MQ4_DOUT = P3^0;   // MQ4传感器数字输出引脚
sbit MQ4_AIN = P3^1;    // MQ4传感器模拟输入引脚sfr IAP_DATA = 0xe2;    // 定义IAP_DATA寄存器
sfr IAP_ADDRH = 0xe3;   // 定义IAP_ADDRH寄存器
sfr IAP_ADDRL = 0xe4;   // 定义IAP_ADDRL寄存器
sfr IAP_CMD = 0xe5;     // 定义IAP_CMD寄存器
sfr IAP_TRIG = 0xe6;    // 定义IAP_TRIG寄存器
sfr IAP_CONTR = 0xe7;   // 定义IAP_CONTR寄存器// 函数声明
void delay(uint ms);
void startIIC();
void stopIIC();
void sendByte(uchar dat);
uchar receiveByte();
void writeDAC(uchar dat);
uchar readADC();void main() {uchar mq4Value;while (1) {mq4Value = readADC();  // 读取ADC转换结果// 处理mq4Value值,进行相应操作delay(100);  // 延时一段时间}
}// 延时函数
void delay(uint ms) {uint i, j;for(i = ms; i > 0; i--) {for(j = 110; j > 0; j--);}
}// IIC总线起始信号
void startIIC() {SDA = 1;_nop_();SCL = 1;_nop_();SDA = 0;_nop_();SCL = 0;_nop_();
}// IIC总线停止信号
void stopIIC() {SDA = 0;_nop_();SCL = 1;_nop_();SDA = 1;_nop_();
}// 发送一个字节的数据
void sendByte(uchar dat) {uchar i;for (i = 0; i < 8; i++) {SDA = dat >> 7;_nop_();SCL = 1;_nop_();SCL = 0;_nop_();dat <<= 1;}SDA = 1;_nop_();SCL = 1;_nop_();SCL = 0;_nop_();
}// 接收一个字节的数据
uchar receiveByte() {uchar i, dat = 0;SDA = 1;for (i = 0; i < 8; i++) {dat <<= 1;SCL = 1;_nop_();dat |= SDA;SCL = 0;_nop_();}return dat;
}// 写入DAC数值
void writeDAC(uchar dat) {startIIC();sendByte(0x90);  // 地址和写命令receiveByte();   // 接收应答sendByte(0x40);  // DAC通道A,并写入数据receiveByte();   // 接收应答sendByte(dat);   // DAC数据receiveByte();   // 接收应答stopIIC();
}// 读取ADC转换结果
uchar readADC() {uchar adcValue;startIIC();sendByte(0x91);   // 地址和读命令receiveByte();    // 接收应答adcValue = receiveByte();  // 读取ADC数据stopIIC();return adcValue;
}

4.2 OLED显示屏代码

以下是通过STC89C52控制IIC接口的OLED显示屏显示ADC数据实现代码。

#include <reg51.h>#define SCL P1_0   // IIC时钟线
#define SDA P1_1   // IIC数据线#define OLED_ADDR 0x78   // OLED显示屏的IIC地址// OLED显示屏初始化函数
void OLED_Init() {// 初始化OLED显示屏// ...// 发送初始化命令到OLED显示屏// ...
}// IIC总线开始信号
void IIC_Start() {SDA = 1;SCL = 1;SDA = 0;SCL = 0;
}// IIC总线停止信号
void IIC_Stop() {SDA = 0;SCL = 1;SDA = 1;
}// IIC总线发送一个字节的数据
void IIC_WriteByte(unsigned char dat) {unsigned char i;for (i = 0; i < 8; i++) {SCL = 0;if (dat & 0x80)SDA = 1;elseSDA = 0;SCL = 1;dat <<= 1;}SCL = 0;SDA = 1;SCL = 1;
}// 设置OLED显示屏光标位置
void OLED_SetPos(unsigned char x, unsigned char y) {IIC_Start();IIC_WriteByte(OLED_ADDR);IIC_WriteByte(0xb0 + y);IIC_WriteByte(((x & 0xf0) >> 4) | 0x10);IIC_WriteByte((x & 0x0f) | 0x01);IIC_Stop();
}// 在OLED显示屏上显示一个字符
void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch) {unsigned char c = 0, i = 0;c = ch - ' ';   // 获取字符在字库中的偏移量if (x > 128 - 8 || y > 64 - 16)return;   // 超出屏幕范围,退出函数OLED_SetPos(x, y);for (i = 0; i < 8; i++) {IIC_Start();IIC_WriteByte(OLED_ADDR);IIC_WriteByte(0x40);IIC_WriteByte(*(OLED_CharSet + c * 16 + i));IIC_Stop();x++;}
}// 在OLED显示屏上显示字符串
void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *str) {while (*str) {OLED_ShowChar(x, y, *str);x += 8;str++;}
}// ADC模拟数值转换为字符串
void ADC_ToString(unsigned int adcValue, unsigned char *str) {unsigned char i, j;unsigned int temp;temp = adcValue;for (i = 0; i < 4; i++) {str[i] = temp % 10 + '0';temp /= 10;}// 反转字符串i = 0;j = 3;while (i < j) {temp = str[i];str[i] = str[j];str[j] = temp;i++;j--;}str[4] = '\0';   // 字符串结束符
}// 主函数
void main() {unsigned int adcValue = 0;unsigned char str[5];// 初始化OLED显示屏OLED_Init();while (1) {// 读取ADC数据adcValue = ADC_Read();   // 假设使用的函数为ADC_Read(),用于读取ADC数据// 将ADC数据转换为字符串ADC_ToString(adcValue, str);// 在OLED显示屏上显示ADC数据OLED_ShowString(0, 0, "ADC Value:");OLED_ShowString(0, 2, str);}
}

4.3 主代码逻辑

#include <reg51.h>#define SCL P1_0    // IIC时钟线
#define SDA P1_1    // IIC数据线#define OLED_ADDR 0x78    // OLED显示屏的IIC地址
#define MQ4_PIN P2      // MQ4传感器连接的引脚sbit Buzzer = P3^0;    // 蜂鸣器控制引脚
sbit VentilationFan = P3^1;    // 换气扇控制引脚// 全局变量
unsigned int alarmThreshold = 100;    // 报警阈值,默认为100
unsigned int adcValue = 0;    // 保存ADC采集到的数值// IIC总线开始信号
void IIC_Start() {SDA = 1;SCL = 1;SDA = 0;SCL = 0;
}// IIC总线停止信号
void IIC_Stop() {SDA = 0;SCL = 1;SDA = 1;
}// IIC总线发送一个字节的数据
void IIC_WriteByte(unsigned char dat) {unsigned char i;for (i = 0; i < 8; i++) {SCL = 0;if (dat & 0x80)SDA = 1;elseSDA = 0;SCL = 1;dat <<= 1;}SCL = 0;SDA = 1;SCL = 1;
}// 设置OLED显示屏光标位置
void OLED_SetPos(unsigned char x, unsigned char y) {IIC_Start();IIC_WriteByte(OLED_ADDR);IIC_WriteByte(0xb0 + y);IIC_WriteByte(((x & 0xf0) >> 4) | 0x10);IIC_WriteByte((x & 0x0f) | 0x01);IIC_Stop();
}// 在OLED显示屏上显示一个字符
void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch) {unsigned char c = 0, i = 0;c = ch - ' ';    // 获取字符在字库中的偏移量if (x > 128 - 8 || y > 64 - 16)return;    // 超出屏幕范围,退出函数OLED_SetPos(x, y);for (i = 0; i < 8; i++) {IIC_Start();IIC_WriteByte(OLED_ADDR);IIC_WriteByte(0x40);IIC_WriteByte(*(OLED_CharSet + c * 16 + i));IIC_Stop();x++;}
}// 在OLED显示屏上显示字符串
void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *str) {while (*str) {OLED_ShowChar(x, y, *str);x += 8;str++;}
}// ADC转换函数
unsigned int ADC_Convert(unsigned char channel) {ADC_CONTR = ADC_POWER | ADC_START | channel | ADC_SPEED;_nop_();_nop_();_nop_();_nop_();while (!(ADC_CONTR & ADC_FLAG));ADC_CONTR &= ~ADC_FLAG;return (ADC_RES * 256 + ADC_RESL);
}// ADC模拟数值转换为字符串
void ADC_ToString(unsigned int adcValue, unsigned char *str) {unsigned char i, j;unsigned int temp;temp = adcValue;for (i = 0; i < 4; i++) {str[i] = temp % 10 + '0';temp /= 10;}// 反转字符串i = 0;j = 3;while (i < j) {temp = str[i];str[i] = str[j];str[j] = temp;i++;j--;}str[4] = '\0';    // 字符串结束符
} 主函数
void main() {unsigned char str[5];// 初始化OLED显示屏OLED_Init();// 设置初始报警阈值SetAlarmThreshold();while (1) {// 读取MQ4传感器的ADC数值adcValue = ADC_Convert(0);    // 假设MQ4传感器连接到ADC的通道0// 将ADC数值转换为字符串ADC_ToString(adcValue, str);// 在OLED显示屏上显示ADC数值OLED_ShowString(0, 0, "Gas Level:");OLED_ShowString(0, 2, str);// 判断是否触发报警if (adcValue > alarmThreshold) {// 触发报警ActivateAlarm();} else {// 取消报警DeactivateAlarm();}// 检测是否按下设置阈值的按键if (IsThresholdButtonPressed()) {// 设置报警阈值SetAlarmThreshold();}// 检测是否按下通风换气的按键if (IsVentilationButtonPressed()) {// 控制通风换气ControlVentilation();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/125651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cocosCreator 调用wxAPI 及后台授权设置、获取用户昵称和头像

版本&#xff1a; 3.8.0 语言&#xff1a; TypeScript 环境&#xff1a; Mac 官方文档&#xff1a; 微信官方文档 - 开放能力 微信 API 小游戏环境 在cocosCreator的3.x版本项目开发中&#xff0c;TypeScript最终会被转换为JavaScript语言。 JavaScript的运行时调用的API…

联发科MT6893(天玑1200)_MTK5G芯片规格参数性能_安卓手机主板方案

联发科天玑1200集成MediaTek 5G调制解调器&#xff0c;通过包含6大维度、72个场景测试的德国莱茵TV Rheinland认证&#xff0c;支持高性能5G连接&#xff0c;带给用户全场景的高品质5G连网体验。 进入5G时代&#xff0c;AI多媒体成为主流应用&#xff0c;天玑1200以强劲的平台…

【高效开发工具系列】你真的会使用Mac吗?

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

uniapp实现瀑布流

首先我们要先了解什么是瀑布流&#xff1a; 瀑布流&#xff08;Waterfall Flow&#xff09;是一种常见的网页布局方式&#xff0c;也被称为瀑布式布局或砌砖式布局。它通常用于展示图片、博客文章、商品等多个不同大小和高度的元素。 瀑布流布局的特点是每个元素按照从上到下…

现代的简洁,诠释轻奢的精致!福州中宅装饰,福州装修

轻奢风是一种生活新时尚 优雅、低调、舒适、简单&#xff0c;不断地推陈出新 站在时尚的前沿&#xff0c;引领潮流 中宅装饰集团轻奢风格产品 追求高品质生活细节 以设计精致的空间构造营造出 一种优雅、时尚生活氛围 将低调奢华之美注入现代家居设计中 客厅|The Sitt…

世界电信日 | 人大金仓助力中国移动租赁核算系统升级上线

世界电信日 5月17日恰逢第五十四个世界电信日&#xff0c;运营商作为新型基础设施建设以及维护网信安全的主力军&#xff0c;掌握关键核心技术&#xff0c;实现科技自立自强刻不容缓。 作为数据库领域国家队&#xff0c;人大金仓坚持原始创新&#xff0c;低难度、低成本、低风…

早安心语微语早读,保持一颗平常心,坐看云起落花开谢得之淡然

1、保持一颗平常心&#xff0c;坐看云起落花开谢得之淡然&#xff0c;失之坦然&#xff0c;让生命中每一天都充满着阳光和希望&#xff01; 2、每个人都一样&#xff0c;都有一段独行的日子&#xff0c;或长或短&#xff0c;这都是无可回避的。不必总觉得生命空空荡荡&#xf…

ArcGIS计算土地现状容积率

本文讲解在ArcGIS中,基于建筑数据和地籍边界数据,计算土地容积率。 一、容积率介绍 容积率(Plot Ratio/Floor Area Ratio/Volume Fraction)是指一个小区的地上建筑总面积与净用地面积的比率。又称建筑面积毛密度。 二、数据分析 (1)建筑数据(dwg) (2)地籍边界数据…

利用AI Chat 将电子书自动截屏并保存成pdf文件

电子书如果要下载下来&#xff0c;无非就两种类型的方法&#xff0c;一种是从内部破解&#xff0c;通常是某些极客将软件破解成免费版&#xff0c;但是风险也大。另一种是从外部破解&#xff0c;就是截屏保存&#xff0c;然后将所有图片拼成pdf文件。 如果要将整本电子书截屏保…

LeetCode刷题---简单组(六)

文章目录 &#x1f352;题目一 69. x 的平方根&#x1f352;解法一&#x1f352;解法二&#x1f352;题目二 70. 爬楼梯&#x1f352;解法一 &#x1f352;题目一 69. x 的平方根 &#x1f352;解法一 class Solution(object):def mySqrt(self, x):""":type x:…

制作一个简单的C语言词法分析程序

1.分析组成 C语言的程序中&#xff0c;有很单词多符号和保留字。一些单词符号还有对应的左线性文法。所以我们需要先做出一个单词字符表&#xff0c;给出对应的识别码&#xff0c;然后跟据对应的表格来写出程序 2.程序设计 程序主要有循环判断构成。不需推理即可产生的符号我…

SSM培训报名管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 培训报名管理系统是一套完善的信息系统&#xff0c;结合SSM框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主 要采用B/S模式开…

Windows2008系统怎么隐藏或打开文件后缀

打开服务器的控制面板-选择小图标-文件夹选项 在文件夹选项那边点击查看-隐藏一直文件类型的扩展名 选择勾选&#xff08;隐藏一直文件类型的扩展名&#xff09;-下图示文件后缀不显示 选择不勾选&#xff08;隐藏一直文件类型的扩展名&#xff09;-下图示文件后缀显示

VsCode 只有一个标签页 编辑区只能打开一个文件

产生如图所示的问题&#xff1a; 可能是不小心取消了勾选 勾选&#xff0c;Show Tabs

前端 : 用HTML ,CSS ,JS 做一个点名器

1.HTML&#xff1a; <body><div id "content"><div id"top"><div id "name">XAiot2302班点名器</div></div><div id "center"><div id "word">你准备好了吗?</di…

【Docker 内核详解】cgroups 资源限制(二):组织结构与基本规则、子系统简介

cgroups 资源限制&#xff08;二&#xff09;&#xff1a;组织结构与基本规则、子系统简介 1.组织结构与基本规则2.子系统简介 1.组织结构与基本规则 在之前的博客已经介绍过&#xff0c;传统的 Unix 任务管理&#xff0c;实际上是先启动 init 任务作为根节点&#xff0c;再由…

Specializing Smaller Language Models towards Multi-Step Reasoning论文精读

0 Abstract 普遍认为&#xff0c;LLM涌现出来的few-shot learning能力是超大参数模型独有的&#xff08;>100B&#xff09;【emergent abilities】&#xff1b;作者认为&#xff0c;小模型&#xff08;<10B&#xff09;可以将这些能力从大模型&#xff08;>100B&…

uniapp中APP端使用echarts用formatter设置y轴保留2位小数点不生效

uniapp使用echarts&#xff0c;在内置浏览器中&#xff0c;设置保留2位小数能正常显示&#xff08;代码如下&#xff09;&#xff0c;但是在APP端这个设置不起作用。 yAxis: {type: value,axisLabel: {formatter: function (val) {return val.toFixed(2); //y轴始终保留小数点…

测试计划驱动开发模式 TPDD:一种比 TDD 更友好的开发模式

相信大部分开发团队都在使用TDD&#xff0c;并且还有很多开发团队都 对外声明 在使用 TDD 开发模式。 之所以说是“对外声明”&#xff0c;是因为很多开发团队虽然号称使用的是 TDD 开发模式&#xff0c;实际开发过程中却无法满足 TDD 的要求。 实际上&#xff0c;测试驱动的…

Pytorch 猫狗识别案例

猫狗识别数据集https://download.csdn.net/download/Victor_Li_/88483483?spm1001.2014.3001.5501 训练集图片路径 测试集图片路径 训练代码如下 import torch import torchvision import matplotlib.pyplot as plt import torchvision.models as models import torch.nn as…