Go Down

Topic: High speed pulse counting? (Read 35857 times) previous topic - next topic


I am new to Arduino, but I'm a very experienced programmer.
A couple of years ago, I made my own PLC controller for my induction wind turbine.  I am now interested in making a microcontroller for my wind turbine and so I have a few questions:

I would like to interface with a 500 pulse per revolution rotary encoder (24v, so I will use an optoisolator). In my current PLC controller, I had to purchase a special "high speed" card to accomplish this (very expensive!). Considering that I need to measure up to 2200 RPM @ 500 PPR, this means that I need to count up to almost 20,000 pulses per second. I'm assuming that this will be hard to do with the Arduino.
I am willing to change encoders to a lower PPR count - but was wondering what anyone though the maximum PPR (pulse per revolution) encoder value should be?

Also, I'm not sure of main loop resolution on an average program (how many ms/us between iterations of the loop - my Arduino is still on its way so I can't test for myself yet). I am wondering if it is fast enough that I can use a standart input pin, or if I should use an interrupt.  Any advice on this would be appreciated as well!



Sep 07, 2010, 08:37 pm Last Edit: Sep 07, 2010, 08:38 pm by mpeuser Reason: 1
I  made some experiments the other day having to do with generating pulses of around 80 kHz. This is possible with timer interrupts of 12us.

The "loop" as such is very fast, as there is nothing happening outside the loop - it's kind of a fake  ;)

Your application is just edge counting, where - counters are made for (nothing to do with interrupts!).

You might use this library for it


I would look into using either a prescaler or an external counter.

You are looking at 20KHz which isn't really that fast for the Arduino but why waste a microcontroller to just count, it should be busy handling other (higher-level) tasks.

How accurate and how often do you need to monitor the speed?


I would like to monitor the speed at about 20hz - count how many pulses every 50ms and calculate RPM from that.

Maybe I would be better with a low PPR count(5PPR for example) and actually measure microseconds between pulses to calculate RPM? Does this sound more feasible?


Is this a quadrature encoder or a single-line encoder? If single-line you may want to use the input capture functionality of the microcontroller. I don't think there's a high-level Arduino function for this yet but you can always work with the chip registers at the lower level. This will give you single-cycle resolution in period (i.e., 62.5ns if you're running at 16 MHz).

Using interrupts will give you good accuracy but there will be jitter and latency depending upon whatever else is going on in the system. Interrupts are pretty much the only solution if you have a quadrature encoder unless you want to ignore one of the quadrature lines and go back to the single-line encoder case.

And I don't think there's a need for optoisolation if you can connect grounds together; just use a voltage divider to knock down the 24V down to 5V.

Check out our new shield: http://www.ruggedcircuits.com/html/gadget_shield.html


Yes, I'm using a quad encoder - but only using one "pulse train" (I don't need direction information) so essentially its a single-line encoder for how I'm using it.

I'm starting to lean towards using a low PPR value and counting elapsed time between pulses - this should be a lot less demanding.

I'm not sure what you mean by tieing the grounds together to eliminate the optoisolation, could you explain?  Thanks!

