2894 views|1 replies

46

Posts

0

Resources
The OP
 

[Beetle ESP32-C3 review] Part 3: vscode+idf+oled+ssd1306+dht11 [Copy link]

Preface: I have a DHT11 temperature and humidity sensor with three pins, GND, VCC and DATA. Connect an IO to the DATA pin to fetch data according to the chip output data format. Next, refer to the universal network to refer to the code of the senior brother to adapt to our ESP32-C3.

Development environment: VSCode+IDF+OLED+SSD1306+DHT11

  1. Refer to the DHT11 acquisition code of the senior brother, which is organized as follows:

Add a new DHT11.c file to the component directory in the project, and add a DHT11.h file to the include directory in the same directory. The specific DHT11.c is shown below.

#include "esp_log.h"

#include <stdint.h>

#include <stdlib.h>

#include <string.h>

#include "sdkconfig.h"

#include "driver/gpio.h"

#include "DHT11.h"

static void InputInitial(void) //Set the port to input

{

gpio_pad_select_gpio(DHT11_PIN);

gpio_set_direction(DHT11_PIN, GPIO_MODE_INPUT);

}

static void OutputHigh(void)//Output 1

{

gpio_pad_select_gpio(DHT11_PIN);

gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT);

gpio_set_level(DHT11_PIN, 1);

}

static void OutputLow(void)//output 0

{

gpio_pad_select_gpio(DHT11_PIN);

gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT);

gpio_set_level(DHT11_PIN, 0);

}

static uint8 getData() //Read status

{

return gpio_get_level(DHT11_PIN);

}

//Read a byte of data

static void COM(void) // Temperature and humidity write

{

uchar i;

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

{

ucharFLAG=2;

//Wait for the IO port to become low, and after it becomes low, use the delay to determine whether it is 0 or 1

while((getData()==0)&&ucharFLAG++) ets_delay_us(10);

ets_delay_us(35); //Delay 35us

uchartemp=0;

//If this bit is 1, it will still be 1 after 35us, otherwise it will be 0

if(getData()==1)

uchartemp=1;

ucharFLAG=2;

//Wait for the IO port to become high. When it becomes high, it means that the next bit can be read

while((getData()==1)&&ucharFLAG++)

ets_delay_us(10);

if(ucharFLAG==1)

break;

ucharcomdata<<=1;

ucharcomdata|=uchartemp;

}

}

void Delay_ms(uint16 ms)

{

int i=0;

for(i=0; i<ms; i++){

ets_delay_us(1000);

}

}

void DHT11_get(void) //Temperature and humidity sensor start

{

OutputLow();

Delay_ms(19); //>18MS

OutputHigh();

InputInitial(); //Input

ets_delay_us(30);

if(!getData()) // indicates that the sensor pulls down the bus

{

ucharFLAG=2;

//Wait for the bus to be pulled high by the sensor

while((!getData())&&ucharFLAG++)

ets_delay_us(10);

ucharFLAG=2;

//Wait for the bus to be pulled low by the sensor

while((getData())&&ucharFLAG++)

ets_delay_us(10);

COM(); //Read the first byte,

ucharRH_data_H_temp=ucharcomdata;

COM(); //Read the second byte,

ucharRH_data_L_temp=ucharcomdata;

COM(); //Read the third byte,

ucharT_data_H_temp=ucharcomdata;

COM(); //Read the 4th byte,

ucharT_data_L_temp=ucharcomdata;

COM(); //Read the 5th byte,

ucharcheckdata_temp=ucharcomdata;

OutputHigh();

// Check if the checksum is consistent

uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_temp+ucharRH_data_L_temp);

if(uchartemp==ucharcheckdata_temp)

{

//Checksum is consistent,

ucharRH_data_H=ucharRH_data_H_temp;

ucharRH_data_L=ucharRH_data_L_temp;

ucharT_data_H=ucharT_data_H_temp;

ucharT_data_L=ucharT_data_L_temp;

ucharcheckdata=ucharcheckdata_temp;

//Save temperature and humidity

Humi=ucharRH_data_H;

Humi_small=ucharRH_data_L;

Temp=ucharT_data_H;

Temp_small=ucharT_data_L;

}

else

{

Humi=100;

Temp=100;

}

}

else //No successful reading, return 0

{

Humi=0,

Temp=0;

}

OutputHigh(); //Output

}

The DHT11.h file code is as follows:

#ifndef DHT11_h

#define DHT11_h

#include <sys/types.h>

#include "driver/gpio.h"

#include "string.h"

#define DHT11_PIN 4 //define the pin of DHT11

#define uchar unsigned char

#define uint8 unsigned char

#define uint16 unsigned short

// Temperature and humidity definition

uchar ucharFLAG,uchartemp;

