Tacômetro Digital com PIC16F877A
O TIMER0 do PIC no modo contador, funciona fornecendo pulsos no pino RA4/T0CKI durante 1 segundo. Este valor corresponde ao número de revoluções por segundo (RPS), que é transformado para rpm para exibição no LCD.
A rotação máxima é de 15300rpm e a mínima é de 120rpm.
Para o projeto utlizei um cristal de 4Mhz.
DOWNLOAD
Firmware: tacometro_digital.hex;
Arquivo de simulação do Proteus:tacometro_digital.dsn;
CÓDIGO-FONTE
MikroC PRO PIC
//Configuração dos pinos do LCD sbit LCD_RS at RB4_bit; sbit LCD_EN at RB5_bit; sbit LCD_D4 at RB0_bit; sbit LCD_D5 at RB1_bit; sbit LCD_D6 at RB2_bit; sbit LCD_D7 at RB3_bit; sbit LCD_RS_Direction at TRISB4_bit; sbit LCD_EN_Direction at TRISB5_bit; sbit LCD_D4_Direction at TRISB0_bit; sbit LCD_D5_Direction at TRISB1_bit; sbit LCD_D6_Direction at TRISB2_bit; sbit LCD_D7_Direction at TRISB3_bit; //variaveis char texto1[7], numflancos=0; int rpm, rads; void main() { OPTION_REG=0b10111111;//configura o timer0 com clock externo e prescaller off. Lcd_Init(); //Inicializa o LCD. Lcd_Cmd(_LCD_CLEAR); //Limpa o display. Lcd_Cmd(_LCD_CURSOR_OFF); //Apaga o cursor. Lcd_Out(1,1,"MICROCONTROLANDOS"); //Escreve no LCD Lcd_Out(2,1,"TACOMETRO DIGITAL"); //Escreve no LCD Delay_ms(10); Lcd_Cmd(_LCD_CLEAR); //Limpa o display. while (1){ TMR0=0; //Inicializa o registro TMR0 com o valor 0. Delay_ms(1000); //Conta durante 1 segundo. numflancos=TMR0; //numflancos=velocidade em rps. rpm=60*numflancos; //Transforma para rpm. IntToStr(rpm,texto1); //Transforma rpm em texto. Lcd_Out(1,10,texto1); //Escreve no LCD Lcd_Out(1,1,"RPM :"); //Escreve no LCD Delay_ms(10); //Espera para nova medição. } }
Boa tarde, alguém conseguiria incluir uma rotina no programa para ligar um led quando a rotação atingir 100RPM e desligar quando estiver abaixo deste valor, obrigado.
ResponderExcluirOlá!
ExcluirApós "void main(){" coloque "TRISC.F0=0;" para definir o pino rc0 como saida e após "rpm=60*numflancos;" insira "if(rmp>=100) PORTC.F0=1; else PORTC.F0=0;"
Boa tarde pegando carona na idéia deste projeto do RPM estou tentando criar um frequencímetro com o pic 18f4520 de forama mais simples usando o TIMER1 e esta funcionando bem e estável, porém só estou conseguindo ler até 256HZ preciso que ele leia até no mínimo 5KHZ goataria de uma ajuda.
ResponderExcluirEstou usando o compilador Mikroc-Pro, segue o código.
//****************************// VARIÁVEIS //******************************
char texto1 [20];
int contador;
int HZ;
// **************************// FUNÇÃO PRINCIPAL // ***********************
void main() {
T1CON=0b00000011; // Timer 1 configurado no modo contador
TMR1H=0Xec; //Parte auta da contagem
TMR1L=0x78; // Parte baixa da contagem
TRISC.RC0=1; // Configura porta como entrada
PORTC.RC0=0; // Condição inicial zero
ADCON1=0X0F; //Configura todos os pinos A/D como I/O xde uso geral
Lcd_Init(); //Inicializa o LCD.
Lcd_Cmd(_LCD_CLEAR); //Limpa o display.
Lcd_Cmd(_LCD_CURSOR_OFF); //Apaga o cursor.
Lcd_Out(1,5,"PROJETO."); //Escreve no LCD
Lcd_Out(2,2,"FREQUENCIMETRO"); //Escreve no LCD
Delay_ms(2000); // Aguarda
Lcd_Cmd(_LCD_CLEAR); //Limpa o display.
//***************************// LAÇO DE REPETIÇÃO //***********************
while (1){
tmr1l=0;//Zera parte baixa do timer1
Delay_ms(1000); //Conta durante 1 segundo.
contador = tmr1l; //Atribui o a contador o valor contido em tmr1l.
HZ=1*contador;//1*contador; //Transforma para Hz.
IntToStr(contador,texto1); //Transforma HZ em texto.
Lcd_Out(2,7,texto1); //Escreve no LCD
Lcd_Out(1,4,"FREQUENCIA"); //Escreve no LCD
Lcd_Out(2,6,"HZ :");
Delay_ms(5); //Espera para nova medição.
}
}
voce tem que utilizar a parte alta e baixa do timer1.
ExcluirDentro do while vc pegou somente o valor de TMR1L(o valor max. é 255)
voce tem q fazer o seguinte:
...
while(1){
TMR1L=0;
TMR1H=0;
Delay_ms(1000);
contador = (TMR1H << 8) + TMR1L;//o valor max q é 65536
...
Boa noite
ResponderExcluirEstou com uma dúvida estou montando esse projeto só que não está dando certo estou usando essa programação com está relação de itens gostaria de uma ajuda?
Emissor IR
Receptor IR
Arduino Uno
Resistor 220ohm
LCD 16x2
potenciômerto de 10ohms
Programa
#include
/*
* Optical Tachometer
*
* Uses an IR LED and IR phototransistor to implement an optical tachometer.
* The IR LED is connected to pin 13 and ran continually. A status LED is connected
* to pin 12. Pin 2 (interrupt 0) is connected across the IR detector.
*
*
*/
int ledPin = 13; // IR LED connected to digital pin 13
int statusPin = 6; // LED connected to digital pin 12
volatile byte rpmcount;
volatile int status;
unsigned int rpm;
unsigned long timeold;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
void rpm_fun()
{
//Each rotation, this interrupt function is run twice, so take that into consideration for
//calculating RPM
//Update count
rpmcount++;
//Toggle status LED
if (status == LOW) {
status = HIGH;
} else {
status = LOW;
}
digitalWrite(statusPin, status);
}
void setup()
{
Serial.begin(9600);
//Interrupt 0 is digital pin 2, so that is where the IR detector is connected
//Triggers on FALLING (change from HIGH to LOW)
attachInterrupt(0, rpm_fun, FALLING);
lcd.begin(16,2);
//Turn on IR LED
//pinMode(ledPin, OUTPUT);
//digitalWrite(ledPin, HIGH);
//Use statusPin to flash along with interrupts
//pinMode(statusPin, OUTPUT);
rpmcount = 0;
rpm = 0;
timeold = 0;
status = LOW;
}
void loop()
{
//Update RPM every second
delay(1000);
lcd.clear();
//Don't process interrupts during calculations
detachInterrupt(0);
//Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
//happened once per revolution instead of twice. Other multiples could be used
//for multi-bladed propellers or fans
rpm = 10*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;
//Write it out to serial port
Serial.println(rpm,DEC);
lcd.print("RPM: ");
lcd.print(rpm);
//Restart the interrupt processing
attachInterrupt(0, rpm_fun, FALLING);
}
Olá!!
Excluiresse código rpm = 10*1000/(millis() - timeold)*rpmcount; resultara em erros, pois recebe o valor do rpm durante 1000ms, mas neste calculo, (millis()-timeold) será um valor um pouco maior que 1000ms e tbm não há necessidade de colocá-lo.
Tomei a liberdade de resumir seu código:
int ledPin = 13; // IR LED connected to digital pin 13
int statusPin = 6; // LED connected to digital pin 12
volatile char rpmcount;
unsigned int rpm;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
void rpm_fun()
{
rpmcount++;
digitalWrite(statusPin, !digitalRead(statusPin));
//OU
//digitalWrite(statusPin, digitalRead(statusPin)^1);
}
void setup()
{
Serial.begin(9600);
pinMode(statusPin,OUTPUT);
lcd.begin(16,2);
rpmcount = 0;
attachInterrupt(0, rpm_fun, FALLING);
}
void loop()
{
delay(1000);
detachInterrupt(0);
rpm = 10 * rpmcount;
lcd.clear();
lcd.print("RPM: ");
lcd.print(rpm);
Serial.println(rpm, DEC);
attachInterrupt(0, rpm_fun, FALLING);
rpmcount = 0;
}
Gostaria de saber como ficaria o codigo fonte (pic) pra usar um sensor de efeito hall e que a cada 4 ou 8 pulsos seria um rpm. e para incluir um Velocimetro seria posivel no mesmo PIC e LCD.
ResponderExcluirPOis tenho uma Mobilete e gostaria de colocar um LCD 16x2 com velocidade e RPM
Caso voce utilize um sensor hall com saida digital,
Excluirvoce teria que modificar a seguinte linha:
rpm = 60 * numflancos;
e substituir por:
rpm = (60/4) * numflancos;
gostaria de implementar um velocimetro juntamente com este tacômetro, alguem poderia me ajudar?
ResponderExcluirVoce tem q converter o valor de rpm em km/h.
Excluirboa noite.
ResponderExcluirquais são as alterações necessárias para que o sensor indutivo conte cada metal que ele identificar ? por exemplo em uma esteira de latinhas,para que possa contar quantas latinhas passam na esteira.
obrigado !
Se for com saída digital, não há necessidade de alterar nada, mas deve alimentar o sensor indutivo com 5V.
ExcluirOlá,
ResponderExcluirEu estou tentando compilar o código com o mikroC mas está dando alguns erros, um deles é que a variável não está declarada, poderia me ajudar??
Vc tem q habilitar a biblioteca LCD
ExcluirOlá,
ResponderExcluirConsegui compilar deu certo, mas agora tenho um novo problema, esse PIC 16F877A está saindo de linha, estou tentando usar o PIC16F887 no lugar dele, mas não ta rodando, saberia me dizer se é possível? e o que mudaria no código?
Muito obrigado
Não mudaria nada!!!
ExcluirMontei o projeto conforme acima e estou usando um sensor optico PNP, liguei a saida do sensor no pino 6 do PIC...porém os valores de RPM ficam oscilando e não me retornam nenhuma resposta consistente... variam entre 9000 - 12000...saberia me dizer o que pode ser?
ResponderExcluirTeria como fazer um tacometro com maior resolução? pois este pula de 60 em 60 RPM certo? gostaria de um que tivesse precisão de 1 RPM...
ResponderExcluirCara, por favor tem como me ajudar?
ResponderExcluirEste é um trabalho que preciso fazer para faculdade, e não estou conseguindo.. e o que preciso é exatamente isto, não consegui testar o seu código porque não tenho certeza do que mudar, o meu pic é o F184550, além de que preciso visualizar isto no Pc em vez de no Lcd, mas não consegui nem fazer o básico (estou usando CCP no modo compare), mas o led fica oscilando. Me passa seu e-mail (se vc puder), te envio o código..)
Valeu!!
Olá bom dia.
ResponderExcluirGosto muinto do seu site e tenho aprendido muinto com seus projetos, fiz um curso na microgenios do pic 18f452 copilador mikroc e notei que para o pic16f877 muda os comandos. Vc teria um programa fonte para o pic18f452, vc teria pra vender ou alguma coisa curso, documentários, etc, sobre pic16f628a para mikroc.
no aguardo, Toninho
Ola gostaria de um codigo pronto de pic 18f4550 para um limitador de velocidade ou seja se a velocidade em km/h atingir acima de 10km/h corta um rele.
ResponderExcluiralguem pode me ajudar
negociamos valor.
Não Funciona Direito !!
ResponderExcluira resolução vai de 60 em 60 . Você não consegue alcançar 134 rpm ,só múltiplos de 60 .
O RPM de verdade é calculado pela largura de pulso.
Olá. achei interessante o seu projeto... gostaria de construir um hodómetro baseando-se neste tecómetro, neste caso como seria a programação, o que mudaria?
ResponderExcluirgoooood
ResponderExcluirPorque o minimo de 120RPM.
ResponderExcluirComo posso chegar a 0,1RPM?
trabalhe com uma janela de captura maior que 1 segundo.
ExcluirOlá, estou com certa dificuldade se puder auxiliar muito grato..
ResponderExcluirEstou fazendo um projeto onde vou usar volts para aquecer uma resistência ( resistência de choveiro) onde vai de 0* celsius a 90* celsius ,porém ao chegar nos 90* deve ficar fixa e abrir uma contagem de 15 minutos . terminando a contagem sera desligado o aquecedor.
VC usou timer0 no modo contador e com pulsos no pino r4 , com o valor sendo de rpm sendo calculado para LCD.. Nao estou conseguindo fazer o mesmo porém mandar pulsos no r4 e exibir a temperatura em celsius no LCD simultaneamente com o contador de tempo de 15 minutos, estou usando LM35 para temperatura, sendo 0,01 volts = 1* celsius.
Dê uma estudada em PID (Proporcional Integral derivativa). Acredito que lhe será útil para entender seu projeto. Boa sorte.
ExcluirPID é lógica de controle. Não tem muito a ver com a dúvida dele. O problema é que o pic não consegue ler o LM35 e mostrar com resolução de 0,1°C por conta dos limites do conversor AD. O valor da diferença entre as tensões de referencia máxima e mínima é de 2,5 volts em alguns modelos e 3,0 volts em outros.
ExcluirOlá, gostaria de poder ajustar o rpm de forma analógica, numa interface entre o gerador de sinal e o microcontrolador, como devo prosseguir. Obrigado
ResponderExcluirBoa tarde,eu pretendo fazer um tac[ometro com 2 saidas a reles.Um rele e acionado quando atingir por exemplo 500rpm e o outro quando atingir por exemplo 10000rpm, mas queria que estes valores fossem selecionados externamente e nao por software ,por um dip switch ou por um trimpot=trimmer potentiometer.Alguem me pode ajudar.Agradecido Abraço
ResponderExcluirBoa tarde gostaria de usar para o tacômetro o pic 16F628A e como entrada de sinal o pino RA1 para o RPM , e estou fazendo junto um para temperatura que quero usar de entrada o pino RA0 , o que eu precisaria moodificar no código para isso. estou arecem aprendendo e estou apanhando um pouco .
ResponderExcluirLucas. O problema inicial que vejo é que você pretende usar o PIC16F628A, porém o mesmo não tem conversor analógico-digital (CAD) e portanto você não vai conseguir ler temperatura com precisão.
ExcluirOlá amigo, o que seris necessario para mim transformar isso num velocimetro que imprime a velocidade instantânea em km/h ?
ResponderExcluirBoa Tarde
ResponderExcluirComo fazer para seu exemplo acima passar de 15300?
Lucas
Bom dia ! Eu estou tentando fazer esse mesmo projeto e segui tudo na mesma ordem que você, no proteus consigo simular tudo funciona ok, porem no protoboard não funciona, não aparece nada no display. Poderia me ajudar ?
ResponderExcluirBom dia ! Eu estou tentando fazer esse mesmo projeto e segui tudo na mesma ordem que você, no proteus consigo simular tudo funciona ok, porem no protoboard não funciona, não aparece nada no display. Poderia me ajudar ? Preciso desse trabalho para a aprensentação do meu TCC, se puder me responder aqui ou no meu email caio.ribeiro2017@bol.com.br ficarei muito grato
ResponderExcluirBom dia: tive aulas de pic no senai a a alguns anos mas trabalhei com PLCs ou seja nao usei o pic. agora um amigo me pedio pra fazer um velocimetro digital pra adpitar em um carro antigo que ele esta fazendo "robi" esse carro tem sensor de velocidade no cabio e rotação rall no distribuidor 'RPM'. alguem tem ideia de como fazer esse programa .
ResponderExcluirOlá! O que seria necessário para aumentar a capacidade de captura? Entre 600hz e 800hz.
ResponderExcluirBoa noite Amigo;
ResponderExcluirGostaria de incrementar neste Projeto sensor Oxigênio e Sensor temperatura.
É possivel? tem como me ajudar?
Agradeço desde já.
muy didáctico y aplicable todos los proyectos...
ResponderExcluirmuchas gracias y bendiciones
Blz Thiago o meu funciona de boa só fica oscilando quando nao esta conectado a nenhum sinal variável os números fica mudando tem como deixar ele em zero nessa situação? Nao consegui acerta isso
ResponderExcluir