IR RPM counter with Arduino

Today we will show the implementation of the Arduino Uno microcontroller (ATmega328P) in the infrared tachometer project. We will use the KY-032 module, also called the Obstacle Sensor. The module contains 2 diodes - transmitting and receiving and digital output, called DOUT. The transmitting diode has a constant 5V supply and emits light with a frequency of 38 kHz at a wavelength of 950, resp. 940 nm (depending on the diode model used).

The receiving IR diode is dark. It is also called a daylight filter. Such an adjustment significantly reduces the sensitivity of the diode to light, which in this case can be called interference. The receiving IR diode is directly connected to the terminal of the DOUT module. The sensor module is equipped with a potentiometer for sensitivity control - it responds to the distance of the object at which it will detect it. There are several versions of these modules, I used the first version in the simplest version.

The upcoming version of the KY-032 module (version 2) has several potentiometers to control other effects on the read signal quality and sensitivity, gain control. It provides better signal filtering, which results in less interference in the measurements, thus also increasing the reliability of the output from the point of view of oscillations.

Sensor functionality
The sensor responds to an obstacle at a certain distance (set by a potentiometer) 2-40 cm. When the transmitted light is reflected and reflected from an obstacle, it can be received by the receiving LED, which is connected to the DOUT. This digital output is connected to the Arduino Uno microcontroller to its digital input with interrupt support - D2 or D3. One of the advantages of IR sensors is that light is reflected more effectively from shiny surfaces than from matte surfaces. In practice, this means that at a certain distance, the sensor can detect light from a shiny surface, but not from a matte surface. We can thus use the situation with the recording of the glossy surface during its transition (recording of wheel speed, pulleys).

For my implementation of the tachometer, I glued a strip of tape about 1 cm wide to the crankshaft pulley, or it is good to use aluminum foil as well, it has very good light reflection properties. I set the gain intensity with a potentiometer so that at a constant distance from the pulley, the module responds only to the tape as it passes in front of the module at each revolution of the crankshaft, not to the pulley itself.
Let's take a model situation:
The engine of the diesel tractor has a maximum speed of 2500 rpm. This means that at maximum engine speed per second, the Arduino records 41 reflex element transitions. There will be a pause of 24 milliseconds between the individual pulses at maximum speed, which can also be used, for example, for software smoothing of debris - Debouncing to distinguish two consecutive pulses.

The arduino in the interrupt will read pulses and increment the variable INT. The interrupt will respond to the rising edge of the signal - RISING. Based on the evaluation of the formula every second (1 Hz refresh rate of the display speed), the number of motor revolutions per minute is calculated and the value is displayed on the LCD character display, which communicates with the Arduino.

Thanks to the I2C converter, 4 wires are enough to connect the display and the Arduino. Power supply (5V), ground (GND), clock signal (SCL), data (SDA). The tachometer can be used on various machines, monitoring the speed of tractor pulleys, combines, but also in industry for monitoring processes, operation and activity of machines, feed speeds. The standard implementation uses a communication speed with a display of 100 kHz, up to 400 kHz can be used for faster display rewriting.

Conversion formula (1Hz routine -> run every 1000 ms):
time = actual_time- last_time; // time difference
rpm = (number_of_pulses / time) * 60000; // calculate speed / min
oldtime = actual_time; // save current time
number_of_pulses = 0;

The simplified program implementation, which is available on the project website, does not solve the distraction from the fuss. Debounce should be implemented separately in the resulting program. If debouncing is not used, the error rate can be up to + - 30%.

You can find the program of the basic version for RPM counter:

possibly it is available at Github Otáčkomer na platforme Arduino Uno s modulom IR senzora prekážok KY-032 · GitHub

Advanced program
It uses the conversion of the pause between pulses at compile time based on the value from the macro, which represents the maximum speed of the machine it acquires. Unlike the classic program, the volatile variable uint_32 is also integrated, which stores the time of the last pulse. This, in combination with the known pause, guarantees the correct addition of the pulse without any oscillations that may occur. The measurement is more accurate than in the classic program. The extended program does not use delay(), replaced by the millis() function, for more accurate timing every 1000 ms without delay caused by rendering (display in the original program 1000 ms delay + 3 ms performing display on each loop iteration).

Communication with the display is faster as the clock signal is set to 400 kHz (Fast speed). Character redrawing takes 4 times shorter than the standard communication speed of 100 kHz. Detach and attach interrupt functions replaced with cli (), sei () macros. The implementation is also suitable for projects with a higher number of revolutions per minute.

An extended version of the RPM counter project with software debouncing available from the author: