Base on frequency meter code by Rajendra Bhatt of embedded-lab.com, I made a tachometer reading using PIC18F458 timer0 (configured to 8 bit and read from RA4 pin) but before making the actual circuit, I had it simulated using Proteus. Here's the code
sbit LCD_RS at RC2_bit;
sbit LCD_EN at RC3_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;
sbit LCD_RS_Direction at TRISC2_bit;
sbit LCD_EN_Direction at TRISC3_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;// Define Messageschar msg2[]="RPM=";char*rpm ="0000";int RPM1;int RPM2;long Calc_RPM;// Display RPMvoid Display_RPM(unsignedlong rpm2write){
rpm[0]=(rpm2write/1000)%10+48;
rpm[1]=(rpm2write/100)%10+48;
rpm[2]=(rpm2write/10)%10+48;
rpm[3]= rpm2write%10+48;
Lcd_Out(1,5, rpm);}// Main Programvoid main(){
CMCON =0x07;// Disable Comparators
ADCON0 =0x00;// All AN to Digital Input
ADCON1 =0x00;
TRISC =0x00;// PORTC O/P
TRISA =0b01010000;// RA4/T0CKI input, RA6 is input for Ext OSC
T0CON =0b01111000;// Prescaler (1:1)// 0------- TMR0ON off// -1------ T08BIT is set for 8 bit counter// --1----- T0CS is set T0CKI pin// ---1---- TOSE set increment hi-low// ----1--- PSA Prescaler not assigned// -----000// Initialize LCD display
Lcd_Init();// Initialize LCD
Lcd_Cmd(_LCD_CLEAR);// CLEAR display
Lcd_Cmd(_LCD_CURSOR_OFF);// Cursor off
Lcd_Out(2,1,msg2);do{
T0CON.TMR0ON=1;// On the timer
TMR0L=0;
Delay_ms(1000);// Delay 1 Sec//-- RPM Calculation = (60 x Frequency)/PPR --//
Calc_RPM =(60*TMR0L)/4;
Display_RPM(Calc_RPM);}while(1);// Infinite loop}
basically what I did is calculating the RPM using formula RPM = (60 x f )/ Pulse per revolution, where the pulse per revolution is set to
4 PPR in my case. It then displayed to LCD display using Display_RPM function. below is the simulation circuit using Proteus.
as you can see in the picture, the rpm number seem to be fluctuating, it actually jump from 450 to 465 when simulated. I just wonder why is that happened and is it a way around it?.
Thank you so much in advance for any help from you guys.
so ,it means that change in TMR0L could be from 30 up to 30.6666
not possible ,because its' a byte ( 0 to 255)
and you are working with integer ,not floating point, so rounded value.
Resoltution is to poor by using this methode.
Try to measure the periode , time between each pulse , using timer0 in 16 bits mode.
and convert to RPM with a formula using floating point.
or much better, using capture mode CCP1 with Timer 1 and RC2 input.
Have a look on my web page **broken link removed**
you will get 2 examples
one in mikroC with 16F877
one in C18 with 18F262
2 ranges of measure .. 4.8Hz up to 25000Hz
tested with a Quartz generator
but it's could be fine, if you know what is your range of RPM (aproxmaively)
to apply the best solution Frequency counting or periode couting.
.
if you have the frequency in Hz , easy to transforme in RPM !