This project demonstrates how FreeRTOS task priorities and task control APIs (vTaskSuspend() and vTaskResume()) can be used to manage system behavior on an Arduino UNO.
The system simulates a simple control panel with normal operation, emergency handling, and user interaction using buttons
Project OverviewIn real-time systems, some events must be handled immediately, while others can wait. FreeRTOS allows this through task priorities and dynamic task control.
- This project uses multiple tasks to:
- Blink a green LED during normal operation
- Detect and handle an emergency condition
- Start and stop the system using buttons
The FreeRTOS library is included as usual:
#include <Arduino_FreeRTOS.h>
#include <task.h>Hardware SetupThe project can be simulated using Wokwi Simulator and includes:
- Arduino UNO running FreeRTOS
- Green LED on Pin 9 (normal operation)
- Red LED on Pin 8 (emergency indicator)
- Emergency Button on Pin 2
- Start Button on Pin 3
- Stop Button on Pin 4
⚠️ Buttons are active LOW and use INPUT_PULLUP for simple wiring.
Green LED Blink Task (Low Priority)
This task represents normal system operation. It blinks the green LED every 500 ms and can be suspended or resumed by other tasks.
void TaskBlink(void *pvParameters) {
pinMode(LED_GREEN, OUTPUT);
while (1) {
digitalWrite(LED_GREEN, HIGH);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(LED_GREEN, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}Emergency Task (Highest Priority)
This task continuously monitors the emergency button. When pressed, it preempts all other tasks, suspends the blink task, and turns on the red LED.
void TaskEmergency(void *pvParameters) {
pinMode(BUTTON_EMERG, INPUT_PULLUP);
pinMode(LED_RED, OUTPUT);
while (1) {
if (digitalRead(BUTTON_EMERG) == LOW && !emergency) {
emergency = true;
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GREEN, LOW);
vTaskSuspend(xHandleBlink);
Serial.println("🛑 EMERGENCY ACTIVATED");
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}Start and Stop Tasks (Medium Priority)
- Start Task
Resumes normal operation only if the system is not in emergency mode.
void TaskStart(void *pvParameters) {
pinMode(BUTTON_START, INPUT_PULLUP);
while (1) {
if (digitalRead(BUTTON_START) == LOW && !emergency && !systemStarted) {
systemStarted = true;
vTaskResume(xHandleBlink);
Serial.println("✅ SYSTEM STARTED");
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}- Stop Task
Stops the system by suspending the blink task and turning off the green LED.
void TaskStop(void *pvParameters) {
pinMode(BUTTON_STOP, INPUT_PULLUP);
while (1) {
if (digitalRead(BUTTON_STOP) == LOW && !emergency && systemStarted) {
digitalWrite(LED_GREEN, LOW);
vTaskSuspend(xHandleBlink);
systemStarted = false;
Serial.println("⏹️ SYSTEM STOPPED");
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}Task Creation and Scheduler Control
All tasks are created with appropriate priorities in setup(). The blink task is suspended at startup until the system is started
void setup() {
Serial.begin(9600);
xTaskCreate(TaskBlink, "Blink", 128, NULL, 1, &xHandleBlink);
xTaskCreate(TaskEmergency, "Emergency", 96, NULL, 3, NULL);
xTaskCreate(TaskStart, "Start", 96, NULL, 2, NULL);
xTaskCreate(TaskStop, "Stop", 96, NULL, 2, NULL);
vTaskSuspend(xHandleBlink);
}The loop()
function is unused because FreeRTOS manages execution:
void loop() {}Expected Behavior- Task priorities determine system responsiveness
- vTaskSuspend() and vTaskResume() allow dynamic task control
- High-priority tasks preempt lower-priority tasks immediately
- Button polling inside tasks does not block the system
- Understand FreeRTOS task priority scheduling
- Learn how to suspend and resume tasks safely
- Design responsive, event-driven embedded systems
This project provides a realistic and practical example of task control and priority-based scheduling in FreeRTOS, commonly used in safety-critical embedded applications.
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