attachInterrupt()
attachInterrupt(digitalPinToInterrupt(pino), funcao, modo)
Imagine que você precisa reagir na hora em que um botão é pressionado ou um sensor dispara, mas seu loop() está ocupado com outras coisas. A interrupção resolve isso: você pede pro Arduino "largar tudo" e rodar uma função sua no exato instante em que um pino muda de estado. É como um alarme que interrompe qualquer tarefa pra te avisar.
Sintaxe
attachInterrupt(digitalPinToInterrupt(pino), funcao, modo);
Parâmetros
- pino: o pino que vai ser monitorado. No Uno, só os pinos 2 e 3 aceitam interrupção. Sempre embrulhe com
digitalPinToInterrupt(pino)— é o jeito portátil e correto. - funcao: o nome da sua função que será chamada (a chamada ISR — Interrupt Service Routine). Ela não recebe argumentos nem retorna nada.
- modo: quando disparar —
RISING(subida de LOW pra HIGH),FALLING(descida de HIGH pra LOW),CHANGE(qualquer mudança) ouLOW(enquanto o pino estiver em LOW).
Retorno
Nada (void).
Exemplo
const byte pinoBotao = 2;
volatile int contador = 0;
void contar() {
contador++;
}
void setup() {
Serial.begin(9600);
pinMode(pinoBotao, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(pinoBotao), contar, FALLING);
}
void loop() {
Serial.println(contador);
delay(500);
}
Notas e cuidados
- No Uno, apenas os pinos 2 e 3 têm interrupção externa. No ESP32, quase todos os GPIOs servem (lembre que ele é 3,3 V — nunca aplique 5 V num pino dele).
- A função da interrupção precisa ser curta e rápida: evite
delay(),Serial.print()pesado e cálculos longos. Dentro dela omillis()não avança e odelay()nunca termina, porque ambos dependem de interrupções. - Qualquer variável compartilhada entre a ISR e o
loop()deve ser declarada comovolatile, senão o compilador pode "esquecer" de atualizá-la.