Teach Remote lab lessons

Teach lesson

STM32 Mbed CodeIDE (8/8): integrated controller capstone

Students combine analog input, button acknowledgement, RGB/status LED output, and serial evidence to build a small integrated STM32 controller.

  • STM32 Nucleo (Mbed)
  • 65 min
  • Upper secondary / introductory vocational electronics
  • English
  • Embedded systems
Controller architecture with potentiometer pot2 on PC1 and button B1 on PC5 as inputs, leading to a controller that drives RGB PWM on PA8 to PA10, the status LED on PB13, and serial evidence.
STM32 Nucleo (Mbed)

Learning Outcomes

  • Combine analog input, button input, RGB PWM output, a status LED, and serial evidence in one controller.

  • Use a test matrix to prove controller behavior one state at a time.

  • Explain how code, serial output, and visible lab evidence support a controller claim.

Student activity preview

Activity Content

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

1

Controller requirements

12 min

Embedded systems become useful when several small skills work together: read a level, decide what state it belongs to, show a visible warning, and print enough evidence to trust the result.

The controller uses one potentiometer as simulated receiver pressure and one button as an alarm acknowledge control. In a real installation, a calibrated pressure transmitter and safety-rated protection would be required; this training controller only practices indication and acknowledgement logic.

Hardware map used by the starter controller:

- PC_1 is the simulated pressure input, controlled by the Pot. pot2 slider.
- PC_5 is the acknowledge button input, controlled by the B1 button.
- PA_8, PA_9, and PA_10 are the RGB PWM channels.
- PB_13 is the active-low green status LED.

Inputs, controller, and evidence outputs

Controller architecture with potentiometer pot2 on PC1 and button B1 on PC5 as inputs, leading to a controller that drives RGB PWM on PA8 to PA10, the status LED on PB13, and serial evidence.

Read this map as a set of Mbed objects working together: AnalogIn reads the level, DigitalIn reads the acknowledge button, PwmOut drives the RGB channels, and DigitalOut drives the status LED. The capstone is mainly about connecting those API pieces into one readable controller.

The required behavior is:

- Level below 40%: RGB output green, status LED off, serial evidence like
percent=25 level=SAFE ack=0.
- Level from 40% to 69%: RGB output yellow, status LED off, serial evidence like
percent=55 level=WARNING ack=0.
- Level 70% or higher with the button released: RGB output red, status LED
blinking, serial evidence like percent=80 level=CRITICAL ack=0. Watch
for at least two seconds before recording this state; count it as blinking
only if the status LED turns on and off repeatedly.
- Level 70% or higher after the button has been pressed once: RGB output blue,
status LED off, serial evidence like percent=80 level=CRITICAL ack=1.
Releasing the button does not remove the acknowledgement while the level
remains critical.

The acknowledge button does not reduce pressure or make a critical condition safe. It latches only the local indication so the operator can show that the alarm has been noticed; level=CRITICAL must remain in the serial evidence. The latch clears automatically after the simulated pressure falls below the critical threshold.

Start both cases with the latch clear, then press the button. Answer in this
format:

1. 69% | level=... | ack=...
2. 70% | level=... | ack=...
3. Explanation: ...

In the explanation, state why equality at 70% changes both the branch and
whether acknowledgement can latch.

2

Run the starter controller

30 min

  1. Open the STM32 Mbed CodeIDE lab.

  2. Open main.cpp.

  3. Replace the file with the controller below.

  4. Complete TODO 1 with the active-low button expression and TODO 2 with the warning-range threshold decision.

  5. Before compiling or observing the board, fill the four Expected response cells in the test table from the requirements above.

  6. Save, compile, and upload. This is planned build 1 of 2.

  7. Use Pot. pot2 to set safe, warning, and critical pressure levels.

  8. In the critical level, first leave the button released for two seconds. Then press and release it; verify that ack=1 remains for at least two later serial lines.

  9. Record one row per state, including the full serial line.

  10. Lower the level below 70% and verify that the latch resets to ack=0 before finishing.

#include "mbed.h"

AnalogIn level_control(PC_1);
DigitalIn acknowledge_button(PC_5, PullUp);

PwmOut rgb_red(PA_8);
PwmOut rgb_green(PA_9);
PwmOut rgb_blue(PA_10);

DigitalOut status_led(PB_13, 1);

constexpr int warning_threshold_percent = 40;
constexpr int critical_threshold_percent = 70;

void status_on() {
    status_led = 0;
}

void status_off() {
    status_led = 1;
}

