如何使用Arduino IDE进行ESP32双核编程

本文将展示如何使用 ESP32的两个内核同时执行两个操作。

ESP 模块因其 Wi-Fi 功能而广受欢迎,例如ESP8266、ESP-12E等。这些都是具有 Wi-Fi 功能的强大微控制器模块。还有一个 ESP 模块,它比以前的 ESP 模块更强大、更通用——它的名字是ESP32。它具有蓝牙和 Wi-Fi 连接,我们已经解释了 ESP32 的 BLE 功能,并在许多物联网项目中使用了 ESP32 。但很少有人知道ESP32 是双核微控制器

ESP32具有两个 32 位 Tensilica Xtensa LX6 微处理器,这使其成为功能强大的双核(core0 和 core1)微控制器。它有单核和双核两种变体。但双核版本更受欢迎,因为没有明显的价格差异。


如何使用Arduino IDE进行ESP32双核编程

ESP32 可以使用 Arduino IDE、Espressif IDF、Lua RTOS 等进行编程。使用 Arduino IDE 进行编程时,代码只能在 Core1 上运行,因为 Core0 已经针对射频通信进行了编程。但这是本教程,我们将展示如何使用 ESP32的两个内核同时执行两个操作。这里的第一个任务是闪烁板载 LED,第二个任务是从 DHT11 传感器获取温度数据。

让我们首先看看多核处理器相对于单核的优势。

多核处理器的优势

当有两个以上的进程同时工作时,多核处理器很有用。

由于工作分布在不同的内核之间,它的速度会提高,并且可以同时完成多个进程。

可以降低功耗,因为当任何内核处于空闲模式时,它都可以用来关闭当时未使用的外围设备。

双核处理器必须比单核处理器更少地在不同线程之间切换,因为它们可以一次处理两个而不是一次处理一个。

ESP32 和 FreeRTOS

ESP32 板上已经安装了 FreeRTOS 固件。FreeRTOS 是一个开源实时操作系统,在多任务处理中非常有用。RTOS 有助于管理资源和最大化系统性能。FreeRTOS 有许多用于不同目的的 API 函数,使用这些 API,我们可以创建任务并使它们在不同的内核上运行。

可以在此处找到 FreeRTOS API 的完整文档。我们将尝试在代码中使用一些 API 来构建将在两个内核上运行的多任务应用程序。

查找 ESP32 内核 ID

在这里,我们将使用Arduino IDE 将代码上传到 ESP32中。要知道运行代码的Core ID,有一个API函数

xPortGetCoreID()

可以从void setup()和void loop()函数调用此函数,以了解运行这些函数的核心 ID。

您可以通过上传以下草图来测试此 API:

setup() { 
  Serial.begin(115200);
  Serial.print("setup() 函数在核心上运行:"); 
  Serial.println(xPortGetCoreID()); 
} 
void loop() { 
  Serial.print("loop() 函数在核心上运行:"); 
  Serial.println(xPortGetCoreID()); 
}

上传上面的草图后,打开串口监视器,你会发现这两个功能都在 core1 上运行,如下图所示。

如何使用Arduino IDE进行ESP32双核编程

从以上观察可以得出结论,默认的 Arduino 草图始终在 core1 上运行。

ESP32 双核编程

Arduino IDE 支持 ESP32 的 FreeRTOS,FreeRTOS API 允许我们创建可以在两个内核上独立运行的任务。任务是在板上执行一些操作的代码,例如闪烁的 LED、发送温度等。

以下函数用于创建可以在两个内核上运行的任务。在这个函数中,我们必须给出一些参数,比如优先级、核心 ID 等。

现在,按照以下步骤创建任务和任务功能。

1.首先在void setup函数中创建任务。在这里,我们将创建两个任务,一个用于每 0.5 秒后闪烁 LED,另一个任务是每 2 秒后获取温度读数。

xTaskCreatePinnedToCore() 函数有 7 个参数:

实现任务的函数名(task1)

任务的任何名称(“task1”等)

以字为单位分配给任务的堆栈大小(1 个字=2 字节)

任务输入参数(可以为NULL)

任务的优先级(0为最低优先级)

任务句柄(可以为 NULL)

任务将运行的核心 ID(0 或 1)

现在,通过在 xTaskCreatePinnedToCore() 函数中提供所有参数来创建用于闪烁 LED 的 Task1 。

xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 0);

同样,为 Task2创建 Task2并在第 7个参数中设置 core id 1。

xTaskCreatePinnedToCore(Task2code, "Task2", 10000, NULL, 1, NULL, 1);

您可以根据任务的复杂性更改优先级和堆栈大小。

2. 现在,我们将实现Task1code和Task2code函数。这些函数包含所需任务的代码。在我们的例子中,第一个任务将闪烁 LED,另一个任务将获取温度。因此,在 void setup 函数之外为每个任务创建两个单独的函数。

Task1code功能实现了 0.5 秒后闪烁板载 LED,如下所示。

void Task1code(void * parameter) { 
  Serial.print("Task1 在核心上运行"); 
  Serial.println(xPortGetCoreID()); 
  for(;;) {//无限循环
    digitalWrite(led, HIGH); 
    delay500);
    digitalWrite(led, LOW);
    delay(500); 
  } 
}
同样,实现获取温度的Task2code函数。
rs ){ 
  Serial.print("Task2 在核心上运行"); 
  Serial.println(xPortGetCoreID()); 
  for(;;){
    float t = dht.readTemperature(); 
     Serial.print("温度:"); 
     Serial.print(t); 
     delay(2000);
  } 
}void Task2code( void * pvParamete

3. 这里的void 循环函数将保持为空。我们已经知道循环和设置函数在 core1 上运行,因此您也可以在void 循环函数中实现 core1 任务。

现在编码部分已经结束,所以只需在工具菜单中选择 ESP32 板,使用 Arduino IDE 上传代码。确保您已将 DHT11 传感器连接到 ESP32 的引脚 D13。

如何使用Arduino IDE进行ESP32双核编程

现在可以在 Serial Monitor 或 Arduino IDE 上监控结果,如下所示:

如何使用Arduino IDE进行ESP32双核编程

通过使用 ESP32 的双核同时运行多个任务,可以构建像实时系统这样的复杂应用。


#include "DHT.h"

#define DHTPIN 13
#define DHTTYPE DHT11

const int led = 2;
DHT dht(DHTPIN, DHTTYPE);

setup() {
  Serial.begin(115200);
  pinMode(led,OUTPUT);
  dht.begin();
  xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 1);
  delay(500);
  xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 0);
  delay(500);
}

void Task1code(void * pvParameters ){
  Serial.print("Task1 在核心上运行");
  Serial.println(xPortGetCoreID());
  for(;;){
    digitalWrite(led, HIGH);
    delay(300);
    digitalWrite(led,LOW);
    delay(300);
  }
}

void Task2code(void * pvParameters ){
  Serial.print("Task2 在核心上运行");
  Serial.println(xPortGetCoreID());
  for(;;){
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    float f = dht.readTemperature(true);
    Serial.print("温度:");
    Serial.print(t);
    Serial.print(" *C \n ");
    if (isNan(h) || isNan(t) || isNan(f)) {
      Serial.println("读取 DHT 传感器失败!");
      return;
    }
    delay(2000);
  }
}

loop() {
}
- 本文内容来自网络,如有侵权,请联系本站处理。

2023-08   阅读(1233)   评论(0)
 标签: maker ESP32 Arduino

涨知识
结构化编程

结构化程序设计是采用顺序结构、选择结构(IF语句)、循环结构(FOR,WHILE语句)、子程序等来进行程序设计的一种编程典范。

评论:
相关文章
小鹏物联网 MicroPython 智能浇花方案

相信很多人都有把绿植给养死的经历,可能是浇水过多、忘记浇水、较长时间不在家不能浇水等,本文介绍一种可以灵活定制的智能浇花方案。


MicroPython 开发ESP32应用之线程介绍及实例分析

MicroPython 在 ESP32 上支持线程(Thread)功能,通过_thread模块实现。线程允许程序并发执行多个任务,适合处理需要同时运行的场景,例如传感器数据采集和网络通信。


盛思发布掌控板3.0

掌控板3.0升级了主控,还主打AI。带有双麦克风阵列,增加了音频解码芯片,板载了一个1W喇叭,还把之前的单色屏幕换成了1.47寸的彩色屏幕,有更多的可玩性。


ESP32 MicroPython采集模拟传感器数值

使用了 MicroPython 库,通过 定时器(Timer) 和 ADC(模数转换器) 功能来实时读取传感器数据。使用定时器可以实现高精度、非阻塞、低资源消耗的周期性任务,保证实时性和可靠性,特别适用于嵌入式系统中的多任务处理和低功耗场景。



ESP32 使用DAC模拟输出完成两路呼吸灯

ESP32的DAC函数可以实现真正的模拟输出。


在 ESP32 上使用 LEDC (PWM)

ESP32 没有Arduino输出 PWM 的 analogWrite(pin, value) 方法,取而代之的 ESP32 有一个 LEDC 来实现PWM功能。


《米思齐实战手册:Arduino图形化编程指南》

本书由少年创学院联合创始人兼院长、知名创客程晨撰写,以Arduino作为硬件平台,介绍了使用米思齐(Mixly)软件进行程序开发的方法。


Micropython基于ESP32的多线程开发

本文学习如何使用ESP32开发板来进行多线程的开发。


ESP8266 Arduino WIFI

ESP8266有三种工作模式,分别为:AP,STA,AP混合STA

搜索
小鹏STEM教研服务

专属教研服务系统,助您构建STEM课程体系,打造一站式教学环境。