历史上的今天
返回首页

历史上的今天

今天是:2025年07月27日(星期日)

正在发生

2021年07月27日 | 51单片机DHT11温湿度检测手机蓝牙APP显示设计

2021-07-27 来源:eefocus

今天给大家介绍的是一个温湿度检测设计,基于51单片机、蓝牙模块、温湿度传感器、Android APP完成。首先先展示一下设计好的实物,接下来将从系统方案、硬件设计、软件设计这三个方面来阐述。

1.系统方案

先来看一下整体的架构图:硬件部分由STC89C52单片机、DHT11温湿度传感器、BT08蓝牙串口模块和Android手机组成。传感器将采集到的温湿度数据传送给单片机,然后单片机通过蓝牙串口模块将数据发送到手机APP,从而将温湿度在APP显示出来。在APP上可以设置温湿度告警的阈值,超过阈值将显示“偏高”或者“偏低”的相关信息。

2.硬件设计

整个设计的原理图如下所示,由单片机最小系统、蓝牙串口模块、温湿度传感器组成。传感器的DATA管脚连接单片机的P2^0口,蓝牙串口模块的RXD、TXD分别连接单片机的TXD、RXD。

蓝牙串口模块的功能是串口协议和蓝牙协议之间的相互转换,在单片机上自己编写一套蓝牙驱动代码是非常复杂的,借助这个模块我们在编写单片机代码时只需要编写串口收发的代码即可,该模块得到串口数据后会转成蓝牙数据。对于APP它接收到的是蓝牙数据,开发APP时只需要编写蓝牙相关的代码,Android封装了蓝牙相关的API,所以开发起来简单。蓝牙串口模块的引脚图如下图所示,在这个设计中用到了四个引脚,VCC、GND接5V电源和地,蓝牙模块的TXD接单片机的RXD,RXD接TXD。

DHT11温湿度传感器负责采集环境中的温湿度数据,在单片机软件设计部分会详细的介绍该传感器的使用步骤。引脚说明:

VDD 供电3.3~5.5V DC

DATA 串行数据,单总线

NC 空脚

GND 接地,电源负极

3.单片机软件设计

单片机程序主要是两个点,一是读取DHT11传感器的温湿度数据,二是串口通信。DHT11的官方文档写的很规范,有关于读取数据的详细步骤,文档更新也比较及时,最新的更新日期是2017年3月31号,官网的下载地址:http://www.aosong.com/products-21.html


DHT11采用单总线通信,单总线即只有一根数据线,系统中的数据交换、控制均由单总线完成。


传送数据位定义

DATA 管脚用于DHT11与单片机之间的通讯和同步,采用单总线数据格式,一次传送40 位数据,高位先出。

数据格式:

8bit 湿度整数数据+ 8bit 湿度小数数据+ 8bit 温度整数数据+ 8bit 温度小数数据+ 8bit 校验位。

注:其中湿度小数部分为0。


校验位数据定义

8bit 湿度整数数据 +  8bit 湿度小数数据 +  8bit 温度整数数据 +  8bit 温度小数数据 = 8bit 校验位

如果以上等式成立,则本次传感器采集的数据有效,否则无效。


先看采集数据有效的示例,接收到的40 位数据为:

0011 0101     0000 0000     0001 1000     0000 0100      0101 0001

湿度高8 位     湿度低8 位     温度高8 位     温度低8 位    校验位

计算: 0011 0101 + 0000 0000 + 0001 1000 + 0000 0100 = 0101 0001,接收数据正确。

湿度:0011 0101(整数)=35H=53%RH 0000 0000(小数)=00H=0.0%RH =>53%RH + 0.0%RH = 53.0%RH

温度:0001 1000(整数)=18H=24℃ 0000 0100(小数)=04H=0.4℃ =>24℃ + 0.4℃ = 24.4℃


采集数据无效的示例,接收到的40 位数据为:

0011 0101     0000 0000     0001 1000    0000 0100     0100 1001

湿度高8 位    湿度低8 位     温度高8 位    温度低8 位    校验位

计算: 0011 0101 + 0000 0000 + 0001 1000 + 0000 0100 不等于0100 1001,本次接收的数据不正确,放弃,重新接收数据。


通过以上两个示例可以清楚DHT11数据格式以及数据如何去校验有效性。


数据时序图

用户主机(MCU)发送一次开始信号后,DHT11 从低功耗模式转换到高速模式,待主机开始信号结束后,DHT11 发送响应信号,送出40bit 的数据,并触发一次信采集。信号发送如图所示。这里的主机是指单片机,从机是指DHT11传感器。


