The Sensing Principle Behind 4-20mA Application Sensors

Industrial pressure application sensors typically rely on a piezoresistive Wheatstone bridge embedded in a stainless steel diaphragm. As fluid pressure deforms the diaphragm, the strain gauges change resistance, unbalancing the bridge and producing a millivolt-level differential signal. An internal signal conditioning ASIC amplifies this tiny variation, compensates for temperature drift, and linearizes it across the sensor's rated mechanical span.

Instead of outputting a raw voltage, these application sensors convert the conditioned signal into a 4-20mA current loop. At 0% pressure (the lower range value), the sensor draws exactly 4mA; at 100% pressure, it draws 20mA. This current-based output is inherently immune to voltage drop over long cable runs, making it the undisputed standard for harsh industrial, municipal, and agricultural environments where wiring runs exceed 50 feet.

Hardware Interfacing: Wiring and Signal Conditioning

The ESP32's internal ADC is notoriously non-linear, prone to noise, and practically capped at ~3.1V. To accurately read a 4-20mA application sensor, you must use an external 16-bit ADC like the Texas Instruments ADS1115. Furthermore, microcontrollers read voltage, not current. We must pass the current through a precision shunt resistor to convert it to a measurable voltage.

By selecting a 150-ohm, 0.1% tolerance precision shunt resistor, we convert the 4-20mA signal into a 0.6V to 3.0V signal. This safely maximizes the ADC's resolution without risking clipping or exceeding the ESP32's 3.3V logic limits if a fault occurs.

Wiring and Specification Matrix
Component / Node Pin / Terminal Connection Destination Supply / Spec Range
Application Sensor V+ (Brown/Red) External 24V DC PSU (+) 10V - 30V DC
Application Sensor GND (Black/Blue) External 24V DC PSU (-) Common Ground
Application Sensor OUT (White/Signal) 150Ω Shunt Resistor (High Side) 4-20mA Output
150Ω Shunt Resistor Low Side PSU GND & ESP32 GND 0.1% Tolerance, 1/4W
ADS1115 Module A0 (Analog In) 150Ω Shunt Resistor (High Side) 0.6V - 3.0V Input
ADS1115 Module VDD / SDA / SCL ESP32 3V3 / GPIO 21 / GPIO 22 3.3V Logic / I2C

Output Signal Math: Raw ADC to Physical Units

The output of the application sensor is fundamentally an analog current loop, which we condition into an analog voltage, and finally digitize into a 16-bit I2C integer. The ADS1115 uses a programmable gain amplifier (PGA). We will set the PGA to ADS1X15_REG_CONFIG_PGA_4_096V, giving us a full-scale range (FSR) of 4.096V.

Because the ADS1115 is a 16-bit signed ADC and we are using single-ended mode, the maximum positive reading is 32,767. The voltage per bit (LSB) is calculated as: 4.096V / 32,768 = 0.000125V (0.125mV) per bit.

Bench Tip: Never use a standard 5% carbon-film resistor for your shunt. A 5% tolerance on 150 ohms introduces a potential 7.5-ohm error, which translates to a 1.5mA reading error—completely destroying the benefit of a 16-bit ADC. Spend the extra $0.50 on a 0.1% metal-film or wirewound precision resistor.

The Conversion Chain:

  1. Voltage: V = Raw_ADC * 0.000125
  2. Current (mA): I = (V / 150.0) * 1000.0
  3. Pressure (PSI): Assuming a 0-100 PSI sensor, PSI = ((I - 4.0) / 16.0) * 100.0

Step-by-Step ESP32 Implementation

Follow these steps to bring the application sensor online. Ensure your ESP32 and the 24V PSU share a common ground reference, otherwise the shunt voltage will float and yield garbage ADC data.

  1. Wire the 24V PSU to the sensor's power pins. Do not power the sensor from the ESP32's 5V/VIN pin; industrial application sensors require stable, high-current 12-24V rails.
  2. Connect the 150-ohm precision shunt between the sensor's signal output wire and the shared system ground.
  3. Wire the ADS1115 I2C pins to the ESP32 (SDA to GPIO 21, SCL to GPIO 22 on the standard ESP32-WROOM-32E).
  4. Install the Adafruit_ADS1X15 library via the Arduino IDE Library Manager.
  5. Upload the following calibration and reading code.
#include <Wire.h>
#include <Adafruit_ADS1X15.h>

Adafruit_ADS1115 ads;

