When standard I2C or SPI breakout boards fall short of your project's environmental or precision requirements, you must turn to other sensors—specifically industrial 4-20mA current loops and 0-10V voltage transducers. Interfacing these robust devices with a 3.3V microcontroller like the ESP32 requires converting raw analog signals into physical units using precision shunt resistors, voltage dividers, and a stable external ADC. Below is the exact bench procedure, wiring math, and scaling code to get reliable readings from industrial-grade transducers.
The Sensing Principle and Output Signals
Industrial transducers typically rely on a primary sensing element—such as a piezoresistive diaphragm for pressure or a platinum RTD for temperature—that changes its electrical resistance in response to a physical stimulus. Unlike hobbyist modules that package this element with an onboard digital microcontroller, industrial 'other sensors' output a raw, continuous analog signal. An internal transmitter circuit excites the sensing element and scales the resulting millivolt change into a standardized, high-level analog output designed to travel hundreds of feet without degradation.
The output itself is strictly analog, taking one of two forms: a current signal (4-20mA) or a voltage signal (0-10V or 0-5V). A 4-20mA loop is immune to voltage drop over long wire runs because the transmitter actively adjusts its internal resistance to maintain a constant current regardless of wire length. A 0-10V output is simpler to interface but susceptible to voltage drop and electromagnetic interference (EMI) over distance. Neither output is digital; both require an Analog-to-Digital Converter (ADC) to translate the continuous electrical state into a discrete integer your microcontroller can process.
Industrial Sensor Specifications and Scaling Data
Before wiring anything, you must identify the output type and physical range of your specific transducer. The table below details four common industrial sensors you will encounter when moving beyond standard hobby modules. Use this data to calculate your scaling factors.
| Sensor Type | Output Signal | Supply Range | Min Output | Max Output | Physical Range |
|---|---|---|---|---|---|
| Hydraulic Pressure Transducer | 4-20mA | 10-30V DC | 4.0 mA | 20.0 mA | 0 - 100 PSI |
| Duct Temperature Transmitter (RTD) | 0-10V | 15-24V DC | 0.0 V | 10.0 V | -40 to 150 °C |
| Ultrasonic Tank Level Sensor | 4-20mA | 24V DC | 4.0 mA | 20.0 mA | 0.2 - 5.0 Meters |
| Paddlewheel Flow Meter | 0-5V | 5-24V DC | 0.0 V | 5.0 V | 0 - 50 L/min |
Notice that 4-20mA sensors start at 4mA, not 0mA. This is a deliberate design feature called a 'live zero.' If the sensor reads 0mA, the microcontroller instantly knows a wire has broken or the transmitter has lost power, distinguishing a true zero-measurement (4mA) from a system fault (0mA).
Wiring, Pinout, and Raw-to-Unit Math
The ESP32's internal 12-bit ADC is notoriously non-linear and noisy, particularly near the 3.3V rail. For industrial sensors, bypass the internal ADC and use an external 16-bit I2C ADC like the ADS1115. Below is the wiring matrix for interfacing both 4-20mA and 0-10V sensors to an ESP32 via an ADS1115 breakout.
| Component | Pin / Terminal | Connects To | Notes / Supply Range |
|---|---|---|---|
| 24V DC Power Supply (V+) | Positive Terminal | Sensor Red Wire (Supply) | Use an isolated 24V industrial PSU. |
| 24V DC Power Supply (GND) | Negative Terminal | ESP32 GND & ADS1115 GND | Establish a single common ground point. |
| 4-20mA Sensor | Signal Wire (Black/White) | 150Ω Shunt Resistor (Leg 1) | 150Ω yields 0.6V at 4mA, 3.0V at 20mA. |
| 150Ω Shunt Resistor | Leg 2 | ADS1115 A0 Pin & PSU GND | Use a 1% tolerance metal film resistor. |
| 0-10V Sensor | Signal Wire | Voltage Divider (High Side) | Divide 10V down to ~3.0V max for ADS1115. |
| ADS1115 Breakout | VDD / SDA / SCL | ESP32 3V3 / GPIO 21 / GPIO 22 | Pull-ups (4.7kΩ) required on I2C lines. |
The Raw-to-Unit Math
To convert the raw ADC integer into a meaningful engineering unit, we must map the electrical output to the physical range. According to All About Circuits' guide on current loops, the voltage across the shunt resistor is calculated via Ohm's Law (V = I × R).
For a 4-20mA loop with a 150Ω shunt and an ADS1115 (Gain = 1, FSR = 4.096V):
- Voltage:
V = (Raw_ADC / 32767.0) * 4.096 - Current (mA):
I_mA = (V / 150.0) * 1000.0 - Physical Value:
Value = ((I_mA - 4.0) / 16.0) * (Max_Range - Min_Range) + Min_Range
#include <Wire.h>
#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads;
// Sensor physical limits
const float MIN_PSI = 0.0;
const float MAX_PSI = 100.0;
const float SHUNT_OHMS = 150.0;
void setup() {
Serial.begin(115200);
ads.setGain(GAIN_ONE); // +/- 4.096V range
ads.begin();
}
void loop() {
int16_t raw_adc = ads.readADC_SingleEnded(0);
// 1. Convert raw to Voltage
float voltage = (raw_adc * 4.096) / 32767.0;
// 2. Convert Voltage to Current (mA)
float current_mA = (voltage / SHUNT_OHMS) * 1000.0;
// 3. Scale 4-20mA to Physical Units (PSI)
float pressure_psi = ((current_mA - 4.0) / 16.0) * (MAX_PSI - MIN_PSI) + MIN_PSI;
// Constrain to handle noise below 4mA or above 20mA
pressure_psi = constrain(pressure_psi, MIN_PSI, MAX_PSI);
Serial.print("Raw: "); Serial.print(raw_adc);
Serial.print(" | mA: "); Serial.print(current_mA, 2);
Serial.print(" | PSI: "); Serial.println(pressure_psi, 2);
delay(500);
}
Calibration, Interference, and Troubleshooting
Industrial environments are electrically hostile. When interfacing other sensors of this caliber, you must account for calibration offsets and environmental noise that hobbyist tutorials rarely address.
Calibration and Scaling Adjustments
Even with a 1% precision shunt resistor, you will see a slight offset. To calibrate:
- Force the sensor to its known minimum state (e.g., vent a pressure sensor to atmosphere so it reads exactly 0 PSI).
- Record the
current_mAvalue from the serial monitor. It will likely read something like 4.12mA instead of 4.00mA. - Adjust the
- 4.0offset in the scaling formula to match your baseline reading (e.g.,- 4.12), or implement a two-point calibration in your code using themap()function equivalent for floats.
Common Interference Sources
If your ADC readings are jumping erratically by 5-10% on the bench, you are likely suffering from one of three interference sources:
- Ground Loops: If your 24V power supply ground and your ESP32 USB ground are connected to different earth potentials, current will flow through the ADC ground wire. Fix: Power the ESP32 from a battery or an isolated DC-DC converter during testing, or ensure a single-point star ground topology.
- Variable Frequency Drive (VFD) EMI: VFDs on nearby motors inject massive high-frequency noise into adjacent wiring. Because 0-10V sensors are high-impedance, they act as antennas for this noise. Fix: Switch to 4-20mA sensors for high-EMI environments, as current loops are inherently low-impedance and reject voltage-induced EMI.
- ADC Reference Drift: If you rely on the ESP32's internal 3.3V regulator as an ADC reference, any noise on the USB line alters your readings. Fix: The ADS1115 uses an internal precision voltage reference, which is why it is mandatory for this application. For more on ADC architectures, refer to Adafruit's ADC Breakout Guide.
Never connect a 4-20mA sensor that is monitoring a mains-powered or high-voltage system directly to a microcontroller without galvanic isolation. If the sensor's internal isolation fails, 24V or higher could backfeed into your 3.3V I2C bus, instantly destroying the ESP32 and presenting a shock hazard. Use an I2C isolator chip (like the ISO1540) between the ADS1115 and the ESP32 in high-risk industrial panels.
By treating these industrial transducers not as magical black boxes but as predictable analog current and voltage sources, you can reliably integrate heavy-duty 'other sensors' into your embedded projects. Stick to the 150Ω shunt math, use an external 16-bit ADC, and maintain a clean ground plane to achieve bench-top accuracy in the field.






