We are familiar with multiple features of the ESP32 module. Like Wi-Fi capabilities, classic Bluetooth, Bluetooth low energy (BLE), inbuilt sensors etc.
Hello readers, I hope you all are doing great. We have already mentioned in our previous tutorials that, ESP32 is also featured with a Dual-Core Processor. Which provides better performance and efficiency.
In this tutorial, we will learn how to use ESP32’s dual cores. ESP32 has two (32-bit each) Tensilica Xtensa LX6 microprocessors namely, core0 and core1 which makes it a powerful dual-core microcontroller and hence stands apart from its predecessors.
When we compile and upload a code using Arduino IDE, we do not have to worry about which core executes the code. It just runs.
Fig. 1 ESP32 dual-core processor
Where To Buy? | ||||
---|---|---|---|---|
No. | Components | Distributor | Link To Buy | |
1 | ESP32 | Amazon | Buy Now |
A FreeRTOS (real-time operating system) firmware is already available in the ESP32 module. FreeRTOS is helpful in improving the system performance and managing the resources of the module. FreeRTOS allows users to handle several tasks like measuring sensor readings, making a network request, controlling motor speed etc. all of them run simultaneously and independently.
FreeRTOS offers multiple APIs for different applications. Those APIs can be used to create tasks and make them run on different cores. You need to create tasks to assign a particular part of code to a specific core. You can also prioritize that on which core the code will run. Priority value starts with level_0.
Whenever we run a code on Arduino IDE, it runs on core_1 by default.
There is a function you can use to check on which core the code is running on.
xPortGetCoreID()
Run the following code in Arduino IDE:
void setup(){
Serial.begin(115200);
Serial.print( " setup() is running on: Core_" );
Serial.println( xPortGetCoreID() );
delay(1000);
}
void loop()
{
Serial.print( " loop() is running on: Core_" );
Serial.println( xPortGetCoreID() );
delay(1000);
}
Fig. 2 Serial Monitor
From the results on the serial monitor, you can see that both setup() function and loop() function are running on core_1.
Fig. 3
This function takes seven arguments:
Fig. 4
For example, we have created a function named task_code(). Inside the task_code() function a for(;;) loop is used which will create an infinite loop. All the instructions to be given for a particular core to perform a particular task like led blinking, sensor readings etc. will be written inside this for(;;) loop.
Fig. 5
You can use the function vTaskDelete() during the code execution to delete a task. This function takes the task handle (task) as an argument.
In this code we will use two LEDs to be processed by different core.
TaskHandle_t task1;
TaskHandle_t task2;
// Assign GPIOs pins to LEDs
const int led1 = LED_BUILTIN;
const int led2 = 25;
void setup() {
Serial.begin(115200 );
pinMode( led1, OUTPUT );
pinMode( led2, OUTPUT );
//create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
xTaskCreatePinnedToCore(task_1code, // Task function.
"Task1", // name of task.
10000, // Stack size of task
NULL, // parameter of the task
1, // priority of the task
&task1, // Task handle to keep track of created task
1); // pin task to core 1
delay(1000);
//create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1
xTaskCreatePinnedToCore(task_2code, //Task function.
"task2", //name of task.
10000, //Stack size of task
NULL, //parameter of the task
1, //priority of the task
&task2, //Task handle to keep track of created task
0); //pin task to core 0
delay(1000);
}
//task_1code: blinks an LED every 1000 ms
void task_1code( void * pvParameters ){
Serial.print( "task1 running on: core " );
Serial.println( xPortGetCoreID() );
for(;;)
{
digitalWrite( led1, HIGH);
delay(1000);
digitalWrite(led1, LOW);
delay(1000);
}
}
//task_2code: blinks an LED every 500 ms
void task_2code( void * pvParameters )
{
Serial.print( "task2 running on: core " );
Serial.println(xPortGetCoreID() );
for(;;){
digitalWrite(led2, HIGH );
delay(500);
digitalWrite(led2, LOW );
delay(500);
}
}
void loop(){
Serial.print( " loop() is running on: Core " );
Serial.println( xPortGetCoreID() );
delay(1000);
}
Fig. 6
Fig. 7
Fig. 8 setup() function
Fig. 9
Fig. 10
Fig. 11
Fig. 12
Fig. 13 loop function
Components required:
Fig. 14 connecting LED with ESP32
Fig. 15 Results on the serial monitor
This concludes the tutorial. We hope you found this helpful and also hope to see you soon with a new tutorial on ESP32.