Randomnerdtutorials Com Esp32 Freertos Arduino Tasks
Randomnerdtutorials Com Esp32 Freertos Arduino Tasks
HOME ESP32 ESP8266 ESP32-CAM RASPBERRY PI MICROPYTHON RPi PICO ARDUINO REVIEWS
Learn ESP32
ESP32 with FreeRTOS (Arduino IDE) – Getting Affiliate Disclosure: Random Nerd Tutorials
is a participant in affiliate advertising
ESP32 Introduction
Started: Create Tasks programs designed to provide a means for
ESP32 Arduino IDE us to earn fees by linking to Amazon, eBay,
AliExpress, and other sites. We might be
ESP32 Arduino IDE 2.0 In this tutorial, we’ll introduce the basic concepts of FreeRTOS and show you how to use it with the compensated for referring traffic and
VS Code and PlatformIO ESP32 and the Arduino IDE. You’ll learn how to create single and multiple tasks, suspend and business to these companies.
resume tasks, run code on the ESP32’s two cores, and calculate the appropriate stack size needed
ESP32 Pinout (memory) for each task.
ESP32 Inputs Outputs
FreeRTOS is a real-time operating system that allows the ESP32 to manage and run multiple tasks
ESP32 PWM simultaneously in a smooth and efficient way. It’s built into the ESP32 and fully integrated with both
ESP32 Analog Inputs the Arduino core and the Espressif IoT Development Framework (IDF).
Protocols
ESP32 Bluetooth
ESP32 MQTT
ESP32 ESP-NOW
ESP32 Wi-Fi
ESP32 WebSocket
Momentary Switch Web It also provides tools like queues and semaphores so tasks can seamlessly communicate with
Server each other.
Learn LVGL: Build GUIs for ESP32
Physical Button Web
This makes your code more organized and responsive, especially when your ESP32 is handling Projects» Learn how to build Graphical
Server
several tasks at the same time, like reading sensors, handling HTTP requests, and displaying User Interfaces (GUIs) for ESP32 Projects
Input Fields Web Server information on a screen, while listening to interrupts. using LVGL (Light Versatile Graphics Library)
with the Arduino IDE.
Images Web Server
RGB LED Web Server Why is FreeRTOS useful with the ESP32?
Timer/Pulse Web Server The FreeRTOS real-time operating system is built into the ESP32 and integrated into the Espressif
IDF and the Arduino core. It supports:
HTTP Auth Web Server
MPU-6050 Web Server Task Management: create, suspend, resume, or delete tasks (covered in this tutorial).
Scheduling: allows you to give priority to your tasks, so they run in a specific order (covered
MicroSD Card Web Server
in this tutorial).
Stepper Motor Web Server Inter-Task Communication: using things like queues, semaphores, and mutexes, we can
ensure seamless communication between tasks without crashing the ESP32.
Stepper Motor WebSocket
Dual-Core Support: it allows you to run your tasks on either core 0 or core 1 of the ESP32
Gauges Web Server (also covered in this tutorial, but for a more in-depth guide about using dual-core with the
ESP32, check this guide: How to use ESP32 Dual Core with Arduino IDE).
DIY Cloud
Control GPIOs
FreeRTOS is useful with the ESP32 because it enables multitasking, allowing multiple tasks like
View Sensor Readings sensor reading, Wi-Fi, and display updates to run without blocking each other.
ESP32 MySQL
It also allows you to take advantage of the ESP32 dual-core processor by letting you assign tasks to
ESP32 PHP Email specific cores for better performance.
ESP32 SIM800L
Cloud Node-RED Additionally, with priority-based scheduling, time-critical tasks can run immediately, making it ideal
Dashboard for real-time applications when you need to react quickly to external events detected by the ESP32
GPIOs.
Cloud MQTT Broker
ESP-NOW Two-Way Tasks: tasks are independent functions running concurrently, each with its own stack
(memory usage allocated) and priority. Tasks can be in states like Running, Ready, Blocked,
ESP-NOW One-to-Many or Suspended.
ESP-NOW Many-to-One Scheduler: the scheduler decides which tasks to run based on their priorities. This is a
preemptive scheduler, which means it can interrupt a lower-priority task at any time to run a
ESP-NOW + Wi-Fi Web
higher-priority one, ensuring that critical tasks are executed as soon as they’re ready.
Server
Priorities: higher numbers indicate higher priority (for example: 1 = low, 5 = high).
Firebase
Firebase Realtime
Database
ESP32 Stepper Motor You can use the preceding links or go directly to [Link]/tools to find all the parts for your
ESP32 MicroSD Card projects at the best price!
ESP32 PIR
ESP32 DHT11/DHT22
ESP32 BME280
ESP32 BME680
ESP32 DS18B20
ESP32 BMP180
ESP32 BMP388
MQTT DHT11/DHT22
MQTT BME280
MQTT BME680
MQTT DS18B20
ESP32 MPU-6050
Displays
ESP32 OLED
ESP32 LCD
OLED Temperature
ESP32 Features
ESP32: Creating FreeRTOS Tasks – Arduino Code
ESP32 Hall Sensor
The following code creates a task that will blink an LED connected to GPIO 2 every second.
ESP32 Touch Sensor
ESP32 I2C /*
ESP32 Flash Memory Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at [Link]
ESP32 Dual Core
Permission is hereby granted, free of charge, to any person obtaining
Useful Guides The above copyright notice and this permission notice shall be include
*/
ESP32 Troubleshooting
#define LED_PIN 2
ESP32 Access Point
// Declare task handle
ESP32 Fixed IP Address
TaskHandle_t BlinkTaskHandle = NULL
NULL;;
ESP32 MAC Address
BlinkTask(
void BlinkTask (void *parameter
parameter)) {
ESP32 Hostname
for (;;) { // Infinite loop
ESP32 OTA digitalWrite(
digitalWrite (LED_PIN
LED_PIN,
, HIGH
HIGH));
Serial.
Serial .println
println(("BlinkTask: LED ON")
ON");
ESP32 OTA Arduino
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS) ); // 1000ms
ESP32 OTA VS Code digitalWrite(
digitalWrite (LED_PIN
LED_PIN,
, LOW
LOW));
ESP32 Solar Panels Serial.
Serial .println
println(("BlinkTask: LED OFF"
OFF")
);
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS) );
ESP32 Alexa Serial.
Serial .print
print(("BlinkTask running on core ")") ;
ESP32 Install SPIFFS Serial.
Serial .println
println((xPortGetCoreID
xPortGetCoreID(());
}
ESP32 Time and Date }
ESP32 Epoch Time
setup(
void setup () {
ESP32 Google Sheets
Serial.
Serial .begin
begin((115200
115200));
ESP32 Email Altert
ESP32 ThingSpeak
View raw code
Weather Station Shield
VS Code SPIFFS
Task Handle
VS Code Workspaces
Then, declare the task handle. A TaskHandle_t is a variable that points to a FreeRTOS task,
Save Data Preferences letting you control it, like resuming it, stopping it, or delete it. In this example, we won’t need the task
Library
handle, but we’re creating it nonetheless to show you how it’s done.
Reconnect to Wi-Fi
Other Projects
Telegram Sensor Then, we create a task. A task is nothing more than a function that executes whatever commands
Readings you want. Here’s the BlinkTask function used in this example.
ESP32 Camera
This function is a FreeRTOS task, which is a special kind of function that runs independently under
ESP32 LoRa
the FreeRTOS scheduler, allowing multitasking on the ESP32.
ESP32 OLED
FreeRTOS tasks must return void and must accept a single argument, which can be used to pass
ESP32 SIM800L
data to the function (not used in our case).
Learn More
Learn ESP8266
Learn ESP32-CAM The for(;;) creates an infinite loop to ensure the task runs indefinitely until explicitly stopped.
This is similar to the loop() function used in Arduino code.
Learn MicroPython
Learn Arduino
for (;;) { // Infinite loop
Build Web Servers
eBook
Then, we use the digitalWrite() function to turn the LED on and off. Notice that instead of
Smart Home eBook using the typical delay() function, we use vTaskDelay() .
Firebase Web App
eBook
digitalWrite(
digitalWrite (LED_PIN
LED_PIN,, HIGH
HIGH));
ESP32 Premium Course Serial.
[Link](
println("BlinkTask: LED ON")
ON");
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS)); // 1000ms
Search … digitalWrite(
digitalWrite (LED_PIN
LED_PIN,, LOW
LOW));
Serial.
Serial .println
println(("BlinkTask: LED OFF")
OFF");
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS));
vTaskDelay()
vTaskDelay() is a FreeRTOS function that pauses a task for a specified number of ticks,
allowing other tasks to run during that time. It doesn’t block your code like delay() . The
vTaskDelay() function accepts ticks. On the ESP32, each tick is typically 1ms (defined by
portTICK_PERIOD_MS ), so vTaskDelay(1000 / portTICK_PERIOD_MS) pauses the task
for 1000ms (1 second).
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS));
For demonstration purposes, we also print in which core the task is running. We can get that
information by calling the xPortGetCoreID() function.
Serial.
Serial .print
print(("BlinkTask running on core ")
") ;
Serial.
Serial .println
println((xPortGetCoreID
xPortGetCoreID(());
setup()
In the setup() , we initialize the Serial Monitor and set the LED as an output.
setup(
void setup () {
Serial.
Serial .begin
begin((115200
115200));
pinMode(
pinMode (LED_PIN
LED_PIN,, OUTPUT
OUTPUT));
Create a Task
Now, to actually create a FreeRTOS task and assign it to a specific core, we need to use the
xTaskCreatePinnedToCore() function. This function also specifies the task function, name,
stack size, parameters, priority, and task handle.
xTaskCreatePinnedToCore(
xTaskCreatePinnedToCore (
BlinkTask,
BlinkTask , // Task function
"BlinkTask",
"BlinkTask" , // Task name
10000,
10000 , // Stack size (bytes)
NULL,
NULL , // Parameters
1, // Priority
BlinkTaskHandle,
&BlinkTaskHandle , // Task handle
1 // Core 1
);
The task function is BlinkTask that we defined earlier. We can also give a name to the task. In
this case, “BlinkTask” .
BlinkTask,
BlinkTask , // Task function
"BlinkTask",
"BlinkTask" , // Task name
We set the task stack size to 10000 bytes. The task stack size is the amount of memory allocated
for the task to store its variables, function calls, and temporary data while it runs, ensuring it has
enough space to operate without crashing the ESP32. It is defined in bytes. In a later example, we’ll
see how to get the stack size of a task.
10000,
10000 , // Stack size (bytes)
In this case, our task doesn’t have any parameters, so we set that parameter to NULL .
NULL,
NULL , // Parameters
We give the task priority 1 . The higher the number, the higher the priority. In this case, it doesn’t
matter much because we only have one task.
1, // Priority
We also define the task handle for the task that we created at the beginning of the code.
BlinkTaskHandle,
&BlinkTaskHandle , // Task handle
And finally, we define in which core we want to run the task. The ESP32 has two cores, designated
core 0 and core 1. In this example, we’re using core 1.
1 // Core 1
loop()
The loop() is empty because the FreeRTOS scheduler will run the task. However, it is possible to
add code to the loop() to run any other commands you want.
loop(
void loop () {
// Empty because FreeRTOS scheduler runs the task
}
Demonstration
Upload the code to your ESP32 board. After uploading, open the Serial Monitor at a baud rate of
115200. You should get a similar result.
Parts Required
For this example, you need the following parts:
Recommended reading: ESP32 Pinout Reference: Which GPIO pins should you use?
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at [Link]
Permission is hereby granted, free of charge, to any person obtaining
The above copyright notice and this permission notice shall be include
*/
#define LED1_PIN 2
#define BUTTON_PIN 23
// Task handle
TaskHandle_t BlinkTaskHandle = NULL
NULL;;
#define LED1_PIN 2
#define BUTTON_PIN 23
We create volatile variables that will be used in the ISR (interrupt service routine for the
pushbutton). The taskSuspended variable is used to determine whether the task is suspended or
not, and the lastInterruptTime and debounceDelay are needed to debounce the
pushbutton.
To detect pushbutton presses, we’re using interrupts. When we use interrupts, we need to define an
interrupt service routine (a function that runs on the ESP32 RAM). In this case, we create the
buttonISR() function. We must add IRAM_ATTR to the function definition to run it on RAM.
buttonISR(
void IRAM_ATTR buttonISR () {
Recommended reading: ESP32 with PIR Motion Sensor using Interrupts and Timers.
First, we debounce the pushbutton, and if a button press is detected, we toggle the state of the
taskSuspended flag variable.
// Debounce
millis(
uint32_t currentTime = millis ();
debounceDelay)
if (currentTime - lastInterruptTime < debounceDelay ) {
return;
return ;
}
currentTime;
lastInterruptTime = currentTime ;
Then, if the taskSuspended variable is true , we call the vTaskSuspend() function and pass
the task handle as an argument. Here, you can see one of the uses of the Task Handle. It is a way
to refer to the task to control it.
if (taskSuspended
taskSuspended)) {
vTaskSuspend(
vTaskSuspend (BlinkTaskHandle
BlinkTaskHandle));
If the taskSuspended variable is false, we call the vTaskResume() function to resume the
execution of the task.
} else {
vTaskResume(
vTaskResume (BlinkTaskHandle
BlinkTaskHandle));
setup()
attachInterrupt(
attachInterrupt (digitalPinToInterrupt
digitalPinToInterrupt((BUTTON_PIN
BUTTON_PIN)), buttonISR
buttonISR,, FALLING
FALLING));
Demonstration
Upload the code to your ESP32 board.
The LED will start blinking. If you press the pushbutton, the LED will stop blinking. Press again and
the LED will start blinking again.
00:13
At the same time, you should get all the information on the Serial Monitor.
3) Creating and Running Multiple Tasks
In this section, you’ll learn how to create and run multiple FreeRTOS tasks simultaneously. As an
example, we’ll create two tasks to blink two different LEDs.
Parts Required
For this example, you need the following parts:
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at [Link]
Permission is hereby granted, free of charge, to any person obtaining
The above copyright notice and this permission notice shall be include
*/
#define LED1_PIN 2
#define LED2_PIN 4
Task1(
void Task1 (void *parameter
parameter) ) {
pinMode(
pinMode (LED1_PIN
LED1_PIN,, OUTPUT
OUTPUT));
for (;;) {
digitalWrite(
digitalWrite (LED1_PIN
LED1_PIN,, HIGH
HIGH)
);
Serial.
Serial .println
println(("Task1: LED1 ON"
ON")
);
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS));
digitalWrite(
digitalWrite (LED1_PIN
LED1_PIN,, LOW
LOW)
);
Serial.
Serial .println
println(("Task1: LED1 OFF"
OFF"));
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS));
}
}
Task2(
void Task2 (void *parameter
parameter)) {
pinMode(
pinMode (LED2_PIN
LED2_PIN,, OUTPUT
OUTPUT));
for (;;) {
First, you need to define your tasks. In our case, we have two different tasks to blink two different
LEDs at different rates. We call them Task1 and Task2 .
Task1(
void Task1 (void *parameter
parameter) ) {
pinMode(
pinMode (LED1_PIN
LED1_PIN,, OUTPUT
OUTPUT));
for (;;) {
digitalWrite(
digitalWrite (LED1_PIN
LED1_PIN,, HIGH)
HIGH);
Serial.
Serial .println
println(("Task1: LED1 ON"
ON")
);
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS)
);
digitalWrite(
digitalWrite (LED1_PIN
LED1_PIN,, LOW
LOW));
Serial.
Serial .println
println(("Task1: LED1 OFF")
OFF");
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS)
);
}
}
Task2(
void Task2 (void *parameter
parameter) ) {
pinMode(
pinMode (LED2_PIN
LED2_PIN,, OUTPUT
OUTPUT));
for (;;) {
digitalWrite(
digitalWrite (LED2_PIN
LED2_PIN,, HIGH)
HIGH);
Serial.
Serial .println
println(("Task2: LED2 ON"
ON")
);
vTaskDelay(
vTaskDelay (333 / portTICK_PERIOD_MS
portTICK_PERIOD_MS)
);
digitalWrite(
digitalWrite (LED2_PIN
LED2_PIN,, LOW
LOW));
Serial.
[Link](
println("Task2: LED2 OFF")
OFF");
vTaskDelay(
vTaskDelay (333 / portTICK_PERIOD_MS
portTICK_PERIOD_MS));
}
}
Then, in the setup() , we just need to create the tasks using the xTaskCreatePinnedToCore .
In this example, we’re running both tasks on core 1 of the ESP32 and both have the same priority.
xTaskCreatePinnedToCore(
xTaskCreatePinnedToCore (
Task1,
Task1 , // Task function
"Task1",
"Task1" , // Task name
10000,
10000 , // Stack size (bytes)
NULL,
NULL , // Parameters
1, // Priority
Task1Handle,
&Task1Handle , // Task handle
1 // Core 1
);
xTaskCreatePinnedToCore(
xTaskCreatePinnedToCore (
Task2,
Task2 , // Task function
"Task2",
"Task2" , // Task name
10000,
10000 , // Stack size (bytes)
NULL,
NULL , // Parameters
1, // Priority
Task2Handle,
&Task2Handle , // Task handle
1 // Core 1
);
Demonstration
Upload the code to your board. After uploading, press the ESP32 RST button so that it starts
running the code. You’ll have two different LEDs blinking at different rates.
00:09
As you can see, it is super simple to achieve this by creating FreeRTOS tasks instead of using
delays or other complex timing calculations.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at [Link]
Permission is hereby granted, free of charge, to any person obtaining
The above copyright notice and this permission notice shall be include
*/
#define LED1_PIN 2
#define LED2_PIN 4
Task1(
void Task1 (void *parameter
parameter) ) {
pinMode(
pinMode (LED1_PIN
LED1_PIN,, OUTPUT
OUTPUT));
for (;;) {
digitalWrite(
digitalWrite (LED1_PIN
LED1_PIN,, HIGH
HIGH)
);
Serial.
Serial .println
println(("Task1: LED1 ON")
ON");
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS)
);
digitalWrite(
digitalWrite (LED1_PIN
LED1_PIN,, LOW
LOW));
Serial.
Serial .println
println(("Task1: LED1 OFF"
OFF")
);
vTaskDelay(
vTaskDelay(1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS)
);
Serial.
Serial .print
print(("Task 1 running on core ")
") ;
Serial.
Serial .println
println((xPortGetCoreID
xPortGetCoreID(());
}
}
void Task2(
Task2(void *parameter
parameter)) {
i M d (LED2 PIN OUTPUT)
OUTPUT)
View raw code
xTaskCreatePinnedToCore(
xTaskCreatePinnedToCore (
Task2,
Task2, // Task function
"Task2",
"Task2" , // Task name
10000,
10000 , // Stack size (bytes)
NULL,
NULL , // Parameters
1, // Priority
Task2Handle,
&Task2Handle , // Task handle
0 // Core 0
);
Demonstration
If you upload the code to your ESP32, the result will be the same as the previous example. Two
LEDs are blinking at different rates.
In the Serial Monitor, you can actually check that each task is running in a different core.
5) Tasks Memory Usage
In this section, we’ll cover how to measure stack and heap usage for your tasks so that you can
optimize memory allocation.
Stack and heap are two types of memory used by FreeRTOS tasks on the ESP32, each serving a
unique role in managing a program’s memory needs.
What exactly is the Stack Usage? The stack is a dedicated memory area for each FreeRTOS
task, used to store temporary data like local variables, function call information, and task state
during execution. Each task has its own stack, allocated when the task is created. You’ve seen that
in previous examples, we’re allocating a 10000-byte stack to each task.
There is a function that you can call inside your task to determine the stack usage: the
uxTaskGetStackHighWaterMark() function. That function determines the allocated stack size
that is not being used.
What is the Heap Usage? The heap is a shared memory pool in the ESP32’s SRAM, used for
dynamic memory allocation, including task stacks, buffers, and other runtime data allocated by
FreeRTOS or the Arduino core. We can call the xPortGetFreeHeapSize() function in our code
to determine the free heap.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at [Link]
Permission is hereby granted, free of charge, to any person obtaining
The above copyright notice and this permission notice shall be include
*/
#define LED1_PIN 2
#define LED2_PIN 4
Task1(
void Task1 (void *parameter
parameter) ) {
pinMode(
pinMode (LED1_PIN
LED1_PIN,, OUTPUT
OUTPUT));
for (;;) {
digitalWrite(
digitalWrite (LED1_PIN
LED1_PIN,, HIGH)
HIGH);
Serial.
Serial .println
println(("Task1: LED1 ON")
ON");
vTaskDelay(
vTaskDelay ( 1000 / portTICK_PERIOD_MS)
portTICK_PERIOD_MS);
digitalWrite(
digitalWrite (LED1_PIN
LED1_PIN,, LOW
LOW));
Serial.
Serial .println
println(("Task1: LED1 OFF"
OFF")
);
vTaskDelay(
vTaskDelay (1000 / portTICK_PERIOD_MS
portTICK_PERIOD_MS));
Serial.
Serial .printf
printf(("Task1 Stack Free: %u bytes\n"
bytes\n",
, uxTaskGetStackHighWate
}
}
Task2(
void Task2 (void *parameter
parameter) ) {
pinMode(
pinMode (LED2_PIN
LED2_PIN,, OUTPUT
OUTPUT));
f ( ) {
View raw code
Demonstration
After uploading the code to your board, you should get something similar on your Serial Monitor.
The uxTaskGetStackHighWaterMark reports 8556 bytes free for Task1 and 8552 bytes free for
Task2, meaning each task uses 1444–1448 bytes of its 10000-byte stack at peak. So, we can
greatly reduce the allocated stack size to each task.
A good stack size should cover the task’s peak usage (1444 bytes) plus a safety margin of 500–
1000 bytes to handle unexpected increases
In the case of free heap, in my case, the xPortGetFreeHeapSize() reports 247616 bytes free
(not shown in the screenshot), indicating the remaining heap after allocating stacks (20000 bytes for
two tasks) and other system resources.
Wrapping Up
This tutorial was a detailed introduction to FreeRTOS with the ESP32. You learned how to create
single and multiple tasks, assign a core to each task, suspend and resume tasks, and even
calculate the task stack.
Using FreeRTOS with the ESP32 is a great choice because it allows you to perform multiple tasks
simultaneously in a simple way, with priorities to run the most critical tasks first.
In future tutorials, we’ll cover communication between tasks using semaphores and queues.
Recommended Resources
Paulo Robalo
August 15, 2025 at 4:21 pm
Just a correction: the resistor is not “220 kOhm”, it’s only “220 Ohm” (red / red / brown)
Keep up the good work!
Reply
Sara Santos
August 17, 2025 at 10:52 am
Hi.
You’re right.
It’s already fixed.
Regards,
Sara
Reply
Henry
August 19, 2025 at 11:19 am
Reply
Flavio
August 15, 2025 at 6:04 pm
Great! As always.
Reply
Sara Santos
August 17, 2025 at 10:52 am
Thanks
Reply
Serg
August 15, 2025 at 6:33 pm
Reply
Sara Santos
August 17, 2025 at 10:51 am
Thanks
Reply
DuAlvim
August 15, 2025 at 8:20 pm
Excellent!
Today I was looking the ESP-IDF tutorials and they were awesome.
Then I was writing some ESP32 stuff using the ESP-IDF and then I saw this post on my e-
mail. After reading this tutorial, I solved what I was trying to solve in just few minutes and in
a more friendly framework (theArduino IDE). I believe that the results and the performance
of the project I just built will be similar to the results that I would see if I had continued in the
ESP-IDF.
Reply
DuAlvim
August 15, 2025 at 8:20 pm
Excellent!
Today I was looking the ESP-IDF tutorials and they were awesome.
Then I was writing some ESP32 stuff using the ESP-IDF and then I saw this post on my e-
mail. After reading this tutorial, I solved what I was trying to solve in just few minutes and in
a more friendly framework (theArduino IDE). I believe that the results and the performance
of the project I just built will be similar to the results that I would see if I had continued in the
ESP-IDF.
Reply
Sara Santos
August 17, 2025 at 10:48 am
Hi.
That’s great!
I’m glad this content is useful.
Regards,
Sara
Reply
DuAlvim
August 17, 2025 at 3:08 pm
Reply
Shahzad
August 15, 2025 at 9:24 pm
Wow great tutorial as usual… Really very clear and easy to understand.
Can we use a simple quadrature rotary encoder but with fast pulses like 1000/Rev without
losing any pulse forward or reverse? This idea came to my mind by reading FreeRTOS
tasking capability of handling events in real time. Thanks.
Reply
Dr_Phil
August 16, 2025 at 6:41 am
Boy those LEDs must be fantastic to operate via 220k ohm resistors.
Perhaps you are using 220 ohms instead!
Reply
Sara Santos
August 17, 2025 at 10:47 am
Hi.
I’m sorry. My mistake.
I mean 220 Ohm. It’s already fixed.
Regards,
Sara
Reply
Robin Ellams
August 16, 2025 at 10:54 am
Hey Sara!
Red red brown…= 220 ohms
Reply
Sara Santos
August 17, 2025 at 10:46 am
Hi.
Sorry. My mistake.
It’s already fixed.
Regards,
Sara
Reply
bob
August 16, 2025 at 11:28 am
interupts in rtos???
Reply
Sara Santos
August 17, 2025 at 10:46 am
Hi.
What do you mean?
Regards,
Sara
Reply
Larry Dalton
August 16, 2025 at 1:50 pm
You are on to something with this one. Much more please. If my 52 years of IT is worth
something it is worth supporting this. Perhaps you and your partner could create a book on
RTOS, and its growing into Linux with a standard way of wrapping it together.
Larry…
Reply
Sara Santos
August 17, 2025 at 11:00 am
Hi Larry.
Thank you so much for your feedback.
We already have three more FreeRTOS tutorials prepared that will be published
during the next few months. So, stay tuned!
Regards,
Sara
Reply
Dave K.
August 21, 2025 at 1:26 pm
Thank You for opening up this style of coding and for the up coming content!
Reply
Jim Weatherby
August 16, 2025 at 4:56 pm
Thank you for your tutorials and books. I find these well thought out and provide lots of
information. As I read one and think of questions I find that pretty quick here comes an
article that addresses those concerns. Thank you for what you do.
Reply
Sara Santos
August 17, 2025 at 10:59 am
That’s great!
Thank you so much for your feedback.
Regards,
Sara
Reply
Roger
August 17, 2025 at 7:06 pm
I was wondering whether it is possible to have one core accessing the WEB over Wi-Fi
while at the same time having the other core communicate with another ESP device using
ESP-NOW?
Regards,
Roger
Reply
DuAlvim
August 17, 2025 at 9:38 pm
I believe it is possible Roger, because i did it couple times in an ESP32, without
using the FreeRTOS, just using the Arduino IDE resources. So, I really think this is
possible too with FreeRTOS.
Reply
Sara Santos
August 18, 2025 at 4:19 pm
Hi.
Yes. I think it should be possible.
It can be done in only one core actually. We have a tutorial about ESP-NOW and
web server simultaneously: [Link]
web-server/
Regards,
Sara
Reply
Roger
August 20, 2025 at 8:46 pm
Thanks.
Reply
Ed
August 18, 2025 at 8:57 am
Reply
Ed
August 18, 2025 at 10:39 am
I know little to nothing of RTOS, but after looking a bit deeper in it, I understand there is a
difference between the implementation in the ESP-IDF and the Arduino IDE.
I understand the IDF verdion to be more optimized and to have more debugging features,
whereas the IDE version is much simpler to use/install and suffices for most applications
Reply
Sara Santos
August 18, 2025 at 4:17 pm
Reply
Bart
August 18, 2025 at 3:00 pm
Oh boy, this brings back memories. Early nineties I was programming in HP-RTOS,
VxWorks and LynXOS. Unbelievable that this is now coming to these little devices!
Reply
Dan
August 23, 2025 at 12:52 am
Reply
Dan
August 23, 2025 at 12:56 am
I used this code after trying the one in the example with 2 tasks:
TaskHandle_t Task0;
TaskHandle_t Task1;
void setup() {
[Link](115200);
[Link]();
//create a task that executes the Task0code() function, with priority 1 and executed
on core 0
xTaskCreatePinnedToCore(Task0code, “Task0”, 10000, NULL, 1, &Task0, 0);
//create a task that executes the Task0code() function, with priority 1 and executed
on core 1
xTaskCreatePinnedToCore(Task1code, “Task1”, 10000, NULL, 1, &Task1, 1);
}
void loop() {
// nothing to do here, everything happens in the Task1Code and Task2Code
functions
[Link](“Loop”);
delay((int)random(1000, 3000));
}
for (;;) {
[Link](“Core 0 processing”);
delay((int)random(100, 1000));
}
}
for (;;) {
[Link](“Core 1 processing”);
delay((int)random(100, 1000));
}
}
Reply
Dan
August 23, 2025 at 1:16 am
I’m using the XIAO_ESP32C3. I found the example I’m using above here:
[Link]/posts/2023/arduino-running-tasks-on-multiple-cores/
I tried commenting out creating the task1 and assigned the task0 to core 1
and it still says:
Reply
Sara Santos
August 23, 2025 at 5:19 pm
Hi.
The ESP32C3 is not dual core. You must use another ESP32 board
model.
Regards,
Sara
Reply
Dan
August 23, 2025 at 8:24 pm
Reply
DuAlvim
August 25, 2025 at 1:24 am
Hey Guys,
I’m still entertained with this tutorial, so, thank you very much for this great class! Of couse,
also very wishful to see the next FreeRTOS tutorials!
I was trying the second example of this tutorial and happened a very funny situation here
and, probably, you guys would know my question, since it looks like a very elementary one.
This example executed very unstable here. Most of the times I touched the button, the
monitor serial showed an error and the board rebooted, but not always, because
sometimes, everything worked as spected.
The things went less unstable when I connected a 10K resistor and a 10uF capacitor to the
button and made this chanes in the ‘setup()’ function:
“””
pinMode(BUTTON_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonISR, RISING);
“””
Of course this situation kept coming here, but less often than before.
Do you guys know if this is something related to the ESP32 hardware or Arduino Driver? Or
it is something I’m doing wrong?
Rebooting…
ets Jun 8 2016 [Link]
…
“””
Reply
Sara Santos
August 26, 2025 at 10:29 am
Hi.
That’s probably an issue with the wiring.
What ESP32 board are you using? Depending on the board model, you may need to
use a different GPIO.
Additionally, you may want to double-check the legs of your pushbutton and
breadboard to make sure there aren’t any short-circuits.
Regards,
Sara
Reply
DuAlvim
August 26, 2025 at 1:04 pm
Hi Sara,
I’m Using a tradicional ESP32 board, one that I use since long time ago.
Probably, what you told is the best try to do now… because wiring is a real
“box full of surprises”. And try other GPIOs too.
Reply
Sara Santos
August 29, 2025 at 9:59 am
Ok.
Then, let me know your results.
Regards,
Sara
Reply
Andrei-Viorel ENACHE
August 26, 2025 at 8:33 am
Hi
I have a problem with connecting to WiFi. If the ESP is reset and does not have WiFi, all
other functions freeze (EX: sensors connected to I2C, display). I tried to put the WiFi
connection on one core and the display on another core, but I have the same problem, what
could I do?
Thanks in advance!
Reply
Sara Santos
August 26, 2025 at 10:32 am
Hi.
It’s very hard to tell your issue without further information.
Probably you have a condition that checks wi-fi before moving to other functions. So,
the code keeps blocked on the Wi-Fi connection before doing other tasks.
Regards,
Sara
Reply
Andrei-Viorel ENACHE
August 26, 2025 at 10:35 am
Code:
// Inițializare Firebase
config.api_key = API_KEY;
config.database_url = DATABASE_URL;
[Link] = USER_EMAIL;
[Link] = USER_PASSWORD;
[Link](&config, &auth);
[Link](true);
[Link](“Obținere UID”);
while ([Link] == “”) {
[Link](“.”);
vTaskDelay(pdMS_TO_TICKS(500));
}
uid = [Link].c_str();
[Link]();
[Link](“UID: “);
[Link](uid);
// Setăm căile
path1 = “/UsersData/” + uid + “/comanda1”;
path2 = “/UsersData/” + uid + “/comanda2”;
path3 = “/UsersData/” + uid + “/pic”;
void setup() {
tftMutex = xSemaphoreCreateMutex(); // creează mutex-ul
[Link](115200);
xTaskCreatePinnedToCore(
taskAutomat, // Task function
“taskAutomat”, // Task name
10000, // Stack size (bytes)
NULL, // Parameters
5, // Priority
&taskAutomatHandle, // Task handle
0 // Core 1
);
xTaskCreatePinnedToCore(
taskWiFiFirebase,
“taskWiFiFirebase”,
10000,
NULL,
2, // Poți da o prioritate puțin mai mare
&taskWiFiHandle,
1
);
// Initialize RTC
if (! [Link]()) {
[Link](“Couldn’t find RTC”);
[Link]();
while (1) delay(10);
}
//Opțiunea 2: Manuală (decomentează și ajustează data și ora dorită)
//[Link](DateTime(2025, 1, 19, 6, 59, 15)); // An, lună, zi, oră, minut,
secundă
//Opțiunea 1: Automată (folosind data și ora compilării)
//[Link](DateTime(F(DATE), F(TIME)));
if (! [Link]()) {
[Link](“RTC is NOT running, let’s set the time!”);
[Link](DateTime(F(DATE), F(TIME)));
}
Reply
Andrei-Viorel ENACHE
August 26, 2025 at 10:33 am
Hy
I have a problem with the WiFi connection of the ESP 32. When it resets and has no WiFi, it
blocks the entire code (EX: sensors connected via I2C, display, etc.). I tried to put the WiFi
connection on one core and the display on another core, but that doesn’t work either, what
can I do?
Thanks in advance!
Reply
Andrei-Viorel ENACHE
August 26, 2025 at 12:31 pm
I solved the problem (I initialize the display after trying to display), it works absolutely
perfectly, with some small changes to memory and priority.
Reply
Sara Santos
August 29, 2025 at 9:58 am
Ok, great.
I’m glad the issue is solved.
Regards,
Sara
Reply
Leave a Comment
Name *
Email *
Website
Post Comment
About Support Terms and Conditions Privacy Policy Refunds Complaints’ Book [Link] Join the Lab