When tracking physical sensor position in embedded projects, the output you are actually measuring from a linear Hall effect sensor (like the TI DRV5055) is a ratiometric analog voltage. Unlike digital Hall switches that simply snap HIGH or LOW when a magnet passes, a linear Hall sensor outputs a continuous voltage proportional to the magnetic flux density. To convert this raw voltage into a physical distance (millimeters or inches), you must account for the sensor's quiescent voltage, its sensitivity scaling, and the specific magnetic field decay curve of your chosen magnet.

This guide details the exact wiring, the raw-to-unit ADC math, and the calibration procedure required to interface a 3.3V-native analog Hall sensor with an ESP32. We will strictly focus on analog proportional sensing; conflating this with digital Hall switches (like the A3144) is a common mistake that will ruin your position resolution.

The Sensing Principle

Linear Hall effect sensors rely on the Lorentz force to measure magnetic fields. When a bias current flows through a thin semiconductor element inside the sensor package, an external magnetic field perpendicular to the current deflects the charge carriers to one side of the element. This charge accumulation creates a measurable transverse voltage differential (the Hall voltage) that is strictly proportional to the magnetic flux density (measured in milliTesla, mT) passing through the die.

For sensor position tracking, we exploit the fact that a magnet's field strength decays predictably over distance. By mounting a permanent magnet to a moving carriage and fixing the Hall sensor to the stationary frame, the physical displacement of the carriage alters the magnetic field at the sensor die. The sensor's internal operational amplifier scales this microvolt-level Hall voltage into a robust, ratiometric analog output (typically 0.1V to VCC-0.1V) that a microcontroller's ADC can read directly.

Wiring and Pinout Specification

For modern 3.3V microcontrollers like the ESP32 or Raspberry Pi Pico, the TI DRV5055 is the ideal choice. It operates natively on 3.3V, eliminating the need for voltage dividers that degrade analog resolution. Below is the wiring specification for the DRV5055A2 variant (optimized for a ±42mT range).

DRV5055 Pin Function ESP32 Connection Notes & Supply Range
1 (VCC) Power Supply 3V3 Pin Supply range: 2.5V to 5.5V. Use a stable 3.3V LDO; do not use the USB 5V rail.
2 (OUT) Analog Output GPIO 34 (ADC1_CH6) Ratiometric output. Quiescent voltage is exactly 0.5 × VCC (1.65V at 3.3V supply).
3 (GND) Ground GND Pin Keep ground return path short to minimize EMI pickup.
Bench Tip: Always use an ADC1 channel (GPIO 32-39) on the ESP32 for analog position sensing. ADC2 channels (GPIO 0, 2, 4, 12-15, 25-27) are shared with the WiFi radio and will drop readings or throw errors when WiFi is active.

Output Signal Math: Raw ADC to Millimeters

Converting the ESP32's raw ADC reading into a physical sensor position requires a three-step mathematical translation. The ESP32's 12-bit ADC (0-4095) is notoriously non-linear at the extreme top and bottom of its range. To bypass manual lookup tables, we use the analogReadMilliVolts() function introduced in ESP32 Arduino Core v2.x, which leverages the chip's internal eFuse calibration data to return a highly accurate millivolt reading.

Step 1: Calculate Magnetic Flux Density (B)
The DRV5055A2 has a nominal sensitivity of 25 mV/mT at 5.0V. Because it is ratiometric, at a 3.3V supply, the sensitivity scales linearly: 25 * (3.3 / 5.0) = 16.5 mV/mT. The quiescent voltage (zero magnetic field) is 3.3V / 2 = 1.65V (1650 mV).

Step 2: Map Flux Density to Distance
The magnetic field of a cylindrical magnet decays non-linearly (roughly following an inverse-cube law in the far field). However, in the close-proximity region (typically 2mm to 8mm from the sensor face for a 6x2.5mm N42 NdFeB magnet), the decay is sufficiently linear to use a simple slope-intercept equation: Position (mm) = (B_field - Offset) * Scale.

// ESP32 Arduino Core v2.x+
const int SENSOR_PIN = 34;
const float VCC_MV = 3300.0;
const float QUIESCENT_MV = VCC_MV / 2.0; // 1650 mV
const float SENSITIVITY_MV_MT = 16.5;    // DRV5055A2 at 3.3V

