1khz frequency downsampling for phototransistor 40k RPM counter

After consolidating my first project, a temperature/pressure/humidity/sensor, I'm working to integrate it on a bigger project, a full shield ready for making an engine test bench.

On my ArduinoUno I have: A0 & A1 reserved for thermocouples reading after two AD595 to linearize output of K. Thermocouples read cylinder head temp. & exhaust gas temp. A2 & A3 reserved for torque & thrust load cells after INA125 signal conditioner A4 & A5 I2C pins reserved for barometric sensor.

D0 & D1 are free, I'm sending serial data via USB so they couldn't be used, am I wrong? D2 "start data acquisition" button D3 "stop data acquisition" button D4 humidity sensor D5 to D10 are reserved to LCD D11 is the RPM signal input D12 is the "propeller blade number" switch, they could be 2 or 1 depending on formula

the code, which starts to be a little HEAVY to run, makes me think that I couldn't make an RPM counter like the one described in the playground. In fact, being it a small model engine for an airplane, I would read propeller passages between IR led and phototransistor, 30000 RPM for two blades of the propeller will be 60k pulse per minute, or if you prefer 1khz. The other case is an engine running up to 40k RPM but with a single blade propeller. If my program will took even if only 1 ms to run, it seems to me that reading won't be accurate, Arduino-based RPM counters that I've seen on the net are intended up to about 5k RPM, while I'm up of one order of magnitude! I thought I won't be able to recognize proper signals, so initially I thought to make a mechanical device, such as a 1:10 gear reducer or an optical chopper, but these two aren't solutions easy to follow and realize at home, and even not so easy to integrate in my own shield! ...plus I have to connect phisically one of these devices with propeller hub, one more problem...

So, my question: would using a "binary counter" like 74ls393 be a good solution for downsampling input frequence of a 16x / 32x / 64 factor? would it recognize the dirty signal from phototransistor or would exist a better solution (e.g. something with a 555 timer, but I have no idea where to start with the circuit!)?

Many thanks for the attention @ my loooooooooooooooooooong post!

D0 & D1 are free, I'm sending serial data via USB so they couldn't be used, am I wrong?

No that is very wise,

you can add an extra serial LCD to the TX pin (harmless if same baudrate)

D2 "start data acquisition" button D3 "stop data acquisition" button

You could merge this to one Start/Stop button. => one pin free

D5 to D10 are reserved to LCD

Consider using a serial LCD with newsoftserial, it will use only one pin (+5V & GND)

60K pulses ==> go for interrupts - http://www.arduino.cc/en/Reference/AttachInterrupt

Below is the basic IRQ sketch, that measures the rotations once per second (in fact a bit longer, to be tuned) and converts it to RPM. Should get you started.

volatile unsigned long counter=0;

void setup()
  pinMode(pin, OUTPUT);
  attachInterrupt(0, IRQ, RISING);

void loop()
  unsigned long tc = counter; // make a working copy of the counter
  counter = 0; // and reset the counter

  Serial.print(millis());          // to tune the delay at the end of loop
  Serial.print(", ");

  unsigned long rpm = tc * 30;  // 2 blades, convert RPS to RPM  *60/2 == *30   - adapt to your specs **
  Serial.print(", ");

  delay(1000);  // should be less to tune to "exact" one second = 1000 millis() per loop

void IRQ()

** Note this formula will change if frequency of reading changes.

I think that if you can tolerate the impact on resolution, then the binary counter idea would be a good way of reducing overhead. My other thought is a second microcontroller handling this portion and communicating the frequency over serial, I2C etc.

Robert, Thank you for the suggestions for how to free some pins. Now it's not a problem for me, but in the future who knows? If I haven't misunderstood the interrupt will lock the cycle to perform rpm measure subroutine, am I wrong? thinking about making an inertial test bench, the resolution on the RPM chart will be reduced onemoretime. In fact, the pulse in output from the phototransistor is very disturbed, I thought to insert a flip-flop to obtain a more "squared" signal. so the consequent idea of a "digital motoreducer" like the binary counter. A resolution of 16 or 32 rpm won't affect the test bench accuracy, even if running an engine of only 1600 RPM it would affect at least a +/- 1%, which is enourmosly good for me!

