Projeto 79 - Interrupção por timer no Arduino - disparo de alarme com sensor de toque

Básico - Projeto 79

Interrupção por timer no Arduino - alarme com sensor touch TP223B

Objetivo

Neste projeto vou mostrar como realizar interrupções por timer (leds piscando alternadamente) através do acionamento de um sensor de toque capacitivo TTP2233B por uma interrupção externa no Arduino. Assim, ao tocarmos o sensor, geramos uma interrupção externa que dispara um alarme, cuja ação será dois leds piscando alternadamente a cada segundo. Para que os leds pisquem a cada segundo utilizaremos interrupções por timer para executar uma função a cada intervalo de tempo pré-definido.

Definições

Sensor Touch Capacitivo TTP223B: Sensor baseado no CI TTP223B que foi desenvolvido para detectar toques. Seu funcionamento é bem simples: ao tocar a região indicada, a saída do sensor é ativada (HIGH).

Obs.: Os sensores de toque, assim como os botões de pressão (push button ou chaves tácteis) apenas mudam seu estado enquanto estamos pressionando ou tocando, voltando ao seu estado original quando liberados. Neste projeto, teremos uma rotina para atribuir a um só sensor duas funções: ligar e desligar um componente eletrônico qualquer através de uma interrupção externa.

Interrupção externa (External Interrupts)

É quando o programa do Arduino está instruído para reagir à mudança de um sinal externo, por exemplo, mudança do nível lógico de um sinal gerado por um botão ou por um sensor qualquer (Referência Arduino). Faça o projeto Projeto 78 - Como realizar interrupção externa no Arduino usando sensor de toque para entender melhor como funciona a interrupção externa.

  • A ideia de utilizar a interrupção externa no Arduino em certos projetos, é quando precisamos realizar duas ou mais tarefas ao mesmo tempo.

Interrupção por timer (Timer Interrupts)

Embora semelhante à interrupção externa, a interrupção por timer ocorre através do tempo e não por uma ação externa do hardware, como um toque no sensor, por exemplo. Assim, a cada período podemos executar uma função independente, sem que a contagem do tempo seja interferida pelos demais comandos do programa. A interrupção por timer substitui as funções: delay(), millis() e o controle de loop for, gerando um intervalo de tempo independente.

Obs.: Para utilizarmos o recurso da interrupção por timer no Arduino precisaremos instalar a biblioteca TimerOne, conforme mostraremos durante o tutorial do projeto.

Aplicação

Para fins didáticos e projetos gerais.

Componentes necessários

Referência

Componente

Quantidade

Imagem

Observação

Protoboard Protoboard 830 pontos 1 Resultado de imagem para protoboard 830v

No mínimo utilizar protoboard com 400 pontos

Jumpers Kit cabos ligação macho / macho 1  
Sensor de toque capacitivo Sensor touch TP223B 1

Tensão de Operação: 2 a 5V

Saída estado Alto (HIGH): 0,8V

Saída estado Baixo (LOW): 0,3V

Tempo de resposta: 220ms (LOW) e 60ms (HIGH)

(datasheet)

Led Difuso 5mm LEDs 5mm 3

3 LEDs alto brilho ou difuso nas cores laranja, verde e vermelho (mas poderão ser utilizados leds de qualquer cor)

Você poderá utilizar também LEDs de 3 mm na cor que desejar.

Resistor

Resistor

 3

3 Resistores 150Ω

Se precisar usar outros valores, calcule o resistor apropriado para o led utilizado

Arduino UNO R3 Arduino UNO 1

Você poderá utilizar uma placa Arduino UNO original ou similar

Montagem do Circuito

Conecte os componentes no Protoboard como mostra a figura abaixo. Verifique cuidadosamente os cabos de ligação antes de ligar seu Arduino. Lembre-se que o Arduino deve estar totalmente desconectado da força enquanto você monta o circuito.


Atenção

1. Lembre-se que o LED tem polaridade: O terminal maior tem polaridade positiva e o lado do chanfro tem polaridade negativa.

1.1. Portanto, faça a conexão do Arduino no terminal positivo do led (anodo) e o GND no terminal negativo (catodo).

