⑦ ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 DHT11 温湿度传感器】

目录

 

一、准备材料

二、硬件连接

三、软件编程

1、修改工程名

2、添加组件

3、编程

4、反馈结果

 5、核心代码

四、总结


 

⑦ ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 DHT11 温湿度传感器】

本章介绍ESP8266 IDF 框架下 如何使用GPIO口进行单总线时序模拟,介绍DHT11温湿度传感器的使用方法,实现对温湿度的采集。

 

一、准备材料

①开发板:NodeMcu (ESP8266)

②环境:Ubuntu 18.04 、 ESP-IDF 操作系统( ESP8266_RTOS_SDK V3.2)

③传感器:DHT11

④辅助材料:杜邦线、面包板

 

二、硬件连接

⑦ ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 DHT11 温湿度传感器】_第1张图片

       DHT11的硬件只包含三个引脚,分别是VCCGND数据输出引脚DATA。其模块输入电压VCC的输入范围是3.3V~5V。采样周期为1秒。传感器接3.3V电源、GND和ESP8266的GPIO5,信号引脚DATA接5kΩ上拉电阻,完成DHT11的硬件系统。

⑦ ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 DHT11 温湿度传感器】_第2张图片

三、软件编程

        DHT11能够使用单总线传输协议与ESP8266进行通信。其中ESP8266作为主机,DHT11作为从机。主机给传感器DHT11发送起始信号,收到从机应答信号后初始化成功,能够进行数据传输。


        DHT11回复响应信号后,会发送40bit的传感器数据,包括两个字节的湿度数据(一个字节整数、一个字节小数),两个字节的温度数据整数(一个字节整数、一个字节小数),最后是一个字节的校验和数据。通过求和校验的数据将会作为最后发送的数据。

 

⑦ ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 DHT11 温湿度传感器】_第3张图片  DHT11通信时序图

 

 本次例程是基于EPS8266 IDF的example “project_template” 进行开发,直接在模板基础上进行新内容的添加。

1、修改工程名

首先,将MakeFile中模板中的工程名字

PROJECT_NAME := project_template

修改为

PROJECT_NAME := project_DHT11

 

2、添加组件

然后添加工程组件文件夹 dht11_driver 到自己工程的 components (组件) 下

(PS:本次首先提供C++版本的驱动,工程中C++的具体使用方法可以参考我的系列博客内容)

3、编程

修改user_main.c 为 user_main.cpp

添加 dht11驱动的头文件 "dht11_driver.hpp"

void app_main(void) 函数添加修饰符 extern "C" 如下:

#include 
#include "esp_system.h"

#include "dht11_driver.hpp"

//生成 DHT11 的实例化对象
DHT_Sensor my_DHT11(GPIO_NUM_5,DHT11);
/******************************************************************************
 * FunctionName : app_main
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
extern "C" void app_main(void)
{
    printf("SDK version:%s\n", esp_get_idf_version());
    my_DHT11.DHTInit();

    while(1)
    {
        my_DHT11.DHTRead();
        ESP_LOGI("DHT11","DHT: Temperature*100 =  %d *C, Humidity*100 = %d %% (GPIO%d)",
                (int) (my_DHT11.Sensor_Data.temperature * 100), (int) (my_DHT11.Sensor_Data.humidity * 100), my_DHT11.data_pin);

        vTaskDelay(1000 / portTICK_RATE_MS);
    }
}

4、反馈结果

⑦ ESP8266 开发学习笔记_By_GYC 【ESP8266 驱动 DHT11 温湿度传感器】_第4张图片

 

5、核心代码



//温湿度传感器数据读取(并将数据写入到传入指针)

bool DHT_Sensor::DHTRead(DHT_Sensor_Data* output)

{

	int counter = 0;

	int laststate = 1;

	int i = 0;

	int j = 0;

	int checksum = 0;

	int data[100];

	data[0] = data[1] = data[2] = data[3] = data[4] = 0;

	gpio_num_t pin = (gpio_num_t)data_pin;



    gpio_set_direction(pin,GPIO_MODE_OUTPUT);

	// Wake up device, 250ms of high

	gpio_set_level(pin, 1);

	sleepms(250);

	// Hold low for 20ms

	gpio_set_level(pin, 0);

	sleepms(20);

	// High for 40ns

	gpio_set_level(pin, 1);

	delay_us(40);

	// Set DHT_PIN pin as an input

	gpio_set_direction(pin,GPIO_MODE_INPUT); //GPIO_DIS_OUTPUT(pin);



	// wait for pin to drop?

	while (gpio_get_level(pin) == 1 && i < DHT_MAXCOUNT) {

		delay_us(1);

		i++;

	}



	if(i == DHT_MAXCOUNT)

	{

		DHT_DEBUG("DHT: Failed to get reading from GPIO%d, dying\r\n", pin);

	    return false;

	}



	// read data

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

	{

		// Count high time (in approx us)

		counter = 0;

		while (gpio_get_level(pin) == laststate)

		{

			counter++;

			delay_us(1);

			if (counter == 1000)

				break;

		}

		laststate = gpio_get_level(pin);

		if (counter == 1000)

			break;

		// store data after 3 reads

		if ((i>3) && (i%2 == 0)) {

			// shove each bit into the storage bytes

			data[j/8] <<= 1;

			if (counter > DHT_BREAKTIME)

				data[j/8] |= 1;

			j++;

		}

	}



	if (j >= 39) {

		checksum = (data[0] + data[1] + data[2] + data[3]) & 0xFF;

	    DHT_DEBUG("DHT%s: %02x %02x %02x %02x [%02x] CS: %02x (GPIO%d)\r\n",

	              sensor_type==DHT11?"11":"22",

	              data[0], data[1], data[2], data[3], data[4], checksum, pin);

		if (data[4] == checksum) {

			// checksum is valid

			output->temperature = scale_temperature(data);

			output->humidity = scale_humidity(data);

			DHT_DEBUG("DHT: Temperature*100 =  %d *C, Humidity*100 = %d %% (GPIO%d)\n",

		          (int) (output->temperature * 100), (int) (output->humidity * 100), pin);

		} else {

			DHT_DEBUG("DHT: Checksum was incorrect after %d bits. Expected %d but got %d (GPIO%d)\r\n",

		                j, data[4], checksum, pin);

		    return false;

		}

	} else {

	    DHT_DEBUG("DHT: Got too few bits: %d should be at least 40 (GPIO%d)\r\n", j, pin);

	    return false;

	}

	return true;

}

四、总结

驱动DHT11主要就是遵从时序图,按照时序图中规定的时序控制和读取单线的DHT11传感器数据,最终通过原始数据换算得到最终的温湿度数据的值。

 

本次的工程我会开源到自己的github上(https://github.com/gengyuchao),欢迎大家来和我一起交流呀。

你可能感兴趣的:(Github,ESP,ESP8266小项目学习笔记)