Dave, thank you a lot. I was thinking too for installing a 2nd microcontroller, but having to do build benches for me and my friends would make me thinking about that they didn't chew almost any word of electronic, and pushin' start button on their PC is never a simple issue :stuck_out_tongue_closed_eyes: :D but employing I2C bus is a really great idea, thank you a lot!

Made some thinking last night... I decide to use both binary counter & interrupt, in addiction to an i2c RTC. Thought this would be the more precise solution! interrupt won't slow cycle excessively but with no error. Then the output will be time between "x" RPM (16 for my case) based on RTC, plus my previously stated data

Thank you to all!

I'm intrigued by the one blade v. two blade selection - as far as I was aware propellers need to be balanced so 'one blade' doesn't make sense (unless its counter-weighted).

I don't see why you need an RTC, the Arduino clock should be well accurate enough for this.


I’m intrigued by the one blade v. two blade selection - as far as I was aware propellers need to be balanced so ‘one blade’ doesn’t make sense (unless its counter-weighted).

XD if you wanna go faster up to 300 km/h, with a prop of Ø6,5 in, two blades are not the best. In fact each blade is running in the disturbed wake of the other, employing a sigle blade will reduce power loss. Obviously you’ve reason, it’s counter-balanced by a brass counterweight hidden inside the spinner

The first image in http://www.controlline.it/galleria_1.html is of an F2A speed model of my uncle, which has one blade propeller, one side wing and one side tailwing. Half of all to fly twice faster!

Graynomad: I don't see why you need an RTC, the Arduino clock should be well accurate enough for this.


Dunno know if it's a shame... interrupt won't affect internal clock?

The only interrupt running apart from yours is the millis() timer, I doubt this will have any serious affect on the timing and anyway you can calibrate the code.

I'd just use the code from reply #1, I see no reason that wouldn't do the job. And make sure your input is a clean waveform.


Hi lucareds7 I'm making a similar test bench for brushless motor for RC plane.. I'm using an integrated sensor "CNY70" that include an IR led and a phototransistor for detection of the reflection. I paint one side of the propeller with a white dot that reflects the light and can be seen by the sensor.. It works, but I have the same problem on the high RPM that a brushless motor can reach (for example a ducted fan can also have many blades, so an high frequency output). I use this code


and it works good, but it seems that does not reach high rpm counts, but i'm not sure if the problem is in the code/arduino or in the sensor... do you think the code is not good for these type of measurement? (a PC fan reaches about 2000 - 3000 rpm, so they are "slow")

This is another example of code, but I don't try it yet, it seems to reach very high frequency measurement. Your idea of "downsampling" with a counter can be useful relying on "hardware" counter and not arduino software.


do you think the code is not good for these type of measurement? (a PC fan reaches about 2000 - 3000 rpm, so they are “slow”)

Hi StePava, sorry for late answer…

I think that problems could be do from many causes, e.g:

  • IR emitter/sensor group is too far from propeller blade - try to place it as close as you can, few millimeters could be even a too large gap! it depends from sensors…
  • the blade has a convex and angulated profile, so reflectance is not constant and optimal during blade passage - try to place the sensor orthogonal to blade surface, or follow my solution, that is to place IR emitter in front of the blade and receiver on the back, so the blade CUT the beam, which is a more efficient system than trying to reflect it. Many IR emitter/receiver groups are made with U shape essentialy for this purpose.

Keep in mind that a 8 blades propeller of a PC fan rotating @ 3k RPM gives 24k pulse per minute, that is 400 Hz, not so far from the field of frequency counting problems, so take in consideration to use interrupts!

Let me know future developements!

Using a counter to divide the input frequency to something the Arduino can handle more easily is a good solution. I'd use a CMOS counter rather than the 74LS393 and use a CMOS Schmitt trigger between the phototransistor and the counter. For example, use a 4093 or 40106 schmitt trigger gate or inverter followed by a 4020 counter.