Measuring motor speed and display result on LCD

For measuring motos speed there can Optical interrupter used like H21A1. This is a device where IR LED and photo-transistor is coupled in to plastic housing. The gap between then allows interrupting signal with opaque material and this way switching the output from ON to OFF.

This device can be connected to Microcontrollers ICP pin and this way measuring PWM disk (with hole in it) speed can be measured. Disk has to me fixed to axis of motor. Each time the hole of disk passes the gap, optical interrupter will form a pulse which goes to ICP pin to trigger the timer. If take measuring interval 1s, then counted pulses will be equal to turns in Hz.

Lets take Atmega8 microcontroller which is clocked at 8MHz. For this lets use timer pre-scaler 8, then timer will run at frequency equal 1MHz(period 1μs ). Each time the pulse reaches ICP(Atmega8 – PB0 pin) pin then on falling front of pulse input capture interrupt occur. Interrupt service routine counts the number of timer pulses between two pulses. Number of timer counts define the disk speed (RPM - revolutions per minute).


T – duration of one disk turn. The results will be displayed on 2x16 LCD. LCD is connected to AVR as follows:

LCD data pins to AVR PORTD;

LCD control pins to AVR PORTC (RS->PC0, R/W->PC1, E->PC2).

#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd_lib.h"
#define RPM 60000000u
#define ICP PINB0
//timer overflow counter
uint8_t ovs=0;
uint32_t T;
uint16_t PreviousTime, CurrentTime;
uint8_t buffer[15];
uint8_t calculate=0;
//timer1 input capture interrupt service routine
	else if (calculate==1)
			//Saving current timer value on falling edge
	else if(calculate==2)
			//form string with RPM value
			sprintf(buffer,"RPM: %06u",RPM/T);
			//output to LCD
			LCDstring(buffer, 15);
int main(void)
	LCDinit();//init LCD 8 bit, dual line, cursor right
	LCDclr();//clears LCD
	LCDhome();//cursonr home
	LCDstring("Count RPM", 9);
	PORTB|=1<<ICP;//pullup enable
	DDRB&=~(1<<ICP);//ICR1 as input
	TCNT1=0;// start counting from zero
	TIMSK|=(1<<TICIE1);//|(1<<TOIE1);//enable input capture interrupts
	TCCR1B|=(1<<CS11);//start with prescaller 8, rising edge ICP1
	return 0;

LCD library can be found in previous posts.


main.c: In function '__vector_10':main.c:35: warning: implicit declaration of function 'sprintf'main.c:35: warning: incompatible implicit declaration of built-in function 'sprintf'main.c:35: warning: pointer targets in passing argument 1 of 'sprintf' differ in signednessmain.c:35: warning: format '%06u' expects type 'unsigned int', but argument 3 has type 'long unsigned int'What's Wrong with this code?Please help me. Thank you

Dear AdministratorThe code above are worng. You need include the folowwing line and modifications1) #include 2) %06u replace for %06luThe folowing code are incomplet or wrong=============================ISR(TIMER1_CAPT_vect){ if(calculate==0) { TCNT1=0; calculate=1; } else if (calculate==1) { //Saving current timer value on falling edge CurrentTime=ICR1; calculate=2; } else if(calculate==2) { CurrentTime=ICR1; T=(uint32_t)CurrentTime; //form string with RPM value sprintf(buffer,"RPM: %06lu",RPM/

could you sent me this program for mikroc pro.

am getting error like this pls help me outavr-gcc.exe: slt.elf: No such file or directory

This example is pretty old and needs to be re-done due to errors.