In this project we use IR Tx diode and IR Rx diode. The sensor circuit diagram is as follow-
The RPM meter based on two procedures
- Count the pulse
- Calculate the value per second
It is easy to calculate pulse using external interrupt pin. Let use ATmega8 for this purpose. The logic should be as soon as any falling edge is found, it triggered an external interrupt. Now to enable external interrupt on falling edge
#include<avr/interrupt.h>
sei(); //Global Interrupt Enable
GICR |=(1<<INT0); // External Interrupt Request 0 Enable
MCUCR|=(1<<ISC01); // The falling edge of INT0 generates an interrupt request
ISR(TIMER1_COMPA_vect)
{
Global_Variable ++; // update your global variable
}
The next step is to make a delay of 1s with the help of Timer so that we can easily find the counting value of the pulse. This counting pulse is the RPS (Revolution Per second). Let use Timer1 with F_CPU=8MHz and Prescaler=256. The logic is
TCCR1B|=(1<<WGM12); //CTC mode with TOP=OCR1A
TCCR1B|=(1<<CS12); //Prescaler=256
OCR1A=31249; //F_CPU=8MHz,Prescaler=256 Delay= 1s
TIMSK|=(1<<OCIE1A); //Timer/Counter1, Output Compare A Match Interrupt Enable
ISR(TIMER1_COMPA_vect)
{
rps= Global_Variable; //RPS Value
rpm= Global_Variable *60; //RPM Value
Global_Variable =0;
}
Since for purity external interrupt will be executed first than the timer compare interrupt. The main program is as follow-
/************************************************************************************************
*************************************************************************************************
*************************************RPM Meter***********************************************
*************************************************************************************************
Subeer Kumar Sarkar
Electrical & Electronic Engineer
************************************************************************************************
************************************************************************************************
***********************************************************************************************/
#include<stdio.h>
#include<avr/io.h>
#include<avr/interrupt.h>
#include"lcd.h"
float rpm,sample=0,rps;
char display[16];
int main(void)
{
LCD_INIT(); //LCD Initilation
sei(); //Globel Interrupt Enable
GICR |=(1<<INT0); //External Interrupt Request 0 Enable
MCUCR|=(1<<ISC01); //The falling edge of INT0 generates an interrupt request
TCCR1B|=(1<<WGM12); //CTC mode with TOP=OCR1A
TCCR1B|=(1<<CS12); //Prescaler=256
OCR1A=31249; //F_CPU=8MHz,Prescaler=256 Delay= 1s
TIMSK|=(1<<OCIE1A); //Timer/Counter1, Output Compare A Match Interrupt Enable
while(1)
{
LCD_write_string(1,1,"***RPM Meter***");
sprintf(display,"RPM=%.0fRPS=%.0f",(double)rpm,(double)rps);
LCD_write_string(1,2,display);
}
return 0;
}
ISR(INT0_vect)
{
sample++;
}
ISR(TIMER1_COMPA_vect)
{
rps=sample;
rpm=sample*60;
sample=0;
}