When building a tachometer for Arduino, the microcontroller doesn't actually measure rotational speed directly; it measures pulse frequency. The Arduino calculates RPM based on the time between interrupts. If your LCD or serial monitor is displaying erratic, zero, or wildly fluctuating RPM values, the issue is rarely in your C++ code. It is almost always signal degradation, improper biasing, or electrical noise at the sensor level. To debug a tachometer circuit, you must stop looking at the serial plotter and start probing the physical signal with a digital multimeter (DMM) or oscilloscope.
Sensor Signal Profiling and Meter Setup
The most common sensor used in DIY Arduino tachometers is the A3144 Hall effect switch. It is an open-collector NPN transistor output, meaning it can pull the signal line to ground, but it cannot drive it high. Before writing a single line of interrupt code, you must verify the physical layer is outputting clean, square pulses.
- Dial Position: Hz / Duty Cycle (for frequency) or DC Volts (for static state verification).
- Lead Jacks: Black lead to COM, Red lead to V/Ω/Hz.
- Range: Auto-ranging preferred. If manual, set to 20V DC for voltage checks, or 200 Hz / 2 kHz for frequency depending on expected motor speed.
- Red Probe: Touch the sensor's OUT (Signal) pin. If using a pre-wired module, probe the DO (Digital Out) terminal.
- Black Probe: Touch the sensor's GND pin or the Arduino's GND header. Ensure both share a common ground reference.
With your meter set to Hz and the motor spinning, you should see a stable frequency reading. Because RPM is simply revolutions per minute, and frequency is cycles per second (Hertz), the relationship is fixed. Assuming your motor shaft has exactly one magnet pole pair passing the sensor, the expected readings will follow the data-dense profile below.
| Motor Speed (RPM) | Expected Frequency (Hz) | Pulse Period (ms) | High State Voltage (Voh) | Low State Voltage (Vol) |
|---|---|---|---|---|
| 60 RPM | 1.0 Hz | 1000.0 ms | 4.8V - 5.0V | 0.1V - 0.4V |
| 600 RPM | 10.0 Hz | 100.0 ms | 4.8V - 5.0V | 0.1V - 0.4V |
| 3,000 RPM | 50.0 Hz | 20.0 ms | 4.8V - 5.0V | 0.1V - 0.4V |
| 6,000 RPM | 100.0 Hz | 10.0 ms | 4.8V - 5.0V | 0.1V - 0.4V |
Note: If your setup uses two magnets on the shaft, divide the expected frequency by 2. The Arduino attachInterrupt() function will trigger on every magnetic pass, so your code's math must account for the physical pole count.
Expected Readings: Good vs. Bad Signal States
When troubleshooting, switch your DMM back to DC Volts and manually rotate the motor shaft to hold the magnet directly over the sensor, then pull it away. This static test isolates wiring faults from timing bugs. A good reading numerically means seeing a clean transition between the logic HIGH and logic LOW thresholds of the Arduino's ATmega328P or ESP32 microcontroller.
| Measurement Point | Good Reading (Healthy Circuit) | Bad Reading (Fault Condition) | Root Cause of Bad Reading |
|---|---|---|---|
| Signal HIGH (Magnet Away) | 4.8V to 5.0V (or 3.3V on ESP32) | 1.5V to 2.5V (Floating) | Missing or broken pull-up resistor. |
| Signal LOW (Magnet Near) | 0.1V to 0.4V | 0.8V to 1.5V | Weak ground connection or excessive current draw on the sensor. |
| Frequency (Hz Mode) | Stable value matching RPM | Flickering or double the expected Hz | EMI noise triggering false edges, or magnet too close causing hysteresis bounce. |
| VCC Supply Pin | 4.9V to 5.1V under load | Drops below 4.5V when motor spins | Motor back-EMF sagging the shared Arduino 5V rail. |
Measurement Mistakes That Cause Erratic RPM Data
If your DMM shows good static voltages but your Arduino RPM readout is still chaotic, you are likely falling victim to one of three common measurement and implementation mistakes.
- Forgetting the Pull-Up Resistor: The A3144 and similar Hall sensors like the Texas Instruments DRV50xx series feature open-collector outputs. They act as a switch to ground. If you do not have a 10kΩ resistor pulling the signal line up to VCC (5V or 3.3V), the line will float when the magnet moves away. The Arduino's high-impedance input will read this floating voltage as random noise, generating thousands of false interrupts per second.
- Ignoring Motor Brush EMI: Brushed DC motors are notorious for generating broadband electromagnetic interference (EMI). The carbon brushes sparking against the commutator create high-frequency voltage spikes that travel through the power rails and couple into your sensor signal wire. Fix: Solder a 0.1µF ceramic capacitor directly across the motor terminals, and add a 10µF electrolytic capacitor across the sensor's VCC and GND pins to filter out low-frequency sag.
- Magnet Proximity and Hysteresis Bounce: Hall switches have built-in hysteresis to prevent oscillation, but if the magnet is mounted too close (under 2mm), the magnetic field strength might never drop below the 'release' threshold before the next pole arrives, or it might cause the sensor to chatter at the exact edge of the threshold. Maintain a 3mm to 5mm air gap for standard neodymium magnets.
Safety Categories and Mains-Adjacent Motor Testing
When testing a tachometer on a low-voltage (12V/24V) isolated DC bench supply, a standard un-rated hobby multimeter is sufficient. However, if you are installing a tachometer on a 120V/240V AC induction motor, an HVAC blower, or a VFD-driven CNC spindle, you are operating in a CAT II or CAT III environment.
Inductive kickback from large AC motors can generate transient voltage spikes exceeding 1,000V. You must use a CAT III 600V rated DMM (like a Fluke 87V) and properly insulated probe leads. Never share a ground reference between your Arduino's low-voltage logic and the chassis of a mains-powered motor without using an opto-isolator (like a 6N137) between the sensor output and the Arduino interrupt pin.
By validating the physical signal with a meter before trusting the software, you eliminate the guesswork in Arduino tachometer projects. A clean, 0V-to-5V square wave with sharp edges guarantees that the microcontroller's hardware interrupt will trigger precisely, yielding RPM calculations that are accurate down to the single digit.






