ESP 模塊因其 Wi-Fi 功能而廣受歡迎,例如ESP8266、ESP-12E等。這些都是具有 Wi-Fi 功能的強大微控制器模塊。還有一個 ESP 模塊,它比以前的 ESP 模塊更強大、更通用——它的名字是ESP32。它具有藍牙和 Wi-Fi 連接,我們已經(jīng)解釋了 ESP32 的 BLE 功能,并在許多物聯(lián)網(wǎng)項目中使用了 ESP32 。但很少有人知道ESP32 是雙核微控制器。
ESP32具有兩個 32 位 Tensilica Xtensa LX6 微處理器,這使其成為功能強大的雙核(core0 和 core1)微控制器。它有單核和雙核兩種變體。但雙核版本更受歡迎,因為沒有明顯的價格差異。
ESP32 可以使用 Arduino IDE、Espressif IDF、Lua RTOS 等進行編程。使用 Arduino IDE 進行編程時,代碼只能在 Core1 上運行,因為 Core0 已經(jīng)針對射頻通信進行了編程。但這是本教程,我們將展示如何使用 ESP32的兩個內(nèi)核同時執(zhí)行兩個操作。這里的第一個任務(wù)是閃爍板載 LED,第二個任務(wù)是從 DHT11 傳感器獲取溫度數(shù)據(jù)。
讓我們首先看看多核處理器相對于單核的優(yōu)勢。
多核處理器的優(yōu)勢
當(dāng)有兩個以上的進程同時工作時,多核處理器很有用。
由于工作分布在不同的內(nèi)核之間,它的速度會提高,并且可以同時完成多個進程。
可以降低功耗,因為當(dāng)任何內(nèi)核處于空閑模式時,它都可以用來關(guān)閉當(dāng)時未使用的外圍設(shè)備。
雙核處理器必須比單核處理器更少地在不同線程之間切換,因為它們可以一次處理兩個而不是一次處理一個。
ESP32 和 FreeRTOS
ESP32 板上已經(jīng)安裝了 FreeRTOS 固件。FreeRTOS 是一個開源實時操作系統(tǒng),在多任務(wù)處理中非常有用。RTOS 有助于管理資源和最大化系統(tǒng)性能。FreeRTOS 有許多用于不同目的的 API 函數(shù),使用這些 API,我們可以創(chuàng)建任務(wù)并使它們在不同的內(nèi)核上運行。
可以在此處找到 FreeRTOS API 的完整文檔。我們將嘗試在代碼中使用一些 API 來構(gòu)建將在兩個內(nèi)核上運行的多任務(wù)應(yīng)用程序。
查找 ESP32 內(nèi)核 ID
在這里,我們將使用Arduino IDE 將代碼上傳到 ESP32中。要知道運行代碼的Core ID,有一個API函數(shù)
xPortGetCoreID()
可以從void setup()和void loop()函數(shù)調(diào)用此函數(shù),以了解運行這些函數(shù)的核心 ID。
您可以通過上傳以下草圖來測試此 API:
無效設(shè)置() { Serial.begin(115200); Serial.print("setup() 函數(shù)在核心上運行:"); Serial.println(xPortGetCoreID()); } void loop() { Serial.print("loop() 函數(shù)在核心上運行:"); Serial.println(xPortGetCoreID()); }
上傳上面的草圖后,打開串口監(jiān)視器,你會發(fā)現(xiàn)這兩個功能都在 core1 上運行,如下圖所示。
從以上觀察可以得出結(jié)論,默認(rèn)的 Arduino 草圖始終在 core1 上運行。
ESP32 雙核編程
Arduino IDE 支持 ESP32 的 FreeRTOS,F(xiàn)reeRTOS API 允許我們創(chuàng)建可以在兩個內(nèi)核上獨立運行的任務(wù)。任務(wù)是在板上執(zhí)行一些操作的代碼,例如閃爍的 LED、發(fā)送溫度等。
以下函數(shù)用于創(chuàng)建可以在兩個內(nèi)核上運行的任務(wù)。在這個函數(shù)中,我們必須給出一些參數(shù),比如優(yōu)先級、核心 ID 等。
現(xiàn)在,按照以下步驟創(chuàng)建任務(wù)和任務(wù)功能。
1.首先在void setup函數(shù)中創(chuàng)建任務(wù)。在這里,我們將創(chuàng)建兩個任務(wù),一個用于每 0.5 秒后閃爍 LED,另一個任務(wù)是每 2 秒后獲取溫度讀數(shù)。
xTaskCreatePinnedToCore() 函數(shù)有 7 個參數(shù):
實現(xiàn)任務(wù)的函數(shù)名(task1)
任務(wù)的任何名稱(“task1”等)
以字為單位分配給任務(wù)的堆棧大小(1 個字=2 字節(jié))
任務(wù)輸入?yún)?shù)(可以為NULL)
任務(wù)的優(yōu)先級(0為最低優(yōu)先級)
任務(wù)句柄(可以為 NULL)
任務(wù)將運行的核心 ID(0 或 1)
現(xiàn)在,通過在 xTaskCreatePinnedToCore() 函數(shù)中提供所有參數(shù)來創(chuàng)建用于閃爍 LED 的 Task1 。
xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 0);
同樣,為 Task2創(chuàng)建 Task2并在第 7個參數(shù)中設(shè)置 core id 1。
xTaskCreatePinnedToCore(Task2code, "Task2", 10000, NULL, 1, NULL, 1);
您可以根據(jù)任務(wù)的復(fù)雜性更改優(yōu)先級和堆棧大小。
2. 現(xiàn)在,我們將實現(xiàn)Task1code和Task2code函數(shù)。這些函數(shù)包含所需任務(wù)的代碼。在我們的例子中,第一個任務(wù)將閃爍 LED,另一個任務(wù)將獲取溫度。因此,在 void setup 函數(shù)之外為每個任務(wù)創(chuàng)建兩個單獨的函數(shù)。
Task1code功能實現(xiàn)了 0.5 秒后閃爍板載 LED,如下所示。
void Task1code( void * parameter) { Serial.print("Task1 在核心上運行"); Serial.println(xPortGetCoreID()); for(;;) {//無限循環(huán) digitalWrite(led, HIGH); 延遲(500); digitalWrite(led, LOW); 延遲(500); } }
同樣,實現(xiàn)獲取溫度的Task2code函數(shù)。
void Task2code( void * pvParameters ){ Serial.print("Task2 在核心上運行"); Serial.println(xPortGetCoreID()); for(;;){ 浮動 t = dht.readTemperature(); Serial.print("溫度:"); 序列號.print(t); 延遲(2000); } }
3. 這里的void 循環(huán)函數(shù)將保持為空。我們已經(jīng)知道循環(huán)和設(shè)置函數(shù)在 core1 上運行,因此您也可以在void 循環(huán)函數(shù)中實現(xiàn) core1 任務(wù)。
現(xiàn)在編碼部分已經(jīng)結(jié)束,所以只需在工具菜單中選擇 ESP32 板,使用 Arduino IDE 上傳代碼。確保您已將 DHT11 傳感器連接到 ESP32 的引腳 D13。
現(xiàn)在可以在 Serial Monitor 或 Arduino IDE 上監(jiān)控結(jié)果,如下所示:
通過使用 ESP32 的雙核同時運行多個任務(wù),可以構(gòu)建像實時系統(tǒng)這樣的復(fù)雜應(yīng)用。
#include "DHT.h"
#define DHTPIN 13
#define DHTTYPE DHT11
const int led = 2;
DHT dht(DHTPIN, DHTTYPE);
無效設(shè)置() {
Serial.begin(115200);
pinMode(LED,輸出);
dht.begin();
xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 1);
延遲(500);
xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL, 0);
延遲(500);
}
void Task1code( void * pvParameters ){
Serial.print("Task1 在核心上運行");
Serial.println(xPortGetCoreID());
for(;;){
digitalWrite(led, HIGH);
延遲(300);
數(shù)字寫入(領(lǐng)導(dǎo),低);
延遲(300);
}
}
void Task2code( void * pvParameters ){
Serial.print("Task2 在核心上運行");
Serial.println(xPortGetCoreID());
for(;;){
浮動 h = dht.readHumidity();
浮動 t = dht.readTemperature();
浮動 f = dht.readTemperature(true);
Serial.print("溫度:");
序列號.print(t);
Serial.print(" *C \n ");
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("讀取 DHT 傳感器失敗!");
返回;
}
延遲(2000);
}
}
無效循環(huán)() {
}
-
微控制器
+關(guān)注
關(guān)注
48文章
7903瀏覽量
153683 -
編程
+關(guān)注
關(guān)注
88文章
3679瀏覽量
94862 -
Arduino
+關(guān)注
關(guān)注
188文章
6490瀏覽量
190075 -
ESP32
+關(guān)注
關(guān)注
20文章
1006瀏覽量
18821
發(fā)布評論請先 登錄
ESP8266開發(fā)教程-Arduino IDE安裝、配置與使用以及Arduino編程

基于Arduino IDE進行的ESP32編程方案

【FireBeetle 2 ESP32-S3開發(fā)板測評】Arduino IDE快速開發(fā)體驗

如何使用Arduino IDE對ESP8266進行編程?
在arduino ide中安裝esp32的arduino框架時的問題求解
esp32和arduino的區(qū)別,esp32能否替代arduino
ESP32雙核CPU,利用核0實現(xiàn)藍牙打印機打印,核1完成常規(guī)控制

Arduino-IDE配置ESP32-CAM開發(fā)環(huán)境踩過的那些坑

如何使用Arduino IDE對ESP32進行無線編程

使用Arduino通過USB串行對ESP32S3進行編程和調(diào)試

使用Arduino IDE和Visuino對ESP32 M5Stack StickC進行編程

如何在Arduino IDE中安裝ESP32開發(fā)環(huán)境

評論