Skip to content

ESP32 Dual-Core Usage

In the world of microcontrollers, the ESP32 has gained substantial popularity for its advanced features and capabilities. One distinctive aspect that sets the ESP32 apart from other single-board microcontrollers is its support for dual-core processing. In this blog post, we will delve into the realm of ESP32's dual-core architecture, exploring how to harness its power through Arduino and optimizing code design for multi-core execution.

1. Introduction

The ESP32, an upgraded and enhanced version of the ESP8266, has made its mark as a faster and more feature-rich alternative. One of its standout features that sets it apart is its support for dual-core processing. Unlike its predecessor, the ESP32 allows developers to leverage the power of two processing cores for enhanced performance and multitasking capabilities. In this blog post, we will explore how to configure the ESP32's dual-core setup using the Arduino platform.

2. Hardware

Before we dive into the intricacies of code design, let's take a moment to discuss the hardware that makes this exploration possible. All you need is an ESP32 development board, readily available and equipped to handle the challenges of multi-core programming.

3. Code Design

Now, let's delve into the heart of the matter - designing code that takes full advantage of the ESP32's dual-core capabilities. For this demonstration, we will build upon the concepts introduced in the Queue tutorial to create a practical example. In this scenario, we will create two tasks: "sendTask" and "receiveTask." The "sendTask" will be pinned to Core 0, while "receiveTask" will reside on Core 1. The objective is to send data between these tasks using a Queue.

The key to achieving this lies in the xTaskCreatePinnedToCore API function. By utilizing this function, we can specify which core a particular task should run on. Additionally, the xTaskGetAffinity API function allows us to determine the core affinity of a task, providing insights into task distribution across the dual-core setup.

Here is a snippet of the code demonstrating the task creation and data exchange process:

typedef struct {
    int sender;
    char *msg;
} Data;

xQueueHandle xQueue;
TaskHandle_t xTask1;
TaskHandle_t xTask2;

void setup() {
    xQueue = xQueueCreate(5, sizeof(Data));

    xTaskCreatePinnedToCore(sendTask, "sendTask", 10000, NULL, 1, &xTask1, 0);
    xTaskCreatePinnedToCore(receiveTask, "receiveTask", 10000, NULL, 1, &xTask2, 1);

void loop() {
    // Placeholder, as loop execution is not utilized in this example

void sendTask(void *parameter) {
    // Task logic for sending data

void receiveTask(void *parameter) {
    // Task logic for receiving and processing data

4. Results

The efforts put into configuring and optimizing the ESP32's dual-core usage culminate in tangible results. By effectively distributing tasks across the two cores and utilizing communication mechanisms like Queues, you can achieve efficient multitasking and enhanced performance in your projects.

ESP32 Dual-Core

In this illustration, we see the interplay between the dual-core setup and the tasks assigned to each core. This arrangement allows for seamless data exchange and parallel processing, unlocking the full potential of the ESP32's dual-core architecture.

In conclusion, the ESP32's support for dual-core processing offers an exciting avenue for optimizing performance and multitasking in your projects. By understanding the principles behind task distribution, affinity, and efficient communication, you can harness the power of the ESP32's dual-core capabilities to create more sophisticated and responsive applications.