Skip to Content

← All functionalities

Water pumping (sanitation)ESP32 PLC 38ARGPIOAcquisition

Reading a 4-20 mA level probe on an ESP32 PLC, the right way

A 4-20 mA level sensor is the industrial standard for tank and well measurement, and reading it well takes more than one analogRead. This example, taken from a real water pumping station deployment, reads a hydrostatic probe on input I0_11 of an ESP32 PLC 38AR, filters the raw 0-1023 signal, converts it to centimetres, detects a broken loop and drives the pump with proper hysteresis.

Why 4-20 mA starts at 4, not 0

The live-zero is the diagnostic. A healthy loop never drops below 4 mA, so a reading near 0 mA can only mean a cut cable or a dead transmitter. The example flags anything below ~3.5 mA as broken wire, lights the alarm pilot and falls back to a hard-wired overflow float — the measurement fails, the station stays safe.

Filtering and scaling to engineering units

Current loops pick up ripple from contactors and VFDs. An 8-sample moving average smooths the 0-1023 reading before scaling: subtract the 4 mA offset (~205 counts) and map the remaining span to the probe range, 0-250 cm in this case. Print raw counts and centimetres side by side — that trace is how you calibrate the scale on site.

Hysteresis instead of a single threshold

With one threshold the pump would chatter every time waves cross it. Two setpoints — start above 180 cm, stop below 60 cm — give each cycle a defined volume, fewer motor starts and longer contactor life. The filtered value is also ready to be bit-packed into a LoRaWAN frame for remote monitoring.

A snippet from the implementation

Straight from the example as deployed on the ESP32 PLC 38AR — copy it freely:

void setup() {
  Serial.begin(115200);

  pinMode(I_LEVEL_SENSOR, INPUT);
  pinMode(I_OVERLEVEL, INPUT);
  pinMode(Q_PUMP, OUTPUT);
  pinMode(Q_PILOT, OUTPUT);
  digitalWrite(Q_PUMP, LOW);
  digitalWrite(Q_PILOT, LOW);

  // Preload the filter so it does not start with a zero average
  uint16_t first = analogRead(I_LEVEL_SENSOR);
  for (uint8_t i = 0; i < N_SAMPLES; i++) samples[i] = first;
}

The full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.

Frequently asked questions

How do I connect a 2-wire 4-20 mA sensor to the PLC?

Power the loop from the 24 Vdc supply through the transmitter and into the analog input, which converts the current to the 0-1023 reading. Check the input is configured for current mode, not voltage.

What does a reading below 4 mA mean?

Loop failure — broken cable, disconnected probe or dead transmitter. Treat it as a fault, never as "level zero", and switch to a safe fallback like a hard-wired float switch.

Can I use this on an ESP32 PLC 14?

Yes. Only the pin map changes — pick one of the analog-capable I0_x inputs of your model and keep the same filtering, scaling and broken-wire logic.

Related functionalities