下面这个图表罗列了时序图相关的参考时间,在读取数据的详细步骤中会用到这些数值。

根据时序图和表中的参考时间,我们可以得出读取传感器数据的步骤。


step1:单片机输出低电平保持20ms


step2:单片机拉高电平保持13us等待DHT11传感器的低电平响应信号


step3:判断DHT11是否给出低电平响应,如果有低电平响应则进入步骤4,否则等待下一轮的尝试。


step4:通过while语句等待83us的低电平响应时间结束


step5:通过while语句等待87us的高电平响应时间结束


step6:计算温湿度数据


step7:单片机输出高电平结束一次数据采集的读取


step8:校验数据


在时序图中可以看到,数据读取是每次一位进行的,数据0位和数据1位的低电平时间是相同的,即54us。数据0位的高电平时间是24us,而数据1为的高电平时间是71us,通过高电平时间的差异我们就可以判断出是数据0还是数据1。所以单独写了一个函数用来计算数据0位和1位,由于温湿度的整数和小数部分分别是由8位表示的,我们定义该函数得到8位数据之后给出返回值。步骤6对应的函数computeData() 用来完成上述工作。我们对步骤6进行详细的描述:


step 6.1:等待54us低电平结束


step 6.2:延时30us判断高电平是否结束,因为数据0位的电平最大时长是27us,如果超过27us之后高电平结束,则为数据0位,否则为数据1位。


step 6.3:通过while语句等待高电平结束


step 6.4:通过移位和或与的方式保存一个数据位


step 6.5:循环6.1到6.4步骤8次,得到一个字节的数据


//--------------------------------

//-----湿度读取子程序 ------------

//--------------------------------

//----以下变量均为全局变量--------

//----温度高8位== temperature_H------

//----温度低8位== temperature_L------

//----湿度高8位== humidity_H-----

//----湿度低8位== humidity_L-----

//----校验 8位 == checkdata-----

//--------------------------------

void readData()

{

    U8  humidity_H_temp,humidity_L_temp,temperature_H_temp,temperature_L_temp,checkdata_temp;

    //step1:单片机输出低电平保持20ms

    P2_0=0;

    delayms(20);

    //step2:单片机拉高电平保持13us等待DHT11传感器的低电平响应信号

    P2_0=1;

    delay13us();

    //step3:判断DHT11是否给出低电平响应,如果有低电平响应则进入步骤4,否则等待下一轮的尝试。

    if(P2_0==0)

    {

        //step4:通过while语句等待83us的低电平响应时间结束

        while(P2_0==0);

        //step5:通过while语句等待87us的高电平响应时间结束

        while(P2_0==1);

        //step6:计算温湿度数据

        humidity_H_temp = computeData();

        humidity_L_temp = computeData();

        temperature_H_temp = computeData();

        temperature_L_temp = computeData();

        checkdata_temp = computeData();

        //step7:单片机输出高电平结束一次数据采集的读取

        P2_0 = 1;

        //step8:校验数据

        if(checkdata_temp = humidity_H_temp + humidity_L_temp + temperature_H_temp + temperature_L_temp)

        {

            humidity_H = humidity_H_temp;

            humidity_L = humidity_L_temp;

            temperature_H = temperature_H_temp;

            temperature_L = temperature_L_temp;

            checkdata = checkdata_temp;

        }

    }

 

}

 

/**

*根据时序计算温湿度值

*/

U8 computeData()

{

    U8 i,U8comdata;

    for(i=0; i<8; i++)

    {

        //step 6.1:等待54us低电平结束

        while(P2_0==0);

        //step 6.2:延时30us判断高电平是否结束

        Delay_10us();

        Delay_10us();

        Delay_10us();

        U8temp=0;

        if(P2_0==1)

        {

            U8temp=1;

        }

        //step 6.3:通过while语句等待高电平结束

        while(P2_0==1);

        //step 6.4:通过移位和或与的方式保存一个数据位

        U8comdata<<=1;

        U8comdata|=U8temp;

    }

    return U8comdata;

}

温湿度数据读取完毕,接下来就是通过串口发送出去,串口发送数据的代码相对简单了,我们在主函数中对串口通信进行初始化,然后在一个while语句中每隔2s读取数据然后发送。


//----------------------------------------------

//main()功能描述:  STC89C52RC  11.0592MHz   串口发送温湿度数据,波特率 9600

//----------------------------------------------

void main()

