Teach Remote lab lessons

Teach lesson

STM32 Mbed CodeIDE (3/8): buttons, pull-ups, and debounce

Students read active-low pushbuttons with Mbed DigitalIn and PullUp, test debounce behavior, and connect button evidence to LED output on a real STM32 board.

  • STM32 Nucleo (Mbed)
  • 60 min
  • Upper secondary / introductory vocational electronics
  • English
  • Embedded systems
STM32 Nucleo (Mbed)
STM32 Nucleo (Mbed)

Learning Outcomes

  • Read a push button with Mbed DigitalIn.

  • Verify whether the button behaves as active-low in the current lab view.

  • Use a simple confirm-after-wait debounce check before accepting a press.

Student activity preview

Activity Content

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

1

Read before reacting

10 min

The CodeIDE guide lists PC_5, PC_6, and PC_10 among the button/sensor pins available in the STM32 WB55RG lab. This lesson uses PC_5 first and teaches you to verify the pressed value before building logic around it.

Many button circuits use a pull-up resistor:

- released: reads 1
- pressed: reads 0

That is called active-low. Do not assume it blindly; test it.

DigitalIn button(PC_5, PullUp);
int raw = button.read();

DigitalIn is the Mbed input object for reading a pin. PullUp asks Mbed to use the microcontroller's internal pull-up resistor, so the pin has a defined value when the button is released. button.read() returns the current 0/1 value at the moment your code calls it.

The remote lab UI has round button controls. In this lesson, use B1 for PC_5.

If a button is active-low, what value should button.read() return when the button is pressed?

2

Measure the button value

20 min

  1. Open the STM32 Mbed CodeIDE lab.

  2. Open main.cpp.

  3. Replace the file with the probe program below.

  4. Save, compile, and upload.

  5. Watch the console panel near the bottom of the lab view. The lab manages the serial connection; use the printed lines, not a separate terminal.

  6. Leave the button released and copy one button_raw line.

  7. Hold B1 until at least one or two new console lines appear, then copy the changed button_raw line.

  8. Record the released and pressed readings before changing the code.

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

#include "mbed.h"

DigitalIn button(PC_5, PullUp);
DigitalOut led(PB_13, 1);

void led_on() {
    led = 0;
}

void led_off() {
    led = 1;
}

int main() {
    printf("Button probe start\n");

    while (true) {
        int raw = button.read();

        if (raw == 0) {
            led_on();
        } else {
            led_off();
        }

        printf("button_raw=%d\n", raw);
        ThisThread::sleep_for(500ms);
    }
}

Record the released and pressed readings separately. Copy the exact button_raw number from the console.

Example serial lines should look like this:

button_raw=1
button_raw=0

With the button released, record:

- button control tested;
- exact button_raw value;
- observed LED state.

With the button pressed, record:

- button control that changed the value;
- exact button_raw value;
- how long you held the control before deciding it changed or did not change;
- observed LED state.

Based on your released and pressed readings, is this button active-low in your lab session? Write yes only if released gave 1 and pressed gave 0; otherwise write what you actually measured.

3

Start a sequence from one press

22 min

Now use B1 to start a three-LED sequence. The program treats button_raw=0 as pressed, matching the released/pressed evidence you just recorded.

Mechanical buttons can bounce: during one press, the electrical signal may rapidly switch between 0 and 1 for a few milliseconds. Debouncing means waiting briefly and checking again so one physical press is not treated as several presses.

The running variable marks that the sequence is active. The program waits 50 ms after the first pressed reading and checks the button again before accepting the press. While run_sequence() is executing, the program is busy running the LED sequence and does not accept new presses. After the LEDs turn off, it waits until the button is released before it accepts another press.

  1. Replace main.cpp with the program below.

  2. Save, compile, and upload.

  3. Press and release B1, and watch the full sequence.

  4. Press the button repeatedly while the sequence is running. Extra presses during the sequence are ignored. To start another sequence, wait until the sequence is complete, release the button, then press again.

  5. Change one delay inside run_sequence(), such as one 500ms delay or the 2000ms hold delay. Do not change the 50ms debounce delay or the 20ms polling/release delays for this test. Save main.cpp, compile, upload again, and compare the result.

  6. Only after step 5 is complete, click Mark practice as done.

#include "mbed.h"

DigitalIn button(PC_5, PullUp);
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);
}

void run_sequence() {
    led_on(led1);
    ThisThread::sleep_for(500ms);
    led_on(led2);
    ThisThread::sleep_for(500ms);
    led_on(led3);
    ThisThread::sleep_for(2000ms);
    all_off();
}

int main() {
    const int pressed_value = 0;
    bool running = false;
    all_off();
    printf("Button sequence start\n");

    while (true) {
        bool pressed = (button.read() == pressed_value);

        if (pressed && !running) {
            ThisThread::sleep_for(50ms);
            if (button.read() != pressed_value) {
                continue;
            }

            running = true;
            printf("press detected: running sequence\n");
            run_sequence();
            printf("sequence complete; release button\n");
            while (button.read() == pressed_value) {
                ThisThread::sleep_for(20ms);
            }
            running = false;
            printf("ready for next press\n");
        }

        ThisThread::sleep_for(20ms);
    }
}

Record three sequence tests. For each test, write the expected behavior before you test, then record the observed LED behavior and serial evidence after you test.

Normal press test:

- expected behavior before testing;
- observed LED behavior;
- serial line or lines that prove the sequence started and completed.

Repeated press while sequence is running:

- expected behavior before testing;
- observed LED behavior;
- serial evidence, such as only one press detected line during the first sequence.

Changed-delay version:

- delay value or code line changed;
- confirm that you changed a visible sequence delay inside run_sequence(), not the 50ms debounce delay or a 20ms polling/release delay;
- expected visible timing difference before testing;
- observed LED timing difference after the upload;
- note that the attached final main.cpp is the evidence for the exact code change.

Why does the program wait 50 ms and then check the button again before accepting a press? What kind of physical button problem is that trying to reduce?

4

Submit your code

8 min

Attach your saved final main.cpp

Click Check saved files, confirm that main.cpp contains your final sequence-on-press program, then click Attach saved code. After the code is attached, click Submit submission at the bottom of the activity.