Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
25/05/14 Frederico Möller 1
ARDUINO BÁSICOLição IV
Frederico José Dias Möller
25/05/14 Frederico Möller 2
Sumário
● Uma questão de prioridades
● Interrupções● Timer● Timer1● Interrupção por tempo
● Exemplo VII Blink por interrupção– Software
● Exercício VII● Análise crítica da
resposta.● Parada de
emergência
25/05/14 Frederico Möller 3
Sumário
● Interrupção por mudança de estado
● AttachInterrupt● Exemplo VIII● Exercício VIII● Revisão● Leitura complementar
25/05/14 Frederico Möller 4
Uma questão de prioridades
● Voltemos ao exemplo VI da lição anterior.● Vamos supor que ao invés de ativar, ou
desativar uma cor do rgb, queiramos selecionar qual cor vai piscar.
● Se digitarmos R, a luz vermelha vai começar a piscar, se digitarmos R novamente ela vai parar de piscar.
● Como resolveríamos o problema?
25/05/14 Frederico Möller 5
Uma questão de prioridades
● Pode parecer que a solução é simplesmente alterar o conteúdo dos if-else. Inserindo um delay nele.
● A sequencia troca-estado, escrita digital e delay é uma sequencia de piscagem.
25/05/14 Frederico Möller 6
Uma questão de prioridades
● No entanto há um delay no final do programa.
● Se o programa rodasse direto, ele entraria em um caso, alternaria o valor da variável "valor[]" e com isso alternaria a saída digital da cor.
25/05/14 Frederico Möller 7
Uma questão de prioridades
● O delay no final do programa, pode ser alterado para o intervalo de piscagem.
● O ciclo while então aparece como nosso segundo problema.
25/05/14 Frederico Möller 8
Uma questão de prioridades
● Cada ciclo de piscagem pararia no while e ficaria esperando que o usuário digitasse a letra
● A solução poderia ser retirar o comando "letra = 0;" no fim do loop.
25/05/14 Frederico Möller 9
Uma questão de prioridades
● Dessa forma a variável letra continuaria com seu último valor e pularia o ciclo while
● O led piscaria e o programa funcionaria numa boa.
25/05/14 Frederico Möller 10
Uma questão de prioridades
● Há dois problemas, no entanto, nessa solução.
● Primeiramente haveria um atraso na hora que o usuário resolvesse escolher outra cor para piscar.
25/05/14 Frederico Möller 11
Uma questão de prioridades
● Se o usuário digitou inicialmente um R e depois digitasse um B, por exemplo, o programa só leria esse B quando chegasse no comando "letra = Serial.read()"
25/05/14 Frederico Möller 12
Uma questão de prioridades
● Se o programa já estivesse lidando com os condicionais, o usuário teria que esperar todo o fim do loop para ter seu comando lido.
25/05/14 Frederico Möller 13
Uma questão de prioridades
● O segundo problema é que o led não piscaria num intervalo exatamente igual ao valor na função delay.
● Cada comando leva um tempo para ser executado pela máquina.
25/05/14 Frederico Möller 14
Uma questão de prioridades
● O usuário acabaria tendo que esperar o tempo do delay + quantidade de comandos/capacidade de processamento do Arduíno.
25/05/14 Frederico Möller 15
Uma questão de prioridades
● É claro que para um programa curto e simples como o exemplo VI, tais "desvantagens" não são sensíveis ao usuário.
● No entanto para programas mais complexos, com necessidade de reação imediata e grandes ciclos internos de operações, essas desvantagens podem se mostrar bem desagradáveis.
● Por causa delas existem as interrupções.
25/05/14 Frederico Möller 16
Interrupções
● Interrupções são funções que são chamadas quando algum evento externo acontece.
● Quando isso acontece o programa principal é parado, a função de interrupção é chamada e após sua execução o programa principal pode, ou não voltar a ser executado a partir de onde foi interrompido.
● Existem diversos tipos de interrupções, mas no Arduino vamos tratar de duas.
25/05/14 Frederico Möller 17
Timers
● Um timer é uma espécie de contador do Arduino que conta uma quantidade x de pulsos de clock, equivalentes à uma quantidade pré-estabelecida de ms.
● Quando ele chega no final de sua contagem ele manda um sinal para o Arduino.
● Timers são essênciais para as interrupções por intervalo de tempo.
25/05/14 Frederico Möller 18
Timer1
● O arduíno tem diversos timers, o 0, por exemplo é seu timer principal, que ele usar para a função delay e contagens internas importantes.
● O timer 1 é usado para controle de servo-motores.
● Quando não está sendo usado, ele pode ser chamado pelo usuário para controlar outras rotinas
25/05/14 Frederico Möller 19
Timer1
● Qualquer um dos timers podem ser chamados e configurados atravéz de uma série de comandos. Mas a complexidade dos mesmos fogem dos objetivos desse curso introdutório.
● O Timer 1 e 3 possuem bibliotecas próprias, a partir das quais é possível configurar e usar facilmente os mesmos.
● Elas não vem originalmente com a IDE e podem ser baixadas em http://www.pjrc.com/teensy/td_libs_TimerOne.html
25/05/14 Frederico Möller 20
Timer1
● Para configurarmos o timer1, devemos incluir a biblioteca TimerOne. Essa inclusão é feita de forma semelhante à linguagem c, com o comando #include<TimerOne.h>
● Depois devemos inicializar o timer no setup.● Isso é feito atravéz do comando:
Timer1.initialize(tempo)● A quantidade de tempo é dada em
microsegundos.
25/05/14 Frederico Möller 21
Interrupção por tempo
● A interrupção por tempo usando o timer1 é dada pelo comando: Timer1.attachInterrupt(função);
● Onde "função" é o nome da função que vai ser chamada na interrupção.
● O comando Timer1.attachInterrupt é feito no escopo da setup.
25/05/14 Frederico Möller 22
Exemplo VII Blink por interrupção
● Para exemplificar as funções apresentadas anteriormente, voltaremos a implementar o programa blink.
● A montagem do circuito é feita de forma identica ao circuito montado no exemplo I
● A diferença é que usaremos uma interrupção de tempo e não a função delay para fazer com que o led pisque.
25/05/14 Frederico Möller 23
Exemplo VII Blink por interrupção
● O primeiro comando de nosso programa é a inclusão da biblioteca TimerOne.
● Em seguida declaramos uma variável inteira chamada "sinal", com valor inicial igual a 0.
25/05/14 Frederico Möller 24
Exemplo VII Blink por interrupção
● A primeira função a ser implementada é a função nomeada de "chama".
● Essa função, como veremos a seguir, será chamada pela interrupção. Por isso seu "nome".
25/05/14 Frederico Möller 25
Exemplo VII Blink por interrupção
● A função chama troca o valor da variável sinal. Se ele era 0, passa a ser não 0, ou seja: 1. Se era 1, passa a ser não 1, ou seja: 0.
25/05/14 Frederico Möller 26
Exemplo VII Blink por interrupção
● A segunda função é a função setup.
● Temos a inicialização do Timer1 que tem um intervalo de 10^6 microsegundos, ou seja: 1 segundo.
25/05/14 Frederico Möller 27
Exemplo VII Blink por interrupção
● Temos também a interrupção do timer 1, com sua função a ser chamada, a função "chama".
● A última função a ser implementada é a loop.
25/05/14 Frederico Möller 28
Exemplo VII Blink por interrupção
● É importante observar que a loop só possui um comando.
● Ela vai executar uma escrita digital no pino 13 de acordo com o valor de sinal.
25/05/14 Frederico Möller 29
Exemplo VII Blink por interrupção
● O programa inicial com sinal = 0, então o valor inicial do pino 13 é baixo.
● O programa vai escrever, a cada ciclo, uma saída baixa em 13.
25/05/14 Frederico Möller 30
Exemplo VII Blink por interrupção
● Após 1 segundo o Timer1 vai terminar sua contagem e a interrupção será ativada
● O programa vai "pausar" a função loop e executar a função chama.
25/05/14 Frederico Möller 31
Exemplo VII Blink por interrupção
● A função chama vai trocar o valor lógico da variável sinal.
● O programa vai voltar a ser executado e então teremos uma escrita digital alta no pino 13 por mais 1 segundo...
25/05/14 Frederico Möller 32
Exercício VII
● Reescreva o exemplo VI, faça com que o operador selecione qual led deve piscar.
● Utilize interrupções por tempo para evitar que o tempo de piscagem seja afetado pelos outros comandos do programa.
● Para facilitar: A configuração do circuito não muda em nada com relação ao exemplo VI.
25/05/14 Frederico Möller 33
Exercício VII
● Primeriamente incluimos a biblioteca TimerOne.h
● Note que a variável valor não é mais uma array e tem seu valor inicial setado em 0
● Temos agora uma variável "led"
25/05/14 Frederico Möller 34
Exercício VII
● A função pisca é a função que será chamada na interrupção de tempo
● Ela deve conter a ação que desejamos que seja regida por um intervalo rígido de tempo.
25/05/14 Frederico Möller 35
Exercício VII
● No nosso caso ela coordena a o piscar do led.
● Ou seja, toda vez que a interrupção de tempo acontecer, a função pisca alternará o valor da variável "valor"
25/05/14 Frederico Möller 36
Exercício VII
● E em seguida alternará o valor do pino digital de valor igual ao da variável "led".
● Se led = 13, o pino que sofrerá a alteração será o pino 13.
25/05/14 Frederico Möller 37
Exercício VII
● No setup temos a inicialização do Timer1 para um período de 106 μs
● Temos também a interrupção do Timer1 configurada para chamar a função pisca.
25/05/14 Frederico Möller 38
Exercício VII
● O restante do programa é bem semelhando ao exemplo VI
● A diferença é que nos condicionais da variável letra, a única operação realizada é atribuir um valor à variável led.
25/05/14 Frederico Möller 39
Análise crítica da resposta
● A resposta dada anteriormente cumpre com o que foi pedido, no entanto existem alguns "deslizes" que merecem atenção.
● Inicialmente a variável led é declarada, mas não tem valor atribuido.
● A cada interrupção de tempo a função pisca usa o valor da variável led para determinar qual pino sofrerá mudança em seu sinal digital.
25/05/14 Frederico Möller 40
Análise crítica da resposta
● Isso significa que, até que um R,G, ou B seja digitado pela primeira vez, a função digitalWrite dentro da função pisca usará o valor inicial da variável led, que é arbitrário, imprevisível e geralmente muito alto.
● Isso não implica necessáriamente um erro no programa, mas se led assumir inicialmente um valor "baixo", abaixo de 13, poderemos ter alternância de valores em um dos pinos existentes.
25/05/14 Frederico Möller 41
Análise crítica da resposta
● Pode ser que o led comece já piscando, coisa que não é desejável.
● No entanto em uma aplicação mais complexa, com outros elementos ligados aos demais pinos, esse erro pode ter consequências drásticas! Um sinal pode ser enviado à um dispositivo que não está preparado para recebê-lo e isso pode ocasionar danos ao mesmo e ao Arduino.
25/05/14 Frederico Möller 42
Parada de emergência
25/05/14 Frederico Möller 43
Parada de emergência
● A foto anterior era de um robô de limpeza roomba® Esse tipo de robô já existe a um tempo considerável no mercado e antes, um item exclusivo, agora está ficando cada vez mais acessível.
● Ele possui um conjunto de sensores infravermelho de distância, esses sensores são os responsáveis por evitar colisões e quedas indesejadas.
25/05/14 Frederico Möller 44
Parada de emergência
● Há sensores nas laterais, frente e um conjunto na parte de baixo do robô. Estes últimos servem para medir sua distância em relação ao solo e assim poder detectar um degrau, ou outro desnível grande e assim evitar que o robô role escada abaixo, despenque de um andar para o outro e assim seja danificado severamente.
25/05/14 Frederico Möller 45
Parada de emergência
● Se a leitura desses sensores fosse feita em sequência, dentro da programação normal do robô, teríamos um sério problema.
● Se o robô, em movimento, estivesse em qualquer trecho do programa que não a leitura do sensor inferior e passasse por um degrau ele não teria tempo de evitar sua queda.
25/05/14 Frederico Möller 46
Parada de emergência
● Felizmente (tanto para o robô, quanto para quem o comprou) ele usa interrupções para lidar com seus sensores.
● Isso significa que logo que o sensor capte um "perigo" a rotina do robô é prontamente interrompida, ele corrige seu curso e só então volta a sua rotina normal.
25/05/14 Frederico Möller 47
Interrupção por mudança de estado
● Esse tipo de interrupção no entanto não pode ser uma interrupção de tempo.
● Não sabemos quando o robô vai passar por um risco de queda para dizer quando ele deve ler seu sensor.
● Se colocarmos a leitura dos sensores em uma interrupção por tempo e este for longo (1s é um intervalo longo) um acidente poderá ocorrer nesse meio tempo.
25/05/14 Frederico Möller 48
Interrupção por mudança de estado
● Se o intervalo for muito curto, sobrecarregaremos o robô!
● Por essa razão os sensores possuem esquma lógico interno que faz com que uma saída mude seu valor lógico assim que a distância entre o robô e o obstáculo, ou o chão torne-se crítica.
● Essa saída lógica está ligada ao seu processador
25/05/14 Frederico Möller 49
Interrupção por mudança de estado
● O processador está programado com uma interrupção por mudança de estado.
● Assim logo que o pino referente ao sensor mudar de estado lógico, a função de interrupção é chamada
● A interrupção por mudança de estado pode ser definida para quando ocorrer qualquer alternância de estado, para somente quando o pino for para "ALTO", ou somente quando o pino for para "BAIXO".
25/05/14 Frederico Möller 50
AttachInterrupt
● O Arduino possuí a função AttachInterrupt(pino,função,modo) para esse tipo de interrupção
● Ela deve ser declarada no setup, com os seguintes dados:– PINO: o pino que deve comandar a interrupção.
Não é necessariamente o nº do pino. No modelo de Arduino que usamos, os únicos valores possíveis são 0 e 1, que equivalem ao pino 2 e 3.
25/05/14 Frederico Möller 51
AttachInterrupt
● O Arduino possuí a função AttachInterrupt(pino,função,modo) para esse tipo de interrupção
● Ela deve ser declarada no setup, com os seguintes dados:– PINO: o pino que deve comandar a interrupção.
Não é necessariamente o nº do pino. No modelo de Arduino que usamos, os únicos valores possíveis são 0 e 1, que equivalem ao pino 2 e 3.
25/05/14 Frederico Möller 52
AttachInterrupt
– FUNÇÃO: a função que deve ser chamada quando ocorrer a interrupção.
– MODO: O que deve ocorrer no pino para que a interrupção seja acionada. Os modos possíveis são:– LOW (o pino deve estar em "BAIXO")– CHANGE (qualquer mudança de estado)– FALLING (quando passa de "ALTO" para "BAIXO")– RISING (quando passa de "BAIXO" para "ALTO")
25/05/14 Frederico Möller 53
Exemplo VIII
● Vamos agora fazer um programa que alterna o estado do led de acordo com o pressionar de um botão
● O circuito será montado tal qual no exemplo II, porém somente com um led e com o botão ligado no pino 2.
● O programa no entanto funcionará por interrupções.
25/05/14 Frederico Möller 54
Exemplo VIII
● O programa é bem simples, temos a variável valor que vai corresponder ao valor da saída lógica do pino 13 e 3 temos 3 funções.
25/05/14 Frederico Möller 55
Exemplo VIII
● A primeira função é a que vai ser chamada na nossa interrupção, ela alterna a variável valor (de 0 para 1 e 1 para 0) e dá um delay de 0.1s
25/05/14 Frederico Möller 56
Exemplo VIII
● Em seguida temos o setup, onde configuramos o pino 13 para saída e também confuguramos a interrupção
25/05/14 Frederico Möller 57
Exemplo VIII
● A interrupção está configurada como 0,botão,RISING, ou seja toda vez que o pino 0 de interrupção (que é o pino digital 2) alternar seu valor lógico de BAIXO para ALTO o programa será "pausado" e a função botão() será chamada.
25/05/14 Frederico Möller 58
Exemplo VIII
● No loop tempos uma escrita digital no pino 13 equivalente à variável valor.
● Assim temos que toda vez que o botão for pressionado, ele causará uma interrupção que fará no final das contas que o valor de saída do pino 13 seja alternado.
25/05/14 Frederico Möller 59
Exemplo VIII
● É importante salientar que, apesar do delay , não temos aqui um controle "anti-bouncing", implementar ele para interrupções pode ser um pouco mais complicado. Mas isso será visto na próxima lição.
25/05/14 Frederico Möller 60
Exercício VIII
● Um grande uso para interrupções é o botão de pânico. Esse botão para a máquina em qualquer ponto do procedimento e não permite que ela volta ao funcionamento sem que antes algumas ações sejam executadas.
● Nesse exercício, faremos um botão de pânico.● O arduino executará um ciclo, ascendendo
cada hora um led e apagando os demais, nessa ordem: leds vermelho, amarelo e verde.
25/05/14 Frederico Möller 61
Exercício VIII
● Se o botão de pânico for acionado, o ciclo automático deverá cessar, passando o controle para o modo manual, que será feito por um potenciômetro.
● Com o potenciômetro o operador deve poder escolher qual led vai ficar aceso.
● Para voltar ao modo automático, o operador deve fazer com que o led vermelho fique aceso e em seguida deve apertar um outro botão.
● Apenas um potenciômetro deve ser utilizado.
25/05/14 Frederico Möller 62
Exercício VIII
● Este foi com certeza o exercício mais complexo deste curso. Uma resposta pode ter umas boas 40 linhas de código e dependendo da abordagem pode exigir um certo domínio sobre algebra linear e até derivação.
● Felizmente não é o caso da resposta que será apresentada à vocês. Ela, apesar de grande não é nada mais que uma combinação de vários comandos simples.
25/05/14 Frederico Möller 63
Exercício VIII
● Vamos começar com um diagrama de blocos, para facilitar seu desenho no slide, apresentarei ele horizontalmente ao invés da forma vertical na qual esse tipo de gráfico é comumente apresentado.
25/05/14 Frederico Möller 64
Exercício VIII
Inicialização de variáveis globais
Função panico
Função restaura
Função Setup
Função Loop
25/05/14 Frederico Möller 65
Exercício VIII Inicialização de variáveis globais
● Como na maioria dos exercícios e exemplos, começamos o programa declarando as variáveis globais que serão usadas no decorrer do mesmo
● Temos uma variável lógica "modo_manual", que servirá para indicar que o dispositivo está sendo controlado pelo potenciômetro.
● Temos uma matriz de inteiros "valor" 3x3, contadores k,i,j, uma variável "kbas" e duas variáveis float, pot e pos.
25/05/14 Frederico Möller 66
Exercício VIII
● A função panico é declarada logo em seguida. Ela simplesmente armazenao valor da porta analógica 0 na variável pos.
● A variável pos vai indicar a posição do potênciometro no momento em que a função de pânico foi chamada.
● Em seguida, a o valor da variável k é armazenado na variável kbas.
● Posteriormente veremos o que significa o valor de k.
● Por fim, a função termina assinalando que o modo manual está ativado.
Função panico
25/05/14 Frederico Möller 67
Exercício VIII
● A próxima função é a de restauração. Ela possui um condicional interno.
● A função restaura só vai causar alguma alteração no programa se o modo manual estiver ativado e o valor de k for 0
● Neste caso ela assinalará que o modo manual está desativado
Função restaura
25/05/14 Frederico Möller 68
Exercício VIII
● A função setup segue com a seguinte lógica:
Função Setup
Conf dos pinos
Atribuição das interrupções
i=0 j=0 valor[i][j]=0
valor[i][j]=1
i==j? j++
J<3?
i++
J<3?
J<3?
25/05/14 Frederico Möller 69
Exercício VIII
● Em setup temos declarados inicialmente a função dos pinos 13,12 e 11 (todos saída, estarão ligados à leds)
● Em seguida apontamos as interrupções nos pinos 2 e 3.
● O pino 2, ao passar de valor baixo para alto, vai chamar a função panico. Já o 3 vai chamar a função restaura.
Função Setup
25/05/14 Frederico Möller 70
Exercício VIII
● Em seguida temos dois laços for, um "dentro" do outro.
● De 0 a 2, os laços vão inicialmente preenchendo a matriz valor com 0. No entanto, um condicional interno faz com que se i for igual a j, ou seja, se estivermos na "diagonal principal da matriz", a célula receberá um 1.
Função Setup
25/05/14 Frederico Möller 71
Exercício VIII
● O resultado será uma matriz identidade 3x3
Função Setup
VALOR
J/I valor[i][0] valor[i][1] valor[i][2]
valor[0][j] 1 0 0
valor[1][j] 0 1 0
valor[2][j] 0 0 1
25/05/14 Frederico Möller 72
Exercício VIII
● Uma importante observação pode ser feita sobre essa matriz.
● Considerando cada 1 como um alto e cada 0 como um baixo, a matriz pode representar muito bem a sequência com que os leds devem ser acionados.
● Se considerarmos cada coluna como um dos pinos 13,12,ou 11 e cada linha como um momento, teremos a sequencia de acionamento!
Função Setup
25/05/14 Frederico Möller 73
Exercício VIII
● O resultado será uma matriz identidade 3x3
Função Setup
VALOR
t/PINO 13 12 11
t0 ALTO BAIXO BAIXO
t0+1 BAIXO ALTO BAIXO
t0+2 BAIXO BAIXO ALTO
25/05/14 Frederico Möller 74
Exercício VIII
● Finalmente tempos nossa função loop:
Função Loop
DigitalWrite13a11 de acordo com a linha k da matriz valor
Ler potenciômetro
Modo manual?
K vai variar de 0 a 3 de acordo com a distância em 50 unidades de kbas
Função Loop
K vai variar de 0 a 2 mudando uma unidade a cada 1s
25/05/14 Frederico Möller 75
Exercício VIII
● Finalmente tempos nossa função principal
● Nela primeiramente escrevemos os valores de cada led.
● Depois é feito um teste lógico, se não estivermos no modo manual ele vai esperar um segundo, incrementar k em uma unidade e se k for maior que 2 k retornará a 0
Função Loop
25/05/14 Frederico Möller 76
Exercício VIII
● No entanto, se estivermos no modo manual, ele vai esperar 0.1 segundos e então vai atualizar o valor de k em relação ao kbas e a posição atual do potênciômetro.
● K pode, nessa correção dar um valor entre -2 e 4, quena verdade correspondem 2 ciclos de 0 a 2. As devidas correções são feitas para evitar que o valor seja extrapolado
Função Loop
25/05/14 Frederico Möller 77
Revisão
● Nessa lição, aprendemos sobre:– Conceitos básicos sobre interrupção– Bibliotecas no arduino– Interrupção por tempo e a biblioteca timerOne– Interrupção por sinal.
25/05/14 Frederico Möller 78
Leitura complementar
● Aqui vão alguns exemplos de como usar as interrupções de tempo SEM usar a biblioteca timerOne:– http://blog.oscarliang.net/arduino-timer-and-
interrupt-tutorial/
25/05/14 Frederico Möller 79
Dúvidas???
25/05/14 Frederico Möller 80
Obrigado e até a próxima lição!!!