// Sensor Configuration
const float SHUNT_RESISTANCE = 150.0; // Ohms
const float MAX_PRESSURE_PSI = 100.0; // Sensor rated max
const float ADC_LSB = 0.000125;       // 4.096V FSR / 32768

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22); // SDA, SCL for standard ESP32
  
  if (!ads.begin(0x48)) {
    Serial.println("Failed to initialize ADS1115. Check I2C wiring.");
    while (1);
  }
  
  // Set PGA to 4.096V range (1 bit = 0.125mV)
  ads.setGain(GAIN_ONE);
}

void loop() {
  int16_t raw_adc = ads.readADC_SingleEnded(0);
  
  if (raw_adc < 0) raw_adc = 0; // Prevent negative voltage math errors
  
  // 1. Convert Raw ADC to Voltage
  float voltage = raw_adc * ADC_LSB;
  
  // 2. Convert Voltage to Current (mA)
  float current_mA = (voltage / SHUNT_RESISTANCE) * 1000.0;
  
  // 3. Scale Current to Physical Unit (PSI)
  float pressure_psi = 0.0;
  if (current_mA >= 4.0 && current_mA <= 20.0) {
    pressure_psi = ((current_mA - 4.0) / 16.0) * MAX_PRESSURE_PSI;
  } else if (current_mA < 3.8) {
    Serial.println("FAULT: Broken wire or sensor power loss (< 4mA)");
  } else if (current_mA > 20.5) {
    Serial.println("FAULT: Sensor overload or short circuit (> 20mA)");
  }

  Serial.printf("Raw: %d | V: %.3f | I: %.2f mA | Pressure: %.2f PSI\n", 
                raw_adc, voltage, current_mA, pressure_psi);
  
  delay(500);
}

Common Interference Sources and Troubleshooting

When deploying application sensors in the field, the physical environment will attack your signal. Here is how to identify and defeat common interference sources:

  • Ground Loops: If your 24V PSU ground and your ESP32 USB ground are tied to different earth potentials, current will flow through the I2C ground wire, shifting your ADC baseline. Fix: Use an I2C isolator (like the ISO1540) or power the ESP32 from the same isolated 24V-to-5V DC-DC converter that feeds the sensor loop.
  • VFD and Motor EMI: Variable Frequency Drives generate massive high-frequency common-mode noise. While 4-20mA loops reject differential noise, capacitive coupling can still inject spikes into the ADC. Fix: Use shielded twisted-pair (STP) cable for the sensor run, and terminate the shield at the PSU ground only (never at both ends). Add a 100nF ceramic capacitor in parallel with your 150-ohm shunt to form a low-pass hardware filter.
  • Shunt Thermal Drift: If your shunt resistor is undersized (e.g., 1/8W), the 20mA current will heat it, changing its resistance and causing the pressure reading to slowly climb over the first 10 minutes of operation. Fix: Always use a 1/4W or 1/2W resistor for 4-20mA shunts to keep the thermal coefficient stable.

Frequently Asked Questions About Application Sensors

Why do industrial application sensors use 4-20mA instead of 0-10V?

A 0-10V voltage signal is highly susceptible to voltage drop over long wire runs; a 500-foot cable run will measurably reduce the voltage, causing the receiving PLC or microcontroller to read a lower value than the sensor actually outputted. A 4-20mA current loop, governed by Kirchhoff's Current Law, ensures that the current pushed by the sensor is exactly the same current received at the shunt, regardless of cable length or resistance. Furthermore, the "live zero" at 4mA allows the controller to instantly detect a broken wire (which reads 0mA), whereas a 0-10V sensor cannot distinguish between a true 0 reading and a severed cable.

How do I calibrate low-cost application sensors for precision IoT projects?

Cheap application sensors often have a 1-2% full-scale error right out of the box. To calibrate, apply a known physical zero (e.g., atmospheric pressure for a gauge sensor) and record the raw ADC value. Then, apply a known physical span (using a deadweight tester or a calibrated reference gauge) and record the second ADC value. In your ESP32 code, replace the hardcoded 4.0mA and 20.0mA assumptions with your measured zero_offset_mA and span_multiplier. Always perform this two-point calibration after the sensor has been powered on for at least 15 minutes to allow internal ASIC thermal equilibrium.

What causes a 4-20mA application sensor to read exactly 0mA or 24mA?

A reading of exactly 0mA almost always indicates an open circuit: a broken signal wire, a blown internal sensor fuse, or a failed 24V power supply. A reading pegged above 20mA (often hitting 22-24mA) indicates that the sensor's internal diagnostic circuit has detected a fault—usually a burst diaphragm, an over-pressure event exceeding 150% of its rated span, or a short circuit in the signal wiring. The ESP32 code provided above includes explicit fault-catching logic to flag these out-of-bounds states rather than returning impossible negative or massive pressure values.