To interface an LVDT sensor to a microcontroller like the ESP32, you cannot connect the raw sensor leads directly to a GPIO or ADC pin. An LVDT outputs a differential AC voltage that requires demodulation. You must use a signal conditioner to convert this AC signal into a 0-5V DC or 4-20mA analog signal, then read it via a precision external ADC (like the I2C ADS1115), because the ESP32's internal ADC is too noisy and non-linear to capture the sub-micron resolution an LVDT provides.

The Sensing Principle: How an LVDT Works

A Linear Variable Differential Transformer (LVDT) consists of one primary coil and two secondary coils wound around a hollow, non-magnetic tube. A movable ferromagnetic core slides freely inside this tube. An AC excitation signal (typically 1 kHz to 10 kHz) drives the primary coil, which induces AC voltages in the two secondary coils via magnetic coupling. For a deeper physics breakdown, All About Circuits provides an excellent primer on LVDT theory.

The two secondary coils are wired in series opposition. When the core is perfectly centered (the null point), the magnetic flux couples equally to both secondaries, and their induced voltages cancel each other out, yielding a zero differential output. As the core moves away from the center, the mutual inductance shifts. This creates a differential AC voltage whose amplitude is strictly proportional to the displacement distance, while its phase (0° or 180° relative to the excitation) indicates the direction of movement.

LVDT Specifications and Signal Conditioning

The raw output of an LVDT is an AC differential signal. Microcontrollers cannot read this directly. You have two paths: build a demodulator circuit using an IC like the Analog Devices AD698, or buy a pre-built DC-LVDT module with an integrated signal conditioner. For most DIY and prototyping applications, a commercial DC-output signal conditioner (costing roughly $40 to $120 depending on stroke length) is the most reliable path.

The conditioner drives the primary coil with a stable AC sine wave, rectifies and filters the secondary AC output, and uses the phase information to output a bipolar or unipolar DC voltage (e.g., 0-5V representing -10mm to +10mm). Below is a specification table for common raw LVDT stroke lengths and their typical electrical characteristics.

Stroke Range (±) Sensitivity (mV/V/mm) Standard Excitation (V RMS) Excitation Frequency Typical Conditioned DC Output
2 mm 10.0 3V 5 kHz 0-5V (2.5V at null)
10 mm 2.5 5V 3 kHz 0-10V (5V at null)
50 mm 0.5 10V 2.5 kHz 4-20mA (12mA at null)
250 mm 0.1 12V 1 kHz ±10V (0V at null)

Wiring the Conditioned LVDT to an ESP32

Because LVDTs are precision instruments capable of resolving displacements down to 0.001 mm, relying on the ESP32's internal 12-bit ADC is a mistake. The internal ADC suffers from severe non-linearity above 2.5V and inherent noise floors that will destroy your sensor's resolution. Instead, we use an external 16-bit I2C ADC like the Texas Instruments ADS1115 (approx. $12 on breakout boards). Refer to the Espressif ADC calibration documentation if you absolutely must use the internal ADC, but expect to lose at least 60% of your LVDT's theoretical resolution.

Pro-Tip: If your signal conditioner outputs 0-10V, you must use a precision voltage divider (e.g., two 0.1% tolerance metal film resistors, 10kΩ and 10kΩ) to scale it down to 0-5V before hitting the ADS1115, which has a maximum input of VDD + 0.3V.
Component Pin Connects To Notes / Supply Range
Signal Conditioner VIN (Power) 24V DC Power Supply Most industrial conditioners require 18-30V DC
Signal Conditioner GND System Common Ground Must share ground with ESP32 and ADS1115
Signal Conditioner SIG OUT ADS1115 A0 Pin Use shielded twisted-pair cable
ADS1115 VDD ESP32 3V3 Pin Supply range: 2.0V to 5.5V
ADS1115 GND ESP32 GND System Common Ground
ADS1115 SCL / SDA ESP32 GPIO 22 / 21 Standard I2C bus, add 4.7kΩ pull-ups

Installation Steps:

  1. Mount the LVDT and secure the core to your moving mechanism. Ensure the core does not bind or rub against the inner bore.
  2. Wire the raw LVDT to the signal conditioner using the manufacturer's color code (typically Red/Black for primary, Blue/Yellow for secondaries).
  3. Power the conditioner and measure the SIG OUT with a multimeter. Adjust the mechanical null point until the output reads exactly the midpoint voltage (e.g., 2.500V).
  4. Connect the SIG OUT to the ADS1115 A0 pin, and wire the I2C bus to the ESP32.

