Teach lesson
STM32 Mbed CodeIDE (3/8): botões, pull-ups e antirrebote
Os estudantes leem botões ativos em nível baixo com Mbed DigitalIn e PullUp, testam o antirrebote e relacionam as evidências do botão à saída de LEDs em uma placa STM32 real.
New to LabsLand? Create your teacher account
Learning Outcomes
Ler um botão com Mbed
DigitalIn.Verificar se o botão se comporta como ativo em nível baixo na sessão atual.
Usar uma segunda leitura após uma breve espera antes de aceitar um pressionamento.
Student activity preview
Activity Content
Preview only. In a class session, students can fill in responses and submit their work to the teacher.
Leia antes de reagir
10 min
As entradas transformam um padrão fixo de luz em um controlador que responde a uma pessoa, chave ou sensor. Primeiro você medirá o valor do botão quando ele está solto e pressionado; depois acrescentará uma verificação simples de antirrebote para que o programa reaja a um toque real, não ao ruído do contato.
O guia CodeIDE lista PC_5, PC_6 e PC_10 entre os pinos de botão/sensor disponíveis no laboratório STM32 WB55RG. Esta lição usa PC_5 primeiro e ensina você a verificar o valor pressionado antes de construir lógica em torno dele.
Muitos circuitos de botão pull-up são ativo-baixo, o que significa que o nível elétrico pressionado é inferior ao nível liberado. A fiação do laboratório ainda deve ser medida antes de você colocar qualquer valor na lógica de controle.
DigitalIn button(PC_5, PullUp);
int raw = button.read();
DigitalIn é o objeto de entrada Mbed para leitura de um pino. PullUp pede a Mbed para usar o resistor pull-up interno do microcontrolador, para que o pino tenha um valor definido quando o botão for liberado. button.read() retorna o valor 0/1 atual no momento em que seu código o chama.
A IU do laboratório remoto possui controles de botão redondo. Nesta lição, use B1 para PC_5.
Uma verificação simples de antirrebote usa duas leituras
Qual valor deverá se tornar pressed_value posteriormente em seu programa de sequência?
Meça o valor do botão
20 min
Planeje três compilações e cerca de 25 minutos de laboratório ativo: medição do botão, sequência e sequência com intervalo alterado. Se estiver na fila, prepare os dois campos de observação e leia os TODOs 1–2 antes do início da sessão.
Abra o laboratório STM32 Mbed CodeIDE.
Abra
main.cpp.Substitua o arquivo pelo programa de análise abaixo.
Salve, compile a compilação 1 e faça upload.
Observe o painel do console próximo à parte inferior da visualização do laboratório. O laboratório gerencia a conexão serial; use as linhas impressas, não um terminal separado.
Deixe o botão liberado e copie uma linha
button_raw.Segure
B1até que pelo menos uma ou duas novas linhas de console apareçam e, em seguida, copie a linhabutton_rawalterada.Registre as leituras liberadas e pressionadas antes de alterar o código.
Somente após a conclusão da etapa 8, clique em Marcar prática como concluída.
#include "mbed.h"
DigitalIn button(PC_5, PullUp);
int main() {
printf("Button probe start\n");
while (true) {
int raw = button.read();
printf("button_raw=%d\n", raw);
ThisThread::sleep_for(500ms);
}
}
Registre as leituras liberadas e pressionadas separadamente. Copie o número button_raw exato do console.
Suas linhas seriais copiadas devem usar valores observados, não valores fornecidos pela lição:
button_raw=<valor observado com o botão solto>
button_raw=<valor observado com o botão pressionado>Com o botão liberado, escreva uma linha neste formato:
Controle testado: B1 | button_raw=...
Substitua os pontos pelo valor exato copiado do console.
Com B1 pressionado, escreva uma linha neste formato:
Controle: B1 | button_raw=... | mantido por: ... s | mudou?: sim/não
Use o valor exato do console e o tempo que você manteve pressionado o botão antes de decidir
se a leitura mudou.
Escreva seu resultado como: solto=<valor observado>, pressionado=<valor observado>. Em seguida, indique se o valor pressionado é inferior ao valor liberado e, portanto, ativo-baixo nesta sessão.
Inicie uma sequência com um toque
22 min
Agora use B1 para iniciar uma sequência de três LEDs. Você inserirá o valor medido com o botão pressionado, em vez de copiar um valor presumido.
Os botões mecânicos podem apresentar rebote: durante um único toque, o sinal elétrico pode alternar rapidamente entre 0 e 1 por alguns milissegundos. O antirrebote consiste em esperar brevemente e verificar novamente para que um toque físico não seja tratado como vários.
Três proteções têm tarefas diferentes:
- Confirmação antirrebote: espere 50 ms, leia novamente e aceite apenas se a segunda amostra ainda for igual ao valor observado com o botão pressionado.
- Bloqueio durante a sequência: run_sequence() é bloqueante; a entrada não é amostrada enquanto a sequência de LEDs é executada. Isso evita um segundo início durante a sequência, mas não é antirrebote.
- Rearme após soltar: depois da sequência, espere até a entrada ser diferente do valor pressionado antes de aceitar outro toque. Isso impede que um botão mantido pressionado reinicie a sequência imediatamente; também não é antirrebote.
O código inicial contém exatamente dois marcadores que impedem a compilação. O TODO 1 usa o valor medido com o botão pressionado. O TODO 2 deve rejeitar de fato uma segunda amostra diferente. Substitua ambos e procure por TODO antes de compilar.
Substitua
main.cpppelo programa abaixo e conclua os TODOs 1-2 a partir da evidência da sua sonda.Procure
TODO. Quando não restar nenhum, salve, compile a compilação 2 e faça upload.Pressione e solte
B1e assista à sequência completa.Pressione o botão repetidamente enquanto a sequência está em execução. Pressões extras durante a sequência são ignoradas. Para iniciar outra sequência, espere até que a sequência seja concluída, solte o botão e pressione novamente.
Altere uma espera visível dentro de
run_sequence()de500mspara1000ms. Não altere a espera antirrebote de50msnem a espera de consulta após soltar de20ms. Salve, compile a compilação 3, faça upload e compare.Somente após a conclusão da etapa 5, clique em Marcar prática como concluída.
#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() {
// 1: substitua pelo valor exato pressionado observado no teste.
const int pressed_value = TODO_PRESSED_VALUE;
all_off();
printf("Button sequence start\n");
while (true) {
bool pressed = (button.read() == pressed_value);
if (pressed) {
ThisThread::sleep_for(50ms);
// 2: rejeitar a prensa se a segunda amostra não for prensada.
if (TODO_CONFIRM_CONDITION) {
continue;
}
printf("press detected: running sequence\n");
run_sequence();
printf("sequence complete; release button\n");
while (button.read() == pressed_value) {
ThisThread::sleep_for(20ms);
}
printf("ready for next press\n");
}
ThisThread::sleep_for(20ms);
}
}
Registre três verificações de sequência curta. Mantenha a previsão e as evidências separadas.
Teste de pressão normal:
- número previsto de inícios de sequência: um;
- observou a ordem LED;
- linha serial que comprove o início e a conclusão.
Pressionar repetidamente enquanto a sequência está em execução:
- número previsto de partidas antes de ready for next press;
- observou o número de linhas press detected antes de ready for next press.
Sequência com intervalo alterado:
- intervalo alterado, em milissegundos;
- linha ou linhas seriais;
- previu diferença visível;
- diferença visível observada após a compilação 3.
Qual instrução separa corretamente o debounce do bloqueio de sequência?
Envie seu código
8 min
Anexe seu main.cpp final salvo
Clique em Verificar arquivos salvos, confirme se main.cpp contém o valor pressionado observado, a condição da segunda amostra, a alteração da sequência 1000ms testada e nenhum TODO. Depois anexe e envie.