当前位置: 首页 > article >正文

STM32-温湿度上传OneNET项目

一、项目需求

使用 ESP8266 连接 OneNET 云平台,并通过 MQTT 协议上传 DHT11 获取的温湿度值。

二、项目框图

三、DHT11工作原理

参考于良许嵌入式手把手教你玩转DHT11(原理+驱动) | 良许嵌入式

3.1 正常工作验证 #​ 

上电后,「电源指示灯/POWER」红灯亮,表示上电成功,正常工作。 

3.2 DHT11工作时序 #​  

3.2.1 整体工作时序 #​  

DHT11 整体工作时序为:主机发送开始信号、DHT11 响应输出、主机接收 40bit 数据(湿度数据+温度数据+校验值),结束信号(可选)。

具体过程如下: 

1.  总线空闲状态为高电平,主机拉低总线等待 DHT11 响应, 主机把总线拉低必须大于 18ms,保证 DHT11 能检测到起始信号; 

2.  主机发送开始信号结束后,拉高总线电平并延时等待 20-40us 后,读取 DHT11 的响应信号;  

3.  DHT11 接收到主机的开始信号后,等待微处理器开始信号结束,发送 80us 低电平响应信号;  

4.  DHT11 发送 80us 高电平准备发送数据;  

5.  DHT11 发送 40bit 数据(湿度数据+温度数据+校验值)。   

过程 主机 DHT11  1 拉低>18ms   2 拉高20~40us   3   响应 80us 低电平  4   拉高 80us  5   发送 40bit 数据(湿度数据+温度数据+校验值) 

 

3.2.2 起始及响应信号 #​  

总流程讲完介绍一下细分流程: 首先主机拉低总线至少 18ms,然后再拉高总线,延时 20~40us,此时起始信号(有时也叫复位信号)发送完毕。 

DHT11 检测到复位信号后,触发一次采样,并拉低总线 80us 表示响应信号,告诉主机数据已经准备好了。

DHT11 之后拉高总线 80us,然后开始传输数据。如果检测到响应信号为高电平,则 DHT11 初始化失败,请检查线路是否连接正常。 

3.2.3 读时序 #​  

DHT11 开始传输数据。每 1bit 数据都以 50us 低电平开始,告诉主机开始传输一位数据了。DHT11 以高电平的长短定义数据位是 0 还是 1:

当 50us 低电平过后拉高总线,高电平持续 26~28us 表示 0,高电平持续 70us 表示数据 1。 

当最后 1bit 数据传送完毕后,DHT11 拉低总线 50us,表示数据传输完毕,随后总线由上拉电阻拉高进入空闲状态。 

位数据0表示方式: 以 50us 低电平开始,高电平持续 26~28us 表示 0。

位数据1表示方式: 以 50us 低电平开始,高电平持续 70us 表示 1。 

3.3 DHT11数据格式 #​ 

DHT11 的 DATA 传输一次完整的数据为 40bit,按照高位在前,低位在后的顺序传输。 

数据格式为:8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位,

一共 5 字节(40bit)数据。 正常情况下,前四个字节的和刚好与校验位相等,通过这种机制可以保证数据传输的准确性。

四、项目实现

复制项目文件19-串口打印

重命名59-DHT11

新建文件dht11

dht11.c

dht11.h

打开项目工程

加载文件

书写头文件

编译

编程思路:

1、之前的模块都需要init函数,而这里的dht11反倒不需要init函数,因为dht11只有一个data的IO口。DHT11的一个data口用于输入和输出,所以需要对DHT11的IO口做一个配置,则需要:dht11_gpio_input,dht11_gpio_output两个函数。

2、接下来是DHT11的起始信号及响应信号需要:dht11_start

3、读时序:dht11_read_byte

4、将读出的数据,存储下来,用指针(地址)承接:dht11_read

5、因为是单总线协议,所以先进行一个封装

        判断1位数据,当IO口电平等于高电平的时候,延时50微妙,判断当下是高电平还是低电平,如果是高电平,则传出来的数据是1,否则就是0,

while(!DHT11_DQ_IN);
        delay_us(50);
        if(DHT11_DQ_IN == 1)
        {
            temp = 1;
            while(DHT11_DQ_IN);
        }
        else
            temp = 0;

        我们知道,一个字节有8位,所以这段代码要执行八次,才是一位,定义一个UINT8_T的变量,这个变量有8位,将受到的一位字节存放在这个变量的像左移一位。

    for(i=0; i<8; i++){
        while(!DHT11_DQ_IN);
        delay_us(50);
        if(DHT11_DQ_IN == 1)
        {
            temp = 1;
            while(DHT11_DQ_IN);
        }
        else
            temp = 0;
        byte = byte << 1;
        byte |= temp;
    }

上面这个函数,是用来返回发送过来的一个字节,DHT11会返回5个字节,所以上述操作,要执行5次,并且第五位是校验位,前四位的和等于第五位时,才证明没有发送错数据,官方文档要求,DH11不可以一直在返回数据,需要延长2s


    for(i=0; i<5; i++)
    {
        dht11_data[i] = dht11_read_byte();
    }
    if(dht11_data[0]+dht11_data[1]+dht11_data[2]+dht11_data[3] == dht11_data[4])
    {
        memcpy(result,dht11_data,4);//将dht11_data中四个数据复制给result
        printf("湿度:%d.%dRH ,",dht11_data[0],dht11_data[1]);
        printf("温度:%d.%d℃ \r\n",dht11_data[2],dht11_data[3]);
    }
    delay_ms(2000);

        在esp8266中需要重写esp8266_send_data函数,因为以前的esp8266_send_data函数是用来模仿printf,所以需要重写函数,用来发送数据

//两个参数分别是:要发送的数据,和要发送数据的长度
void esp8266_send_data(char *data,uint16_t len)
{
    //清空发送缓冲区
    esp8266_rx_clear();
    //发送数据函数
    HAL_UART_Transmit(&esp8266_handle,(unsigned char*)data,len,100);
}

在OneNet创建产品和设备

三元组很重要:产品id,设备id,密钥

设备id的获取,将设备导入出来,就会有一个表,其中有设备id

 将代码中上面部分,按自己的东西改写,


http://www.kler.cn/a/556058.html

相关文章:

  • 这个TensorFlow是一个开源的机器学习框架,怎么用
  • 【蓝桥杯集训·每日一题2025】 AcWing 6135. 奶牛体检 python
  • Scala的宝藏库:探索常用的第三方库及其应用
  • OpenCV机器学习(8)随机森林(Random Forests)算法cv::ml::RTrees类
  • 【Java学习】多态
  • UE地编材质世界对齐纹理旋转
  • 用JMeter给要登录的操作做压力测试
  • 23种设计模式 - 原型模式
  • Pytorch实现之特征损失与残差结构稳定GAN训练,并训练自己的数据集
  • 【HarmonyOS Next】鸿蒙监听手机按键
  • React 高阶组件的优缺点
  • 阿里云ACK+GitLab企业级部署实战教程
  • 大型工业设备翻新集团企业数字化转型SAP解决方案总结
  • NetLogon 权限提升漏洞
  • Angular 中获取 DOM 节点的几种方法
  • C++ Primer string流
  • SpringBoot项目实现用户token和资源的多重校验
  • 【原创】vue-element-admin-plus完成编辑页面中嵌套列表功能
  • 基于AVue的二次封装:快速构建后台管理系统的CRUD方案
  • Amazon Lex:AI对话引擎重构企业服务新范式