1.2. Para evitar danos ao led é necessário a inclusão de um resistor no circuito. Como o resistor é um limitador da corrente elétrica, ele poderá estar conectado no anodo (terminal maior) ou no catodo (terminal menor) do led, tanto faz.

2. Determinamos o valor do resistor através da tabela prática: Tabela prática de utilização de leds 3mm e 5mm. Entretanto, o mais correto é sempre verificar o datasheet do fabricante do LED para você ter os exatos valores de tensão e corrente do mesmo - leia Como calcular o resistor adequado para o led e Leds ligados em série e em paralelo.

2.1. Valores utilizados para nossos projetos: LEDs difusos ou de alto brilho: Vermelho, Laranja e Amarelo: 150 Ω | Led Verde e Azul: 100 Ω

3. Antes de montarmos o nosso sensor, temos que observar que que os microcontroladores Arduino possuem pinos específicos para desempenhar a função de entrada de sinal para a interrupção externa. No Arduino UNO, por exemplo, as portas digitais 2 e 3 têm esta função, sendo nomeadas como int = 0 e int = 1, respectivamente. Veja a tabela a seguir que mostra os pinos das principais placas Arduino que possuem esta função:

Board int.0 int.1 int.2 int.3 int.4 int.5
Uno, Nano, Mini, other 328-based pino 2 pino 3        
Mega, Mega2560, MegaADK pino 2 pino 3 pino 21 pino 20 pino 19 pino 18
Micro, Leonardo, other 32u4-based pino 3 pino 2 pino 0 pino 1 pino 7  
Due número da interrupção = todos pinos digitais = número do pino
Zero todos pinos digitais, exceto 4 = número do pino

4. Conforme vimos na tabela anterior, definiremos o pino digital 2 do Arduino UNO para conectarmos o pino do sensor de toque e obtermos a funcionalidade da interrupção externa no nosso projeto.

Obs.: Se desejar, você também pode utilizar o pino 3 do Arduino para obter a mesma funcionalidade da interrupção externa, lembrando de nomeá-lo como int = 1.

5. Monte o sensor touch TP223B conforme imagem abaixo.

5.1. Montando o componente desta forma, quando o sensor for tocado, o Arduino retornará "HIGH" ou "1".


5.2. Lembre-se, para obtermos a funcionalidade da interrupção externa, devemos ligar o pino do sensor na porta digital 2 ou 3 do Arduino. No nosso projeto, conectamos no pino digital 2.

6. Veja abaixo como realizamos a montagem do nosso projeto utilizando dois protoboard de 430 pontos.

Usando o comando de interrupção externa do Arduino

1. Para que o Arduino leia uma interrupção externa, é necessário utilizarmos a função attachInterrupt() - Leia Referência Arduino - attachInterrupt().

2. Esta função irá verificar se a condição aconteceu e qual função especial (ISR) será executada caso a interrupção ocorra. Veja a sintaxe abaixo:

Obs.: Como já explicamos acima, IRS (Interrupt Service Routine, ou Rotina de Serviço de Interrupções em português) nada mais é do que uma função especial executada quando ocorre uma interrupção externa:

Sintaxe

attachInterrupt(INT,IRS,MODO); //Configurando a interrupção

Onde:

INT: Número da porta usada para a interrupção. No Arduino UNO podemos utilizar INT = 0 que corresponde à porta digital 2 e INT = 1 corresponde à porta digital 3.

Observação: Podemos utilizar no lugar de INT o comando digitalPinToInterrupt(pino) que já faz a correspondência do pino conectado no Arduino e a fonte da interrupção. Portanto, para o Arduino UNO podemos utilizar digitalPinToInterrupt(2) para INT = 0 ou digitalPinToInterrupt(3) para INT = 1.

IRS: Nome da função especial que será chamada e executada quando ocorrer a interrupção.

Atenção: A função IRS tem algumas limitações importantes conforme mencionamos no início deste tutorial, como sendo:

  • Uma ISR não recebe argumentos e não retorna nada.
  • Uma ISR deverá ser a mais curta e rápida possível. Se o seu programa utiliza múltiplas ISRs, apenas uma poderá ser executada de cada vez.
  • A função delay() não funcionara em uma IRS.
  • A função millis() não poderá ser incrementada dentro de uma IRS.
  • A função delayMicroseconds() ao não utilizar nenhum contador, funcionará normalmente em uma ISR.

