Teach Lecciones con laboratorios remotos

Lección Teach

STM32 Mbed CodeIDE (3/8): botones, pull-ups y antirrebote

El alumnado lee botones activos en bajo con DigitalIn y PullUp de Mbed, prueba el antirrebote y conecta la evidencia del botón con la salida LED real.

  • STM32 Nucleo (Mbed)
  • 60 min
  • Secundaria (16–19 años)
  • Español
  • Sistemas embebidos
STM32 Nucleo (Mbed)
STM32 Nucleo (Mbed)

Resultados de aprendizaje

  • Leer un pulsador con DigitalIn de Mbed.

  • Verificar si el botón se comporta como activo en bajo en la vista actual del laboratorio.

  • Usar una comprobación simple de antirrebote confirmando después de una espera antes de aceptar una pulsación.

Vista previa de la actividad del estudiante

Contenido de la actividad

Solo vista previa. En una sesión de clase, los estudiantes pueden completar respuestas y entregar su trabajo al docente.

1

Leer antes de reaccionar

10 min

La guía de CodeIDE enumera PC_5, PC_6 y PC_10 entre los pines de botón/sensor disponibles en el laboratorio STM32 WB55RG. Esta lección usa primero PC_5 y te enseña a verificar el valor pulsado antes de construir lógica alrededor de él.

Muchos circuitos de botón usan una resistencia pull-up:

- suelto: lee 1
- pulsado: lee 0

Eso se llama activo en bajo. No lo supongas a ciegas; pruébalo.

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

DigitalIn es el objeto de entrada de Mbed para leer un pin. PullUp pide a Mbed que use la resistencia pull-up interna del microcontrolador, de modo que el pin tenga un valor definido cuando el botón está suelto. button.read() devuelve el valor 0/1 actual en el momento en que tu código lo llama.

La interfaz del laboratorio remoto tiene controles de botón redondos. En esta lección, usa B1 para PC_5.

Si un botón es activo en bajo, ¿qué valor debería devolver button.read() cuando el botón está pulsado?

2

Medir el valor del botón

20 min

  1. Abre el laboratorio STM32 Mbed CodeIDE.

  2. Abre main.cpp.

  3. Reemplaza el archivo con el programa de prueba siguiente.

  4. Guarda, compila y carga.

  5. Observa el panel de consola cerca de la parte inferior de la vista del laboratorio. El laboratorio gestiona la conexión serie; usa las líneas impresas, no una terminal separada.

  6. Deja el botón suelto y copia una línea button_raw.

  7. Mantén pulsado B1 hasta que aparezcan una o dos líneas nuevas de consola, y copia la línea button_raw cambiada.

  8. Registra las lecturas con el botón suelto y pulsado antes de cambiar el código.

  9. Solo después de completar el paso 8, pulsa Marcar práctica como completada.

#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);
    }
}

Registra por separado las lecturas de suelto y pulsado. Copia el número exacto button_raw desde la consola.

Las líneas serie de ejemplo deberían parecerse a estas:

button_raw=1
button_raw=0

Con el botón suelto, registra:

- control de botón probado;
- valor exacto de button_raw;
- estado observado del LED.

Con el botón pulsado, registra:

- control de botón que cambió el valor;
- valor exacto de button_raw;
- cuánto tiempo mantuviste el control antes de decidir si cambió o no cambió;
- estado observado del LED.

Según tus lecturas con el botón suelto y pulsado, ¿este botón es activo en bajo en tu sesión de laboratorio? Escribe solo si suelto dio 1 y pulsado dio 0; si no, escribe lo que mediste realmente.

3

Iniciar una secuencia con una pulsación

22 min

Ahora usa B1 para iniciar una secuencia de tres LED. El programa trata button_raw=0 como pulsado, de acuerdo con la evidencia de suelto/pulsado que acabas de registrar.

Los botones mecánicos pueden rebotar: durante una pulsación, la señal eléctrica puede cambiar rápidamente entre 0 y 1 durante unos milisegundos. El antirrebote consiste en esperar brevemente y comprobar otra vez para que una pulsación física no se trate como varias pulsaciones.

La variable running marca que la secuencia está activa. El programa espera 50 ms después de la primera lectura de pulsado y vuelve a comprobar el botón antes de aceptar la pulsación. Mientras run_sequence() se ejecuta, el programa está ocupado ejecutando la secuencia de LED y no acepta nuevas pulsaciones. Después de que los LED se apagan, espera hasta que el botón se suelte antes de aceptar otra pulsación.

  1. Reemplaza main.cpp con el programa siguiente.

  2. Guarda, compila y carga.

  3. Pulsa y suelta B1, y observa la secuencia completa.

  4. Pulsa el botón varias veces mientras la secuencia está ejecutándose. Las pulsaciones extra durante la secuencia se ignoran. Para iniciar otra secuencia, espera a que termine, suelta el botón y pulsa otra vez.

  5. Cambia un retardo dentro de run_sequence(), por ejemplo un retardo de 500ms o el retardo de mantenimiento de 2000ms. No cambies el retardo antirrebote de 50ms ni los retardos de sondeo/liberación de 20ms para esta prueba. Guarda main.cpp, compila, vuelve a cargar y compara el resultado.

  6. Solo después de completar el paso 5, pulsa Marcar práctica como completada.

#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);
    }
}

Registra tres pruebas de la secuencia. En cada prueba, escribe el comportamiento esperado antes de probar y luego registra el comportamiento observado de los LED y la evidencia serie.

Prueba de pulsación normal:

- comportamiento esperado antes de probar;
- comportamiento observado de los LED;
- línea o líneas serie que demuestran que la secuencia empezó y terminó.

Pulsación repetida mientras la secuencia está ejecutándose:

- comportamiento esperado antes de probar;
- comportamiento observado de los LED;
- evidencia serie, por ejemplo solo una línea press detected durante la primera secuencia.

Versión con retardo cambiado:

- valor de retardo o línea de código cambiada;
- confirma que cambiaste un retardo visible de secuencia dentro de run_sequence(), no el retardo antirrebote de 50ms ni un retardo de sondeo/liberación de 20ms;
- diferencia de temporización visible esperada antes de probar;
- diferencia de temporización observada después de la carga;
- anota que el main.cpp final adjunto es la evidencia del cambio exacto de código.

¿Por qué el programa espera 50 ms y luego comprueba otra vez el botón antes de aceptar una pulsación? ¿Qué problema físico de los botones intenta reducir?

4

Enviar tu código

8 min

Adjunta tu main.cpp final guardado

Pulsa Comprobar archivos guardados, confirma que main.cpp contiene tu programa final de secuencia por pulsación y luego pulsa Adjuntar código guardado. Después de adjuntar el código, pulsa Enviar entrega al final de la actividad.