在我们上一期代码中,我们利用HTTP将我们的数据上传到局域网,但是由于我们的程序是串行程序,即ADC采集完需要等待数据上传成功才能继续运行我们的代码,因此我们的数据就会出现很严重的数据丢失。
而我们在之前学习过STM32中的FreeRTOS即实时操作系统,将不同的任务按照不同的优先级分别运行。因此我们尝试使用FreeRTOS将ADC采集和数据上传的任务按照不同级别的优先级进行划分。
关于FreeRTOS的介绍可以查看前几期的内容 基于STM32F407的FreeRTOS学习笔记(13)—— 阶段性的总结与后续
FreeRTOS库准备
FreeRTOS在ESP32中的环境配置比在STM32中简单许多,我们只需要在库管理中搜索FreeRTOS即可安装我们的FreeRTOS
我们直接安装最新版本的FreeRTOS
#include <Arduino.h>#include <WiFi.h>#include <HTTPClient.h>#include <freertos/FreeRTOS.h>//FreeRTOS头文件#include <freertos/task.h>//任务头文件#include <freertos/semphr.h>//信号量头文件
之后我们放入相关头文件包含信号量和任务头文件还有FreeRTOS的基本头文件。
** 任务创建 **
任务创建可以参考我们的公众号 文章 基于STM32F407的FreeRTOS学习笔记(2)——任务的创建与删除
TaskHandle_t Task1, Task2; xTaskCreatePinnedToCore( Task1Code, // 任务函数 "Task1", // 任务名称 10000, // 任务堆栈大小 NULL, // 任务参数 1, // 任务优先级 &Task1, // 任务句柄 0); // 核心编号
// 创建任务2,绑定到核心1 xTaskCreatePinnedToCore( Task2Code, // 任务函数 "Task2", // 任务名称 10000, // 任务堆栈大小 NULL, // 任务参数 2, // 任务优先级 &Task2, // 任务句柄 1); // 核心编号
我们创建任务1和任务2
的句柄,并且由于ESP32是双核的MPU,比起STM32我们可以将不同的任务绑定到不同的核心进行使用,我们设置两个任务,并且任务1的优先级大于任务2的优先级。
我们将任务1用于ADC采集,任务2用于数据上传。
String postData = "";String Data;int dataArray[1000];// 任务1的函void Task1Code(void *parameter) { for (;;) { for (int i = 0; i < 1000; i++) { dataArray[i] = analogRead(34); postData += String(dataArray[i]); if (i < 1000-1) { postData += ","; } delay(5); } //采集完成发送信号量 xSemaphoreGive(dataSemaphore); Data = PostData; PostData = ""; }}
// 任务2的函数void Task2Code(void *parameter) { for (;;) { // 等待信号,表示可以使用postData if (xSemaphoreTake(dataSemaphore, portMAX_DELAY)) { HTTPClient http; http.begin(serverUrl); http.addHeader("Content-Type", "text/plain"); int httpResponseCode = http.POST(Data); // 处理响应 if (httpResponseCode > 0) { Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); String response = http.getString(); Serial.println(response); } else { Serial.print("HTTP Request failed. Error code: "); Serial.println(httpResponseCode); } }
delay(1000); }}
接着我们定义我们的任务函数,关于HTTP的部分参考上一期公众号内容。
我们每次采集好数据之后释放信号量,任务2等待信号量的释放,当任务1释放信号量之后我们上传我们的数据,需要注意的是,此时任务2上传数据时
postData依旧在进行改变,所以我们需要用一个新的变量来接受PostData。
效果展示
我们来看看我们的运行效果
可以看到虽然数据丢失的情况依旧存在,但是相比于前面的几乎丢失一般的情况得到了很大的改善。