No Interrupt Tachometer

Hello Forumees,

I've read through the forums a lot regarding a Tachometer plan WITHOUT using an interrupt function, but I couldn't find one.

My problem is that I have multiple codes in one Arduino, and using an Interrupt function to get the RPM every time a magnet passes by would greatly disrupt my other functions. I've calculated the time it takes my other functions to execute and one of them takes more time than it takes for the magnet to make a full revolution and trigger the interrupt again. Also due to other reasons such as using the interrupt for something else that does not happen often... etc so I can't use an interrupt.
I've been thinking of a way to not use the interrupt ,which is to read the hall-effect sensor as an analog pin, since what i will be getting will resemble a pulse train, or a PWM signal, but the problem is that I don't think that each pulse is at the right width and that they are at the right frequency. And to start assembling to test that is costly for me.
Is there anybody that has been able to figure out a way to measure the RPM without using an interrupt function?
Thank you,

  • cuppe

Is there anybody that has been able to figure out a way to measure the RPM without using an interrupt function?

Yes, of course.
Depends on the range to be measured, though. (hint)

You could design a frequency to voltage converter and attach it to an analog input.

The input pulses drive a monostable (perhaps a 555 timer) and its constant duration pulses at a varying frequency can be integrated with a low pass filter (R and C) to give a voltage more or less proportional to the frequency.

Sometime electronics not software is the answer.

Why do you believe an interrupt would greatly disrupt your other functions? As long as the ISR is kept short and fast, there should be no discernible interruption to your other routines.

When i asked if anybody has been able to find a way, I was implying that I would like to know what that method was.

Simply saying Yes, of course, yup, sure, it's been done, why wouldn't it work, some1 must have done it, it's been done, it's possible, i did, i know some1 who did.... etc those statements are of no help to me or anybody else on this forum unless accompanied with the actual explanation of the method. The same applies for "Hints", please spend the extra calories and type out clearer statement of the solution or idea you are suggesting.

The same applies for non-constructive criticism of others' Ideas/suggestions/methods regarding this topic.

Also I posted this topic to find a method regarding NO-INTERRUPT methods, there are plenty of reasons I or anybody else visiting this post might have to not use an interrupt function, I would like to keep the scope of this topic intact and well directed towards the problem in hand. Not to try and turn the topic to an Interrupt Dependent method. there are plenty of those around the forum, posting this would be pointless if we aim in that direction.

I know this is coming out strong and very rude of me and I apologize in advance for what i said, but it is necessary to define those points in order to get somewhere. :slight_smile: :wink:

As for the frequency to voltage conversion, that sounds like a great idea! please correct me if I'm mistaken:

The purpose of this method is to read the RPM as an analog input whenever desired.

Step 1) Attaching the pulse source (In this case a Hall-Effect Sensor) to a stable pulse source with a constant pulse width (in this case a 555 timer) that gets activated every time it receives a pulse from the first source.

That is, the 555 timer would convert the hall-effect sensor's pulse with irregular width to a pulse with a known certain width while in the same time maintaining the same frequency at which the hall-effect sensor is generating it's pulses.

So now we have a train of pulses with a certain known width, this train varies in frequency depending on the RPM.
if rpm increases, the frequency would increase.
if rpm decreases, the frequency would decrease.

Step 2) Now what we need to do is interpret the frequency in terms of voltage:
We use a F/V (Frequency to Voltage converter) such as TC9400 to convert that frequency to an analog voltage.
if frequency increases, the analog voltage output of the F/V increases.
if frequency decreases, the analog voltage output of the F/V decreases.

Step 3) Finally, we connect the analog voltage to an analog input pin on the Arduino and read it.

Concerns regarding this method that hopefully might be answered by me or somebody else through testing or previous experience:

A) Is Step 1 necessary ? or is the F/V able to function properly using non-uniform width pulses generated by the hall-effect sensor.

B) Is there a lower/upper limit to the frequency tested? or does this method work for very low and very high frequencies. And what is your definition of Very low and Very high?

C) How wide should the pulses be at the end of Step 1? That is, to what duration should we set the 555 timer to be on for each pulse entered to it.