{

    U8  i;

    TMOD = 0x20;          //定时器T1使用工作方式2

    TH1 = 253;        // 设置初值

    TL1 = 253;

    TR1 = 1;          // 开始计时

    SCON = 0x50;          //工作方式1,波特率9600bps,允许接收

    ES = 1;

    EA = 1;           // 打开所以中断

    TI = 0;

    RI = 0;

    Delay(1);         //延时100US(12M晶振)

    while(1)

    {

        //调用温湿度读取子程序

        readData();

        str[0]=humidity_H;

        str[1]=humidity_L;

        str[2]=temperature_H;

        str[3]=temperature_L;

        str[4]=checkdata;

        //发送到串口

        for(i=0; i<5; i++)

        {

            sendOneChar(str[i]);

        }

        //读取模块数据周期不易小于 2S

        delayms(2000);

    }

 

}

至此,单片机端的主要代码就讲解完了,可以看到核心代码是如何读取DHT11的数据。


4.手机APP软件设计


APP是用Android Studio(AS)开发的,不建议初学者学习Eclipse结合ADT(Android Eclipse Tools)插件的方式开发Android APP,这种方式已经过时并且以后会被淘汰,Google在2016年底已经停止了对ADT的更新,我之前所在的公司已经将Eclispe的代码全部迁移到AS平台了,推荐使用Google自家的AS集成开发环境。AS有很多优点,但是在使用时也有问题,AS借助gradle进行项目构建,至于为什么Google利用gradle进行Android app项目构建,读者可以自行上网搜索。gradle插件版本要和AS版本相对应,不同的开发者的gradle版本可能不同,所以当你拿到另外一个开发者的代码在自己的AS运行时时有可能会构建失败。这个现象对于国外开发者而言不是一个问题,AS可以自动去下载所需要的gradle插件版本,但是在国内,由于众所周知的原因,如果不会科学上网那么AS直接尝试下载gradle插件时会失败,会令很多初学者不知所措。在以后有时间我会单独写一篇blog来讲解如何去解决这个问题。最近听到Google要重返中国市场,如果能回归成功,对于国内的很多开发者和学术研究者而言是个好消息。


言归正传,本设计APP的代码主要分成两个部分,一是蓝牙数据的接收,二是图表显示。


4.1 APP蓝牙软件设计

蓝牙通信的三个基本步骤:搜索、配对、连接。这之后就可以进行数据传输了。


权限

在蓝牙通信中需要获取Android系统的以下三个权限,如果不能给APP授予相关的权限会影响蓝牙的正常使用:

BLUETOOTH:允许配对的设备进行连接

BLUETOOTH_ADMIN:允许搜索和配对设备

ACCESS_COARSE_LOCATION:广播接收器接收BluetoothDevice.ACTION_FOUND广播需要改权限


在下文中还会提到在Android6.0及以上的版本中关于ACCESS_COARSE_LOCATION权限的申请。


开启蓝牙

建立蓝牙通信之前需要验证是否有蓝牙设备,以及蓝牙设备是否已经开启。对于一个Android系统而言只有一个蓝牙适配器,通过getDefaultAdapter()方法可以返回其一个实例,如果返回为null,则说明该设备不支持蓝牙。


BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter == null) {

        // device doesn't support Bluetooth

}

接下来是检查蓝牙设备是否已经开启,如果没有开启,可以调用startActivityForResult()方法来弹出对话框让用户选择开启,这种方式不会停止当前的应用。


if (!mBluetoothAdapter.isEnabled()) {

        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

}

搜索设备

搜索设备可以分成两部分,一是查找已经与本机配对的设备,通过getBondedDevices()方法返回已经配对的设备信息:


Set pairedDevices = mBluetoothAdapter.getBondedDevices();

if (pariedDevices.size > 0) {

        for (BluetoothDevice device: pairedDevices) {

                String deviceName = device.getName();

                String deviceMACAddress = device.getAddress();

        }

}

二是搜索周围可用的但是还未配对的设备。

系统在发现蓝牙设备会通过广播的形式通知app,所以在搜索设备之前需要注册广播接收器来接收发现蓝牙设备的消息,在销毁Activity时注销广播接收器。