void set_rgb(float red, float green, float blue) {
    rgb_red.write(red);
    rgb_green.write(green);
    rgb_blue.write(blue);
}

void show_safe() {
    set_rgb(0.0f, 0.7f, 0.0f);
    status_off();
}

void show_warning() {
    set_rgb(0.7f, 0.5f, 0.0f);
    status_off();
}

void show_critical(bool acknowledged) {
    if (acknowledged) {
        set_rgb(0.0f, 0.0f, 0.8f);
        status_off();
    } else {
        set_rgb(0.9f, 0.0f, 0.0f);
        status_led = !status_led.read();
    }
}

int main() {
    rgb_red.period_ms(2);
    rgb_green.period_ms(2);
    rgb_blue.period_ms(2);

    printf("Integrated controller start\n");

    bool acknowledged = false;

    while (true) {
        float reading = level_control.read();
        int percent = (int)(reading * 100.0f);
        // TODO 1: replace false with the active-low button expression.
        bool button_pressed = false;

        if (percent < critical_threshold_percent) {
            acknowledged = false;
        } else if (button_pressed) {
            acknowledged = true;
        }

        if (percent < warning_threshold_percent) {
            show_safe();
            printf("percent=%d level=SAFE ack=%d\n",
                   percent,
                   acknowledged);
        // TODO 2: replace false with the WARNING-range threshold test.
        } else if (false) {
            show_warning();
            printf("percent=%d level=WARNING ack=%d\n",
                   percent,
                   acknowledged);
        } else {
            show_critical(acknowledged);
            printf("percent=%d level=CRITICAL ack=%d\n",
                   percent,
                   acknowledged);
        }

        ThisThread::sleep_for(500ms);
    }
}

Prepare and then fill the table in two passes. Before the build, select each Test case, choose the planned button action, and write its Expected response as RGB color plus status-LED behavior. During the live test, enter the actual integer pressure percentage, visible response, and full serial line. Percent is a simulated transmitter percentage, not pressure in bar. For critical-unacknowledged, write blinking only after at least two seconds. For critical-acknowledged, press and release the button and record a later line showing that ack=1 persisted. Leave extra unused rows completely blank.

Four-state controller test table

Before testing, fill expected responses for all four states. During testing, add actual inputs, visible response, and full serial evidence. Leave extra unused rows blank.

Test case Actual pressure input % Button action Expected response Observed visible response Serial evidence

After acknowledging the critical state, copy one complete line printed after releasing B1 that still shows level=CRITICAL ack=1. Then lower the level below 70% and copy the first complete line that shows ack=0. State how the two lines prove the latch and its reset condition.

Choose your strongest test row. Quote the input state and serial line from that row, then explain how the RGB output and status LED matched the requirement.

3

Improve the controller

15 min

The controller above is a starting point. Choose one improvement, implement it in main.cpp, then save, compile, upload, and test it on the receiver-alarm scenario. A plan without running code is not enough.

Choose one bounded improvement:

- Threshold route: change only critical_threshold_percent to a value from
72% to 80%. Choose one fixed test value between 70% and your new threshold,
so the same input changes branch after your edit.
- Very-high route: add a VERY_HIGH branch for values of 90% or more,
immediately before the ordinary critical branch. Give it a magenta RGB
indication, a steady-on status LED, and level=VERY_HIGH serial evidence.
Use 95% with the button released for the before/after test, then check 80%
once to confirm that ordinary critical behavior still works.

Before editing, answer with these lines:

1. Chosen route: threshold / very high
2. Exact code location I will change: ...
3. Input and button action I will repeat before and after: ...
4. For the very-high route only: 80% regression check: ...

Use the matching starter-controller row as your before evidence. Implement the change, save, compile, and upload; this is planned build 2 of 2. Test the same input/button action again for after evidence. Record a complete serial line and visible RGB/status behavior for both versions. If you chose the very-high route, run the additional 80% regression check and report it in the final explanation.

Before-and-after improvement evidence

Use the same controlled input for before and after. Leave extra unused rows blank.

Version Controlled pressure input % Controlled button state Build/upload status Full serial line Visible RGB/status result

State the exact code change, then compare the before and after serial lines and visible results. Say whether the evidence confirmed the intended improvement. For the very-high route, also report whether the 80% regression check still produced ordinary critical behavior.

4

Submit your code

8 min

Attach your saved final main.cpp

Click Check saved files, confirm that main.cpp contains the final controller you tested, then click Attach saved code. After the code is attached, click Submit submission at the bottom of the activity.