This project demonstrates inter-task communication in FreeRTOS using queues. Instead of sharing variables directly, tasks exchange messages to control system behavior in a safe and scalable way.
A button press is detected in one task, sent as a message through a queue, and processed by another task that controls an LED.
Project OverviewIn multitasking systems, tasks often need to exchange information. FreeRTOS queues provide a thread-safe way to send data between tasks without race conditions.
This project uses:
- One task to monitor and debounce a button
- One task to control an LED based on received messages
- A FreeRTOS queue to pass "ON" and "OFF" commands
The FreeRTOS headers are included as follows:
#include <Arduino_FreeRTOS.h>
#include <queue.h>Hardware SetupThe project can be simulated using Wokwi Simulator and includes:
- Arduino UNO running FreeRTOS
- Push button connected to Pin 2
- LED connected to Pin 8
Button Monitoring Task
This task continuously reads the button state, applies software debouncing, detects state changes, and sends messages to the queue.
void TaskButton(void *pvParameters) {
int lastState = LOW;
while (1) {
int currentState = digitalRead(BUTTON_PIN);
if (currentState != lastState) {
char message[4];
strcpy(message, currentState == HIGH ? "ON" : "OFF");
xQueueSend(xQueue, &message, portMAX_DELAY);
Serial.print("Sent: ");
Serial.println(message);
lastState = currentState;
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}LED Control Task
This task waits for messages from the queue and controls the LED accordingly. It reacts immediately when a message is received.
void TaskLED(void *pvParameters) {
char receivedMessage[4];
while (1) {
if (xQueueReceive(xQueue, receivedMessage, portMAX_DELAY) == pdPASS) {
Serial.print("Received: ");
Serial.println(receivedMessage);
if (strcmp(receivedMessage, "ON") == 0) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
}
}
}Queue Creation and Task Setup
A queue capable of holding multiple messages is created in setup(). Both tasks run at the same priority.
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
xQueue = xQueueCreate(5, sizeof(char) * 4);
xTaskCreate(TaskButton, "ButtonTask", 128, NULL, 1, NULL);
xTaskCreate(TaskLED, "LEDTask", 128, NULL, 1, NULL);
}The loop()
function is unused because the FreeRTOS scheduler manages execution:
void loop() {}Expected Behavior- Safe inter-task communication using queues
- Button debouncing with periodic polling
- No shared global variables between tasks
- Real-time system feedback via Serial Monitor
- Queues decouple tasks and improve system reliability
- Message passing avoids race conditions
- Tasks can block efficiently while waiting for data
- FreeRTOS queues are ideal for event-driven designs
- Understand how to create and use FreeRTOS queues
- Learn message-based task synchronization
- Design cleaner, more scalable multitasking systems
This project provides a clear and practical introduction to FreeRTOS queue-based communication, a core concept in professional embedded real-time systems.
That's all!If you have any questions or suggestions, don’t hesitate to leave a comment below.


_ztBMuBhMHo.jpg?auto=compress%2Cformat&w=48&h=48&fit=fill&bg=ffffff)

Comments