[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
- 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.
- 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.
- Compile and download
Just compile and download. If you don’t know how to compile, read the previous article or the one before that.
- 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
|