Practical: Multi-Task Blink & Sensor Monitor
Learning Objectives
- Explain what a Real-Time Operating System (RTOS) is and why it is used.
- Create and run multiple concurrent tasks using FreeRTOS.
- Describe basic task scheduling and priority concepts.
8.1 Why Use an RTOS?
A single loop() is suitable for simple programs, but more complex embedded applications may have several activities operating at different rates. An RTOS provides a structure for managing multiple tasks and scheduling their execution.
8.2 Important RTOS Terms
|
Term |
Meaning |
|
Task |
A unit of work that can be scheduled independently. |
|
Scheduler |
Selects which ready task should run. |
|
Priority |
Helps determine which task receives processor time. |
|
Task state |
A task may be running, ready, blocked/delayed or otherwise managed. |
|
vTaskDelay() |
Delays/yields a task for a specified period. |
|
Queue |
A mechanism for communication between tasks; introduced conceptually here. |
Figure 8.1: Original block diagram showing two concurrent FreeRTOS tasks.
8.3 Practical Activity: Multi-Task Blink & Sensor Monitor
The module specifies an ESP32 or another FreeRTOS-capable board, an LED, buzzer and potentiometer. The following is a simple ESP32 teaching example.
- Prepare the ESP32, LED, 220 Ω resistor, potentiometer, breadboard and jumper wires.
- Connect the LED to a digital output through the resistor.
- Connect the potentiometer wiper to an analog input; the example uses GPIO34.
- Create Task A to toggle the LED every 500 ms using vTaskDelay().
- Create Task B to read the potentiometer every 1 second and print the value.
- Start both tasks and verify that they operate concurrently.
- Change Task A priority with trainer guidance and record observations.
- Document the difference between this structure and a single-loop program.
Example ESP32 FreeRTOS Program
const int LED_PIN = 2;
const int POT_PIN = 34;
void taskBlink(void *parameter) {
pinMode(LED_PIN, OUTPUT);
while (true) {
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
vTaskDelay(pdMS_TO_TICKS(500));
}
}
void taskReadPot(void *parameter) {
while (true) {
int value = analogRead(POT_PIN);
Serial.print(“Potentiometer value: “);
Serial.println(value);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void setup() {
Serial.begin(115200);
xTaskCreate(taskBlink, “Blink Task”, 2048, NULL, 1, NULL);
xTaskCreate(taskReadPot, “Sensor Task”, 2048, NULL, 1, NULL);
}
void loop() {
// Tasks perform the main work.
}
Teaching example: exact FreeRTOS setup can depend on the board and Arduino environment. Use the trainer’s board configuration and verify the actual hardware pins.
8.4 Single Loop versus RTOS Tasks
|
Aspect |
Single loop |
RTOS approach |
|
Program structure |
Most work is coordinated in loop() |
Work is divided into tasks |
|
Timing |
Often uses conditions/millis() |
Tasks can use scheduler delays |
|
Multiple activities |
Developer coordinates activities |
Scheduler manages ready tasks |
|
Priority |
Not normally a task concept |
Tasks can have priorities |
8.5 Practical Questions
- Which task controls the LED?
- How often is the potentiometer read?
- What is the role of vTaskDelay()?
- What does the scheduler do?
- What might happen if one task has a higher priority?
- Why can two tasks appear to operate at the same time?
8.6 Checkpoint
Demonstrate that both tasks run correctly and explain, in simple terms, what a task and the scheduler are doing.


