attachInterrupt()

[Interrupções Externas]

Descrição

Pinos Digitais com Interrupções

O primeiro parâmetro de attachInterrupt() é o número da interrupção. É recomendado usar digitalPinToInterrupt(pino) para converter o número do pino digital para o número específico da interrupção. Por exemplo, se você usar o pino 3, passe digitalPinToInterrupt(3) como o primeiro parâmetro de attachInterrupt().

Placa Pinos digitais possíveis para interrupções

Uno, Nano, Mini e outros com 328p

2, 3

Uno WiFi Rev.2

todos os pinos digitais

Mega, Mega2560, MegaADK

2, 3, 18, 19, 20, 21

Micro, Leonardo e outros com 32u4

0, 1, 2, 3, 7

Zero

todos os pinos digitais, exceto 4

Família MKR

0, 1, 4, 5, 6, 7, 8, 9, A1, A2

Due

todos os pinos digitais

101

todos os pinos digitais (Apenas pinos 2, 5, 7, 8, 10, 11, 12, 13 funcionam com CHANGE)

Para as placas Uno WiFiRev.2, Due, Zero, Família MKR e 101, número da interrupção = número do pino.

Notas e Advertências

Nota
Dentro da função associada, delay() não funcionará e o valor retornado por millis() não será incrementado. Dados recebidos na porta serial enquanto a interrupção é executada podem ser perdidos. Você deve declarar como volatile quaisquer que você modificar dentro da função associada. Veja a seção sobre ISRs abaixo para mais informação.

Usando Interrupções

Interrupções são úteis para fazer coisas automaticamente em programas de microcontroladores, e podem ajudar a resolver problemas de temporização. Boas tarefas para se udar uma interrupção podem icnluir a leitura de um codificador rotativo, ou monitorar entradas de dados pelo usuário.

Supomos que você quisesse ter certeza que um programa sempre captura os pulsos de um codifcador rotativo, sem nunca perder um pulso, seria muito complicado criar um programa que pudesse fazer qualquer outra coisa além disso, porque o programa precisaria checar constantemente os pinos do codificador, para capturar os pulsos exatamente quando eles ocorreram. Outros sensores são similarmente dinâmicos também, como um sensor de som que pode ser usado para capturar um clique, ou um sensor infravermelho (foto-interruptor) para capturar a queda de uma moeda. Em todas essas situações, usar uma interrupção pode permitir o microcontrolador trabalhar em outras tarefas sem perder a interrupção.

Sobre Rotinas de Serviço de Interrupções (ISRs)

ISRs são tipos especiais de funções que possuem algumas limitações únicas que as outras funções não possuem. Uma ISR não recebe argumentos, e não devem retornar nada.

Geralmente, uma ISR deve ser o mais curta e rápida possível. Se o seu sketch usa múltiplas ISRs, apenas uma pode ser executada de cada vez, outras interrupções serão executadas após a atual terminar, em uma ordem que depende de sua prioridade. millis() depende de interrupções para contar, então essa nunca irá incrementar dentro de uma ISR. Como delay() também depende de interrupções, não irá funcionar dentro de uma ISR. micros() funciona inicialmente, mas começará a se comportar erraticamente após 1-2 ms. delayMicroseconds() não usa nenhum contador, então funciona normalmente.

Tipicamente variáveis globais são usadas para passar dados entre uma ISR e o programa principal. Tenha certeza que variáveis compartilhadas entre uma ISR e o programa principal são atualizadas corretamente, para isso, as declare usando o modificador volatile.

Para mais informações sobre interrupções, veja as notas de Nick Gammon’s (Em Inglês).

Sintaxe

attachInterrupt(digitalPinToInterrupt(pino), ISR, modo); (Recomendado)
attachInterrupt(interrupção, ISR, modo); (Não recomendado)
attachInterrupt(pino, ISR, modo); (Não recomendado. Além disso, essa sintaxe só funciona em placas Arduino SAMD, Uno WiFi Rev2, Due, e 101)

Parâmetros

interrupção: o número da interrupção (int)
pino: o número do pino
ISR: a ISR a ser chamada quando a interrupção ocorre; essa função deve não tomar nenhum parâmetro nem retornar nada. Essa função é chamada de rotina de serviço da interrupção ou ISR (do Inglês, interrupt service routine).
modo: define quando a interrupção deve ser ativada. Quatro constantes estão predefinidas como valores válidos:

  • LOW acionar a interrupção quando o estado do pino for LOW,

  • CHANGE acionar a interrupção quando o sempre estado do pino mudar

  • RISING acionar a interrupção quando o estado do pino for de LOW para HIGH apenas,

  • FALLING acionar a interrupção quando o estado do pino for de HIGH para LOW apenas.

Placas Due, Zero e MKR1000 suportam também:

  • HIGH acionar a interrupção quando o estado do pino for HIGH.

Retorna

Nada

Código de Exemplo

O código abaixo usa uma interrupção para capturar a mudança no estado do pino 2 e acender o LED de acordo.

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, CHANGE);
}

void loop() {
  digitalWrite(ledPin, state);
}

void blink() {
  state = !state;
}

Números das Interrupções

Normalmente você deve usar digitalPinToInterrupt(pino), em vez de colocar diretamente o número da interrupção no seu sketch. Os pinos específicos para interrupções, e seu mapeamento para o número da interrupção variam para cada tipo de placa. O uso direto dos números das interrupções pode parecer mais simples, porém pode causar problemas de compatibilidade quando seu sketch for executado em uma placa diferente.

Mesmo assim, sketches mais antigos frequentemente têm os números das interrupções usados diretamente. Frequentemente o número 0 (para o pino digital 2) ou o número 1 (para o pino digital 3) foram usados. A tabela abaixo mostra os pinos com interrupções disponíveis em cada placa.

Note que na tabela abaixo, os números das interrupções se referem aos números a serem passados para attachInterrupt(). Por razões históricas, essa numeração nem sempre corresponde diretamente a numeração do chip ATmega (ex. int.0 corresponde à INT4 no chip ATmega2560).

Placa int.0 int.1 int.2 int.3 int.4 int.5

Uno, Ethernet

2

3

Mega2560

2

3

21

20

19

18

Leonardo, Micro (32u4)

3

2

0

1

7

Para as placas Due, Zero, MKR1000 e 101 o número da interrupção = número do pino.

Ver Também