内容介绍
简易酒精浓度监测器
简介:
选择的是FastBond“环境监测”主题,做了一个酒精浓度监测器。这个模块的主要功能是用于检测环境中的酒精浓度含量,并在液晶屏上显示,来监测环境中的酒精含量,防止酒精浓度过高发生火灾或爆炸等危险。
系统框图:
应用背景:
洒精易燃易爆,有关的各种工业活动中都要特别注意预防这种气体的泄露。从工厂企业到居民家庭,酒精泄露的检测、监控对居身和财产安全都是十分重要且必不可少的。随着科学技术与生活水平的逐步提高,人们安全意识增强,对环境安全性和生活舒 适性要求的提高,再加上气体传感器向低功耗、 多功能、集成化方向的发展,因此,酒精浓度检测仪具有十分广阔的现实市场和潜在的市场要求。
软件介绍:
主控芯片的编程软件是Keil,Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部分组合在一起。运行 Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。
PCB及原理图由立创EDA绘制,立创EDA是一个用心为中国人定制的电路板开发平台,高效的在线电子设计工具,永久免费,同时支持多操作系统Windows、苹果Mac、Linux 。它能够绘制出美观的电路图,吸引电子工程师,学生,无线电爱好者的使用,从电路原理图无缝转换PCB图。同时立创EDA简化了工程师在做的事情,丰富的电子元件库极大的降低了工程师建库时间,加快了设计效率。对于无电子设计背景的人来说,立创EDA是一款很好上手的工具。
主要硬件:
1.主控芯片:STC89C51
资料多,书本多,性能、IO、flash在普通的竞技比赛中已经够用,对于一般学校学生来说学习入门很快。成本比较低,封装大,可以不用转接板或PCB就可以直接插入万用板中,直接使用。
2.酒精传感器:MQ-3
MQ-3酒精传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。当传感器所处环境中存在酒精蒸汽时,传感器的电导率随空气中酒精气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。MQ-3半导体传感器对酒精的灵敏度高,可以抵抗汽油、烟雾、水蒸气的干扰。这种传感器可检测多种浓度酒精气氛,是一款适合多种应用的低成本传感器。
3.液晶显示屏:LCD1602
LCD1602为工业字符型液晶,能够同时显示16 x 2(16列2行)即32个字符。1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5×7或者5×11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形。
4.温湿度传感器:DHT11
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。DHT11是一款温湿度传感器。 其测量精度为:湿度+-5%RH, 温度+-2℃,量程为:湿度20-90%RH, 温度0~50℃,采样周期大于等于1秒/次。传感器包括一个电阻式感湿元件和一个NTC测温元件,并连接一个高性能8位单片机相。DHT11的优点有:品质高、响应快、抗干扰能力强、性价比极高、体积小、功耗低等。
5.wifi模块:esp8266
ESP8266 可以用来做串口透传,PWM 调控,远程控制开关:控制插座、开关、电器等。
该模块有三种工作模式
STA 模式:ESP8266 模块通过路由器连接互联网,手机或电脑通过互联网实现对设备的远程控制。
AP 模式:ESP8266 模块作为热点,手机或电脑直接与模块连接,实现局域网无线控制。
STA+AP 模式:两种模式的共存模式,即可以通过互联网控制可实现无缝切换,方便操作。
原理图:
PCB图:
实物图:
6.双通道AD转换芯片:ADC0832
美国国家半导体公司生产的ADC0832是广泛应用的8 位分辨率、双通道A/D转换芯片。ADC0832是双通道输入,并且可以软件配置成单端或差分输入,其串行输出可以方便的和标准的移位寄存器及微处理器接口。 由于它体积小,兼容性,性价比高而深受单片机爱好者及企业欢迎,其目前已经有很高的普及率。
7.本次活动推荐的ADI芯片:ADT6501SRJZP065RL7
主要特点:1.温度测量具有较高的精度和抗噪性。2.±0.5°C的典型精度,从−45°C到+115°C。3.极低的功耗,电源电流为30μA。4.可通过3脚拉高拉低来选择温度滞后2°C或10°C。
ADT6501是11位数字温度传感器,其第12位作为符号位。车载温度传感器产生与绝对温度精确成正比的电压,并与内部电压参考值进行比较,并输入到精确的数字调制器。来自调制器的12位输出被输入到一个数字比较器中,在那里它与一个工厂设置的跳闸水平进行比较。如果测量的温度大于ADT6502工厂设置的跳闸水平的情况下,则输出跳闸销被激活。
原理图:
PCB板:
实物图:
8.本次活动推荐的Maxim芯片:MAX17624
MAX17624是集成MOS管和内部补偿的高频同步降压DC-DC变换器。 MAX17624的输入电压范围为2.9V到5.5V,支持高达1A,输出电压可在0.8V到3.3V之间调节。
原理图:
该芯片集成在ESP8266核心板上,没有另外打板。
代码说明:
LCD1602驱动:
// 函数: void CheckBusy(void)
// 描述: 检测忙函数
// 参数: none.
// 返回: none.
void CheckBusy(void)
{
uint i;
for(i=0; i<5000; i++) {if(!LCD_B7) break;} //check the LCD busy or not. With time out
// while(LCD_B7); //check the LCD busy or not. Without time out
}
// 函数: void IniSendCMD(uchar cmd)
// 描述: 初始化写命令(不检测忙)
// 参数: cmd: 要写的命令.
// 返回: none.
void IniSendCMD(uchar cmd)
{
LCD_RW = 0;
LCD_BusData(cmd);
LCD_DelayNop();
LCD_ENA = 1;
LCD_DelayNop();
LCD_ENA = 0;
LCD_BusData(0xff);
}
// 函数: void Write_CMD(uchar cmd)
// 描述: 写命令(检测忙)
// 参数: cmd: 要写的命令.
// 返回: none.
void Write_CMD(uchar cmd)
{
LCD_RS = 0;
LCD_RW = 1;
LCD_BusData(0xff);
LCD_DelayNop();
LCD_ENA = 1;
CheckBusy(); //check the LCD busy or not.
LCD_ENA = 0;
LCD_RW = 0;
LCD_BusData(cmd);
LCD_DelayNop();
LCD_ENA = 1;
LCD_DelayNop();
LCD_ENA = 0;
LCD_BusData(0xff);
}
// 函数: void Write_Data(uchar dat)
// 描述: 写显示数据(检测忙)
// 参数: dat: 要写的数据.
// 返回: none.
void Write_Data(uchar dat)
{
LCD_RS = 0;
LCD_RW = 1;
LCD_BusData(0xff);
LCD_DelayNop();
LCD_ENA = 1;
CheckBusy(); //check the LCD busy or not.
LCD_ENA = 0;
LCD_RW = 0;
LCD_RS = 1;
LCD_BusData(dat);
LCD_DelayNop();
LCD_ENA = 1;
LCD_DelayNop();
LCD_ENA = 0;
LCD_BusData(0xff);
}
ADC0832驱动:
unsigned char ADC0832(unsigned char channel) //模数转换
{
uchar i;
uchar x=0x00;
uchar y=0x00;
uchar adc0832_dat=0x00;
CLK=0; //初始化
DI=1;
_nop_();
CS=0;
_nop_();
CLK=1;
_nop_();
if(channel==0x00) //通道选择
{ //通道0
CLK=0;
DI=1;
_nop_();
CLK=1;
_nop_();
CLK=0;
DI=0;
_nop_();
CLK=1;
_nop_();
}
else //通道1
{
CLK=0;
DI=1;
_nop_();
CLK=1;
_nop_();
CLK=0;
DI=1;
_nop_();
CLK=1;
_nop_();
}
CLK=0;
DI=1;
for(i=0;i<8;i++) //读取ADC0832输出的前8位数据
{
x<<=1;
_nop_();
CLK=1;
_nop_();
CLK=0;
if(DO==1)
{
x|=0x01;
}
else
{
x|=0x00;
}
}
for(i=0;i<8;i++) //读取ADC0832输出的后8位数据
{
y>>=1;
if(DO==1)
{
y|=0x80;
}
else
{
y|=0x00;
}
_nop_();
CLK=1;
_nop_();
CLK=0;
}
if(x==y) //校验,比较前8位与后8位的值
{
adc0832_dat=x;
}
_nop_();
CS=1; //释放ADC0832
DO=1;
CLK=1;
return adc0832_dat;
}
DHT11驱动:
//DHT11起始信号
void DHT11_start()
{
Bus=0;
Delay10us();
Delay10us();
delay_ms(20);
Bus=1;
Delay10us();Delay10us();Delay10us();Delay10us();//延时40us
}
//定义DHT11检查,即DHT11_Check(),程序如下:
//返回ERROR :未检测到DHT11的存在
//返回OK :存在
uchar DHT11_Check(void)
{
uchar retry=0;
while (Bus && retry<20) //DHT11 拉低80us,主机检测BUS是否收到来自DHT11的低电平
{
retry++;
Delay10us();
}
if(retry>10) //未检测到DHT11的存在
return ERROR;
else
retry=0;
while (!Bus && retry<20) //DHT11拉低后会再次拉高40~80us
{
retry++;
Delay10us();
}
if(retry>10)
return ERROR; //未检测到DHT11的存在
else
return OK; //DHT11存在
}
//读取 DHT11数值,温度的范围是0-50度,湿度的范围是20%-90%,返回值:0是正常,1是读取失败
uchar DHT11_Read_Data(void)
{
uchar i;
for(i=0; i<5; i++) //读取40位数据
{
buf[i]=DHT11_Read_Byte(); //读取DHT11的五个字节
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
return OK; //校验正确
}
else
return ERROR;
}
//从DHT11读取一个字节,既是DHT11_Read_Byte,返回值是读到的数据
uchar DHT11_Read_Byte(void)
{
uchar i,dat;
dat=0;
for (i=0; i<8; i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
//从DHT11读取一个位,既是DHT11_Read_Bit,返回值是1或者0:
uchar DHT11_Read_Bit(void)
{
uchar retry=0;
while(Bus&&retry<10) //Bus变为低电平50us
{
retry++;
Delay10us();;
}
retry=0;
while(!Bus&&retry<10) //Bus变为高电平
{
retry++;
Delay10us();;
}
Delay10us();Delay10us();Delay10us();Delay10us();
if(Bus)
return 1;
else
return 0;
}
主函数驱动:
void main(void)
{
uchar result,temp,hum,key_flag;
beep = 0;
Initialize_LCD();
Uart_Init();
delay_ms(3000);
WriteChar(1,0,'T');
WriteChar(1,1,':');
WriteChar(1,4,0XDF);
WriteChar(1,5,'C');
WriteChar(1,7,'H');
WriteChar(1,8,':');
WriteChar(1,11,'%');
WriteChar(0, 1, '.');
WriteChar(0, 4, 'V');
WriteChar(0, 7, '.');
PutString(0,10, "mg/100");
while(1)
{
delay_ms(3000);
num1=Convert(0x00, alcohol);
num2=Convert(0x11, temp_ss);
DHT11_start() ;
if(DHT11_Check()==ERROR)//DHT11检测不正常!
{
delay_ms(500);
}else
{
result=DHT11_Read_Data();
delay_ms(500);
}
if(result==OK)
{
temp=buf[2]; //温度值,只取整数部分
hum=buf[0]; //湿度值,只取整数部分
WriteChar(1,2,temp / 10 + '0');
WriteChar(1,3,temp % 10 + '0');
WriteChar(1,9,hum / 10 + '0');
WriteChar(1,10,hum % 10 + '0');
PutString(1,14," ");
}
WriteChar(0, 0, alcohol[2] + '0');
WriteChar(0, 2, alcohol[3] + '0');
WriteChar(0, 3, alcohol[4] + '0');
WriteChar(0, 6, temp_ss[2] + '0');
WriteChar(0, 8, temp_ss[3] + '0');
WriteChar(0, 9, temp_ss[4] + '0');
key_flag = key_scan();
Flag++;
if(key_flag == 3)
{
printf("AT+CIPMUX=1\r\n");
delay_ms(500);
printf("AT+CIPSERVER=1,8080\r\n");
PutString(1,14,"ok");
key_tx_flag=1;
}
if((key_tx_flag == 1) && (Flag == 2))
{
printf("AT+CIPSENDEX=0,85\r\n");
delay_ms(50);
printf("\r\ntemperature range:%d.%d%dV\r\n",(int)alcohol[2],(int)alcohol[3],(int)alcohol[4]);
printf("alcohol strength:%d.%d%dmg/100ml\r\n",(int)temp_ss[2],(int)temp_ss[3],(int)temp_ss[4]);
printf("Temp:%d\r\n",(int)temp);
printf("Humidity:%d\r\n",(int)hum);
Flag = 0;
}
if((num1<100) && (num2>3))
{
beep = 1;
}
delay_ms(2000);
}
}
功能演示:
上电后,蜂鸣器会鸣叫一下,液晶屏上显示,通过ADC0832读取的ADT6501的电压值、酒精传感器的数值,和DHT11的温度、湿度。通过ESP8266WIFI模块,将数据传送到手机上。
总结:
第一次接触这个活动,还是同学推荐的。迷迷糊糊的就参加了,自己去学习如何绘制原理图和PCB,KiCad的操作可能对我来说过于复杂,而且自己也学习的马马虎虎,还是在立创EDA上去绘制原理图和PCB了,可能是比较傻瓜式操作。作为一名将要毕业的大四学生,独立的完成这个作品,个人认为还是有一定的难度的。毕竟在学校的学习不是很认真,学习的知识点没有很到位。原理图、PCB、送板打样都是第一次接触。虽然这次做的东西在别人眼里有点简单,但是我会再接再厉,争取在下一次完成一个更加完善的作品。