Interrupção externa no Arduino com attachInterrupt()

Olá pessoal, tudo certo? no artigo de hoje vamos aprender a ler entradas digitais do Arduino (botões, etc) sem interromper nosso código por muito tempo, através de interrupção externa. Utilizaremos a função attachInterrupt().

   Existem pelo menos três formas de se fazer exatamente a mesma coisa (ler botões) utilizando Arduino (e qualquer microcontrolador):

  • Utilizando a função delay() e literalmente parando o programa para esperar o botão ser pressionado,
  • Utilizando um código pseudo-interrompível através das funções micros() ou millis(); já escrevi sobre esta forma neste link,
  • Através de interrupções externas de hardware.

   Das três formas acima citadas, as interrupções são a forma mais segura de controlar tarefas em qualquer sistema, pois o programa não é parado e as suas diferentes partes tornam-se independentes.

   Neste artigo vou implementar a função attachinterrupt(), disponível originalmente na página oficial do Arduino; utilizaremos um Arduino UNO, um botão e um LED (pino 13 do Arduino) para demonstrar o conceito. O diagrama esquemático do experimento está na imagem abaixo:

Fonte: o autor. Feito em TinkerCAD

   Observer que a chave (botão) não está sozinha no protoboard; isto porque adicionei um circuito RC série, afim de executar o debounce da chave. Já falei bastante sobre debounce de chaves neste artigo, mas aí vai uma rápida explicação: nenhum contato seco (chave) vai do estado “desligado” para “ligado” instantaneamente.

   Sempre há uma incerteza por alguns milésimos de segundo, então se o microcontrolador ler a chave neste exato momento pode interpretar um ligado como desligado e vice-versa.

O circuito RC proposto serve para atrasar e estabilizar a forma de onda da tensão. Consequentemente possibilita mais certeza na leitura do estado pelo microcontrolador.

O código

   O código que vamos implementar tem a função de alterar o estado do LED (ligado ou desligado) a cada vez que pressionamos o botão na protoboard. Pressionando uma vez ligamos o LED e pressionando o botão novamente desligamos o LED.

Abaixo está disponível o código completo para este teste, adaptado do original disponível no site do Arduino.

// Exemplo retirado da documentação oficial do Arduino,
// https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
//
 
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
 
void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);
}
 
void loop() {
  digitalWrite(ledPin, state);
}
 
void blink() {
  state = !state;
}

O código funciona da seguinte maneira:

  • Utilizamos o LED disponível no pino 13 da placa do Arduino e um botão (chave) conectado ao pino 2 (uma das duas portas do Arduino UNO que aceita interrupções).
  • A função attachInterrupt fica dentro do setup() do sketch, aguardando uma mudança de estado no interruptPin – RISING que dizer na subida do sinal de 0 para 5V.
  • Ao detectar esta subida de sinal (pressionar do botão) a função blink() é acionada; ela contém apenas um mudança de estado, state = !state. O estado anterior sempre é diferente do atual (operador ! no arduino).
  • Dentro do loop() do programa fica apenas a função digitalWrite, que aplica ao ledPin (pino 13) o estado recebido na variável state. Portanto você pode executar qualquer outro código dentro do loop(), pois a única coisa a mais sendo executada ali é o digitarWrite().

Abaixo deixo um vídeo do teste funcionando:

Vejam que ao pressionar o botão o LED é ligado, pressionando novamente é desligado. Veja que é uma aplicação simples, mas já dá pra ter uma ideia do funcionamento da função.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *