99 000 RPM Contact-Less Digital Tachometer

99 000 RPM Contact-Less Digital Tachometer

This article describes how to build a contact -less tachometer (device used to count the revolutions per minute of a rotating shaft) using a 8051 microcontroller and a proximity sensor.

As the name implies, what makes this device special, is that it can very accurately measure the rotational speed of a shaft without even touching it. This is very interesting when making direct contact with the rotating shaft is not an option or will reduce the velocity of the shaft, giving faulty readings.

This device is built on an AT89S52 (or AT89C52) microcontroller, an alpha-numeric LCD module and and a proximity sensor to detect the rotation of the shaft whose speed is being measured.

A 600 mA.h Ni-Cd battery provides months of regular use of this device before it needs to be recharged.

Key Features

  • Measures up to 99 000 RPM
  • Instantaneous measurement
  • Automatic DATA Hold Function
  • LCD display
  • Ni-Cad Rechargeable battery

Important: this tachometer uses a proximity sensor. In case you don’t know how to make a proximity sensors, and/or how to operate them, please refer to this article first.

Contact less tachometer principle of operation

The idea behind most digital counting device, frequency meters and tachometers, is a micro-controller, used to count the pulses coming from a sensor or any other electronic device.

In the case of this tachometer, the counted pluses will come from proximity sensor, which will detect any reflective element passing infront of it, and thus, will give an output pulse for each and every rotation of the shaft, as show in the picture. Those pulses will be fed to the microcontroller and counted.

To understand how a micro controller counts pulses, and deduce the frequency of those pulse, please refer to this tutorial about building a frequency meter, that elaborates the process of frequency counting.

The main difference between this tutorial about tachometer and frequency meters, is that we need the reading in pulses per minutes (to count revolutions per minutes), but in the same time, we don’t want to wait a whole minute before getting a correct reading. Thus we need some additional processing to predict the number of revolutions per minute in less than a second.

Instantaneous measurement algorithm

To be able to deduce an RPM reading in less than second, while constantly refining the reading’s accuracy, a simple algorithm have been developed, where a counter and a timer are used. Counter and timers are part of the internal features of a micro-controller, (like the AT89C52 used in this project) and they can be easily configured through programming.

The schematic below (figure 1), shows how the timer and the counter are used for this task; The counter is connected i such a way to count pulses coming from the proximity sensor, while the timer is used to precisely feed the counted value to the microcontroller every filth of a second, and reset the counter to 0. The microcontroller can now take an average of the last 3 readings (saved in C1, C2 and C3) and calculate the average numbers of pulses per fifth second, then multiply this value by 5, to get the number of pulses per second, then multiply this value by 60 to get the number of pulses per minute, which represents the measured RPM. The only purpose of calculating an average reading is that it will allow to get more stable reading and prevent display flickering.

C1, C2 and C3 are used to store the last three reading.

figure 1

 The electronic Circuits

This device is composed of two electronic circuits: the Sensor, which is a slightly modified proximity sensor, and the microcontroller board, which analyses pulses coming from the sensor, process them and display the result on the LCD display.

The micro controller board:

Circuit explanation:

The LCD connections in the green shading is a standard for most of alpha numeric LCDs, the only feature I added is to be able to control the back light via the 80c52 micro controller. The LCD protocol can seem complicated to some of you, and an article should be released soon to explain it.

The part in the blue shading is also standard in any 8051 microcontroller circuit, which includes the reset circuitry along with the crystal resonator that generates the clock pulses required.

The power supply, shaded in light red, regulates a 9V rechargeable Ni-CD battery and also provides a very simple battery monitor, with a green and a red LED, showing whether the battery need to be recharged or not.

The switch SW1, shown in the upper yellow circle, is used to enable/disable the measurement or the counting process. When the switch is pressed, the device measures the RPM of the shaft under test, and constantly updates the reading on the LCD, when the switch is released, the last reading is held unchanged on the display, as long as the device stays on. When the switch is pressed again the old reading is replaced by the new one.