uchar Humi,Humi_small,Temp,Temp_small;

uchar ucharT_data_H,ucharT_data_L,ucharRH_data_H,ucharRH_data_L,ucharcheckdata;

uchar ucharT_data_H_temp,ucharT_data_L_temp,ucharRH_data_H_temp,ucharRH_data_L_temp,ucharcheckdata_temp;

uchar ucharcomdata;

void DHT11_get(void); //Temperature and humidity sensor start

#endif

The final code of the i2c_example_main.c file is as follows:

/* SSD1306 Example

See README.md file to get detailed usage of this example.

This example code is in the Public Domain (or CC0 licensed, at your option.)

Unless required by applicable law or agreed to in writing, this

software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR

CONDITIONS OF ANY KIND, either express or implied.

*/

#include <stdio.h>

#include "esp_log.h"

#include "driver/i2c.h"

#include "sdkconfig.h"

#include "OLEDDisplay.h"

#include "DHT11.h"

static const char *TAG = "oled-example";

#define _I2C_NUMBER(num) I2C_NUM_##num

#define I2C_NUMBER(num) _I2C_NUMBER(num)

#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< gpio number for I2C master clock */

#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< gpio number for I2C master data */

#define I2C_MASTER_NUM I2C_NUMBER(CONFIG_I2C_MASTER_PORT_NUM) /*!< I2C port number for master dev */

SemaphoreHandle_t print_mux = NULL;

static void i2c_test_task(void *arg)

{

char temp[16]={0};

char humi[16]={0};

OLEDDisplay_t *oled = OLEDDisplay_init(I2C_MASTER_NUM,0x78,I2C_MASTER_SDA_IO,I2C_MASTER_SCL_IO);

// OLEDDisplay_fillRect(oled,7,7,18,18);

// OLEDDisplay_drawRect(oled,6,32,20,20);

//OLEDDisplay_display(oled);

// vTaskDelay(500 / portTICK_PERIOD_MS);

while(1) {

DHT11_get(); //Read temperature and humidity

printf("Temp=%d.%d℃--Humi=%d.%d%%RH \r\n", Temp,Temp_small,Humi,Humi_small);

sprintf(temp,"%d.%d",Temp,Temp_small);

sprintf(humi,"%d.%d",Humi,Humi_small);

OLEDDisplay_clear(oled);

OLEDDisplay_setFont(oled,ArialMT_Plain_16);

OLEDDisplay_drawString(oled,16, 00, "DHT11 TEST");

OLEDDisplay_display(oled);

// vTaskDelay(500 / portTICK_PERIOD_MS);

OLEDDisplay_setFont(oled,ArialMT_Plain_10);

OLEDDisplay_drawString(oled,16, 25, "Temp:");

OLEDDisplay_display(oled);

// vTaskDelay(500 / portTICK_PERIOD_MS);

OLEDDisplay_setFont(oled,ArialMT_Plain_10);

OLEDDisplay_drawString(oled,16,36, "Humi:");

OLEDDisplay_display(oled);

OLEDDisplay_setFont(oled,ArialMT_Plain_10);

OLEDDisplay_drawString(oled,60, 25, temp);

OLEDDisplay_display(oled);

// vTaskDelay(500 / portTICK_PERIOD_MS);

OLEDDisplay_setFont(oled,ArialMT_Plain_10);

OLEDDisplay_drawString(oled,60,36, humi);

OLEDDisplay_display(oled);

vTaskDelay(1000/portTICK_PERIOD_MS);

}

vSemaphoreDelete(print_mux);

vTaskDelete(NULL);

}

void app_main(void)

{

print_mux = xSemaphoreCreateMutex();

ESP_LOGI(TAG,"Running");

xTaskCreate(i2c_test_task, "i2c_test_task_0", 1024 * 2, (void *)0, 10, NULL);

}

The specific code path is shown in the figure.

  1. Modify project configuration

Modify the CMakeLists.txt file in the component directory and add the compilation item of DHT11.c, as shown in the figure.

  1. Compile and download

Just compile and download. If you don’t know how to compile, read the previous article or the one before that.

  1. Demo

At first, I wanted to refresh only the location where the data changed, which is actually the best. Currently, the entire screen is cleared and redisplayed. I don’t know much about the refresh principle of OLED, so I don’t know whether it is better to keep it all the time or refresh the interface regularly. If you are interested, you can try to refresh only the location where the data changes.

dht11-oled

This post is from RF/Wirelessly

Latest reply

I think this transplant is quite convenient!   Details Published on 2022-8-24 14:53
 

6788

Posts

2

Resources
2
 

I think this transplant is quite convenient!

This post is from RF/Wirelessly
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

快速回复 返回顶部 Return list