STM32
直播中

刘玉兰

8年用户 1096经验值
私信 关注
[问答]

如何去实现一个基于51单片机+DHT11温湿度模块+ESP8266模块+上传oneNET APP显示+LCD1602显示呢

如何去实现一个基于51单片机+DHT11温湿度模块+ESP8266模块+上传oneNET APP显示+LCD1602显示呢?其实现步骤有哪些呢?

回帖(1)

王云玲

2021-12-17 11:59:12
基本介绍

最近做了一个基于51单片机(STC89C52)+DHT11温湿度模块+ESP8266模块+上传oneNET APP显示+LCD1602显示。51单片机采集DHT11模块的温度和湿度,通过ESP8266模块上传温湿度到oneNET平台,然后通过APP查看温湿度模块,同时LCD1602也同样显示温度和湿度。还可以设定按键控制但单片机外设,比如APP按键按下让单片机点亮一个灯等等。。。。。





器件

51单片机

ESP8266

我用的是 01s

DHT11温湿度

u***-ttl模块

实现思路






get方式 是获取平台上面的数据,正常我们单单做温湿度显示 不需要用到,如果需要用到按键等则需要。
实现步骤

1:注册oneNET平台

进入中国移动oneNETo平台:oneNET 先注册平台




















2:测试ESP8266是否正常

这里就需要ESP8266 和 USB-TTL接好线了
2.1:接线:
[tr]ESP8266USB-TTL[/tr]
3.3V3.3V
TXRX
RXTX
注意模块是3.3V
2.2:打开电脑串口小助手发送指令:
指令: AT





esp8266波特率默认是115200 我们51单片机晶振11.0592或者12 太低上不去,所以先把esp8266波特率改成9600 记得你得是跟esp8266模块波特率同样你才发送哦 不一样发送了也没用。
指令: AT+UART=9600,8,1,0,0
指令: AT+CWMODE=3 //设置WIFI应用模式 (成功返回会有OK)
指令: AT+RST //重置WIFI模块 (成功返回会有OK)
3:连接网络

指令: AT+CWJAP=“wifiNane”,“password” //连接无线路由器(手机热点啥的)
Wifiname: 就是你的热点名字 或者WiFi的名字
Password: 你的热点密码 或者WiFi密码





4:上传数据

指令:
AT+CIPSTART=“TCP”,“183.230.40.33”,80 //和服务器建立TCP连接
AT+CIPMODE=1 //进入透明传输模式
AT+CIPSEND //开始传输
POST /devices/XXXXXXXXX/datapoints?type=5 HTTP/1.1
api-key:??????????????????
Host:api.heclouds.com
Content-Length:10
,;temp,27
XXXXXXXXX:设备ID
??????????????????:api-key值





5:设置APP应用
















获取平台上的数据呢?(想点击按键 让单片机点灯?播放音乐?等等)





6:代码编写呈现(部分)

mian.c


#include
#include "stdlib.h"
#include "lcd1602.h"
#include "delay.h"
#include "uart.h"
#include "dht11.h"
#include "esp8266.h"


/*主程序入口*/
void main()
{
        BEEP = 0;
        initEsp8266();  //初始化ESP8266
        initUart();                //初始化串口
        init_lcd();                //初始化LCD1602
        display_str();  //LCD1602 显示 temp: humi:                       
        BEEP = 1;
        while(1)
        {
               
                delay1s();
                DHT_receive();                  //DHT11读取函数
                DHT_LCD1602_display();        //1602显示温湿度
                temp_upload();                        //上传温度数据
                humi_upload();                        //上传湿度数据
                LED1 = ~LED1;                                                       
        }
}


lcd1602.c
#include
#include "lcd1602.h"


#define LCD P0
***it E = P2^7;
***it RS = P2^6;
***it RW = P2^5;


/******延迟5毫秒函数********/
void delay5ms()   //误差 -0.000000000001us
{
    unsigned char a,b;
    for(b=15;b>0;b--)
        for(a=152;a>0;a--);
}




/******LCD1602写命令函数********/
void write_com(unsigned char command)
{
        RS = 0;
        RW = 0;         //高读低写
        LCD = command;
        delay5ms(); //这里延时最低要30纳秒 我们直接给5ms
        E = 1;                //使能拉高
        delay5ms(); //最低要求延迟150纳秒 我们直接给5ms
        E = 0;
}


/******LCD1602写数据函数********/
void write_data(unsigned char dat)
{
        RS = 1;
        RW = 0;
        LCD = dat;
        delay5ms(); //这里延时最低要30纳秒 我们直接给5ms
        E = 1;                //使能拉高
        delay5ms(); //最低要求延迟150纳秒 我们直接给5ms
        E = 0;
}
/******初始化LCD1602********/
void init_lcd()
{       
        write_com(0x06); //写入数据后光标自动右移 整屏不移动。 0x40(光标左移 整屏不移动)0x05(左移 整屏右移)0x07(右移 整屏右移)
        write_com(0x0c); //开显示功能 无光标 不闪烁
        write_com(0x38); //数据总线8位 16X2显示 5*7点阵
        write_com(0x01); //清屏 0000 0001
}


esp8266.c
#include
#include "esp8266.h"
#include "delay.h"
#include "uart.h"
#include


#define time 100     //宏定义 延时的时间
char T[5] = {''}; //上传平台的温度值
char H[5] = {''};        //上传平台的湿度值


