在我们上一期代码中,我们利用HTTP将我们的数据上传到局域网,但是由于我们的程序是串行程序,即ADC采集完需要等待数据上传成功才能继续运行我们的代码,因此我们的数据就会出现很严重的数据丢失。

而我们在之前学习过STM32中的FreeRTOS即实时操作系统,将不同的任务按照不同的优先级分别运行。因此我们尝试使用FreeRTOS将ADC采集和数据上传的任务按照不同级别的优先级进行划分。

关于FreeRTOS的介绍可以查看前几期的内容基于STM32F407的FreeRTOS学习笔记(13)—— 阶段性的总结与后续

FreeRTOS库准备

FreeRTOS在ESP32中的环境配置比在STM32中简单许多,我们只需要在库管理中搜索FreeRTOS即可安装我们的FreeRTOS

我们直接安装最新版本的FreeRTOS


#include 
#include 
  
#include 
   
#include 
    //FreeRTOS头文件
#include 
     //任务头文件
#include 
      
       //信号量头文件 
      
     
    
   
  
 

之后我们放入相关头文件包含信号量和任务头文件还有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 (xSemaphoreTak(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。

效果展示

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

#include&lt;Arduino.h&gt;#
#include&lt;HTTPClient.h&gt;#
嘉立创PCB

还没有评论,抢个沙发!