Teach Remote lab lessons

Teach lesson

STM32 Mbed CodeIDE (7/8): servo position control

Students control a servo with Mbed PWM pulse widths, test positions safely, and record approximate movement evidence from the remote STM32 setup.

  • STM32 Nucleo (Mbed)
  • 60 min
  • Upper secondary / introductory vocational electronics
  • English
  • Embedded systems
Signal path from potentiometer pot2 on PC1 through AnalogIn values from 0.0 to 1.0 and pulse_us values from 700 to 2300 to the servo output on PA15.
STM32 Nucleo (Mbed)

Learning Outcomes

  • Control a servo output with Mbed PwmOut.

  • Map a potentiometer reading to an approximate angle.

  • Use serial evidence to support an observation that may be hard to judge visually.

Student activity preview

Activity Content

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

1

Servo pulse width basics

10 min

Some outputs should move, not only light up. Servos are used when a controller needs to point, open, steer, latch, or position something in a repeatable way. In this lesson, you will connect the servo position command to a potentiometer reading.

PWM for an LED changes average brightness. A servo also uses repeated pulses, but the important value is the pulse width:

- about 700 microseconds: one broad side of travel
- about 1500 microseconds: middle
- about 2300 microseconds: the other broad side of travel

In Mbed, the servo signal is produced with PwmOut. servo.period_ms(20) sets the usual 20 ms repetition period, and servo.pulsewidth_us(...) changes the high-pulse width that the servo interprets as position.

The exact mechanical angle can vary. This lesson deliberately stays inside the conservative 700-2300 us exercise range, which is inside the wider range already exercised on this remote setup. Do not command values outside 700-2300 us. If the arm chatters continuously, appears to press against a hard stop, or does not settle after a move, end the run and tell your instructor instead of widening the range.

Your job is to show a controlled relationship: low potentiometer value gives one broad position, high value gives a different position, and the serial output matches your mapping.

The camera may show the servo only as a small arm on the training board. Treat angle as an estimate calculated by your code. The strongest evidence is the combination of serial pulse_us, serial angle estimate, and a visible change in broad servo position.

Pin and evidence checklist for this lesson:

- Servo signal output: PA_15
- Potentiometer used later: Pot. pot2 -> PC_1
- Required serial evidence: pulse_us
- Camera evidence: broad servo position change, not a precise measured angle

From the potentiometer to a servo pulse

Signal path from potentiometer pot2 on PC1 through AnalogIn values from 0.0 to 1.0 and pulse_us values from 700 to 2300 to the servo output on PA15.

Use the camera for broad position evidence and the console for exact
pulse_us evidence. The diagram shows the command path, not a precise angle.

If your code maps a low potentiometer value to 700 microseconds and a high value to 2300 microseconds, what should happen as you turn the potentiometer from low to high?

2

Run a three-position test

20 min

  1. Open the STM32 Mbed CodeIDE lab.

  2. Open main.cpp.

  3. Replace the file with the program below.

  4. Save, compile, and upload.

  5. Watch the camera and console together.

  6. Watch for three broad servo positions.

  7. Record the serial pulse widths and what you observed.

#include "mbed.h"

PwmOut servo(PA_15);

void set_servo_us(int pulse_us) {
    servo.pulsewidth_us(pulse_us);
}

int main() {
    servo.period_ms(20);
    printf("Servo three-position test start\n");

    while (true) {
        set_servo_us(700);
        printf("pulse_us=700 position=low\n");
        ThisThread::sleep_for(2000ms);

        set_servo_us(1500);
        printf("pulse_us=1500 position=middle\n");
        ThisThread::sleep_for(2000ms);

        set_servo_us(2300);
        printf("pulse_us=2300 position=high\n");
        ThisThread::sleep_for(2000ms);
    }
}

Fill three rows, one for each fixed pulse width: 700 us, 1500 us, and 2300 us. Pulse width is a number in microseconds (us); Printed position is the exact console label; and Observed motion or position is only a broad camera description. If motion is unclear, choose unclear and describe what you could see instead of inventing a precise angle. Leave extra unused rows completely blank.

Fixed servo pulse-width table

Complete 700 us, 1500 us, and 2300 us rows. Leave extra unused rows blank.

Pulse width us Printed position Observed motion or position Confidence
3

Map potentiometer to servo angle

22 min

Now map AnalogIn PC_1 to an approximate angle and pulse width. Use the Pot. pot2 slider for PC_1.

  1. Replace main.cpp with the program below.

  2. Complete TODO 1 to map a reading from 0.0-1.0 to 700-2300 microseconds.

  3. Complete TODO 2 so the mapped pulse width is written to the servo.

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

  5. Move the Pot. pot2 slider to low, middle, and high positions.

  6. Record the printed percent, estimated angle, pulse width, and observed motion.

#include "mbed.h"

AnalogIn pot(PC_1);
PwmOut servo(PA_15);

int main() {
    servo.period_ms(20);
    printf("Potentiometer servo control start\n");

    while (true) {
        float reading = pot.read();
        int percent = (int)(reading * 100.0f);
        int angle = (int)(reading * 180.0f);
        // TODO 1: replace 700 with the full 700-2300 us mapping.
        int pulse_us = 700;

        // TODO 2: replace 700 with the mapped pulse_us variable.
        servo.pulsewidth_us(700);

        printf("percent=%d angle=%d pulse_us=%d\n",
               percent,
               angle,
               pulse_us);
        ThisThread::sleep_for(500ms);
    }
}

Fill the three required cases: low, middle, and high potentiometer positions. Serial percent has unit %; Serial angle estimate is a calculated estimate in degrees, not a camera measurement; Serial pulse width is in microseconds (us); and the camera field records only broad position. Leave any extra unused rows completely blank.

Potentiometer-to-servo evidence table

Complete low, middle, and high rows with console values and broad camera evidence. Leave extra unused rows blank.

Potentiometer position Serial percent % Serial angle estimate degrees Serial pulse width us Observed servo position

Use your low, middle, and high rows to explain whether the potentiometer controlled the servo as expected. Include the serial pulse_us trend and the broad camera observation.

4

Submit your code

8 min

Attach your saved final main.cpp

Click Check saved files, confirm that main.cpp contains the potentiometer-controlled servo version, then click Attach saved code. After the code is attached, click Submit submission at the bottom of the activity.