(I dont' have a whole lot of experience with electronic circuits, but am trying to learn!)


Can you provide a reference for the encoder that you're using (link to a datasheet would be good). Then I could show you how to hook things up.

Check out our new shield: http://www.ruggedcircuits.com/html/gadget_shield.html


Any of these TRD-N series encoders:

Again, I'm probably going to lean towards a low pulse device, which gives me the option of instead going with a simple hall effect pickup that senses magnets embeded in the turbine blades etc.

The power supplied to the encoder is 24v.

thanks again!


Does this sound more feasible?

I am a little bit astonished about your question. There is no need for any "more feasibility". It is absolutely feasible as I explained, and there is no need for interrupts....
You do not measure the width of pulses for such frequencies!! You count the number of pulses for a definite (gate) time.

This is a most simple application, needing 20 lines of code, or less if you use existing and well working libraries....


Here's what should work for the totem-pole version of the encoders:

Check out our new shield: http://www.ruggedcircuits.com/html/gadget_shield.html


Jon, is there some other reason to replace the encoder?

New encoder >$100
counter IC <$1

Using a 74HC4020 will let you select from resolutions of 500, 250, 125, 62.5, 31.25, all the way down to 0.030 PPR.

The encoder systems I'm most familiar with (extremely high-accuracy position encoders) use a counter and latch system. You feed the quadrature pulses into a quadrature detector which changes it to either COUNT_UP or COUNT_DOWN pulses that feed a series of counter ICs that count continously. Every so often (let take your 50 mSec) a clock pulse comes along and latches the encoder counter which also generates an interrupt. The controller can than takes its time to service the interrupt (as long as it <50 mSec) without losing a single count (because the counter is still counting). Speed can be determined by subtracting the previous from current count and dividing by the sample clock (50 mSec).

Do you really need to monitor continously and a such a high rate? It would seem to me that a wind turbine would not vary it's speed substantially over a period of 100-200 mS.

Frankly, I'm intrigued by the library that deSilva posted.


Yes, the programming will be very easy, I have over 20 years of programming experience. My question was more hardware related.
Let me explain a bit -

Using a low count PPR encoder will only provide a low resolution measurement by using a pulse counting method. For example, if I decide to poll every 50 MS (20hz) for the number of pulses on a 5 PPR encoder rotating at 1800 rpm, would only receive about 6-7 pulses per 50ms polling peroid. This essentially means each pulse would cover a 150ms gap, and thats at the high end of the RPM I need to measure.

However, counting time between pulses allows me to calculate the RPM just using the delta time between any 2 pulses, regardless of the speed at which they are coming in.  This will allow my program to make much quicker decisions, as connecting a 1800RPM generator to the grid before it overspeeds needs to happen very quickly! (I know this from experience using a PLC to do this currently).  I chose 500PPR in the past, as this allowed fairly high resolution for me to respond in a low amount of time.

My thinking was that now that I would like to try a microprocessor instead of a PLC, I should use a lower pulse count and calculate based on delta time instead of counting pulses. (High PPR encoders seem to suffer from  noise a lot more in out application - also the PLC I use didn't have good funtions for measuring elapsed time, which didn't allow me the option to count delta time between pulses)


Sep 07, 2010, 11:27 pm Last Edit: Sep 07, 2010, 11:28 pm by jondecker76 Reason: 1
Tim Williams:

Most of the time, you are correct in that the wind turbine will not change speed quickly. However, one of the main objectives of the controller is the connect the wind turbine to the power grid (through an SCR) as soon as possible after it crosses 1800RPM - the more beyond 1800RPM the alternator is when you connect the line, the higher the THD is as the alternator struggles to get in phase with the line (yes, this has more to do with difference in phase angle than rpm, but trust me, it is very hard on things when you have a large phase angle difference AND a lot of RPM to "slow down" to synchronous speed (i use simple PWM to do this currently, to slowly coax it into phase).  Therefore, it is a huge advantage to start the PWM the instant the alternator hits 1800RPM.  Consider that our turbine blades have a 7:1 lift ratio, the alternator speed can go from 1799 to over 1830 in the matter of a second with a normal gust! THerefore, the quicker I can detect a change in the RPM the better!


Sep 07, 2010, 11:32 pm Last Edit: Sep 07, 2010, 11:33 pm by udoklein Reason: 1
The datasheet http://www.atmel.com/dyn/resources/prod_documents/doc8025.pdf says:

15.2.1 Registers
The Timer/Counter can be clocked internally, via the prescaler, or by an external clock source on
the T1 pin. The Clock Select logic block controls which clock source and edge the Timer/Counter
uses to increment (or decrement) its value. The Timer/Counter is inactive when no clock source
is selected. The output from the Clock Select logic is referred to as the timer clock (clkT1).

And with regard to the sampling times it says

16.3 External Clock Source
Enabling and disabling of the clock input must be done when T1/T0 has been stable for at least
one system clock cycle, otherwise it is a risk that a false Timer/Counter clock pulse is generated.
Each half period of the external clock applied must be longer than one system clock cycle to
ensure correct sampling. The external clock must be guaranteed to have less than half the system
clock frequency (fExtClk < fclk_I/O/2) given a 50/50% duty cycle. Since the edge detector uses
sampling, the maximum frequency of an external clock it can detect is half the sampling frequency
(Nyquist sampling theorem). However, due to variation of the system clock frequency
and duty cycle caused by Oscillator source (crystal, resonator, and capacitors) tolerances, it is
recommended that maximum frequency of an external clock source is less than fclk_I/O/2.5.

The Arduino uses fclk I/O = 16MHz, so your frequency of 80kHz is way below the maximum rating.

Check out my experiments http://blog.blinkenlight.net


Sep 08, 2010, 12:04 am Last Edit: Sep 08, 2010, 12:42 am by mpeuser Reason: 1
As always in such discussions the real constrains and rationals only show up one after the other.

So you have a maximum reaction time when the signals cross some 1800 RPM line = 15 kHz = pulse distance 66us

The Arduino, without tricks, can distinguish between 64 and 68us which is around +/-3% if that suffices you have a response time = gate time  of 1 pulse.

Assume a somewhat more sensible response time of around 1ms. You can precisely determine the combined length of 15 pulses. They will be 1000 us @ 1800 RPM with an error of 4us = +/- 0.2% Does that suffice?

Note the fine difference! This algorithm is not a simple brute force pulse counter but takes into account the exact length of the pulse - it is "phase sensitive" so to speak. A counter would only distinguish between 14 or 15 pulses which gives an error of +/- 3%

The drawback of this algorithm - in its simplest implementation - is, that it is most sensitive around 1800 RPM only, and will not work below 120 RPM at all..

Go Up