Measuring rotational speed reliably without optical encoders requires a sensor that ignores dust, oil, and ambient light. The hall effect sensor for speed applications fills this exact niche, outputting clean electrical pulses as a magnet passes its active area. To measure speed, you count these pulses over time (frequency) or measure the time between them (period), then apply a scaling factor based on your magnet configuration. Below is the complete bench-to-code guide for interfacing these sensors with 5V Arduinos and 3.3V ESP32s.
Sensing Principle and Sensor Selection
A hall effect sensor relies on the Lorentz force. When a magnetic field passes perpendicular to a biased semiconductor plate inside the sensor, it deflects charge carriers to one side, creating a measurable transverse voltage. In speed sensing, a magnet mounted on a rotating shaft (or a gear tooth passing by) modulates this field. The sensor's internal circuitry—either a Schmitt trigger for digital switching or a linear amplifier for analog output—converts this microscopic voltage shift into a usable microcontroller signal.
Choosing the right sensor hinges entirely on understanding its output stage. Digital (switch) sensors output a clean HIGH/LOW square wave, making them ideal for simple RPM counting via hardware interrupts. Analog (linear/ratiometric) sensors output a continuous voltage proportional to the magnetic field strength. While analog sensors can be used for speed by setting a software threshold, they are primarily intended for position profiling or current sensing. Never conflate the two; feeding a 5V analog output into a 3.3V ESP32 GPIO without a voltage divider will damage the pin, whereas a digital open-drain output requires a pull-up resistor to function at all.
| Part Number | Output Type | Supply Range (V) | Max Switching Freq | Typical Price |
|---|---|---|---|---|
| A3144EUA-T (Allegro) | Digital (Open-Drain, Unipolar) | 3.8V to 24V | 10 kHz | $0.45 |
| SS49E (Honeywell) | Analog (Ratiometric Linear) | 2.7V to 6.5V | 20 kHz (Bandwidth) | $0.85 |
| DRV5053A (TI) | Analog (Ratiometric) | 2.5V to 38V | 20 kHz (Bandwidth) | $0.65 |
| TLE4906K (Infineon) | Digital (Push-Pull, Unipolar) | 2.7V to 18V | 100 kHz | $0.90 |
Wiring, Pinouts, and Interference Mitigation
Wiring a digital hall sensor is straightforward, but the output stage dictates your pull-up requirements. The ubiquitous A3144 is an open-drain device; it can pull the signal line to ground, but it cannot drive it high. You must provide the high state via a pull-up resistor. The TLE4906, conversely, features a push-pull output and can drive the line both high and low without external resistors, making it vastly superior for 3.3V ESP32 logic without level shifting.
| Sensor Pin | Arduino (5V) Connection | ESP32 (3.3V) Connection | Notes & Requirements |
|---|---|---|---|
| VCC (Pin 1) | 5V | 3.3V (Check sensor min VCC!) | A3144 needs min 3.8V; use 5V and level-shift the output, or use a 3.3V-native sensor like DRV5053. |
| GND (Pin 2) | GND | GND | Must share a common ground with the MCU. |
| OUT (Pin 3) | GPIO (e.g., Pin 2) | GPIO (e.g., GPIO 4) | Requires 10kΩ pull-up to VCC for open-drain sensors (A3144, SS441A). |
Motor environments are electrically hostile. The most common interference sources for hall sensors are electromagnetic interference (EMI) from brushed DC motor commutators and stray magnetic fields from nearby high-current wiring. If your RPM readings spike erratically when the motor is under load, EMI is likely inducing false triggers in your sensor cable.
Unlike mechanical reed switches, hall sensors do not suffer from physical contact bounce. However, they do suffer from magnetic chatter if the magnet passes exactly at the sensor's threshold point. To fix this, ensure your magnet passes well within the sensor's operate point (Bop) and fully retreats past its release point (Brp). Furthermore, always place a 100nF ceramic decoupling capacitor directly across the VCC and GND pins at the sensor body, and use twisted-pair wire for runs longer than 15cm to reject common-mode noise.
Raw-to-RPM Math and Calibration
Converting raw microcontroller readings into physical RPM requires understanding your physical setup and choosing the right mathematical approach. The fundamental variable is N, the number of magnetic pulses per single shaft revolution. If you have one magnet on the shaft, N=1. If you are using a multi-pole ring magnet with 4 North/South pole pairs, N=4 (assuming a unipolar sensor that only triggers on the South poles).
There are two distinct ways to calculate speed, and choosing the wrong one is the primary cause of jittery readings:
- Frequency Method (Best for High Speed): Count the number of pulses over a fixed time window (e.g., 1 second).
RPM = (Pulse_Count × 60) / N
Drawback: At low speeds, a 1-second window yields terrible resolution. A motor spinning at 30 RPM with N=1 will only generate 1 pulse every 2 seconds, causing the reading to jump between 0 and 60 RPM. - Period Method (Best for Low to Medium Speed): Measure the exact time (in microseconds) between consecutive pulses.
RPM = 60,000,000 / (Delta_Microseconds × N)
Drawback: At very high speeds, microsecond timer overflow or interrupt overhead can introduce jitter, though on a 240MHz ESP32, this is rarely an issue below 10,000 RPM.
For most robotics and DIY motor control applications, the Period Method provides the smoothest low-speed control loop feedback. Below is a robust, copy-pasteable implementation for Arduino and ESP32 that uses the period method, complete with a stall timeout to prevent division-by-zero errors when the motor stops.
// Hall Effect Speed Sensor (Period Method)
// Compatible with Arduino Uno/Nano and ESP32 DevKit
// Target: Digital Open-Drain or Push-Pull Hall Sensor
const int HALL_PIN = 2; // Use an interrupt-capable pin
const int MAGNETS_PER_REV = 1; // N: Change to match your physical setup
volatile unsigned long lastMicros = 0;
volatile unsigned long deltaMicros = 0;
volatile bool newPulse = false;
// Stall timeout in microseconds (e.g., 1 second = 1,000,000 us)
const unsigned long STALL_TIMEOUT = 1000000;
void IRAM_ATTR pulseISR() {
unsigned long currentMicros = micros();
if (lastMicros > 0) {
deltaMicros = currentMicros - lastMicros;
newPulse = true;
}
lastMicros = currentMicros;
}
void setup() {
Serial.begin(115200);
// INPUT_PULLUP handles open-drain sensors (like A3144) on 5V Arduinos.
// For 3.3V ESP32s with 5V open-drain sensors, use an external 10k pull-up to 3.3V
// and set pinMode to INPUT to avoid back-feeding voltage.
pinMode(HALL_PIN, INPUT_PULLUP);
// Trigger on FALLING edge (when magnet pulls the open-drain output to GND)
attachInterrupt(digitalPinToInterrupt(HALL_PIN), pulseISR, FALLING);
Serial.println("Hall Sensor Speed Monitor Initialized.");
}
void loop() {
float rpm = 0.0;
// Check if we have a new pulse or if the motor has stalled
if (newPulse) {
// Raw-to-Unit Math: 60M us/min divided by (time per pulse * pulses per rev)
rpm = 60000000.0 / (deltaMicros * MAGNETS_PER_REV);
newPulse = false; // Reset flag
}
else if (micros() - lastMicros > STALL_TIMEOUT) {
rpm = 0.0; // Motor has stalled or stopped
deltaMicros = 0; // Prevent stale data
}
Serial.print("Calculated RPM: ");
Serial.println(rpm, 1); // Print with 1 decimal place
delay(100); // Update serial monitor at 10Hz
}
Calibration Gotcha: Unipolar vs. Bipolar Magnets
If you buy a cheap "multi-pole ring magnet" from an online marketplace and your RPM reads exactly half of what you expect, you have likely hit the unipolar trap. Sensors like the A3144 are unipolar—they only activate when exposed to a South magnetic pole and ignore North poles. If your ring magnet has 8 alternating poles (4 North, 4 South), a unipolar sensor will only output 4 pulses per revolution. You must either set MAGNETS_PER_REV = 4 in your code, or switch to a bipolar/omnipolar hall sensor (like the DRV5055 or MLX92232) that triggers on both polarities, allowing you to set MAGNETS_PER_REV = 8.
For deeper integration into high-speed motor control loops on the ESP32, bypassing software interrupts entirely in favor of the hardware Pulse Counter (PCNT) peripheral is recommended to eliminate CPU jitter. For foundational theory on magnetic field thresholds and sensor hysteresis, refer to the All About Circuits guide on Hall Effect measurement or the Allegro Micro A3144 datasheet for exact Bop/Brp Gauss values.






