Teach Remote lab lessons

Teach lesson

STM32 Mbed CodeIDE (2/8): LED sequences and timing

Students program timed LED sequences on a real STM32 board with Mbed DigitalOut and delays, then change timing and explain the observed order.

  • STM32 Nucleo (Mbed)
  • 55 min
  • Upper secondary / introductory vocational electronics
  • English
  • Embedded systems
Three green LED symbols labeled led1 PB13, led2 PB14, and led3 PB15.
STM32 Nucleo (Mbed)

Learning Outcomes

  • Control several Mbed DigitalOut pins in a planned sequence.

  • Use timing changes to make an output pattern easier to observe.

  • Explain the relationship between code order and physical LED order.

Student activity preview

Activity Content

Preview only. In a class session, students can fill in responses and submit their work to the teacher.

1

Plan the sequence

8 min

A single blink proves the board is programmable; a timed LED pattern can carry information, like a startup sweep, a warning sequence, or a status code. The important idea in this lesson is not just "turn on LEDs"; it is that code order plus timer delays becomes visible behavior on hardware.

A microcontroller follows the order of your code exactly. The program below will use helper calls such as led_on(led1) so the code reads like the physical action you want to see.

If you write:

led_on(led1);
ThisThread::sleep_for(500ms);
led_on(led2);

then LED 1 should turn on before LED 2.
LED 1 will stay on while LED 2 turns on, because the code has not called led_off(led1) yet.

This lesson uses three Mbed output pins available in the STM32 WB55RG lab:

- PB_13
- PB_14
- PB_15

These are custom green LED outputs on the training board. In the local CodeIDE Mbed examples, they are active-low: writing 0 turns one on and writing 1 turns it off. That is why the starter code uses helper functions instead of asking you to remember raw 0/1 polarity.

In Mbed, each DigitalOut line creates one output object connected to one STM32 pin. The object keeps its last value while the program waits, so ThisThread::sleep_for(500ms) pauses the code without erasing the LED state you just set.

Use this mapping when you compare your code with the camera:

- led1 = PB_13 = leftmost green LED in the three-LED group.
- led2 = PB_14 = middle green LED in that group.
- led3 = PB_15 = rightmost green LED in that group.

Three green LED outputs used in this lesson

Three green LED symbols labeled led1 PB13, led2 PB14, and led3 PB15.

Use the camera view to check the order of this visible LED group. If the LEDs are hard to tell apart, slow the pattern to 1000ms, use the mapping above, and record not distinguishable on camera only if the camera view still cannot confirm the order.

In the helper header DigitalOut &led, the & means the helper works on the actual LED object you pass in, not on a copy. In 500ms, ms means milliseconds.

If LED 1 turns on, then LED 2, then LED 3, with no led_off() call between them, what appears just before all_off()?

2

Run the guided sequence

26 min

Plan for two builds and about 20 minutes of active lab time. Build 1 uses a left-to-right order and 500ms; build 2 changes only the step delay to either 250ms or 1000ms. While queued, answer the cumulative-pattern question, choose your second timing, and write the expected order.

The starter has exactly four compile-blocking placeholders. Replace TODOs 1-4 before saving or compiling. Search for TODO; a compile-ready file has no matches.

  1. Open the STM32 Mbed CodeIDE lab.

  2. Open main.cpp.

  3. Replace the file with the code below. For build 1, set TODO 1 to 500ms, then set TODOs 2-4 to led1, led2, and led3 in that order.

  4. Search for TODO. When none remain, save, compile build 1, and upload.

  5. Observe at least three complete cycles and note the LED order and timing.

  6. Change only step_delay from 500ms to either 250ms or 1000ms.

  7. Save main.cpp, compile build 2, upload, and compare whether the new timing is easier or harder to verify.

  8. Only after step 7 is complete, click Mark practice as done.

#include "mbed.h"

DigitalOut led1(PB_13, 1);
DigitalOut led2(PB_14, 1);
DigitalOut led3(PB_15, 1);

void led_on(DigitalOut &led) {
    led = 0;
}

void led_off(DigitalOut &led) {
    led = 1;
}

void all_off() {
    led_off(led1);
    led_off(led2);
    led_off(led3);
}

int main() {
    // 1: replace the timing placeholder with 500ms for build 1.
    const auto step_delay = TODO_STEP_DELAY;
    const auto reset_delay = 1000ms;
    all_off();

    while (true) {
        // 2-4: choose each LED once to make a left-to-right order.
        led_on(TODO_FIRST_LED);
        ThisThread::sleep_for(step_delay);

        led_on(TODO_SECOND_LED);
        ThisThread::sleep_for(step_delay);

        led_on(TODO_THIRD_LED);
        ThisThread::sleep_for(reset_delay);

        all_off();
        ThisThread::sleep_for(reset_delay);
    }
}

Record the two tested versions separately. Because the starter code leaves previous LEDs on until all_off() runs, the expected visible sequence is cumulative: LED 1 on -> LEDs 1+2 on -> LEDs 1+2+3 on -> all off.

For the original 500ms version, record:

- visible order or cumulative pattern you confirmed in the camera;
- whether the LED positions matched the led1/led2/led3 mapping;
- what made the pattern easy or hard to verify.

For the changed timing version, record:

- the delay value you tested;
- whether the visible order or cumulative pattern stayed the same;
- whether the new timing made the pattern easier or harder to verify;
- not distinguishable on camera only if you slowed the pattern and still could not confirm the order.

Choose one helper call that changes an LED. Name the line, such as led_on(led2);, and explain what physical change that line caused and when it happened in the sequence.

3

Explain your final timing choice

13 min

Keep the left-to-right TODO order in the final file. Your only second-build change is the timing choice: 250ms gives a faster comparison; 1000ms gives a slower, camera-friendly comparison. Both are valid if the evidence matches.

State your final step_delay in milliseconds. Explain why you chose 250ms or 1000ms and whether the camera evidence supported that choice.

4

Submit your code

8 min

Attach your saved final main.cpp

Click Check saved files, confirm that main.cpp contains the tested left-to-right order, your final timing choice, and no TODO text. Then click Attach saved code and Submit submission.