private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        public void onReceiver(Context context, Intent intent) {

                String action = intent.getAction();

                if (BluetoothDevice.ACTION_FOUND.equals(action)) {

                        BluetoothDevie device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                }

推荐阅读

史海拾趣

冠图电子(GTL-POWER)公司的发展小趣事

冠图电子(GTL-POWER)发展故事之一:初创与技术积累

冠图电子(GTL-POWER)的故事始于2009年,当时它作为一家专注于中小功率模块电源、定制电源的新兴企业在广州成立。创始人凭借对电力电子技术的深刻理解和敏锐的市场洞察力,组建了一支专业的研发团队,致力于高品质模块电源的研发与生产。在公司成立初期,团队就明确了技术创新和质量为先的发展策略,逐步建立了微功率模块电源样品生产线,为后续的发展奠定了坚实基础。

冠图电子(GTL-POWER)发展故事之二:市场拓展与战略布局

随着技术实力的不断增强,冠图电子开始积极拓展市场。2010年至2012年间,公司先后在北京、上海、深圳等城市设立了办事处,构建了遍布全国的销售网络。这一战略布局不仅拓宽了销售渠道,还加强了与当地客户的紧密联系,进一步提升了品牌知名度。同时,公司还根据市场需求,不断优化产品结构,推出了多款具备自主知识产权的特色产品,如宽压DC-DC模块电源、光伏电源等,深受市场欢迎。

冠图电子(GTL-POWER)发展故事之三:技术突破与行业标准

冠图电子在技术创新方面不断取得突破,陆续开发了多款具有行业领先水平的电源产品。例如,公司成功开发出小型全功能单列直插DC-DC模块电源,解决了传统电源体积大、效率低的问题。此外,冠图电子还积极参与行业标准的制定工作,通过技术创新推动整个电源行业的发展。这些努力不仅提升了公司的行业地位,还为客户提供了更加可靠、高效的电源解决方案。

冠图电子(GTL-POWER)发展故事之四:品质管理与国际认证

为了确保产品质量,冠图电子建立了严格的质量管理体系,并通过了ISO9001权威认证。公司注重生产过程的每一个环节,从原材料采购到成品出厂都实行严格的质量控制。这种对品质的执着追求使得冠图电子的产品在市场上赢得了良好的口碑,吸引了来自全球30多个国家的600多家客户。国际市场的认可不仅提升了公司的品牌形象,还为公司带来了更多的业务机会。

冠图电子(GTL-POWER)发展故事之五:客户服务与持续发展

冠图电子始终坚持以客户为中心的服务理念,为客户提供从项目咨询、系统设计到技术支持的一站式服务。公司拥有一支专业的客服团队,能够迅速响应客户需求并提供专业的解决方案。此外,冠图电子还注重与客户的长期合作,通过持续改进产品和服务来满足客户的不断变化的需求。这种以客户为导向的发展策略使得冠图电子在激烈的市场竞争中保持了稳步发展,并逐渐成长为一流的微功率模块电源、定制电源供应商。

Aavid Thermalloy公司的发展小趣事

Aavid Thermalloy公司是一家专注于热管理解决方案的公司,以下是关于该公司发展的五个相关故事:

  1. 公司成立和早期发展: Aavid Thermalloy公司成立于1964年,总部位于美国新罕布什尔州。最初,公司主要从事铝材料加工和制造业务,为电子行业提供散热器和热管理解决方案。在成立初期,公司注重产品质量和技术创新,逐渐赢得了客户的信赖和认可。

  2. 技术创新和产品扩展: 随着市场需求的变化和技术的进步,Aavid Thermalloy不断进行技术创新,并逐步扩展产品线。公司不仅提供各种类型的散热器产品,还涉足导热材料、热管、热板等领域,为客户提供全方位的热管理解决方案。

  3. 国际市场拓展: Aavid Thermalloy致力于拓展国际市场,与全球各地的客户建立了广泛的合作关系。公司产品远销美国、欧洲、亚洲等地区,销售网络覆盖了全球主要的电子市场。同时,公司在一些国家设立了分支机构和办事处,加强了对当地市场的服务和支持。

  4. 合并和收购: 为了进一步扩大业务规模和增强竞争力,Aavid Thermalloy进行了一系列的合并和收购活动。公司通过并购具有相关技术和市场资源的企业,扩大了产品线和市场份额,加强了在热管理领域的领先地位。

  5. 可持续发展和未来展望: Aavid Thermalloy公司致力于可持续发展,注重环境保护和社会责任。公司通过采取节能减排、提高资源利用率等措施,努力降低对环境的影响。未来,公司将继续致力于技术创新和产品升级,为客户提供更优质的产品和服务,推动热管理行业的发展和进步。

Hisetec Electronic Co Ltd公司的发展小趣事

背景:随着全球化进程的加速,电子产品的供应链越来越复杂,国际合作成为必然趋势。Hisetec Electronic Co Ltd公司敏锐地洞察到这一点,开始实施国际化战略。

发展:公司首先在欧洲设立研发中心,与当地高校和科研机构合作,共同开发新技术。随后,又在亚洲多个国家和地区建立生产基地和销售网络,实现了全球范围内的资源配置和市场覆盖。通过这一系列举措,Hisetec公司不仅降低了生产成本,还提升了品牌知名度,实现了业务的高速增长。

EHC(ELECTRONICHARDWARE)公司的发展小趣事

面对日益全球化的市场环境,EHC公司积极实施国际化战略。公司通过与国外知名企业的合作,引进先进的技术和管理经验,不断提升自身的竞争力。同时,EHC公司还积极参加国际展会和论坛,拓展海外市场。经过多年的努力,EHC公司的产品已经成功打入国际市场,并在多个国家和地区建立了稳定的销售渠道。

CLARE公司的发展小趣事

为了进一步拓展市场,CLARE公司积极开拓国内市场,并与多家知名企业建立了战略合作关系。同时,公司还积极进军国际市场,通过参加国际展会、设立海外分支机构等方式,加强与国际客户的交流与合作。这些举措不仅为CLARE公司带来了更多的商业机会,也进一步提升了其在全球电子行业中的地位和影响力。

客益(Guestgood)公司的发展小趣事

为了进一步拓展市场,CLARE公司积极开拓国内市场,并与多家知名企业建立了战略合作关系。同时,公司还积极进军国际市场,通过参加国际展会、设立海外分支机构等方式,加强与国际客户的交流与合作。这些举措不仅为CLARE公司带来了更多的商业机会,也进一步提升了其在全球电子行业中的地位和影响力。

问答坊 | AI 解惑

分享招聘信息

人才交流,招聘信息…

查看全部问答>

世界各國電視制式

世界各國電視制式…

查看全部问答>

图片颜色识别

本人想做一个图片颜色识别的设备,比较简单。功能就是识别图片区域颜色,分辨出颜色块的大小。详细要求联系我面谈。 联系方式:QQ 65179655…

查看全部问答>

用Delphi开发串口通信软件

用Delphi开发串口通信软件一般有两种方法:一是利用Windows的通信API函数,另一种是采用Microsoft的MSComm控件。利用API编写串口通信程序较为复杂,需要掌握大量通信知识,其优点是可实现的功能更强大,应用面更广泛,更适合于编写较为复杂的低层次 ...…

查看全部问答>

救命用的

本人来自西部,飘泊沿海,渴盼还乡。 近日投递家乡一家国内知名重工的机电一体化职位,奈何软件由于,硬件不足,被通知转换工具二次开发。 还要做“弈衡招聘选拔测评系统”的评测,搜索之,发现并非分数越高越高,而是要契合。 为了能够凹凸恰到 ...…

查看全部问答>

急问:采用2812dec外扩双口ram调试问题。

   在2812dec外扩展了一片2m的双口ram。使用的是存储器扩展总线的zone2空间。采用ce0片选。按照书上的存储器空间映射地址应该为:0x80000-0x100000。调试的时候存在的问题如下:    1)我往这段地址写数、读数的时候,结构争 ...…

查看全部问答>

转 从《江南style》中看LED照明营销

自今年7月15日《江南style》MV视频被上传到youtube之后,其表现不得不说是一个“奇迹”。截至今日凌晨,上传102天,超5亿点击量,两破吉尼斯、35个国家iTunesMV榜单排行榜冠军,在youtube“史上点击率最多的视频”中排名第三,并极有可能力压美国歌 ...…

查看全部问答>

【转】给电子学生的忠告:大学生需学的电子知识

    今天早上在新浪微博看到这篇问题,就转过来跟大家分享一下。     有不少的在校的大学生写信给我,问在学校里应该学习什么电子知识.就业形势越来越严峻,不光是在中国,全球都一样,全球经济的发展速度放慢,至少会持续几年的时 ...…

查看全部问答>

SiTime样品中心为中国工程师恭送晶振,喜迎新年

1-220MHz任意频率SiTime硅晶振免费样品申请,多种尺寸7050、5032、3225、2520、2016和电压。 新年新选择,改变从新开始。前十名申请者另外还可以领取2.015MHz、20.15MHz、201.5MHz其中一种晶振作为纪念。 SiTime晶振申请网址:http://sitime.join ...…

查看全部问答>