Menu
CoddyTech

Contar pressionamentos com interrupção

Parte da seção Temporização sem delay do Journey de Arduino da Coddy. Lição 15 de 18.

Como você viu na seção Entradas, os botões oscilam: por cerca de um milissegundo, os contatos se tocam, se separam e se tocam novamente, tanto ao pressionar quanto ao soltar. Uma interrupção detecta cada toque, então uma ISR FALLING que adiciona 1 conta um clique várias vezes.

Uma ISR não pode eliminar a oscilação com delay(): delay() precisa da própria interrupção do relógio, e as interrupções ficam pausadas enquanto uma ISR está em execução. Use o relógio em vez disso. Lembre-se de quando ocorreu o último pressionamento contado e ignore qualquer borda de descida que aconteça logo em seguida:

unsigned long lastPress = 0;

void onPress() {
  unsigned long now = millis();
  if (now - lastPress >= 200) {
    presses = presses + 1;
    lastPress = now;
  }
}

Ler millis() em uma ISR não tem problema: ele fornece o horário em que a ISR começou. Escolha uma janela maior do que a duração de um clique, para que as oscilações ao soltar ocorram dentro dela, e menor do que o intervalo entre dois cliques rápidos. 200 ms funciona bem para as pessoas.

challenge icon

Desafio

Médio

Este contador contabiliza cada clique várias vezes. Aplique o debounce dentro de onPress():

  • adicione uma variável unsigned long lastPress
  • conte uma borda de descida somente se tiverem passado pelo menos 200 ms desde lastPress e, em seguida, armazene o horário em lastPress

Pressione Executar, clique no botão algumas vezes e observe a contagem; depois, Verificar.

Experimente você mesmo

const int buttonPin = 2;

volatile int presses = 0;
int shown = 0;

void onPress() {
  // cada transição de nível alto para baixo do pino conta, inclusive as oscilações do contato: faça o debounce aqui
  presses = presses + 1;
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);
}

void loop() {
  // imprima a contagem sempre que ela mudar
  if (presses != shown) {
    shown = presses;
    Serial.println(shown);
  }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Temporização sem delay

Pratique por conta própria: Playground de Arduino