因为lvgl本身的定时任务就是个死循环,读取dh11又是个很慢的过程,为了不让gui卡主。就得使用多任务来。esp32的arduino 本身就是运行在free rtos里的 。可以直接新建任务
这里使用的库是 DHT sensor library for ESPx 这个库只能用于esp
直接运行它的例子当然可以。这里改造下程序适配gui显示。为了尽量不让main。c显得混乱。这里把例程当做库使用。在lib文件夹下新建文件夹DHT,里边新建一个cpp文件
把例子中的除了setup跟loop的都靠过来,并添加lvlg跟main.c里声明的变量的引用
这里是DHT。cpp的全文
#include "DHTesp.h" // Click here to get the library: http://librarymanager/All#DHTesp
#include <Ticker.h> //引入定时中断库
#ifndef ESP32
#pragma message(THIS EXAMPLE IS FOR ESP32 ONLY !)
#error Select ESP32 board.
#endif
/**************************************************************/
/* Example how to read DHT sensors from an ESP32 using multi- */
/* tasking. */
/* This example depends on the Ticker library to wake up */
/* the task every 20 seconds */
/**************************************************************/
/************************************************* *************/
/* 示例如何使用 从 ESP32 读取 DHT 传感器 */
/* 多任务。 */
/* 这个例子依赖于 Ticker 库来唤醒 */
/* 每 20 秒执行一次任务 */
/************************************************* *************/
#include "gui_guider.h" //需要引用lv_ui的定义文件 ,在这个文件里不认识lv-ui结构体
extern lv_ui guider_ui; // ectern表示从外部的定义引用,这里是引用main文件里的定义,
DHTesp dht;
void tempTask(void *pvParameters);
bool getTemperature();
void triggerGetTemp();
/** Task handle for the light value read task */
/** 值读取任务的任务句柄 */
TaskHandle_t tempTaskHandle = NULL;
/** Ticker for temperature reading */
/** 温度读数的代码 */
Ticker tempTicker;
/** Comfort profile */
/** 舒适度配置文件 */
ComfortState cf;
/** Flag if task should run */
/** 标记任务是否应该运行 */
bool tasksEnabled = false;
/** Pin number for DHT11 data pin */
/** DHT11 数据引脚的引脚号 */
int dhtPin = 25;
/**
* initTemp
* Setup DHT library
* Setup task and timer for repeated measurement
* * 初始化温度
* 设置 DHT 库
* 为重复测量设置任务和计时器
* @return bool
* true if task and timer are started
* false if task or timer couldn't be started
* * 如果任务和计时器启动则为真
* false 如果任务或计时器无法启动
*/
bool initTemp()
{
byte resultValue = 0;
// Initialize temperature sensor 初始化温度传感器
dht.setup(dhtPin, DHTesp::DHT11);
Serial.println("DHT initiated");
// Start task to get temperature 开始任务
xTaskCreatePinnedToCore(
tempTask, /* Function to implement the task任务要运行的函数*/
"tempTask ", /* Name of the task 任务的名字*/
4000, /* Stack size in words 分配的堆栈大小*/
NULL, /* Task input parameter 给任务传递的参数*/
5, /* Priority of the task 优先级*/
&tempTaskHandle, /* Task handle.任务勾柄 */
1); /* Core where the task should run 运行在那个核心*/
if (tempTaskHandle == NULL)
{
Serial.println("Failed to start task for temperature update");
return false;
}
else
{
// Start update of environment data every 20 seconds每20秒运行一次测量温度
tempTicker.attach(20, triggerGetTemp);
}
return true;
}
/**
* triggerGetTemp
* Sets flag dhtUpdated to true for handling in loop()
* called by Ticker getTempTimer
* * 触发GetTemp
* 将标志 dhtUpdated 设置为 true 以便在 loop() 中处理
* 由 Ticker getTempTimer 调用
*/
void triggerGetTemp()
{
if (tempTaskHandle != NULL)
{
xTaskResumeFromISR(tempTaskHandle);
}
}
/**
* Task to reads temperature from DHT11 sensor 读传感器的任务
* @param pvParameters
* pointer to task parameters 任务指针
*/
void tempTask(void *pvParameters)
{
Serial.println("tempTask loop started");
while (1) // tempTask loop 任务无限循环
{
if (tasksEnabled)
{
// Get temperature values获得温度
getTemperature();
}
// Got sleep again 睡眠
vTaskSuspend(NULL);
}
}
/**
* getTemperature
* Reads temperature from DHT11 sensor
* * 获取温度
* 从 DHT11 传感器读取温度
* @return bool
* true if temperature could be aquired
* false if aquisition failed
* * 如果可以获取温度,则为 true * 如果获取失败,则为 false
*/
bool getTemperature()
{
// Reading temperature for humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
// 读取湿度的温度大约需要 250 毫秒!
// 传感器读数也可能长达 2 秒“旧”(这是一个非常慢的传感器)
TempAndHumidity newValues = dht.getTempAndHumidity();
// Check if any reads failed and exit early (to try again).
// 检查是否有任何读取失败并提前退出(重试)。
if (dht.getStatus() != 0)
{
Serial.println("DHT11 error status: " + String(dht.getStatusString()));
return false;
}
//计算体感温度,凝露点,舒适度
float heatIndex = dht.computeHeatIndex(newValues.temperature, newValues.humidity);
float dewPoint = dht.computeDewPoint(newValues.temperature, newValues.humidity);
float cr = dht.getComfortRatio(cf, newValues.temperature, newValues.humidity);
String comfortStatus;
switch (cf)
{
case Comfort_OK:
comfortStatus = "Comfort_OK";
break;
case Comfort_TooHot:
comfortStatus = "Comfort_TooHot";
break;
case Comfort_TooCold:
comfortStatus = "Comfort_TooCold";
break;
case Comfort_TooDry:
comfortStatus = "Comfort_TooDry";
break;
case Comfort_TooHumid:
comfortStatus = "Comfort_TooHumid";
break;
case Comfort_HotAndHumid:
comfortStatus = "Comfort_HotAndHumid";
break;
case Comfort_HotAndDry:
comfortStatus = "Comfort_HotAndDry";
break;
case Comfort_ColdAndHumid:
comfortStatus = "Comfort_ColdAndHumid";
break;
case Comfort_ColdAndDry:
comfortStatus = "Comfort_ColdAndDry";
break;
default:
comfortStatus = "Unknown:";
break;
};
String TempHumTodisplay = " 温度:" + String(newValues.temperature) + " 湿度:" + String(newValues.humidity) + " 体感温度:" + String(heatIndex) + " 凝露点:" + String(dewPoint) + " " + comfortStatus;
Serial.println(TempHumTodisplay);
/*把测量结果显示到屏幕ta对象上*/
lv_textarea_set_text((&guider_ui)->screen_ta_1, TempHumTodisplay.c_str()); // guider_ui是结构体的名字不能直接当指针用,当然用.也是可以的
return true;
}
main.cpp里加入对dht。cpp的引用,并把setup跟loop里的代码复制过来。(如果是典型的arduino文件夹,会是一个跟文件夹同名的ino文件,arduo是会把这个文件内所用。ino的文件都合并成一个文件的)
#include "DHTesp.h" // Click here to get the library: http://librarymanager/All#DHTesp
#include <Ticker.h> //引入定时中断库
#ifndef ESP32
#pragma message(THIS EXAMPLE IS FOR ESP32 ONLY !)
#error Select ESP32 board.
#endif
/**************************************************************/
/* Example how to read DHT sensors from an ESP32 using multi- */
/* tasking. */
/* This example depends on the Ticker library to wake up */
/* the task every 20 seconds */
/**************************************************************/
/************************************************* *************/
/* 示例如何使用 从 ESP32 读取 DHT 传感器 */
/* 多任务。 */
/* 这个例子依赖于 Ticker 库来唤醒 */
/* 每 20 秒执行一次任务 */
/************************************************* *************/
#include "gui_guider.h" //需要引用lv_ui的定义文件 ,在这个文件里不认识lv-ui结构体
extern lv_ui guider_ui; // ectern表示从外部的定义引用,这里是引用main文件里的定义,
DHTesp dht;
void tempTask(void *pvParameters);
bool getTemperature();
void triggerGetTemp();
/** Task handle for the light value read task */
/** 值读取任务的任务句柄 */
TaskHandle_t tempTaskHandle = NULL;
/** Ticker for temperature reading */
/** 温度读数的代码 */
Ticker tempTicker;
/** Comfort profile */
/** 舒适度配置文件 */
ComfortState cf;
/** Flag if task should run */
/** 标记任务是否应该运行 */
bool tasksEnabled = false;
/** Pin number for DHT11 data pin */
/** DHT11 数据引脚的引脚号 */
int dhtPin = 25;
/**
* initTemp
* Setup DHT library
* Setup task and timer for repeated measurement
* * 初始化温度
* 设置 DHT 库
* 为重复测量设置任务和计时器
* @return bool
* true if task and timer are started
* false if task or timer couldn't be started
* * 如果任务和计时器启动则为真
* false 如果任务或计时器无法启动
*/
bool initTemp()
{
byte resultValue = 0;
// Initialize temperature sensor 初始化温度传感器
dht.setup(dhtPin, DHTesp::DHT11);
Serial.println("DHT initiated");
// Start task to get temperature 开始任务
xTaskCreatePinnedToCore(
tempTask, /* Function to implement the task任务要运行的函数*/
"tempTask ", /* Name of the task 任务的名字*/
4000, /* Stack size in words 分配的堆栈大小*/
NULL, /* Task input parameter 给任务传递的参数*/
5, /* Priority of the task 优先级*/
&tempTaskHandle, /* Task handle.任务勾柄 */
1); /* Core where the task should run 运行在那个核心*/
if (tempTaskHandle == NULL)
{
Serial.println("Failed to start task for temperature update");
return false;
}
else
{
// Start update of environment data every 20 seconds每20秒运行一次测量温度
tempTicker.attach(20, triggerGetTemp);
}
return true;
}
/**
* triggerGetTemp
* Sets flag dhtUpdated to true for handling in loop()
* called by Ticker getTempTimer
* * 触发GetTemp
* 将标志 dhtUpdated 设置为 true 以便在 loop() 中处理
* 由 Ticker getTempTimer 调用
*/
void triggerGetTemp()
{
if (tempTaskHandle != NULL)
{
xTaskResumeFromISR(tempTaskHandle);
}
}
/**
* Task to reads temperature from DHT11 sensor 读传感器的任务
* @param pvParameters
* pointer to task parameters 任务指针
*/
void tempTask(void *pvParameters)
{
Serial.println("tempTask loop started");
while (1) // tempTask loop 任务无限循环
{
if (tasksEnabled)
{
// Get temperature values获得温度
getTemperature();
}
// Got sleep again 睡眠
vTaskSuspend(NULL);
}
}
/**
* getTemperature
* Reads temperature from DHT11 sensor
* * 获取温度
* 从 DHT11 传感器读取温度
* @return bool
* true if temperature could be aquired
* false if aquisition failed
* * 如果可以获取温度,则为 true * 如果获取失败,则为 false
*/
bool getTemperature()
{
// Reading temperature for humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
// 读取湿度的温度大约需要 250 毫秒!
// 传感器读数也可能长达 2 秒“旧”(这是一个非常慢的传感器)
TempAndHumidity newValues = dht.getTempAndHumidity();
// Check if any reads failed and exit early (to try again).
// 检查是否有任何读取失败并提前退出(重试)。
if (dht.getStatus() != 0)
{
Serial.println("DHT11 error status: " + String(dht.getStatusString()));
return false;
}
//计算体感温度,凝露点,舒适度
float heatIndex = dht.computeHeatIndex(newValues.temperature, newValues.humidity);
float dewPoint = dht.computeDewPoint(newValues.temperature, newValues.humidity);
float cr = dht.getComfortRatio(cf, newValues.temperature, newValues.humidity);
String comfortStatus;
switch (cf)
{
case Comfort_OK:
comfortStatus = "Comfort_OK";
break;
case Comfort_TooHot:
comfortStatus = "Comfort_TooHot";
break;
case Comfort_TooCold:
comfortStatus = "Comfort_TooCold";
break;
case Comfort_TooDry:
comfortStatus = "Comfort_TooDry";
break;
case Comfort_TooHumid:
comfortStatus = "Comfort_TooHumid";
break;
case Comfort_HotAndHumid:
comfortStatus = "Comfort_HotAndHumid";
break;
case Comfort_HotAndDry:
comfortStatus = "Comfort_HotAndDry";
break;
case Comfort_ColdAndHumid:
comfortStatus = "Comfort_ColdAndHumid";
break;
case Comfort_ColdAndDry:
comfortStatus = "Comfort_ColdAndDry";
break;
default:
comfortStatus = "Unknown:";
break;
};
String TempHumTodisplay = " 温度:" + String(newValues.temperature) + " 湿度:" + String(newValues.humidity) + " 体感温度:" + String(heatIndex) + " 凝露点:" + String(dewPoint) + " " + comfortStatus;
Serial.println(TempHumTodisplay);
/*把测量结果显示到屏幕ta对象上*/
lv_textarea_set_text((&guider_ui)->screen_ta_1, TempHumTodisplay.c_str()); // guider_ui是结构体的名字不能直接当指针用,当然用.也是可以的
return true;
}
图形界面就是用gui guider 简单添加一个textarea就行
实际运行效果
9.79 OxS:/ c语言坑各踩一遍,给找不变量定义的程序加引用 显示中文 https://v.douyin.com/jqFYFMy/ 复制此链接,打开Dou音搜索,直接观看视频!