/*esp8266初始化*/
void initEsp8266()
{
        delayms(300);
           sendString("AT+CWMODE=3rn");                //设置WIFI应用模式
        delayms(300);                                                //设置WIFI应用模式
        sendString("AT+RSTrn");                        //重置WIFI模块
        delayms(300);
        sendString("AT+CIFSRrn");                        //查询本地IP
        delayms(1000);
        sendString("AT+CWJAP="wifi_name","password"rn");//连接无线路由器
        delayms(6000);
}


uart.c
#include
#include "uart.h"


/*单片机发送一个字节函数*/
void sendChar(unsigned char a)                                
{
        SBUF = a;
        while(TI==0);
        TI=0;       
}




/*发送一个字符串函数*/
void sendString(unsigned char *s)                       
{
        while(*s!='')
        {
                sendChar(*s);
                s++;
        }
               
}




/*串口初始化函数*/
void initUart()
{
        /*串口中断定时器初始化*/
        TMOD=0x20;                                                        //定时器1工作在方式2  
        TH1=0xfd;                                                        //波特率为9600,精振为11.0592MHz
        TL1=0xfd;
        REN=1;                                                                //启动串行口接收数据
        SM0=0;                                                                //串口工作在方式1
        SM1=1;                                                                //串行口工作方式选择
        EA=1;                                                                //打开总中断
        ES=0;                                                                //关中断
        TR1=1;                                                                //打开定时器中断


}


dht11.c
#include
#include "dht11.h"
#include "delay.h"
#include "esp8266.h"
#include "lcd1602.h"
#include


unsigned char DHTDATA[5] = {''}; //存放40位 数据
unsigned char code array[] = {"humi:"};  //LCD1602显示 humi: 字符
unsigned char code array1[] = {"temp:"}; //LCD1602显示 temp: 字符




/*DHT11接收数据函数*/
unsigned char DHT_receive_data()
{
        unsigned char i;
        unsigned char dat=0;  //0000 0000


               
        for(i=0;i<8;i++)
        {
                while(!DATA); //等待DHT 50us低电平信号过去
                delay30us(); //延时大概30us 如何还是高电平 则为1
               


                dat<<=1; //左移一位 因为数据是从高位开始传
                if(DATA == 1)
                {
                        dat|=0x01;
                }
/*                else
                {
                        dat|=0x00;
                }         
*/
               
                while(DATA); //等待DHT 拉低 准备下一位开始


        }
        return dat;
       
}






/*DHT11读取函数*/
void DHT_receive()
{
        unsigned char R_H,R_L,T_H,T_L,CHECK;
         //主机发送信号


        DATA = 1;
        delay30us();
        DATA = 0;
        delay20ms(); //延时大于18ms
        DATA=1;
        delay30us();         //延时30us  20-40us 均可


        DATA=1;
        if(DATA == 0)   //判断DHT是否进入响应
        {


                while(!DATA);           //等待从机80us低电平响应信号过去
                while(DATA); //等待从机80us高电平信号过去


                   /*获取温湿度数据*/
                R_H = DHT_receive_data();        //湿度高位
                R_L = DHT_receive_data();
                T_H = DHT_receive_data();
                T_L = DHT_receive_data();


                CHECK = DHT_receive_data();


                DATA=0;
                delay55us();
                DATA=1;
       
                /*校验*/
                if((R_H + R_L + T_H + T_L) == CHECK)
                {
                        DHTDATA[0] = R_H;
                        DHTDATA[1] = R_L;
                        DHTDATA[2] = T_H;
                        DHTDATA[3] = T_L;


                        DHTDATA[4] = CHECK;
                }
                       
        }
}




/*显示DHT11数据函数*/
void DHT_LCD1602_display()
{
        write_com(0x85);
        write_data(DHTDATA[0]/10 + 0x30);
        write_com(0x86);
        write_data(DHTDATA[0]%10 + 0x30);
       
        write_com(0x87);
        write_data('.');       


        write_com(0x88);
        write_data(DHTDATA[1]/10 + 0x30);
        write_com(0x89);
        write_data('%');


       
        write_com(0xC5);
        write_data(DHTDATA[2]/10 + 0x30);
        write_com(0xC6);
        write_data(DHTDATA[2]%10 + 0x30);
       
        write_com(0xc7);
        write_data('.');


        write_com(0xC8);
        write_data(DHTDATA[3]/10 + 0x30);
        write_com(0xC9);
        write_data(0xDF); //度


        write_com(0xca);               
        write_data('C');
}


/*显示字符temp: humi:函数*/
void display_str()
{
        unsigned char i;
        write_com(0x80);  //第一行第一个开始显示 humi:
        for(i=0;i<5;i++)
        {
                write_data(array);
        }


        write_com(0xc0);  //第二行第一个开始显示 temp:
        for(i=0;i<5;i++)
        {
                write_data(array1);
        }
}


总结

单单的温湿度上传oneNET平台APP显示没啥问题,加了一个按键则速度慢了许多,之前就因为加一个按键功能用了挺长时间才做出来了,由于GET方式返回字节太多,需要找到需要的字节,现在按键是能做出来了但是响应速度有点慢,还是挺菜,但是还能用,就是响应速度慢了,还得继续加油,总的来说还行吧哈哈哈自我鼓励一下。
如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈
举报

更多回帖

×
20
完善资料,
赚取积分