Realizando Interrupções no Arduino
Olá tudo bem? Preparado para interromper seu Arduino hoje? Porque hoje estaremos realizando interrupções no arduino. O que da inicio ao nosso estudo sobre programação em Arduino. Isso porque, para qualquer projeto que você for desenvolver, o conhecimento sobre programação deve ser o mais elevado possível.
Por este motivo, hoje iremos começar estudando sobre as interrupções no Arduino. Quer saber como realizar interrupções em seu código? Então me acompanhe!
Realizar interrupções no Arduino
Certamente, a ideia de utilizar uma interrupção no código vem do fato de que em determinados projetos, será preciso realizar duas ou mais tarefas ao mesmo tempo. Um exemplo disso é quando você está executando o seu programa, mas se por acaso algum sensor for acionado (um infravermelho talvez), o seu programa para totalmente e realiza uma outra tarefa automaticamente no mesmo instante.
Dessa forma, uma interrupção vai ter sempre dois pontos chaves, que são:
- Condição de interrupção: É a condição que vai indicar o início de uma interrupção. Será essa condição que vai avisar a hora de executar uma tarefa totalmente diferente. No nosso exemplo, essa condição é o acionamento do infravermelho.
- Função a ser executada: Quando a condição de interrupção acontece, temos que executar uma lista de instruções referentes a essa interrupção. Ou seja, quando o infravermelho for acionado, a interrupção vai rodar uma função a qual tem nela, os passos que o programa precisa seguir.
Rotinas de Serviço de Interrupções (ISR’s)
Mas que nome é esse? Bom, sabe quando falamos das “funções a serem executadas” alí em cima? Pois bem, essas funções recebe o nome de Rotinas de Serviço de Interrupção ou ISR (do Inglês, interrupt service routine).
Mas o que tem de diferente?
Essas funções são especiais e possuem algumas limitações únicas que as outras funções normais não possuem. Uma ISR não recebe argumentos, e não devem retornar nada. Combinado?
Mas normalmente, uma ISR deve ser a mais curta e rápida possível. Sendo assim, se o seu código utiliza múltiplas ISRs, apenas uma pode ser executada de cada vez, seguindo a ordem do programa. Contudo, devemos tomar alguns cuidados:
- Dentro da função que será chamada na interrupção, a função delay() não funcionará e a função millis() não será incrementado.
- delayMicroseconds() não usa nenhum contador, portanto ela funcionará normalmente durante uma interrupção.
Mas antes de entrar no nosso exemplo de hoje e trabalhamos em cima do código, vamos primeiro conhecer as funções de interrupção que podemos utilizar com o Arduino.
Comandos de interrupções no Arduino
Temos apenas 4 funções que podemos utilizar para controlar as interrupções. Vamos conhecer a primeira delas:
attachInterrupt()
Essa função que irá verificar se a condição aconteceu e vai dizer qual função será executada caso a interrupção ocorra. Ela é escrita da seguinte forma:
attachInterrupt(digitalPinToInterrupt(pino), ISR, modo); // Função de interrupção
Parâmetros
- Pino: Essa variável vai ser o número do pino (vale somente para Arduino Due, Zero, MKR1000 apenas);
- ISR: Aqui é onde colocamos a função a ser chamada quando a interrupção ocorre; essa função, como já falado, deve não tomar nenhum parâmetro e nem retornar nada. Combinado?
- Modo: Aqui vamos definir quando a interrupção deve ser ativada. Ou seja, o que vai ser preciso ocorrer para que a interrupção seja ativada?. Quatro constantes estão predefinidas como valores válidos:
- LOW: Nesse caso, a interrupção será acionada quando o estado do pino for LOW;
- CHANGE: Nessa configuração, a interrupção será acionada sempre quando o estado do pino mudar;
- RISING: Nessa configuração, a interrupção será acionada toda vez que o estado do pino for de LOW para HIGH apenas;
- FALLING: Nessa configuração, a interrupção será acionada toda vez que o estado do pino for de HIGH para LOW apenas.
Para as placas Arduino Due, Zero e MKR1000 suportam também a função:
- HIGH: Nessa configuração, a interrupção será acionada toda vez que o estado do pino for HIGH.
Além disso, um detalhe importante é que o primeiro parâmetro do attachInterrupt() é o número da interrupção. Para representar esse número, é recomendado usar o comando 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, utilize digitalPinToInterrupt(3) como o primeiro parâmetro de attachInterrupt(). Maravilha?
detachInterrupt()
Este comando vai desativar a interrupção especificada. Ou seja, sabe aquela função que colocamos para ser ativada no attachInterrupt()? Pois bem, podemos desativar ela utilizando esse comando, fica assim:
detachInterrupt(Função da Interrupção) detachInterrupt(pino) // Funciona apenas para Arduino Due
noInterrupts()
Este comando é semelhante ao detachInterrupt(), entretanto, diferente de desabilitar uma interrupção específica, essa função vai acabar desativando todas as interrupções do código. Para implementar ela basta apenas escrever:
noInterrupts(); // Função para desabilitar todas as interrupções
interrupts()
Bom, como temos um noInterrupts, que desabilita todas as interrupções. Essa função é a função do lado do bem, a qual vai habilitar novamente as funções desabilitadas pelo noInterrupts(). Ela também é simples de chamar, basta escrever:
interrupts(); // Função para habilitar todas as interrupções desabilitadas pelo noInterrupts()
Pinos de Interrupção no Arduino
Vamos agora, para finalizar toda essa parte teórica, na tabela abaixo tem a relação de quantidade de pinos que cada arduino possui e qual a numeração deles, observe:
Fonte: ArduinoProg
Mas agora para poder aprender como implementar uma interrupção, está na hora de praticar não? Por isso, vamos fazer uma experiência simples para depois eu te explicar o código ok? Analisando o código você poderá entender melhor esse conceito de interrupção em um microcontrolador. Vamos nessa!
Componentes Utilizados
- 1x Arduino UNO
- 1x PushButton
- 6x LED 5mm
- 1x Resistor 1kΩ
- 6x Resistor 470Ω
- Alguns Jumper’s
- 1x Protoboard
Montagem do Circuito
Fonte: AutoCore Robótica
Código do Projeto Comentado
/* Projeto: Utilizando Interrupções com Arduino Autor: Danilo Nogueira - AutoCore Robótica Data: 25/08/2018 */ // Daremos um nome ao pino que ficara o LED: int led_vermelho[5] = {10, 9, 8, 7, 6}; int led_verde = 12; // Essa é função criada para a interrupção void interrupcao() { digitalWrite(led_verde, HIGH); // Liga o LED Verde (HIGH = nível lógico alto) } void setup() { for(int i=0; i <= 5; i++) pinMode(led_vermelho[i], OUTPUT); pinMode(led_verde, OUTPUT); // Aqui vamo configurar a interrupção // Como estamos utilizando o RISING // A interrupção vai acontecer quando // Ele mudar do estado baixo para alto attachInterrupt(digitalPinToInterrupt(2),interrupcao,RISING); } void loop() { for(int i=0; i <= 5; i++) { digitalWrite(led_vermelho[i], HIGH); // Liga o LED (HIGH = nível lógico alto) delay(1000); // Espera um segundo digitalWrite(led_vermelho[i], LOW); // Desliga o LED (LOW = nível lógico baixo) delay(1000); // Espera um segundo } }
Resultado do Projeto interrupções no Arduino
Mas agora para terminar esse post, estou deixando um vídeo mostrando o funcionamento do programa no qual ao pressionar o botão, o loop dos leds vermelho irá parar e o led verde irá começar a piscar no mesmo instante. Confira o vídeo abaixo!
Mas caso você queira saber mais sobre interrupção externa no Arduino, você pode ler sobre ela no site oficial da Arduino. Clique no Link e saiba mais!
E ai? gostou? Caso tenha ficado algo incompleto para você, comenta abaixo 📝
Dicas? 😯 Dúvidas? 🤔 Idéias de post?💭 Críticas? 😱 Só comentar também! 😉
Forte abraço!
como usar uma interrupção por exemplo um mostrador de temperatura e horas? q uando pressionar um botão interrompe o que antes mostrava horas e passa a mostrar temperatura e vice versa?
Olá Davidson tudo bom?
Se você quiser apenas visualizar a hora durante 5 segundos por exemplo. Pode alterar a função “Interrupção” do post para uma função que mostre as horas durante 5 segundos e depois volte para o void loop e nele estaria calculando a temperatura e vice versa.
Agora, se você quer deixar um ou outro rodando infinitamente, apenas querendo alternar entre eles, creio que não será possível!
Mas vou pesquisar sobre e posto aqui caso encontre algo. Tem o link sobre interrupções no site do Arduino, acho que deve ajudar:
http://arduino.cc/en/Reference/attachInterrupt
Abraços!
Oi Danilo, parabéns pelo seu trabalho. Tira apenas uma dúvida: No seu texto você afirma que a função delay() não funciona dentro de uma interrupção. Isto faz todo sentido porque se permitirmos o uso de delay(), toda a temporização do programa poderá ficar comprometida. Mas, no seu exemplo, você usa a função delay() dentro de uma interrupção.
Olá Arquimedes, espero que esteja bem!
Realmente houve um erro na programação. Obrigado pelo aviso e ele já foi corrigido!
Assim, continua sendo verdadeiro o fato da função delay() não funcionar dentro da função chamada em uma interrupção!
Grande abraço!
Olá Danilo, Tudo bem ? espero que sim ! Será que você pode me ajudar ? Tenho conhecimento em eletrônica, circuitos digitais e presto serviços para clientes na minha localidade, Criciúma/SC. Comprei uma estação de solda Infra vermelho, uma T870A. mas essa máquina controla somente temperatura sem rampas e sem temporizador. Então peguei uma adaptação de um colega no Youtube que fez controles de temperatura e tempo dentro de rampas através de um visor nokia 5110. Só que ela é adaptada para trabalhar com calor em soprador térmico ( ar e resistência) e a minha máquina trabalha com luz infra vermelho. mas usando a mesma saída pino10 (Digital pin10 PWM do arduino uno, que por pulso PWM nessa saída aciona o relé estado sólido e consigo ligar a lâmpada IR. A operação inicia pelo botão Start (Pino 2 do arduino se acionado ao terra) mostrando no display a temperatura decorrente as rampas , seja elas pré definidas nas 4 rampas criadas, atingindo cada patamar de temperatura, aciona o tempo escolhido e pula para próxima rampa ou seja Rampa 1 = 0ºC/880 segundos. coloquei 0ºC para esperar a resistência debaixo da máquina a pré heater atingir a media que é 120°C e leva aproximadamente 880 seg = 15 minutos… e assim o pula para rampa2 onde aciona a saida 10 PWM para o relé ligar a lâmpada IR para atingir a temperatura de 186ºC e quando atingir permanece por 10 segundos e pula para próxima rampa… e assim até a rampa 4 de 233 º C por 10 segundos e aí que tá o problema! depois de contar esses 10 segundos na última rampa 4 quero que a lâmpada IR se desligue, seja interrompida, pois já atingiu a temperatura de fusão da solda. Mas a saída 10 do arduino continua acionada e faz um loop retornando para a rampa 1 acionado o pino 10 e fazendo a rotina . Tem como você compilar uma linha de comando para exatamente parar depois dos 10 segundos da rampa4 tirar esse “loop”. Se eu acionar manualmente o botão start ele para o processo, mas quero que seja automatizado. Estou enviando o arquivo “BGA_Controler_IR_4_RAMPAS .ino ” da minha máquina se você com seu conhecimento técnico poder fazer essa compilação para encerrar ou de alguma forma me ajudar, ficaria grato!
Disponibilizando abaixo os links do arquivo a ser compilado e uma foto do projeto original pra ter uma idéia de ligações. Desde já agradeço a atenção!
Arquivo .ino 4 rampas
https://onedrive.live.com/?authkey=%21AM0nmEjpTu5zuJo&cid=2309F8B95054E0FB&id=2309F8B95054E0FB%211084&parId=2309F8B95054E0FB%211044&o=OneUp
Imagem do esquema elétrico original sem modificação para Lâmpada IR
https://onedrive.live.com/?authkey=%21AM0nmEjpTu5zuJo&cid=2309F8B95054E0FB&id=2309F8B95054E0FB%211084&parId=2309F8B95054E0FB%211044&o=OneUp
alex_auth@hotmail.com
(48) 991261662
Olá Alexandro tudo bem? Eu dei uma olhada sim em seu código. Ele contém variáveis que foram criadas e não estão sendo utilizadas, aconselho retirar elas, vai ajudar demais!
Analisando por cima, o problema pode ser na linha 131, onde tem a função de interrupção. Mas também pode ser no loop onde faz a troca dos menus para mostrar no display.
Os links que você mandou são iguais rs’. Se possível, manda o link do vídeo para ver o funcionamento!
Abraços!
Olá Danilo Nogueira , é possivel utilizar a interrupção com modulo ethernet?
Fala David tudo bem? Muito obrigado pelo contato!
Bom vamos lá, é possível sim! Contudo, se for utilizar outros shields que necessitem utilizar interrupções no circuito, fique ligado nos pinos de interrupção tanto do módulo como também do modelo de Arduino que esta utilizando!
Uma rápida pesquisa no Google, você consegue a pinagem de seu arduino e depois é apenas conferir o pino correto de interrupção no Ethernet!
Este tópico no fórum do Arduino deve ajudar: Interrupt Ethernet
Grande abraço!