D) Most importantly, Does this method work?

Other Ideas, Methods, Schemes anybody has any experience with to achieve measurement of RPM (or Speed, Revolutions... etc) WITHOUT using an interrupt function are all welcome and encouraged !!! :slight_smile:

anybody has any experience with to achieve measurement of RPM (or Speed, Revolutions... etc) WITHOUT using an interrupt function

How about if you answer Mike's question. Are you trying to measure something that is rotating once a week, twice a century, or 30000 RPM. There is a big difference in you one would measure slow rotation speed versus very fast rotation speed.

The size of the thing rotating has an impact, too, along with the amount of space you have to work with, and your ability to attach stuff to the rotating shaft.

My problem is that I have multiple codes in one Arduino, and using an Interrupt function to get the RPM every time a magnet passes by would greatly disrupt my other functions.

Does receiving serial data, which uses interrupts, adversely impact those other functions?

How have you managed to have multiple codes in one Arduino. The usual limit is one. Lots of people would like to be able to load more than one sketch at a time. Or are you just being loose and free with the term "codes"?

the RPM (Revolutions PER MINUTE) I am trying to measure can be any where from 0 to 4000.

As for the availability to attach components on the rotating part also vary from a disk with a radius of 5 cm to a disk with a radius of 30 cm.

As for the availability to attach components on a stationary part beside the rotating part, the space also varies between a square with width of 1cm to a square with a width of 30 cm.

As for the multiple code statement, I was using Code in a loose and free context, i meant multiple functions that each have an unrelated purpose. However, those functions must not be interrupted as they are being executed.

Regardless of the reasons of why I do not want to use an interrupt function, I would like to stress on the point that the topic is about finding a solution that does not include the interrupt function.

For now, since this is getting people confused, let us assume that our starting point is a hall-effect sensor that provides us with pulses of unknown widths and unknown frequency, and we wish for the Arduino to either count those pulses or in one way or another be able to interpret them and be able to get the RPM from them.

At slow speeds, if loop is not delayed, the Arduino will be available to read each pulse using digitalRead in a polling manner.

If loop is delayed, it can't poll often enough to be assured of getting every pulse.

If this is the case, you have two choices.

First, wait for a pulse, using pulseIn. Assume that all pulses have the same time between them (constant rotational speed).

This may, or may not be a reasonable assumption.

If not, you have to use the other method - interrupts.

Properly used, interrupts will suspend what the current function is doing, do there thing, and the current function will resume right where it left off.

The key is properly used. The ISR must be fast, typically just incrementing a counter.

But, you've absolutely ruled out using interrupts. So, you can use only polling or pulseIn, both of which have limitations as discussed.

Thank you for the reply PaulS. So we're back to the only plausible idea which is Si's suggestion of using a timer to regulate the pulse widths and then an F/V to convert to analog.

I've been doing some research on this topic in general, and somebody on one of the many forums I've been through mentioned a method that seemed very interesting. However he did not explain things in more than two lines and so people after him were left confused as to how he pulled that off.

The method is the following:

you set the counter of the atmega chip to count every pulse.
when the counter is full, it will raise a flag.
each flag is 256 rotations.
take the time between flags to get rpm.

Now, I'm not sure exactly what he meant but I think what he was trying to say is that he sets the chip counter to 8 bits, and SOMEHOW mapped the counter to the interrupt pin, where when the interrupt pin triggers, it ONLY increments the chip built in counter rather than interrupt the function. then once the counter's 8 bits (256) slots are full, it raises a flag bit. If we take the time difference between two flag raises it would give us the speed.
That idea would be GREAT, if it worked.
But what I'm not sure about is whether it's possible to have the interrupt pin trigger or increment the counter bits in the chip counter without disrupting the running programs, doesn't that imply multi-threading ???

On the other hand, if it's possible, then problem solved, we would only need to poll for the flag bit.

This topic needs to get more attention as I think making a clear guide on how to achieve our goal would be greatly helpful to many people.

