Engine RPM (Part 3)

Part 1, 2, 3, 4, 5

Previous posts on measuring engine RPM are featuring electronic interfaces with devices that sense the engine rotation. It is sometimes impossible to connect such sensor so that other techniques must be used in order to check and adjust an engine RPM. Today, we will use a contact-less technique featuring a light beam directed toward a reflecting target attached to the rotating device. The proposed application features the stroboscopic effect, well known by those who like to go dancing in clubs. A quick search on the net will give you plenty of information related to the principle of operation and examples of use of stroboscopes. In simple words, a flash light directed toward a moving object will decompose the motion of this object in successive snapshots. If this object has a periodical motion which is synchronized with the light beam, the target will look immobile. The least change in synchronization will result in a slow motion of the spotted target clockwise or counter-clockwise.

Building a stroboscope with Arduino is quite simple as we only need a bright LED and few lines of code. It is also a good programming exercise for improving the accuracy and usability of the measurement device.

In its simplest version, the stroboscope shall be able to measure speeds with an accuracy better than 2% between 1 and 6 000 rpm which degrades down to 4% at higher frequencies. The sketch is an extrapolation of the most famous “blink” sketch using microseconds as time base. Next lines of pseudo code illustrate a full flashing cycle:

  • Turn light ON
  • Wait for next change in light state
  • Turn light OFF
  • Wait for next change in light state

And here is the full sketch:

int32_t _interval, _onTime, _offTime;
const int16_t _onTimeRatio = 10; // %
int32_t _now, _lastTime;
const uint8_t _ledPinMask = (1 << PINB5);

void setup()

void loop()
	PORTB |= _ledPinMask;
	do {
		_now = micros();  
	} while ((_now - _lastTime) < _onTime);
	_lastTime = _now;

	PORTB &= ~_ledPinMask;
	do {
		_now = micros();  
	} while ((_now - _lastTime) < _offTime);
	_lastTime = _now;	

void SetTimer(float rpm)
	_interval = int32_t(1000000.0 * 60.0 / rpm); // in micros	
	_onTime = ((_interval * _onTimeRatio) / 100);
	if (_onTime < 1) { /* prevent null time */
		_onTime = 1;
	_offTime = (_interval - _onTime);
	_lastTime = micros();

void InitLED(void) 
	/* Make the pin an output pin */
	DDRB |= _ledPinMask;


Pretty simple. The hardware section is even simpler as it consists in a white bright led and its biasing resistor.


Checking the signal on a scope gives us some information about the signal accuracy and stability.


Do not take the figures as absolute values as in fact they are captured from an (slightly) unstable signal. These are extreme results and the instability is mainly due to the handling of the micros() function and to the activity of both timer 1 and timer 2 under standard operating conditions. Although this version will suffice in most cases (under 6000 rpm, so as to say 100 Hz) , an advanced version of the arduino stroboscope shall be considered in the next posts.

Next is a picture illustrating the use of the arduino based stroboscope. A simple piece of white adhesive tape sticks to the blades of a fan. This is the target taht the pulsed light beam will try to hit in a synchronous manner:


And here is a short video illustrating the stroboscopic effect:

From the video, you can see that the spot light “disappears”. In fact, the stroboscope looses its synchronization due to the slight slips of fan speed. If the spot light looks like it goes clockwise, the actual speed is slower than expected. If the spot light looks like it goes counter-clockwise, the actual speed is faster than expected. In next versions, we will add some extra features for adjusting the proper synchronization…

Next post on same subject

Leave a Reply

You must be logged in to post a comment.