lingxin_yuhe 发表于 2022-8-24 10:27

【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 >&nbsp;</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 &quot;esp_log.h&quot;</p>

<p >#include &lt;stdint.h&gt;</p>

<p >#include &lt;stdlib.h&gt;</p>

<p >#include &lt;string.h&gt;</p>

<p >#include &quot;sdkconfig.h&quot;</p>

<p >#include &quot;driver/gpio.h&quot;</p>

<p >#include &quot;DHT11.h&quot;</p>

<p >&nbsp;</p>

<p >static void InputInitial(void)//设置端口为输入</p>

<p >{</p>

<p >&nbsp;&nbsp;gpio_pad_select_gpio(DHT11_PIN);</p>

<p >&nbsp;&nbsp;gpio_set_direction(DHT11_PIN, GPIO_MODE_INPUT);</p>

<p >}</p>

<p >&nbsp;</p>

<p >static void OutputHigh(void)//输出1</p>

<p >{</p>

<p >&nbsp;&nbsp;gpio_pad_select_gpio(DHT11_PIN);</p>

<p >&nbsp;&nbsp;gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT);</p>

<p >&nbsp;&nbsp;gpio_set_level(DHT11_PIN, 1);</p>

<p >}</p>

<p >&nbsp;</p>

<p >static void OutputLow(void)//输出0</p>

<p >{</p>

<p >&nbsp;&nbsp;gpio_pad_select_gpio(DHT11_PIN);</p>

<p >&nbsp;&nbsp;gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT);</p>

<p >&nbsp;&nbsp;gpio_set_level(DHT11_PIN, 0);</p>

<p >}</p>

<p >&nbsp;</p>

<p >static uint8 getData()//读取状态</p>

<p >{</p>

<p >return gpio_get_level(DHT11_PIN);</p>

<p >}</p>

<p >&nbsp;</p>

<p >//读取一个字节数据</p>

<p >static void COM(void) &nbsp;&nbsp;&nbsp;// 温湿写入</p>

<p >{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;uchar i;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;for(i=0;i&lt;8;i++)</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharFLAG=2;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//等待IO口变低,变低后,通过延时去判断是0还是1</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((getData()==0)&amp;&amp;ucharFLAG++) ets_delay_us(10);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ets_delay_us(35);//延时35us</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchartemp=0;</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//如果这个位是1,35us后,还是1,否则为0</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(getData()==1)</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchartemp=1;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharFLAG=2;</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//等待IO口变高,变高后,表示可以读取下一位</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((getData()==1)&amp;&amp;ucharFLAG++)</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ets_delay_us(10);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(ucharFLAG==1)</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharcomdata&lt;&lt;=1;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharcomdata|=uchartemp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;}</p>

<p >}</p>

<p >&nbsp;</p>

<p >void Delay_ms(uint16 ms)</p>

<p >{</p>

<p >int i=0;</p>

<p >for(i=0; i&lt;ms; i++){</p>

<p >ets_delay_us(1000);</p>

<p >}</p>

<p >}</p>

<p >&nbsp;</p>

<p >void DHT11_get(void) &nbsp;&nbsp;//温湿传感启动</p>

<p >{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;OutputLow();</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;Delay_ms(19); &nbsp;//&gt;18MS</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;OutputHigh();</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;InputInitial(); //输入</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;ets_delay_us(30);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;if(!getData())//表示传感器拉低总线</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharFLAG=2;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//等待总线被传感器拉高</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((!getData())&amp;&amp;ucharFLAG++)</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ets_delay_us(10);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharFLAG=2;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//等待总线被传感器拉低</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while((getData())&amp;&amp;ucharFLAG++)</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ets_delay_us(10);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COM();//读取第1字节,</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharRH_data_H_temp=ucharcomdata;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COM();//读取第2字节,</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharRH_data_L_temp=ucharcomdata;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COM();//读取第3字节,</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharT_data_H_temp=ucharcomdata;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COM();//读取第4字节,</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharT_data_L_temp=ucharcomdata;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;COM();//读取第5字节,</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharcheckdata_temp=ucharcomdata;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputHigh();</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//判断校验和是否一致</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_temp+ucharRH_data_L_temp);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(uchartemp==ucharcheckdata_temp)</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//校验和一致,</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharRH_data_H=ucharRH_data_H_temp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharRH_data_L=ucharRH_data_L_temp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharT_data_H=ucharT_data_H_temp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharT_data_L=ucharT_data_L_temp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucharcheckdata=ucharcheckdata_temp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//保存温度和湿度</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Humi=ucharRH_data_H;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Humi_small=ucharRH_data_L;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Temp=ucharT_data_H;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Temp_small=ucharT_data_L;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Humi=100;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Temp=100;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;}</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;else //没用成功读取,返回0</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp; Humi=0,</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp; Temp=0;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;}</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;OutputHigh(); //输出</p>

<p >}</p>

<p >DHT11.h文件代码如下所示:</p>

<p >#ifndef DHT11_h</p>

<p >#define DHT11_h</p>

<p >#include &lt;sys/types.h&gt;</p>

<p >#include &quot;driver/gpio.h&quot;</p>

<p >#include &quot;string.h&quot;</p>

<p >&nbsp;</p>