doncuppe, your question is a very good one and you're learning, just like I did, that you have to put up a certain abrasiveness here, but the answers are usually worth it. Best to rise above and ignore it :slight_smile:

I think the freq to voltage converter is an interesting idea, and measuring pulses without using interrupts, even as a thought problem, is a great question, and one I've had.

What if you want to monitor pulses from several sources? With frequency to voltage, you could easily do that, but with interrupts, there could be missed pulses, right?

I hope we have more discussion of it here, thanks for starting the thread and keeping it focused!

Can't help you, but I to would be interested in a "No interrupt Tachometer. I had built a project using a hall effect switch and the tach is pretty accurate, but it uses the interrupt. Without using an interrupt, the thing worked, but was not consistently accurate.

I'm not sure if it would work or not, but you might be able to get enough accuracy by polling the input multiple times per loop. I realize this might not work if your other code doesn't allow for gaps.

I can't think of the registers to play with right now but you can route timer clock to the outside world on one of the pins (pins T0 for timer 0 and T1 for timer 1).

Therefore you can clock the timer with your pulse.

Having done that you can read the timer value at regular intervals to determine the count and therefore the frequency.

This will only give you a resolution of 1 in 256 though and at slow speeds even worse unless you accululate pulses for a long time, in fact a sliding accumulation window width would be a good idea to keep the resolution good for all speeds.


Rob

The frequency to voltage converter approach is unlikely to work well: 0 to 4000 RPM (it took six replies to get that value) is a dynamic range of almost 12 bits, but the A/D converter is only 10 bits.

There may be some abrasiveness here, but when people ask vague questions without a complete specification or explanation of constraints, what do you expect?

The method is the following:

you set the counter of the atmega chip to count every pulse.
when the counter is full, it will raise a flag.
each flag is 256 rotations.
take the time between flags to get rpm.

How were you planning to measure RPM before? To measure RPM by software you'll need a timer and a counter. You can count by polling, although I'm quite sure it won't work on 4000 RPM, or use a counter.

You set a timer to create an interrupt, say every 10ms or so, and you create the interrupt when the counter overflows. Every time the counter overflows you increment a variable.

Every time, the timer gives you an interrupt, you divide the pulses you counted (the incremented variable *256 + actual counts) by the time you set your timer to and there you have it. PULSES/ms. You then just need to do the math to get RPM.

Otherwise, if you want to go without interrupts at all, the frequency converter sounds like a pretty good idea to me.

I know that you wanted to measure without interrupts, I just got confused as to how you would measure time without them.

I don't think that you'll have much trouble with interrupts, depending on the rest of the code of course, you may feel the program gets slow at high speeds of the wheel.

Thank you very much for all the support from everybody, we are definitely getting somewhere with this!

Regarding the input polling, yes that is always an option however that leaves huge room for error, as well as it is inefficient. However, it IS one of the simplest methods, I will be making a comparison later regarding the simplicity of the methods and their efficiency.

As for Graynomad thank you very much for the information, that was exactly what I was looking for when i mentioned the example of the chip counter, i forgot it was called "timer counter" :stuck_out_tongue:

It is late here and I need to go to sleep, but I will be back tomorrow in order to organize all the possible methods we have, If anybody gets around on finding out the register bits needed to be modified to achieve what Graynomad has mentioned that would be great, I will be doing my due diligence as well.

As for the A/D being 10 bits and not having the capacity for 4000 numbers, we can always divide the resolution by 4, It won't make much difference between 3024 and 3028 RPM. Besides, Other people visiting this topic might not have a number as high as 4000 RPM.

As for the concerns I've written about earlier regarding the frequency-to-voltage converter method that Si suggested, I've been able to find some guidelines that would help address them.

In a nut shell, since I need to go for the moment, pulse width that is generated by the timer is specified by the F/v (Frequency-to-voltage converter), the same applies for the lower/upper limits of RPM/frequency, however it's always easy to manipulate that by adding/removing magnets. But more of all that later in detail.

Keep the information coming guys/girls and thank you all again, this is a great step towards the goal of this topic, and maybe other future topics as well.

:slight_smile: