segunda-feira, 6 de maio de 2013

Quão rápido isto gira?

Não, não me esqueci de vocês. E pros que estava com saudades, venho com mais uma aula de programação: usando o TMR0 (Timer 0) do PIC para fazer um tacômetro. Nessa aula vou usar o PIC18F4550, mas a teoria se aplica a qualquer microcontrolador que tenha ao menos 1 timer.

O TMR0

Como eu já disse, quanto ao hardware, explicarei aqui para o PIC18F4550. O TMR0 pode operar tanto como contador como timer. Para nós interessará o contador, que pode operar no modo de 8 ou 16 bits. Para cada pulso introduzido no pino T0CKI irá aumentar o valor registrado no TMR0L, responsável pelo TMR0. E isso é tudo que nos interessa por enquanto.

Como usar o TMR0 em um tacômetro?

Primeiramente, pensemos na unidade de medida: o RPM, ou rotações por minuto, ou seja, quantas rotações tenho em um minuto. O tempo podemos "contar" usando o comando delay_ms ou delay_us mas e as rotações? O TMR0. Então, usando um pouco de matemática podemos chegar a uma expressão que nos ajudará a converter um número x de rotações em um tempo t em rotações por minuto. Calculando e quebrando a cabeça pra aliviar pra vocês (até porque nem todos se dão bem com a matemática. OK, tbm não me dou bem) cheguei à seguinte fórmula:

60=P.t.R
 
"Beleza. mas como uso esse troço aí?" Vamos lá:
P= Pulsos por volta. Esse dado varia de caso para caso. Por exemplo: uma ventoinha dessas como as usadas em computador (cooler) gera 2 pulsos por volta, o motor do vídeo mais a seguir gera 8 pulsos. Então você, se não souber, terá que descobrir;
t= Tempo em segundos. Este tempo é o tempo de atualização e que durante este tempo serão contados os pulsos no TMR0;
R= Resolução em RPM. Aqui é a variação em RPM que o circuito mostrará.
"Beleza, mas como aplico?" Vamos a alguns exemplos:

1º: Um cooler que gera 2 pulsos por volta. Quero resolução de 10 RPM. Qual deve ser o tempo entre as leituras?

Vamos lá: 
60=2.t.10 mudando os valores de membro ---> 60/20=t  =>  t=3 segundos

2º: Um motor gera, em sua saída, 5 pulsos por volta, e desejo ter uma suave leitura com atualização de meio segundo. qual será minha resolução?

60=5.0,5.R  mudando os valores de membro --> 60/2,5=R  =>  R=24 RPM

3º: Durante 1 segundo o TMR0 conta os pulsos, com uma resolução de 10 RPM. Quantos pulsos meu motor gera por volta?
 
60=P.1.10  passando pro outro lado ---> 60/10=P  =>  P=6 pulsos por volta.

Passando os cálculos, vamos ao programa.


Teoria na prática

Agora a coisa fica mais simples. Veja esse exemplo:


















Vamos desmontar esse código:
1ª linha: temos a variável rpm sendo declarada como o valor de TMR0L multiplicado por 10, minha resolução (R).
2ª a 9ª linha: extraio os valores de cada casa (unidade, dezena, centena e etc) e escrevo no LCD. Note que o valor é escrito como ch+48: isso pois o LCD recebe caracteres em ASCII, e para se converter um número decimal para ASCII é só adicionar 48 ao valor a ser enviado.
10ª a 13ª linhas: da um espaço (160) e escreve RPM.
14ª linha: zera o TMR0. OBRIGATÓRIO FAZER ISSO, caso contrário, o programa irá somar as RPMs.
15ª linha: dou a pausa de duração t.

Agora vamos lá: apliquemos minha fórmula nesse código para ver se funciona. Meu motor gera 8 pulsos por volta, porém finjamos que não soubéssemos.

60=PtR => 60=P.0,75.10 => 60/7,5=P ==> P=8 pulsos por volta 
Voilá! Funciona =D

Este código exemplificado é apenas parte do programa todo, que não explanarei aqui. Caso hajam dúvidas no resto, me perguntem aqui nos comentários. Lembre-se: sua dúvida pode ser a de outros.
Este fragmento de código DEVE ser inserido dentro de um loop, como While true/Wend, Do/Loop Until 1=0 ou Loop:/goto loop.



Configurando o TMR0 no PIC18F4550

Vou dar uma rápida aqui de como configurar o T0CON, que é o registrador do TMR0. A imagem a seguir é parte do datasheet do PIC18F4550, que trata do TMR0. Quem quiser saber mais sobre o TMR0 e outros módulos dos microcontroladores pode encontrar o datasheet no google.



Vamos lá:
Bit 7: deve ser 1 para habilitar o Timer0;
Bit 6: deve ser 1 para usar o Timer0 no modo de 8-bit;
Bit 5: deve ser 1 para selecionar como fonte o pino T0CKI;
Bit 4: variará conforme a saída do seu sensor;
Bit 3: deve ser 1, pois agora o Prescaler não nos interessa.
Bit 2-0: pode ser qualquer coisa pois não estamos usando o Prescaler. para facilitar, usarei tudo 1.

No programa ficaria:
T0CON=%11111111 ou
T0CON=$FF (deixa o código mais limpo).


Bem, espero que tenha fica bem explicado a teoria. Como já disse, qualquer dúvida pergunte aqui nos comentários. Peço desculpas pela aparência, mas o Blogger está com problemas e não consigo usar recursos importantes. Segue um vídeo demonstrando o funcionamento de um tacômetro com o PIC18F4550. Boa sorte nos estudos e até a próxima.