<p >#define DHT11_PIN &nbsp;&nbsp;4//定义DHT11的引脚</p>

<p >&nbsp;</p>

<p >#define uchar unsigned char</p>

<p >#define uint8 unsigned char</p>

<p >#define uint16 unsigned short</p>

<p >&nbsp;</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); &nbsp;&nbsp;//温湿传感启动</p>

<p >&nbsp;</p>

<p >#endif</p>

<p >i2c_example_main.c文件最终代码如下所示:</p>

<p >/* SSD1306 Example</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;&nbsp;See README.md file to get detailed usage of this example.</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;&nbsp;This example code is in the Public Domain (or CC0 licensed, at your option.)</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;&nbsp;Unless required by applicable law or agreed to in writing, this</p>

<p >&nbsp;&nbsp;&nbsp;software is distributed on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR</p>

<p >&nbsp;&nbsp;&nbsp;CONDITIONS OF ANY KIND, either express or implied.</p>

<p >*/</p>

<p >#include &lt;stdio.h&gt;</p>

<p >#include &quot;esp_log.h&quot;</p>

<p >#include &quot;driver/i2c.h&quot;</p>

<p >#include &quot;sdkconfig.h&quot;</p>

<p >#include &quot;OLEDDisplay.h&quot;</p>

<p >#include &quot;DHT11.h&quot;</p>

<p >&nbsp;</p>

<p >static const char *TAG = &quot;oled-example&quot;;</p>

<p >&nbsp;</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 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*!&lt; gpio number for I2C master clock */</p>

<p >#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*!&lt; gpio number for I2C master data &nbsp;*/</p>

<p >#define I2C_MASTER_NUM I2C_NUMBER(CONFIG_I2C_MASTER_PORT_NUM) /*!&lt; I2C port number for master dev */</p>

<p >&nbsp;</p>

<p >SemaphoreHandle_t print_mux = NULL;</p>

<p >&nbsp;</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 >&nbsp;</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 >&nbsp;</p>

<p >while(1) {</p>

<p >DHT11_get(); //读取温湿度</p>

<p >printf(&quot;Temp=%d.%d℃--Humi=%d.%d%%RH \r\n&quot;, Temp,Temp_small,Humi,Humi_small);</p>

<p >sprintf(temp,&quot;%d.%d&quot;,Temp,Temp_small);</p>

<p >sprintf(humi,&quot;%d.%d&quot;,Humi,Humi_small);</p>

<p >&nbsp;</p>

<p >OLEDDisplay_clear(oled);</p>

<p >OLEDDisplay_setFont(oled,ArialMT_Plain_16);</p>

<p >OLEDDisplay_drawString(oled,16, 00, &quot;DHT11 TEST&quot;);</p>

<p >OLEDDisplay_display(oled);</p>

<p >// vTaskDelay(500 / portTICK_PERIOD_MS);</p>

<p >&nbsp;</p>

<p >OLEDDisplay_setFont(oled,ArialMT_Plain_10);</p>

<p >OLEDDisplay_drawString(oled,16, 25, &quot;Temp:&quot;);</p>

<p >OLEDDisplay_display(oled);</p>

<p >// vTaskDelay(500 / portTICK_PERIOD_MS);</p>

<p >&nbsp;</p>

<p >OLEDDisplay_setFont(oled,ArialMT_Plain_10);</p>

<p >OLEDDisplay_drawString(oled,16,36, &quot;Humi:&quot;);</p>

<p >OLEDDisplay_display(oled);</p>

<p >&nbsp;</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 >&nbsp;</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 >&nbsp;</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;vSemaphoreDelete(print_mux);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;vTaskDelete(NULL);</p>

<p >}</p>

<p >&nbsp;</p>

<p >void app_main(void)</p>

<p >{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;print_mux = xSemaphoreCreateMutex();</p>

<p >ESP_LOGI(TAG,&quot;Running&quot;);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;xTaskCreate(i2c_test_task, &quot;i2c_test_task_0&quot;, 1024 * 2, (void *)0, 10, NULL);</p>

<p >}</p>

<p >&nbsp;</p>

<p >具体代码路径如图所示。</p>

<p > &nbsp;</p>

<ol start="2">
        <li >修改工程配置</li>
</ol>

<p >修改component目录下的CMakeLists.txt文件,增加DHT11.c的编译项,如图所示。</p>

<p > &nbsp;</p>

<ol start="3">
        <li >编译下载</li>
</ol>

<p >编译下载就可以了,不会编译的看上一篇或者上上篇啊。</p>

<p > &nbsp;</p>

<ol start="4">
        <li >演示</li>
</ol>

<p >开始想只刷新数据变更位置,其实这样最好。目前是全屏清除,重新显示,对OLED的刷新原理也不太深入,是一直保存好,还是定时刷界面好,有兴趣的可以尝试只刷新数据变化的位置。</p>

<p >8845635c482e1aa280bbae9c63a53e9e<br />
&nbsp;</p>

wangerxian 发表于 2022-8-24 14:53

<p>感觉这移植的还是挺方便的!</p>
页: [1]
查看完整版本: 【Beetle ESP32-C3测评】第三篇篇:vscode+idf+oled+ssd1306+dht11