MODO: Define em qual tipo de variação do sinal a interrupção será disparada. As opções são:

  • LOW: Dispara a interrupção quando o estado no pino (2 ou 3) for LOW.
  • HIGH: Dispara a interrupção quando o estado no pino for HIGH (Apenas as Placas Due, UNO, Zero e MKR1000 suportam este modo)
  • CHANGE: Dispara sempre que o sinal no pino muda de estado, borda 0V (0) para 5V(1) ou vice-versa;
  • RISING: Dispara somente na borda de subida, 0v (0) para 5V (1);
  • FALLING: Dispara somente na borda de descida, 5V (1) para 0V (0)

Obs.: É importante que você teste todos os modos para entender bem a funcionalidade de cada um.

Incluindo a biblioteca TimerOne

Para realizarmos a interrupção por tempo devemos incluir a biblioteca TimerOne.h que facilita a utilização do timer interno do Arduino via software. Assim, podemos configurar o Arduino através de métodos pré-definidos na biblioteca, para medir repetidamente um período de tempo em microssegundos. No final de cada período, uma função de interrupção poderá ser executada.

Download dos arquivos da biblioteca TimerOne.h

 DOWNLOAD - TimerOne-master.zip

Para saber detalhes desta biblioteca clique aqui.

Instalando a biblioteca pelo IDE do Arduino

Após fazer o download do arquivo Arduino_Led_matrix.zip com todos os arquivos da biblioteca compactados no formato zip, abra o IDE do Arduino e siga o tutorial: Como incluir uma biblioteca no IDE do Arduino.

Comandos básicos da biblioteca TimerOne - Interrupção por timer

1. Usando o timer

1.1. Um timer nada mais é do que um contador que é incrementado a cada intervalo de tempo (em alguns microcontroladores intervalo pode ser configurado, o Arduino é um deles). Os timers funcionam como um relógio que pode ser usado para contar o tempo, medir a duração de certos eventos, entre outras aplicações.

1.2. O Arduino vem equipado com um microcontrolador ATmega168 ou ATmega328 (que diferem apenas na quantidade de memória interna). Esses microcontroladores possuem 3 timerstimer0, timer1 and timer2, timer0 e timer2 são contadores de 8bits, ou seja, contam de 0 a 255, e o timer1 é um contador de 16bits, conta de 0 a 65535.

1.3. O Arduino Mega vem equipado com o ATmega1280 ou ATmega2560 (que diferem apenas na quantidade de memória). Eles possuem 6 timerstimer0, timer1, timer2, timer3, timer4, timer5. Os timers 0, 1 e 2 são idênticos aos do ATmega168/328, e os timers 3, 4 e 5 são de 16bits.

  • timer0 é utilizado pelo Arduino para funções como delay()millis() e micros(). Então não se deve utilizar esse timer para evitar comprometer essas funções.
  • O timer1 no Arduino UNO esse é o timer utilizado pela biblioteca de controle de servos. Caso você não esteja utilizando essa biblioteca, esse timer está livre para ser utilizado para outros propósitos. No Arduino Mega esse timer só será utilizado para controlar os servos se você estiver usando mais de 12 servos. (timer utilizado no projeto)
  • timer2 é utilizado pela função tone(). Então se você não precisar da função tone() esse timer está livre para outras aplicações.

2. Utilização da biblioteca

2.1. O timer (cronômetro) está configurado para medir repetidamente um período de tempo, em microssegundos, portanto 1.000.000 = 1 segundo.

Obs1: Os pinos PWM também podem ser configurados para alternar durante uma parte do período (isto será demonstrado no projeto 80).

Obs2.: Se estiver usando o TimerThree, substitua "Timer1" por "Timer3".

3. Configuração

Inicialização do timer

Timer1.initialize(microseconds); 

Esta função deve ser chamada primeiro. Microssegundos é o período de tempo que o timer leva.

Define novo período

Timer1.setPeriod(microseconds); 

 Define um novo período após a biblioteca já ter sido inicializada.

4. Função de interrupção

Chama uma função IRS (Interrupt Service Routine)

Timer1.attachInterrupt(function); 