// Calibration constants (determined via 2-point calibration)
const float OFFSET_MT = 45.2;  
const float SCALE_MM_PER_MT = -0.18; 

void setup() {
  Serial.begin(115200);
  analogReadResolution(12);
}

void loop() {
  // 1. Read calibrated voltage directly in millivolts
  int raw_mv = analogReadMilliVolts(SENSOR_PIN);
  
  // 2. Convert mV to milliTesla (mT)
  float delta_mv = raw_mv - QUIESCENT_MV;
  float b_field_mt = delta_mv / SENSITIVITY_MVT;
  
  // 3. Convert mT to physical position (mm)
  float position_mm = (b_field_mt - OFFSET_MT) * SCALE_MM_PER_MT;
  
  // Clamp to physical limits of your mechanical assembly
  position_mm = constrain(position_mm, 0.0, 10.0);
  
  Serial.printf("Voltage: %d mV | Field: %.2f mT | Pos: %.2f mm\n", 
                raw_mv, b_field_mt, position_mm);
  delay(20);
}

Calibration and Interference Mitigation

The code above relies on OFFSET_MT and SCALE_MM_PER_MT. You cannot use datasheet theoretical values for these; you must perform a physical 2-point calibration on your specific assembly. Move the magnet to the exact 2.0mm mechanical stop, record the b_field_mt value, then move it to the 8.0mm stop and record the second value. Use the standard slope formula m = (y2 - y1) / (x2 - x1) to calculate your scale factor.

Accurate sensor position tracking is easily derailed by environmental interference. The three most common sources on the workbench are:

  • Ferrous Metal Brackets: Mounting the sensor or magnet to a steel bracket will distort the magnetic flux lines, creating hysteresis and dead zones. Always use 300-series stainless steel, aluminum, or brass for the sensor carriage.
  • AC Mains EMI: 50/60Hz electromagnetic fields from nearby unshielded AC wiring will induce a low-frequency ripple in the analog output. Implement a software low-pass filter (e.g., an exponential moving average) or a hardware RC filter (100Ω resistor + 100nF ceramic capacitor) on the OUT pin.
  • Thermal Drift: While the DRV5055 is ratiometric (meaning its output scales with VCC), the ESP32's internal ADC reference does not scale with VCC. If your 3.3V rail sags by 50mV due to thermal loading, your position reading will shift. Power the sensor from a dedicated, low-noise 3.3V LDO (like the AP2112K-3.3) rather than the ESP32's onboard AMS1117.

FAQ: Sensor Position Tracking

How does temperature affect Hall effect sensor position accuracy?

Temperature affects both the sensor silicon and the permanent magnet. The DRV5055 has an internal temperature compensation circuit that keeps its sensitivity drift below ±0.02%/°C. However, Neodymium (NdFeB) magnets lose about 0.11% of their magnetic flux per degree Celsius rise. In a 30°C ambient temperature swing, your magnet will weaken by ~3.3%, translating to a position reading error of roughly 0.2mm over a 10mm travel range. For high-precision industrial applications, use a Samarium Cobalt (SmCo) magnet, which has a near-zero reversible temperature coefficient.

Can I use a standard neodymium magnet for linear sensor position tracking?

Yes, but the geometry matters more than the grade. A standard N42 or N52 grade is fine, but you must use an axially magnetized cylinder or disc. Avoid block magnets; their sharp corners create localized flux spikes that will cause the sensor output to saturate and clip the ESP32's ADC range. A 6mm diameter by 2.5mm thick axially magnetized cylinder provides the smoothest linear decay curve for a DRV5055A2 sensor.

Why is my ESP32 ADC giving jittery sensor position readings?

The ESP32's SAR ADC is susceptible to noise on the VDD_A (analog power) rail and exhibits ±20 LSB of inherent noise. If your sensor position reading is jumping by 1-2mm at rest, first verify you are using analogReadMilliVolts() rather than the raw analogRead(), which lacks eFuse calibration. Second, add a 100nF decoupling capacitor directly across the VCC and GND pins of the DRV5055, physically touching the sensor legs. Finally, oversample in software: take 16 rapid readings, discard the highest and lowest 2, and average the remaining 12 to achieve a stable 14-bit effective resolution.