ESP32 Arduino: Using Structs As Items In FreeRTOS Queues
Maybe your like
Store CommunityForumWikiBlogLearn $USD
TUTORIALS ESP32 ESP32 Arduino: Using structs as items in FreeRTOS queues DFRobot Apr 19 2018 264537 In this ESP32 tutorial we will check how to use structs as items in FreeRTOS queues. This will allow us to store more complex messages in queues, facilitating the process of inter-task communication. The tests were performed using a DFRobot’s ESP32 module device integrated in a ESP32 development board.
Introduction
In this ESP32 tutorial we will check how to use structs as items in FreeRTOS queues. This will allow us to store more complex messages in queues, facilitating the process of inter- task communication.
You can check a more detailed introduction about FreeRTOS queues on this previous tutorial.
In our program, we will focus on the process of inserting and consuming items from the queue. Thus, we will create a simple data struct, create some variables of that data type, insert them in the queue and then consume them.
Our data struct will represent an IoT sensor measurement. In a real application use case, we could have, for example, one task (or multiple) obtaining measurements from different devices and then sending them to a dispatcher task that would send the measurements to the cloud. The communication mechanism used between the tasks could then be a queue, where each item would represent a measurement’s information.
Naturally this is one of that many possible use cases and you should adapt the data structure to the needs of your application’s architecture.
The tests were performed using a DFRobot’s ESP32 module device integrated in a ESP32 development board.
The code
The first thing we are going to do is declaring our struct. As mentioned, we will create a testing struct that represents an IoT sensor measurement, just for demonstration purposes. For a more detailed tutorial about using structs on the Arduino environment, please consult this blog post.
Our struct will be equal to the one presented on the mentioned tutorial and will have three fields: a device ID, a measurement type and a measurement value. The first two members will be of type int and the third will be of type float.
struct sensor { int deviceId; int measurementType; float value; };Now that we have finished our struct declaration, we will declare a global variable of type QueueHandle_t. This type is used to reference a FreeRTOS queue, which we will create later.
QueueHandle_t queue;Moving on to the Arduino setup function, we will open a serial connection, in order to output the results of our program and obtain them on the Arduino IDE serial monitor when testing the code.
Serial.begin(115200);After this, we will create the FreeRTOS queue. To do it, we simply need to call the xQueueCreate function. This function receives as first input the maximum number of items that the queue can hold and as second input the size, in bytes, of an element of the queue [1]. All the elements of the queue should have the same size.
For the first argument, we will pass the value 10, which means that the queue can hold, at most, 10 items at a single time. You can test with other value if you want.
The size of each item will be equal to the size of the structure we have previously declared. To get its value, in bytes, we can use the sizeof function.
If the queue is successfully created, the xQueueCreate returns an handle for the queue, which is of type QueueHandle_t. This type corresponds to the type of the global variable we declared at the beginning of the program and so we will assign result of the function to that variable.
queue = xQueueCreate( 10, sizeof( struct sensor ) );In case the memory for the queue couldn’t be allocated, then the function returns NULL instead of a queue handle [1]. Thus, we will do an error checking a print a message in case the queue was not created.
if(queue == NULL){ Serial.println("Error creating the queue"); }Moving on to the Arduino loop function, we will start to insert items on the queue. We will do this in a loop with 10 iterations, which corresponds to the size of the queue.
for(int i = 0; i<10; i++){ //Queue insertion code }In each iteration, we will create a variable with the type of our struct and assign values to its fields. We will assign the current iteration value to the deviceId field, so it varies for each message.
We will assign some arbitrary fixed values to the other fields.
struct sensor mySensor; mySensor.deviceId = i; mySensor.measurementType = 1; mySensor.value = 20.4;To insert the item in the queue, we need to call the xQueueSend function, which will insert it at the end of the queue [2].
As first argument, the function receives the queue handle we previously obtained. As second argument, it receives a pointer to the item we want to insert. Note that even tough we are passing a pointer to the item, it will actually be copied into the queue [2], not just referenced.
In our case, it means that the whole struct will be copied into the queue. For larger data structures, it may be a better option to use the queue to store references to those structures, but that is a more advanced use case that we will not cover here.
The last argument corresponds to the maximum amount of time the task should block waiting for space to become available on the queue, in case it is full, to be able to insert the item [2].
We will pass it the value portMAX_DELAY, which means that the task should wait indefinitely in case the queue is full. Nonetheless, we will design or program flow in such a way that ensures this never happen.
for(int i = 0; i<10; i++){ struct sensor mySensor; mySensor.deviceId = i; mySensor.measurementType = 1; mySensor.value = 20.4; xQueueSend(queue, &mySensor, portMAX_DELAY); }Now that we have an insertion loop, we will also design a similar consumption loop, to get the inserted items and print their values to the serial port.
Before the loop, we will declare another variable with the type of our struct, which we will use as buffer to receive the item from the queue. Since we will get each item and print its value right away in the same iteration, we can reuse this variable to get all the items of the queue.
struct sensor element;Then, inside another loop with 10 iterations, we will get each item with a call to the xQueueReceive function.
As first argument, the function receives the queue handle which we have stored on the global variable. As second argument, it receives a pointer to the buffer into which the item will be copied, which we declared before the loop. As third argument, it receives the maximum amount of time the task should block waiting for an item, in case the queue is empty [3]. Again, we will pass the portMAX_DELAY value, taking into account that the task will never block because we will never call the function when the queue is empty.
After receiving the item, which will be of our struct type, we will print the value of each of its members to confirm they match the values of the previously inserted items.
for(int i = 0; i<10; i++){ xQueueReceive(queue, &element, portMAX_DELAY); Serial.print("Device ID: "); Serial.println(element.deviceId); Serial.print("Measurement type: "); Serial.println(element.measurementType); Serial.print("Value: "); Serial.println(element.value); Serial.println("----------------"); }At the end, we will do a small four seconds delay between each iteration of the loop. The final source code can be seen below. It already includes this delay and, at the start of the Arduino loop, an error checking in case the queue was not successfully created.
struct sensor { int deviceId; int measurementType; float value; }; QueueHandle_t queue; void setup() { Serial.begin(115200); queue = xQueueCreate( 10, sizeof( struct sensor ) ); if(queue == NULL){ Serial.println("Error creating the queue"); } } void loop() { if(queue == NULL){ Serial.println("Queue was not created"); return; } for(int i = 0; i<10; i++){ struct sensor mySensor; mySensor.deviceId = i; mySensor.measurementType = 1; mySensor.value = 20.4; xQueueSend(queue, &mySensor, portMAX_DELAY); } struct sensor element; for(int i = 0; i<10; i++){ xQueueReceive(queue, &element, portMAX_DELAY); Serial.print("Device ID: "); Serial.println(element.deviceId); Serial.print("Measurement type: "); Serial.println(element.measurementType); Serial.print("Value: "); Serial.println(element.value); Serial.println("----------------"); } Serial.println(); delay(4000); }Testing the code
To test the code, simply compile it and upload it to your ESP32 using the Arduino IDE. When it finishes, open the serial monitor and check the result. You should get an output similar to figure 1, which shows the values of the items obtained from the queue.
As expected, the items obtained are equal to the ones originally inserted on the queue. The device ID is incremented in each item and the remaining values are equal.

Figure 1 – Output of the program.
DFRobot supply lots of esp32 arduino tutorials and esp32 projects for makers to learn.
ESP32 / ESP8266 ProjectsESP32 / ESP8266 Products Recent Blogs
Beyond the Specs: Why We Built HUSKYLENS 2 (And Should You Upgrade?) Should you upgrade to HUSKYLENS 2? This comparison breaks down processor speed, AI capabilities, LLM integration, and custom model support. Find out which vision sensor fits your robotics or STEM project—specs, prices, and real-world use cases.
SELECTION GUIDE Jan 27 2026
Empowering Future Makers: DFRobot Brings AI Education to the 2026 Fab Educators Summit The landscape of K–12 education is rapidly evolving, moving from simple digital making to complex problem-solving with Artificial Intelligence. At DFRobot, we believe in equipping educators with the best tools and knowledge to navigate this shift. That is why we are thrilled to announce that DFRobot will be a featured presenter at the upcoming 2026 Fab Educators Summit on Friday, January 30th.
NEWS Jan 26 2026
How to Choose Force Sensitive Sensors (FSR) & Thin Film Pressure Sensors From smart wearables and robotic skins to industrial monitoring, Force Sensitive Resistors (FSR) and Thin Film Pressure Sensors are essential components for tactile feedback. DFRobot offers a comprehensive range of force sensors, but choosing the right one can be tricky.
SELECTION GUIDE Jan 23 2026Tag » Arduino Rtos Queue
-
Arduino FreeRTOS Queue Management – How To Use Queues
-
Arduino FreeRTOS Tutorial 2- Using Queues In ... - Circuit Digest
-
Queue In FreeRTOS In Arduino - Tutorialspoint
-
FreeRTOS Arduino: How To Use Queue Set - YouTube
-
ESP32 Arduino: FreeRTOS Queues - Techtutorialsx
-
FreeRTOS-Arduino/queue.h At Master · Makeblock-official ... - GitHub
-
Use Of Queue For Sending Multiple Messages - Tutorials
-
Writing And Reading FreeRTOS Queue From Different ESP32 Cores
-
Can't Get Full Array In Queue RTOS - Arduino Forum
-
Introduction To RTOS - Solution To Part 5 (FreeRTOS Queue Example)
-
Queue. - Hướng Dẫn điện Tử
-
FreeRTOS Queue With Arduino - Embedded Explorer
-
Arduino And FreeRTOS FreeRTOS Queue Management - 文章整合
-
How Can I Send And Receive A Char From One Task To Another Task By ...