Executa uma função sempre que o período do timer terminar. A função é executada como uma interrupção, portanto, é necessário um cuidado especial para compartilhar quaisquer variáveis ​​entre a função de interrupção e seu programa principal.  Esta função é uma IRS (Interrupt Service Routine, ou Rotina de Serviço de Interrupções em português) e possui limitações como já mencionamos anteriormente.

Desativa a interrupção

Timer1.detachInterrupt(); 

Desativa a interrupção para que a função não seja mais executada.

5. Referências

5.1. Eletronics Componentes: https://www.pjrc.com/teensy/td_libs_TimerOne.html

5.2. Laboratório de Garagem: http://labdegaragem.com/profiles/blogs/tutorial-executando-fun-es-em-intervalos-de-tempo-fixos-timers 

5.3. Playground Arduino: https://playground.arduino.cc/Code/Timer1/

5.4. Como usar temporizadores no Arduino

Código do projeto (Sketch)

1. Faça o dowload e abra o arquivo projeto79.ino no IDE do Arduino:  DOWNLOAD - projeto79.ino

1.1. No nosso programa vamos utilizar o modo RISING para a interrupção externa. Recomendamos que teste todos os modos de interrupção como: FALLING, CHANGE, LOW e HIGH.

Ou se preferir, copie e cole o código abaixo no IDE do Arduino:

/*******************************************************************************
**                
*               Projeto 79 - Interrupção por timer com sensor de toque
*               Autor: Angelo Luis Ferreira
*               Data: 13/02/2020 (dd/mm/AA)
*                  http://squids.com.br/arduino
*
*******************************************************************************/
#include <TimerOne.h>

// mapa do hardware
const byte sensorTouch = 2;     //conexão do sinal do sensor capacitivo
const byte pinOrange = 4;     //led de saída (larranja)
const byte pinGreen = 11;     //led de saída (verde)
const byte pinRed = 12;      //led de saída (vermelho)

// variáveis
bool armado = false;

void setup() {
  pinMode(sensorTouch, INPUT);    //configura entrada digital para o sensor
  pinMode(pinOrange, OUTPUT);   
  pinMode(pinGreen, OUTPUT);   
  pinMode(pinRed, OUTPUT);    
  attachInterrupt(digitalPinToInterrupt(sensorTouch),set_alarme,RISING); 
    
  Serial.begin(9600);
}

void loop() {}


void alarme(){
  digitalWrite(pinGreen,!digitalRead(pinGreen));
  digitalWrite(pinRed, !digitalRead(pinRed));  
}

void set_alarme() {
  if(armado){ // desativa o alarme
    Serial.println("Alarme desativado");
    digitalWrite(pinOrange,LOW);
    armado=false;
    Timer1.detachInterrupt(); // remover interrupção do timer
    digitalWrite(pinGreen,LOW);
    digitalWrite(pinRed,LOW);
        
  }else { // ativa o alarme
    Serial.println("Alarme acionado");
    digitalWrite(pinRed,HIGH);            
    digitalWrite(pinOrange,HIGH);
    armado=true;
    Timer1.initialize(1000000); // inicializar timer com período de 1 segundo
    Timer1.attachInterrupt(alarme); // anexar função a ser excutada a cada período
  }
}

Vídeo - Modo RISING

Como o projeto deve funcionar

1. Ao iniciar o programa, todo os leds estarão apagados.

MODO RISING (dispara a função na borda de subida de 0V para 5V)

2. Ao tocar o sensor o led laranja se acenderá e os demais leds piscarão alternadamente.

3. Ao tocar novamente o sensor todos os leds se apagarão, desativando o alarme.

4. Ao abrir o monitor serial, aparecerá na tela "Alarme acionado" quando acender os leds e "Alarme desativado" quando apagar os leds.

MODO FALLING (dispara a função na borda de descida de 5V para 0V)

2. Ao retirar o dedo, após tocar o sensor, o led laranja se acenderá e os demais leds piscarão alternadamente.

3. Ao retirar o dedo novamente do sensor todos os leds se apagarão, desativando o alarme.

O anúncio abaixo ajuda a manter o Squids Arduino funcionando

Comentários

×

Infomações do site / SEO








×

Adicionar Marcadores