RPM meter is very common problem in Embedded system development. Most of the time we need to measure RPM and for this we need some kind of RPM or Tachometer. The most common approach that is used for making Tachometer or RPM Meter is to measure pulses for a specif duration and then multiply it with some constant to get the assumed value of actual Revolutions that could be in One minutes. In this case the resolution of the RPM is very low. In this post we are going to build the RPM Meter with high resolution which could measure rpm with even 1 rotation change. So let’s get started.
Problem with classic approach
We had created Frequency Counter with Arduino and with same approach we could measure the revolution per minute(RPM). One example of Digital Tachometer is explained in This Instructable Post. According to this method the Revolutions are counter as External Interrupts. Every time when a new pulse is occurred then then counter is incremented via external Interrupt ISR function. After One Second Delay the interrupt is disabled and total counted rotations so far are converted into rpm via following formula.
Now because we know that time = 1 second mean total 1000 milliseconds then the actual formula the we get will be just multiplying total rotations got in one seconds with 60. But in this case, the total resolution we get is 60. Which means we are unable to count rpm < 60. Also, We will not be able to count RPM between 60 and 120 and same will be true for 120->180. To conclude we can say that the calculated RPM will be incremented by multiples of 60 so the accuracy will be compromised.
Quick Fix: Increasing the Delay
To increase accuracy with above mentioned algorithm one simple and most common approach which is adopted in most of tachometers is to increase their calculation time. So most of Tachometers calculate pulses for 6 seconds instead of 1 second and after that multiply with 10 to come up with 1 minute calculations. In most of applications this solution somehow satisfy the need. But still the resolution is 10. And most of the time you will see that the display of the tachometer is some how not changing the last digit which is stuck to zero.
Problem: Unable to catch Instantaneous change
Now the total calculations are delayed for 6 seconds and to view the change of total RPM we need to wait for six seconds. The best calculations could be done to calculate the rotation pulses for one minute which will calculate rpm with even 1 rotation change but, We will not be able to adopt the instantaneous change and user have to wait for one minute to view the abrupt change, which is definitely not acceptable in case of tachometer who are required to pick instantaneous change.
Fully Responsive Calculations with High Accuracy
So far we had observed two key problems with classic approaches
- Low Resolution: Not able to measure accurate RPM
- Not Responsive: Not able adopt instantaneous change in rotations.
To handles above problems together we need to change our method of calculations. So instead of calculated the frequency of rotations and then multiplying it with some constant to get assumption of one minute rotations we can calculate time between two revolutions. Here is an Image of square wave with two cycles. In following diagram t(R) means time period between two Rising Edges and t(F) means time period between two Falling Edges
So Instead of calculating the Frequency if we calculate time period of the pulse we can easily convert this to RPM using formula which will tell exact RPM even if the RPM change right next pulse. We will always have the correct and accurate RPM with measurement of Instantaneous change. Modern Microcontrollers like AVR and Microchip PIC Provide special Compare and capture mode of timers to calculate time between two events. You can either use that method or follow our simplest approach that we are gonna implement in this tutorial.
We know that
It means that if time = 1 second then the frequency is 1 Hz. So if we want to convert this to RPM via our old method we will get 60 RPM.
Now lets assume that we want to measure get time period of 100 RPM. So what will be the formula to get it? as we know so far that
Which is simply equal to
So if we know RPM and want to find out time period we can do some simple math like this
So if RPM = 100 then time = 0.6 seconds. As you can see, we were not able to calculate time < 1 second in our previous classic approach but now because we are measure time period we can easily calculate the time period and then convert it to RPM. But we know we do not work in fractions here so what we need to do is to convert the unit of time calculation from Seconds to milliseconds.
Now lets build a quick Proteus simulation to test our algorithm. We are using
- Arduino Uno
- JHD16x2 Character LCD
- Function generator to input Pulses
and here is the actual diagram to test our simulation
To calculate RPM we will first enable external interrupt and mark some flag to zero. Which will indicate that no calculations are done so far. Also will will mark current time stamp and then wait for program to enter into our Interrupt service routine.In our ISR we will simply increment our flag and return. In our main loop we will wait for flag to became 2 which will indicate that almost two times the interrupt has been occurred. From that count we will able to know that two edges had passed. We will stop the interrupt at this point so that no further count could occur before we calculate previous one. After that, We will subtract our previous time stamp from current time stamp and store total time period elapsed so far. With this time information we will calculate RPM via above mentioned formula.