【Beetle ESP32-C3测评】第三篇篇:vscode+idf+oled+ssd1306+dht11
<p>前言:手里有个DHT11的温湿度传感器,三根脚,GND、VCC和DATA。DATA脚接一个IO即可按照芯片输出数据格式进行取数操作,接下来参考万能的网络<a href="https://blog.csdn.net/Changerking/article/details/122366815"><u>参考一下大师兄的代码</u></a>适配咱的ESP32-C3。</p><p > </p>
<p >开发环境:VSCode+IDF+OLED+SSD1306+DHT11</p>
<ol>
<li >参考大师兄的DHT11的采集代码,整理如下:</li>
</ol>
<p >在工程中的component目录下新增DHT11.c文件,同目录下include下增加DHT11.h文件,具体DHT11.c如下所示。</p>
<p >#include "esp_log.h"</p>
<p >#include <stdint.h></p>
<p >#include <stdlib.h></p>
<p >#include <string.h></p>
<p >#include "sdkconfig.h"</p>
<p >#include "driver/gpio.h"</p>
<p >#include "DHT11.h"</p>
<p > </p>
<p >static void InputInitial(void)//设置端口为输入</p>
<p >{</p>
<p > gpio_pad_select_gpio(DHT11_PIN);</p>
<p > gpio_set_direction(DHT11_PIN, GPIO_MODE_INPUT);</p>
<p >}</p>
<p > </p>
<p >static void OutputHigh(void)//输出1</p>
<p >{</p>
<p > gpio_pad_select_gpio(DHT11_PIN);</p>
<p > gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT);</p>
<p > gpio_set_level(DHT11_PIN, 1);</p>
<p >}</p>
<p > </p>
<p >static void OutputLow(void)//输出0</p>
<p >{</p>
<p > gpio_pad_select_gpio(DHT11_PIN);</p>
<p > gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT);</p>
<p > gpio_set_level(DHT11_PIN, 0);</p>
<p >}</p>
<p > </p>
<p >static uint8 getData()//读取状态</p>
<p >{</p>
<p >return gpio_get_level(DHT11_PIN);</p>
<p >}</p>
<p > </p>
<p >//读取一个字节数据</p>
<p >static void COM(void) // 温湿写入</p>
<p >{</p>
<p > uchar i;</p>
<p > for(i=0;i<8;i++)</p>
<p > {</p>
<p > ucharFLAG=2;</p>
<p > //等待IO口变低,变低后,通过延时去判断是0还是1</p>
<p > while((getData()==0)&&ucharFLAG++) ets_delay_us(10);</p>
<p > ets_delay_us(35);//延时35us</p>
<p > uchartemp=0;</p>
<p > </p>
<p > //如果这个位是1,35us后,还是1,否则为0</p>
<p > if(getData()==1)</p>
<p > uchartemp=1;</p>
<p > ucharFLAG=2;</p>
<p > </p>
<p > //等待IO口变高,变高后,表示可以读取下一位</p>
<p > while((getData()==1)&&ucharFLAG++)</p>
<p > ets_delay_us(10);</p>
<p > if(ucharFLAG==1)</p>
<p > break;</p>
<p > ucharcomdata<<=1;</p>
<p > ucharcomdata|=uchartemp;</p>
<p > }</p>
<p >}</p>
<p > </p>
<p >void Delay_ms(uint16 ms)</p>
<p >{</p>
<p >int i=0;</p>
<p >for(i=0; i<ms; i++){</p>
<p >ets_delay_us(1000);</p>
<p >}</p>
<p >}</p>
<p > </p>
<p >void DHT11_get(void) //温湿传感启动</p>
<p >{</p>
<p > OutputLow();</p>
<p > Delay_ms(19); //>18MS</p>
<p > OutputHigh();</p>
<p > InputInitial(); //输入</p>
<p > ets_delay_us(30);</p>
<p > if(!getData())//表示传感器拉低总线</p>
<p > {</p>
<p > ucharFLAG=2;</p>
<p > //等待总线被传感器拉高</p>
<p > while((!getData())&&ucharFLAG++)</p>
<p > ets_delay_us(10);</p>
<p > ucharFLAG=2;</p>
<p > //等待总线被传感器拉低</p>
<p > while((getData())&&ucharFLAG++)</p>
<p > ets_delay_us(10);</p>
<p > COM();//读取第1字节,</p>
<p > ucharRH_data_H_temp=ucharcomdata;</p>
<p > COM();//读取第2字节,</p>
<p > ucharRH_data_L_temp=ucharcomdata;</p>
<p > COM();//读取第3字节,</p>
<p > ucharT_data_H_temp=ucharcomdata;</p>
<p > COM();//读取第4字节,</p>
<p > ucharT_data_L_temp=ucharcomdata;</p>
<p > COM();//读取第5字节,</p>
<p > ucharcheckdata_temp=ucharcomdata;</p>
<p > OutputHigh();</p>
<p > //判断校验和是否一致</p>
<p > uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_temp+ucharRH_data_L_temp);</p>
<p > if(uchartemp==ucharcheckdata_temp)</p>
<p > {</p>
<p > //校验和一致,</p>
<p > ucharRH_data_H=ucharRH_data_H_temp;</p>
<p > ucharRH_data_L=ucharRH_data_L_temp;</p>
<p > ucharT_data_H=ucharT_data_H_temp;</p>
<p > ucharT_data_L=ucharT_data_L_temp;</p>
<p > ucharcheckdata=ucharcheckdata_temp;</p>
<p > //保存温度和湿度</p>
<p > Humi=ucharRH_data_H;</p>
<p > Humi_small=ucharRH_data_L;</p>
<p > Temp=ucharT_data_H;</p>
<p > Temp_small=ucharT_data_L;</p>
<p > }</p>
<p > else</p>
<p > {</p>
<p > Humi=100;</p>
<p > Temp=100;</p>
<p > }</p>
<p > }</p>
<p > else //没用成功读取,返回0</p>
<p > {</p>
<p > Humi=0,</p>
<p > Temp=0;</p>
<p > }</p>
<p > </p>
<p > OutputHigh(); //输出</p>
<p >}</p>
<p >DHT11.h文件代码如下所示:</p>
<p >#ifndef DHT11_h</p>
<p >#define DHT11_h</p>
<p >#include <sys/types.h></p>
<p >#include "driver/gpio.h"</p>
<p >#include "string.h"</p>
<p > </p>
<p >#define DHT11_PIN 4//定义DHT11的引脚</p>
<p > </p>
<p >#define uchar unsigned char</p>
<p >#define uint8 unsigned char</p>
<p >#define uint16 unsigned short</p>
<p > </p>
<p >//温湿度定义</p>
<p >uchar ucharFLAG,uchartemp;</p>
<p >uchar Humi,Humi_small,Temp,Temp_small;</p>
<p >uchar ucharT_data_H,ucharT_data_L,ucharRH_data_H,ucharRH_data_L,ucharcheckdata;</p>
<p >uchar ucharT_data_H_temp,ucharT_data_L_temp,ucharRH_data_H_temp,ucharRH_data_L_temp,ucharcheckdata_temp;</p>
<p >uchar ucharcomdata;</p>
<p >void DHT11_get(void); //温湿传感启动</p>
<p > </p>
<p >#endif</p>
<p >i2c_example_main.c文件最终代码如下所示:</p>
<p >/* SSD1306 Example</p>
<p > </p>
<p > See README.md file to get detailed usage of this example.</p>
<p > </p>
<p > This example code is in the Public Domain (or CC0 licensed, at your option.)</p>
<p > </p>
<p > Unless required by applicable law or agreed to in writing, this</p>
<p > software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR</p>
<p > CONDITIONS OF ANY KIND, either express or implied.</p>
<p >*/</p>
<p >#include <stdio.h></p>
<p >#include "esp_log.h"</p>
<p >#include "driver/i2c.h"</p>
<p >#include "sdkconfig.h"</p>
<p >#include "OLEDDisplay.h"</p>
<p >#include "DHT11.h"</p>
<p > </p>
<p >static const char *TAG = "oled-example";</p>
<p > </p>
<p >#define _I2C_NUMBER(num) I2C_NUM_##num</p>
<p >#define I2C_NUMBER(num) _I2C_NUMBER(num)</p>
<p >#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< gpio number for I2C master clock */</p>
<p >#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< gpio number for I2C master data */</p>
<p >#define I2C_MASTER_NUM I2C_NUMBER(CONFIG_I2C_MASTER_PORT_NUM) /*!< I2C port number for master dev */</p>
<p > </p>
<p >SemaphoreHandle_t print_mux = NULL;</p>
<p > </p>
<p >static void i2c_test_task(void *arg)</p>
<p >{</p>
<p >char temp={0};</p>
<p >char humi={0};</p>
<p >OLEDDisplay_t *oled = OLEDDisplay_init(I2C_MASTER_NUM,0x78,I2C_MASTER_SDA_IO,I2C_MASTER_SCL_IO);</p>
<p > </p>
<p >// OLEDDisplay_fillRect(oled,7,7,18,18);</p>
<p >// OLEDDisplay_drawRect(oled,6,32,20,20);</p>
<p >// OLEDDisplay_display(oled);</p>
<p >// vTaskDelay(500 / portTICK_PERIOD_MS);</p>
<p > </p>
<p >while(1) {</p>
<p >DHT11_get(); //读取温湿度</p>
<p >printf("Temp=%d.%d℃--Humi=%d.%d%%RH \r\n", Temp,Temp_small,Humi,Humi_small);</p>
<p >sprintf(temp,"%d.%d",Temp,Temp_small);</p>
<p >sprintf(humi,"%d.%d",Humi,Humi_small);</p>
<p > </p>
<p >OLEDDisplay_clear(oled);</p>
<p >OLEDDisplay_setFont(oled,ArialMT_Plain_16);</p>
<p >OLEDDisplay_drawString(oled,16, 00, "DHT11 TEST");</p>
<p >OLEDDisplay_display(oled);</p>
<p >// vTaskDelay(500 / portTICK_PERIOD_MS);</p>
<p > </p>
<p >OLEDDisplay_setFont(oled,ArialMT_Plain_10);</p>
<p >OLEDDisplay_drawString(oled,16, 25, "Temp:");</p>
<p >OLEDDisplay_display(oled);</p>
<p >// vTaskDelay(500 / portTICK_PERIOD_MS);</p>
<p > </p>
<p >OLEDDisplay_setFont(oled,ArialMT_Plain_10);</p>
<p >OLEDDisplay_drawString(oled,16,36, "Humi:");</p>
<p >OLEDDisplay_display(oled);</p>
<p > </p>
<p >OLEDDisplay_setFont(oled,ArialMT_Plain_10);</p>
<p >OLEDDisplay_drawString(oled,60, 25, temp);</p>
<p >OLEDDisplay_display(oled);</p>
<p >// vTaskDelay(500 / portTICK_PERIOD_MS);</p>
<p > </p>
<p >OLEDDisplay_setFont(oled,ArialMT_Plain_10);</p>
<p >OLEDDisplay_drawString(oled,60,36, humi);</p>
<p >OLEDDisplay_display(oled);</p>
<p >vTaskDelay(1000 / portTICK_PERIOD_MS);</p>
<p >}</p>
<p > </p>
<p > vSemaphoreDelete(print_mux);</p>
<p > vTaskDelete(NULL);</p>
<p >}</p>
<p > </p>
<p >void app_main(void)</p>
<p >{</p>
<p > print_mux = xSemaphoreCreateMutex();</p>
<p >ESP_LOGI(TAG,"Running");</p>
<p > xTaskCreate(i2c_test_task, "i2c_test_task_0", 1024 * 2, (void *)0, 10, NULL);</p>
<p >}</p>
<p > </p>
<p >具体代码路径如图所示。</p>
<p > </p>
<ol start="2">
<li >修改工程配置</li>
</ol>
<p >修改component目录下的CMakeLists.txt文件,增加DHT11.c的编译项,如图所示。</p>
<p > </p>
<ol start="3">
<li >编译下载</li>
</ol>
<p >编译下载就可以了,不会编译的看上一篇或者上上篇啊。</p>
<p > </p>
<ol start="4">
<li >演示</li>
</ol>
<p >开始想只刷新数据变更位置,其实这样最好。目前是全屏清除,重新显示,对OLED的刷新原理也不太深入,是一直保存好,还是定时刷界面好,有兴趣的可以尝试只刷新数据变化的位置。</p>
<p >8845635c482e1aa280bbae9c63a53e9e<br />
</p>
<p>感觉这移植的还是挺方便的!</p>
页:
[1]