极客秀
搜索

基于C#和ESP32的远程示波器(5)—— 利用FreeRTOS双核运行减少数据丢失

在我们上一期代码中,我们利用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。

效果展示

我们来看看我们的运行效果

可以看到虽然数据丢失的情况依旧存在,但是相比于前面的几乎丢失一般的情况得到了很大的改善。

1.转载请保留原文链接谢谢!
2.本站所有资源文章出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
3.本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户擦亮眼睛自行鉴别,做一个有主见和判断力的用户。
4.本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
5.联系方式(#替换成@):pm#vimge.com

  相关内容