The wire connection P1, which is connected to the output of the sensor, is connected to the pin 3.4 of the microcontroller, this pin has a dual function which is to count incoming pulses and increment a 8, 13, or 16 bit register according to the configuration of the timer T0.

As you may have noticed, this schematics misses tow important items to be called a tachometer: The C code loaded into the microcontroller, which will be discussed later, and the proximity sensor, which will feed the pulses to be counted.

The modified IR proximity sensor

This schematic show the slight modification over the one proposed in this tutorial, which is the fact that the emitter LED uses a current limiting resistor of a higher value, to allow it to be turned on for a long period of time, because in this specific application, we need to turn the IR emissions on or off, but we don’t need to inject high currents to reach high ranges… I recommend the reading of this article that fully covers all the aspects of this sensor.

The CTRL line, is an input coming from the microcontroller (at the wire connection: P4), turning the IR emissions ON and OFF, and the OUT line, is the output of the sensor, which is fed to the microcontroller (at the wire connection: P1).

After analyzing both the main board holding the microcontroller and the sensor, here is a simple diagram (figure 2.A) showing how they are connected together. You will have to refer to the above schematics to see where P1, P2, P3 and P4 goes in the main board, as well as the other lines concerning the sensor.

figure 2.A

This picture also shows what is meant by the connection of the sensor to the main board. The reason for separating the sensor from the main board, is to allow better performance sensors, or even other types of sensors to be connected to the device. In general, modular designs cost more, but is more useful in the prototyping phase…

The software

Here are only small relevant parts of the full C program, that was loaded into the microcontroller after being compiled to a HEX file. Those part of the code were selected as the ones that emphasize the main purpose of a microcontroller in such an application. For examples, function dealing with the LCD operation are not included in this description. Comments in green explains the program. The full code is available in the Project folder, downloadable at the bottom of this article .

#include <REGX51.h>
#include <math.h>

unsigned int clk_tmp,clk_tmp2,clk_sec,clk_sec2;
unsigned intex_pulses,rps,rps_tmp,temp,rps_avg,rps_max;
unsigned int rps_his[5];
char a,b,c,d,e;
unsigned char count1,count2;
unsigned char scale = 4;

