The Hall Effect Sensing Principle and Analog Output
When current flows through a conductor, it generates a proportional magnetic field. In a Hall effect current sensor, this primary current path is routed past a precision Hall element. The magnetic field exerts a Lorentz force on the charge carriers within the semiconductor, pushing them to one side of the element and creating a measurable transverse voltage—the Hall voltage. Because the primary current path is physically separated from the sensing silicon, the load circuit and the microcontroller circuit share no electrical connection, providing robust galvanic isolation up to 2.4 kV RMS in industrial packages.
The output signal of this category of sensors is a continuous, ratiometric analog voltage. For a bidirectional sensor powered by 3.3V, the output sits exactly at VCC/2 (1.65V) when the current is zero. As current flows in the positive direction, the voltage increases linearly; as it flows in reverse, the voltage drops below 1.65V. This analog output is fundamentally different from digital I2C/SPI sensors; it requires your microcontroller's Analog-to-Digital Converter (ADC) to digitize the signal, meaning your measurement resolution is strictly bound by your ADC's bit-depth and reference voltage stability.
Component Selection and Wiring Pinout
Choosing the right IC within this category of sensors depends on your maximum expected current and required resolution. Using a 50A sensor to measure a 2A motor will result in terrible ADC resolution, while pushing 15A through a 5A sensor will saturate the output and potentially damage the internal trace. Below is a data-dense comparison of the most common 3.3V Hall effect ICs used in embedded systems.
| IC Part Number | Current Range | Sensitivity | Primary Path Resistance | Bandwidth (-3dB) |
|---|---|---|---|---|
| ACS724LLCTR-10AB | ±10A | 200 mV/A | 1.2 mΩ | 80 kHz |
| ACS724LLCTR-30AB | ±30A | 66 mV/A | 1.2 mΩ | 80 kHz |
| ACS724LLCTR-50AB | ±50A | 40 mV/A | 1.2 mΩ | 80 kHz |
| ACS72981KLRATR-20B | ±20A | 100 mV/A | 0.6 mΩ | 120 kHz |
Note: Always select a sensor where your continuous maximum load is roughly 70-80% of the sensor's rated range to allow for transient spikes without clipping the ADC.
Wiring and Pin Mapping
Because the output is ratiometric to the supply voltage, the sensor must share the exact same VCC and GND as the ESP32 to ensure the zero-current offset remains accurate.
| Breakout Pin | ESP32 Pin | Wire Gauge / Type | Notes |
|---|---|---|---|
| VCC | 3V3 | 22 AWG Solid | Supply range: 3.0V to 3.6V. Do not use 5V/VIN. |
| GND | GND | 22 AWG Solid | Must share common ground with ESP32. |
| OUT | GPIO 34 | 22 AWG Solid | Use ADC1 pins (GPIO 32-39). Avoid ADC2 (WiFi conflict). |
| IP+ / IP- | Load Circuit | 14-10 AWG Stranded | Carries the high-current load. Torque terminals to 0.5 Nm. |
Raw-to-Ampere Math and ESP32 ADC Scaling
Translating the raw ADC reading into physical Amperes requires accounting for the sensor's sensitivity, the zero-current offset, and the ESP32's specific ADC architecture. The ESP32 features a 12-bit ADC (0-4095), but its analog front-end is notoriously non-linear, and the maximum readable voltage saturates around 3.1V depending on the chip's eFuse calibration data.
Rather than using the legacy analogRead() and manually mapping 0-4095 to 0-3.3V, modern ESP32 Arduino Core (v2.x and v3.x) provides analogReadMilliVolts(). This function reads the raw ADC value and automatically applies the factory-burned eFuse calibration coefficients to return a highly accurate millivolt reading, bypassing the non-linearity headache.
The Conversion Formula
For a bidirectional ACS724-30AB (66 mV/A sensitivity) powered at 3.3V:
- Zero-Current Offset (V_offset): VCC / 2 = 1650 mV.
- Measured Voltage (V_meas): Read via
analogReadMilliVolts(). - Delta Voltage (V_delta): V_meas - V_offset.
- Current (Amps): V_delta / Sensitivity.
// Example calculation for ACS724-30AB (66mV/A)
int raw_mV = analogReadMilliVolts(ADC_PIN);
float v_offset = 1650.0; // Assuming stable 3.3V VCC
float sensitivity = 66.0; // mV per Amp
float current_A = (raw_mV - v_offset) / sensitivity;
If your ESP32's 3V3 rail is slightly off (e.g., 3.28V due to USB voltage sag or onboard regulator tolerance), your V_offset will be 1640 mV, not 1650 mV. This 10 mV error divided by 66 mV/A results in a permanent 0.15A zero-offset error. To fix this, measure the actual VCC with a multimeter, or implement a software zero-calibration routine at startup when the load is known to be disconnected.
Calibration, Interference, and Implementation Steps
Hall effect sensors are highly susceptible to external magnetic fields and power supply noise. Because the output is ratiometric, any ripple on the VCC line directly injects noise into your measurement. If your ESP32 is powered via a cheap switching buck converter with 50mV of ripple, your current reading will jitter by nearly 0.75A (50mV / 66mV/A).
Common Interference Sources
- External Magnets: Keep neodymium magnets, large inductors, and unshielded transformers at least 2 inches away from the sensor IC.
- Switching Regulators: High-frequency EMI from nearby DC-DC converters can couple into the Hall element. Use a 0.1µF ceramic bypass capacitor directly across the sensor's VCC and GND pins.
- Adjacent Current Traces: Routing high-current PCB traces directly under or parallel to the sensor IC will introduce crosstalk. Keep the load path perpendicular to the sensor package.
Step-by-Step Implementation
Follow these steps to integrate the sensor into your ESP32 firmware with proper noise rejection.
- Hardware Prep: Solder a 0.1µF ceramic capacitor across the VCC and GND header pins on the breakout board. Connect the load wires to IP+ and IP- using ferrules to prevent stray strands from shorting.
- Pin Assignment: Assign the analog output to an ADC1 channel (e.g., GPIO 34). Do not use ADC2 channels (GPIO 0, 2, 4, 12-15, 25-27) as they are disabled when WiFi is active.
- ADC Configuration: Set the ADC attenuation to 11dB to allow readings up to ~3.1V, and set the resolution to 12-bit.
- Software Averaging: Because the ESP32 ADC has inherent thermal noise, take multiple samples and apply a moving average or digital low-pass filter.
- Zero Calibration: At boot, before the load is energized, read the sensor 100 times to establish a dynamic V_offset baseline.
Complete ESP32 Arduino Code
This code implements a dynamic zero-offset calibration and an exponential moving average filter to smooth out ADC jitter, providing a stable, real-world current reading.
#include <Arduino.h>
const int ADC_PIN = 34;
const float SENSITIVITY_MV = 66.0; // 66mV/A for ACS724-30AB
const float ALPHA = 0.1; // Smoothing factor (0.0 to 1.0)
float v_offset_mv = 1650.0;
float smoothed_current = 0.0;
void calibrateZeroOffset() {
float sum = 0;
const int samples = 200;
Serial.println("Calibrating zero offset... Ensure load is OFF.");
for (int i = 0; i < samples; i++) {
sum += analogReadMilliVolts(ADC_PIN);
delay(5);
}
v_offset_mv = sum / samples;
Serial.printf("Calibrated V_offset: %.2f mV\n", v_offset_mv);
}
void setup() {
Serial.begin(115200);
analogReadResolution(12);
analogSetAttenuation(ADC_11db);
delay(1000);
calibrateZeroOffset();
}
void loop() {
int raw_mv = analogReadMilliVolts(ADC_PIN);
float instant_current = (raw_mv - v_offset_mv) / SENSITIVITY_MV;
// Exponential Moving Average Filter
smoothed_current = (ALPHA * instant_current) + ((1.0 - ALPHA) * smoothed_current);
Serial.printf("Raw: %d mV | Instant: %.2f A | Smoothed: %.2f A\n",
raw_mv, instant_current, smoothed_current);
delay(50); // 20 Hz sample rate
}
For further reading on the ESP32's ADC behavior and calibration APIs, refer to the official Espressif ADC Oneshot Driver Documentation. Always consult the specific Allegro MicroSystems datasheet for your exact IC variant, as sensitivity and bandwidth vary significantly across the product matrix.