Raw-to-Unit Math and Calibration Code

Converting the raw ADC reading into physical units (millimeters) requires two calibration constants: the null voltage (the voltage output when the core is at the exact center) and the scale factor (millimeters per volt).

Assume a ±10mm LVDT with a 0-5V conditioned output. The null point is 2.5V. At +10mm, the output is 5.0V. At -10mm, the output is 0.0V.
Scale Factor = 10 mm / (5.0V - 2.5V) = 4.0 mm/V.
Formula: Position (mm) = (Measured_Voltage - Null_Voltage) * Scale_Factor

The ADS1115 outputs a raw 16-bit signed integer. At a gain setting of ±4.096V, one bit equals 0.125 mV (4.096V / 32768). Here is the complete, copy-pasteable Arduino code to read the sensor, apply the math, and filter out high-frequency noise using a simple exponential moving average.

#include <Wire.h>
#include <Adafruit_ADS1X15.h>

Adafruit_ADS1115 ads;

// Calibration constants for a ±10mm LVDT with 0-5V output
// Note: If using 3.3V logic, ensure your conditioner output is scaled to 0-3.3V
const float ADC_VOLTAGE_STEP = 0.000125; // 125uV per bit at ±4.096V gain
const float NULL_VOLTAGE = 2.500;        // Voltage at mechanical center
const float SCALE_FACTOR = 4.0;          // mm per Volt
const float ALPHA = 0.2;                 // EMA filter weight (lower = smoother)

float filteredPosition = 0.0;

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22); // SDA, SCL for ESP32
  
  if (!ads.begin()) {
    Serial.println("Failed to initialize ADS1115. Check wiring.");
    while (1);
  }
  ads.setGain(GAIN_ONE); // ±4.096V range (1 bit = 0.125mV)
  
  // Prime the filter
  int16_t raw = ads.readADC_SingleEnded(0);
  filteredPosition = (raw * ADC_VOLTAGE_STEP - NULL_VOLTAGE) * SCALE_FACTOR;
}

void loop() {
  int16_t rawAdc = ads.readADC_SingleEnded(0);
  float voltage = rawAdc * ADC_VOLTAGE_STEP;
  float rawPosition = (voltage - NULL_VOLTAGE) * SCALE_FACTOR;
  
  // Apply Exponential Moving Average to reject 50/60Hz mains ripple
  filteredPosition = (ALPHA * rawPosition) + ((1.0 - ALPHA) * filteredPosition);
  
  Serial.print("Raw ADC: "); Serial.print(rawAdc);
  Serial.print(" | Voltage: "); Serial.print(voltage, 4);
  Serial.print("V | Position: "); Serial.print(filteredPosition, 3);
  Serial.println(" mm");
  
  delay(20); // 50Hz sampling rate
}

Beating EMI: Interference Sources and Mitigation

LVDTs are frequently deployed in harsh industrial environments alongside heavy machinery. If your readings are jittering by ±0.5mm or drifting randomly, you are likely a victim of Electromagnetic Interference (EMI). Here are the three most common culprits and how to fix them.

  • Variable Frequency Drives (VFDs): VFDs switching high currents generate massive broadband EMI. This noise couples into the LVDT's high-impedance secondary coils. Fix: Never run LVDT signal cables in the same conduit as VFD motor leads. Maintain at least 12 inches of separation, and use double-shielded twisted-pair (STP) cable with the shield grounded at the signal conditioner end only.
  • Ground Loops: If the LVDT housing is bolted to a grounded steel chassis, and your signal conditioner is grounded to a different electrical panel, a ground loop will push 50/60Hz AC current through your signal ground. Fix: Use a signal conditioner with galvanic isolation (look for '3-way isolation' on the spec sheet). This breaks the DC path between the sensor ground and the microcontroller ground.
  • Excitation Beat Frequencies: If you have two LVDTs mounted close together and their signal conditioners operate at slightly different excitation frequencies (e.g., 3000 Hz and 3005 Hz), the magnetic fields will cross-couple and create a 5 Hz 'beat' interference pattern in your output. Fix: Synchronize the excitation oscillators of adjacent conditioners, or use conditioners that allow you to manually set the excitation frequency to match exactly.
Safety Note: When wiring 24V DC industrial power supplies for signal conditioners, always de-energize the supply, verify zero voltage with a multimeter, and ensure all exposed DC terminals are covered. While 24V is generally safe from shock, a short circuit can easily arc and melt 22 AWG signal wires if not protected by an inline 2A fuse.