delay(y){ // A function to make software delays
unsigned int i;
setup_interrupts(){ // This function initialises the TIMER and the COUNTER to
EA = 1;             // be used in in the trachometre
ET0 = 1;      //set the Timer/counter 0
TR0 = 1;      //Enable Timer/counter 0 to count
TMOD = 0X25;  //counter 0 in mode 1 (16 bit counter), 
              //timer 1 in mode 2 (auto reload from TH1) 
TH1 = 0;      //start counter from 0
ET1 = 1;      //enable timer 1
TR1 = 1;      //Enable Timer/counter 1 to count
PT0 = 1;      //Setup the priorities of timer 1 and timer 0, a 0 gives a
PT1 = 0;      //higher priority.

void int_to_digits(unsigned int number){ //store the 5 digits of an integer 
float itd_a,itd_b;                       //number in the variable a,b,c,d,e
itd_a = number / 10.0;
e = floor((modf(itd_a,&itd_b)* 10)+0.5);
itd_a = itd_b / 10.0;
d = floor((modf(itd_a,&itd_b)* 10)+0.5);
itd_a = itd_b / 10.0;
c = floor((modf(itd_a,&itd_b)* 10)+0.5);
itd_a = itd_b / 10.0;
b = floor((modf(itd_a,&itd_b)* 10)+0.5);
itd_a = itd_b / 10.0;
a = floor((modf(itd_a,&itd_b)* 10)+0.5);

clk() interrupt 3        //timer 1 interrupt
clk_tmp++;          //Software counter for the timing of the tachometer readings
clk_tmp2++;         //Software counter for the display refresh rate
if (clk_tmp2 > (1236)){  // update display
clk_tmp2 = 0;
rps_avg = floor(((rps_his[0] + rps_his[1] + rps_his[2] + rps_his[3] + ___

if (clk_tmp > (6584/scale)){ // update the measured RPM
clk_tmp = 0;
if (P2_0 == 0){
rps = TL0;
temp = TH0;
temp = temp * 256;
rps = (rps + temp)* scale;
rps_his[4] = rps_his[3];
rps_his[3] = rps_his[2];
rps_his[2] = rps_his[1];
rps_his[1] = rps_his[0];
rps_his[0] = rps;
TL0 = 0;
TH0 = 0;

count_pulses() interrupt 1 //counter 0 interrupt
if (scale < 10)      // If the pulses are so fast that the internal counter
scale++;             // overflows, increase the variable 'scale' so that 
}                    // so that readings are recorded at a higher rate

void main(){
   scale = 10 ;
   P3_3 = 0; // ini proximity sensor, OFF
   P3_4 = 1; // ini sensor input
   P1_1 = 0; //turn LCD backlight ON
   P2_0 = 1; //ini count/hold button
   ini_lcd(); // ini the LCD

      P3_3 = ~P2_0;
         if (P2_0 == 1){
         scale= 4;

To understand the functioning of this source code, you must have some basic microcontroller and C language skills. The variable scale is used to control the rate at which the tachometer reads and resets the counter.

The housing of the tachometer

For the housing, an old floppy disk drive case is used, where the tachometer and the battery fits perfectly. Here, those few pictures are worth a thousands words.


[PrettyFileButton path=”https://www.ikalogic.com/wp-content/uploads/2008/01/IKALOGIC-KB-99000-RPM-CONTACT-LESS-DIGITAL-TACHOMETER.zip”][/PrettyFileButton]

[Note: I use ExpressPCB(FREEWARE) to design the schematics and the PCB]


  1. BIJU March 9, 2015 at 10:39 am

    sir ,
    whats the specification of the crystal oscillator ?

  2. navjot sidhu February 5, 2015 at 7:15 am

    at89c52 has only 8kb of programmable flash memory and the software you have provided is about 8.7 kb.what can i do now?

  3. Ivan October 5, 2013 at 7:56 pm

    Hi, that it serves the function of delay (y) and from where in the code?

  4. kalimuthu September 28, 2013 at 1:57 pm

    sir I am using AT89S52 with 24 MHz.I need program.

  5. kalimuthu September 23, 2013 at 3:38 pm

    i need program.please send it sir.

  6. hasan September 19, 2013 at 5:26 pm

    sir how can i measure that the IR circuit is working or not?please help me.

    • Ibrahim KAMAL September 25, 2013 at 10:27 pm

      Well, does it detect the proximity of a white, reflective stripe in front of it? does the output voltage of the opamp changes..?

  7. Rony September 19, 2013 at 4:54 pm

    hello sir,to simulate this circuit i am using Proteus simulator.to feed the pulse to micro-controller i am using a push button switch because the IR has no real time output in Proteus 7.1.But i did n,t get any output in Lcd. i also made this ckt in breadboard but it did n,t work.sir can you say what can be problem. PLZ sir help me

  8. prince September 6, 2013 at 6:01 pm

    can we use breadboard in thi project

    • Ibrahim KAMAL September 8, 2013 at 12:12 pm

      sure. why not? 🙂

  9. kalimuthu August 12, 2013 at 12:42 pm

    R4 is given 300 what does it mean is it 300 ohm or 300 kilo ohm?

    • Ibrahim KAMAL August 19, 2013 at 1:50 pm

      300 Ohms

      • kalimuthu August 21, 2013 at 1:49 pm

        thank you sir.
        in the microcontroller board circuit what is the value of variable resistor R3?

        • Ibrahim KAMAL August 23, 2013 at 7:39 am

          Something between 5K ohm and 15Kohm will do just fine. 10K would be perfect.

          This resistor is just for contrast control of the LCD

          • kalimuthu August 24, 2013 at 2:23 pm

            thank you sir.
            where is connected to positve of 9V ni-cd rechargeable battery and negative of battery.

      • kalimuthu August 22, 2013 at 2:01 pm

        thank you sir

  10. kalimuthu August 1, 2013 at 12:29 pm

    i need to conform that in the receiver circuit diagram the IR sensor led D1 is receiver or not? why the arrow mark indicates outside?

    • Ibrahim KAMAL August 3, 2013 at 9:33 am

      Both leds are emmiter. However, one of them is used a sensor.. read my other article about IR proximity sensors. 🙂

      • kalimuthu August 6, 2013 at 1:24 pm

        thank you sir

      • AKIL August 17, 2013 at 7:12 am

        Ibrahim bhai

        i need help from u regarding program write

        project is “talking car”
        car will speak all fuction to u like head light on/off speed of car, door open. ect
        i have voice ic programmer and voice for same


  11. Kalimuthu July 31, 2013 at 4:03 am

    what is the part number of IR proximity sensor?

  12. kalimuthu July 30, 2013 at 1:23 pm

    pls say full component list used in this product with range and quantity

  13. ali December 8, 2012 at 6:57 pm

    hi…Hex file is 8.7 KB. But for 8051 must be less than 8KB….plz help me

  14. Jose serra November 23, 2012 at 11:12 am

    Can i get a list of hardware to buy? in doing it for a school project.


  15. ali November 1, 2012 at 8:56 am

    hi….i con’t open d-tach.pcb file …plz help

    • Ibrahim KAMAL November 1, 2012 at 10:11 am

      As far as i remember, you need to open it with express PCB software..

  16. Muinuddin Malik May 27, 2012 at 3:05 pm

    sir i want to learn micro controller programming in c please suggess me some name of book with author name

  17. Rakesh May 19, 2012 at 1:47 pm

    are the wires connected to the lcd in order.. that is from 1 on the top to 16 in the bottom?? and how could we connect a pot to the 3rd pin??

  18. Manish Kumar May 15, 2012 at 8:43 pm


    In the lcd only small blocks are showing, nothing showing any thing else.
    What might be the problem?

  19. ashu April 26, 2012 at 2:43 pm

    how the count can be displayed on the lcd? what are the program codes to display on the lcd?

  20. Rakesh April 14, 2012 at 12:30 pm

    Why is the R/W pin of LCD left to ground ??

  21. Rakesh April 13, 2012 at 2:18 pm

    can we interface the serial port with at89c52 using max232 ,as given in engineers garage with at89c51


    • Ibrahim KAMAL April 14, 2012 at 9:07 am

      Yes – of course.

      • Rakesh April 14, 2012 at 2:03 pm

        But how do we send the .hex file to 89C52 when connected to serial port using max232 ? is there any application in windows for burning and erasing files in the MCU ?

        • Rakesh April 17, 2012 at 11:51 am

          is serial programming possible in at89c52 using max232 ?

  22. Rakesh April 13, 2012 at 4:06 am

    is isp not available for AT89C52?? are there any other means to erase and burn the .hex files to the 89C52??

    • Ibrahim KAMAL April 13, 2012 at 7:48 am

      Nope, AT89C52 does not support ISP. only option to erase and reprogram is parallel programmer.

      • Rakesh April 13, 2012 at 11:09 am

        could you give me some help or references on parallel programming?

        • Ibrahim KAMAL April 14, 2012 at 9:07 am

          This one cannot be built at home – unless you already have a programmer (chicken and egg problem!) . So you have 2 solutions: Buy 89S52 or buy a parallel programmer.

          I suggest you buy a 89S52 and build your own ISP. Because sooner or later you will want to switch to much better MCUs like the AVR, and then you will be able to use the same ISP programmer.

          • Rakesh April 14, 2012 at 12:29 pm

            Thanks a lot.. but i am using max232 to interface serial port with 89C52..

  23. Rakesh April 13, 2012 at 2:55 am

    why so many resistors are used for the lcd?

    • Ibrahim KAMAL April 13, 2012 at 7:50 am

      because AT89C52 port 0 is open drain. it cannot output high levels, so it need pull ups to help it reach VCC!

  24. Rakesh April 12, 2012 at 1:14 pm

    whats the lowest rpm it could record?? could i use this tachometer to find the speed of a moving vehicle??

  25. Rakesh April 8, 2012 at 10:20 am

    which software do i use for compiling the c++ code?? how to use it and how to load it in the chip?

Leave A Comment