The Sensing Principle: Hall Switches vs. Linear Sensors
A hall switch sensor relies on the Lorentz force to detect magnetic fields. When a magnetic flux lines perpendicular to the semiconductor die exceed a specific threshold, they deflect charge carriers, generating a microscopic Hall voltage. Unlike linear hall sensors that output a continuous, proportional analog voltage based on field strength, a hall switch routes this internal voltage through a Schmitt trigger and an open-drain MOSFET. This architecture forces the sensor into one of two states: fully ON or fully OFF.
The internal Schmitt trigger is the critical differentiator here, providing built-in hysteresis. The magnetic field strength required to turn the switch ON (the Operate Point, or Bop) is intentionally higher than the field strength required to turn it OFF (the Release Point, or Brp). This hysteresis gap prevents output chatter and oscillation when a magnet hovers near the edge of the detection zone, yielding a clean digital signal ideal for tachometry, limit switches, and flow meters.
Wiring, Pinouts, and Pull-Up Requirements
The most common hobbyist hall switch is the A3144 (unipolar) or US1881 (latching). However, integrating these 5V-era parts with modern 3.3V microcontrollers like the ESP32 or Raspberry Pi Pico requires careful attention to the output stage. The output pin is open-drain, meaning it can pull the line to ground, but it cannot drive it high. You must provide an external pull-up resistor.
| Pin | Function | A3144 (Legacy) | Diodes AH336x (Modern) | Wiring Notes |
|---|---|---|---|---|
| 1 | VCC | 4.5V – 24V | 1.6V – 5.5V | Use 5V for A3144; 3.3V is fine for AH336x. |
| 2 | GND | Ground | Ground | Keep ground return path short to avoid ground loops. |
| 3 | OUT | Open-Drain | Open-Drain | Requires 10kΩ pull-up to MCU logic voltage (3.3V). |
A frequent mistake is powering an A3144 with 3.3V and wondering why it never triggers. The A3144 requires a minimum of 4.5V on VCC to operate its internal regulator. Power the A3144 VCC pin with 5V, but connect the 10kΩ pull-up resistor from the OUT pin to your ESP32's 3.3V rail. Because the output is open-drain, pulling up to 3.3V safely interfaces the 5V-powered sensor with 3.3V logic without frying your microcontroller's GPIO.
From Raw Pulses to Physical Units: The RPM Math
Because a hall switch outputs a digital square wave, the "raw reading" is not an analog-to-digital converter (ADC) value, but rather a time delta between interrupts. To convert this raw timing data into a physical unit like Revolutions Per Minute (RPM), we use the period measurement method. Period measurement is vastly superior to frequency counting for low-to-medium speeds because it updates on every single pulse rather than waiting for a full one-second sampling window.
The Math:
If Δt is the time in microseconds between two consecutive magnet passes, and N is the number of magnets on the rotating shaft, the formula is:
RPM = 60,000,000 / (Δt × N)
The 60,000,000 constant converts microseconds into minutes (60 seconds × 1,000,000 microseconds).
Numbered Steps: ESP32 / Arduino Interrupt Implementation
- Connect the sensor OUT pin to a GPIO capable of hardware interrupts (e.g., GPIO 4 on an ESP32).
- Configure the GPIO as
INPUT_PULLUP(or use an external 10kΩ resistor for better noise immunity). - Attach an interrupt service routine (ISR) triggered on the
FALLINGedge (when the magnet arrives and pulls the line LOW). - Calculate the time delta using
micros()inside the ISR, storing it in avolatilevariable. - In the main loop, apply the RPM math and include a timeout check to handle stalled motors (0 RPM).
// ESP32 / Arduino Hall Switch RPM Code
const int hallPin = 4;
const int magnetCount = 1; // Number of magnets on the rotor
volatile unsigned long lastMicros = 0;
volatile unsigned long pulseInterval = 0;
void IRAM_ATTR magnetDetect() {
unsigned long now = micros();
pulseInterval = now - lastMicros;
lastMicros = now;
}
void setup() {
Serial.begin(115200);
pinMode(hallPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(hallPin), magnetDetect, FALLING);
lastMicros = micros();
}
void loop() {
unsigned long currentInterval;
// Safely read the volatile variable
noInterrupts();
currentInterval = pulseInterval;
interrupts();
// Timeout: If no pulse for 2 seconds, motor is stalled (0 RPM)
if (micros() - lastMicros > 2000000) {
currentInterval = 0;
}
float rpm = 0;
if (currentInterval > 0) {
rpm = 60000000.0 / (currentInterval * magnetCount);
}
Serial.print("Raw Interval (us): ");
Serial.print(currentInterval);
Serial.print(" | Calculated RPM: ");
Serial.println(rpm, 1);
delay(250);
}
For deeper integration with ESP32 hardware counters, refer to the official ESP32 Arduino GPIO documentation, which details PCNT (Pulse Counter) peripherals that offload this math entirely to hardware.
Interference, Bounce, and Physical Calibration
While digital switches do not require analog scaling (you never map a 0-1023 ADC value to Gauss), they absolutely require physical and electrical calibration. Physical calibration involves tuning the air gap between the magnet and the sensor die. If the gap is too wide, the field never crosses the Bop threshold; if it's too close, the sensor might remain latched due to residual magnetism in nearby steel components.
Common Interference Sources:
- EMI from Brushless Motors and VFDs: High dV/dt switching from nearby motor controllers can induce voltage spikes in the sensor wiring, tricking the Schmitt trigger into registering a false pulse.
- Antenna Effect: Unshielded wires longer than 30cm act as antennas, picking up ambient RF noise. Always twist the signal wire with the ground wire.
- Ferromagnetic Swarf: In machining or automotive environments, microscopic steel dust sticks to the neodymium magnet, altering the magnetic field geometry and causing erratic release points.
If your environment is electrically noisy, software debouncing will cause you to miss high-RPM pulses. Instead, add a hardware RC low-pass filter. Place a 1kΩ resistor in series with the OUT pin, followed by a 10nF to 100nF ceramic capacitor to ground right at the microcontroller's GPIO. This filters out high-frequency EMI spikes without delaying the actual magnetic trigger edge. For comprehensive magnetic design theory, All About Circuits provides an excellent breakdown of Hall effect field geometries.
Hall Switch Sensor FAQ
What is the actual output signal of a hall switch sensor?
The output is strictly digital and open-drain. It does not output a varying analog voltage. When a magnetic field exceeds the threshold, the internal MOSFET turns on, pulling the output pin to Ground (LOW). When the field drops below the release threshold, the MOSFET turns off, leaving the pin floating (high-impedance). An external pull-up resistor is mandatory to see a HIGH state when the magnet is absent.
Does a digital hall switch sensor need calibration?
It does not need software calibration or analog scaling, because the internal Schmitt trigger handles the threshold decision in silicon. However, it requires physical calibration (adjusting the distance between the magnet and sensor to ensure reliable triggering without mechanical binding) and electrical tuning (selecting the correct pull-up resistor value and RC filter components to match your specific EMI environment and maximum expected RPM).
Why is my hall switch sensor triggering randomly without a magnet?
Random triggering without a magnet present is almost always caused by electromagnetic interference (EMI) or a missing pull-up resistor. If the GPIO is left floating (no pull-up), ambient electrical noise will rapidly toggle the pin's logic state. Additionally, if the sensor is mounted near a brushless motor or a high-current relay, voltage spikes induced in the signal wire can mimic a magnetic trigger. Twisting your wires and adding a 0.1µF decoupling capacitor directly across the sensor's VCC and GND pins usually resolves this.






