4-20 mA input reading wrong: check it step by step
83 Views •RS-485: how to check a bus step by step
80 Views •Digital input not reading: NPN or PNP, step by step
72 Views •Relay or transistor output: which one and how to check it
67 Views •Scaling a 4-20 mA signal in the PLC: formula, constants and code
23 Views •Scaling a 4-20 mA signal in the PLC: formula, constants and code
Short answer: a 4-20 mA transmitter sends 4 mA at the bottom of its range, not 0 mA. Subtract 4 mA, divide by the 16 mA span and multiply by the range. If the program scales from zero, an empty tank reads 20 %.
This works for any PLC with analog inputs. Below you will find the constants for each Industrial Shields PLC range and a link to tested code.
The formula
PV = PVmin + (I − 4 mA) / 16 mA × (PVmax − PVmin)
Example: a 0-10 bar transmitter at 12 mA gives 0 + (12 − 4) / 16 × 10 = 5 bar.
On a 0-10 V input with a 500 Ω resistor
A 500 Ω resistor between the input and 0 V turns 4-20 mA into 2-10 V: scale from 2 V, not from 0 V. The input impedance is in parallel with the resistor and lowers the reading a little. For accuracy, calibrate with a loop calibrator at 4 mA and at 20 mA, and use those two readings as the ends of the scale.
Constants for your PLC range
| PLC range | Analog input | analogRead() at full scale |
|---|---|---|
| M-Duino and Ardbox | 0-10 V, 10 bit, input impedance 39 kΩ | 1023 |
| ESP32 PLC | 0-10 V, 11 bit | 2047 |
| ESP32 PLC 14 | AI0.0 and AI0.1: 0-10 V or 4-20 mA mode, selected in software | See the ESP32 PLC 14 datasheet |
| Raspberry PLC V4 and V6 | 0-10 V, 12 bit | 4095 |
| Raspberry PLC V3 | 0-10 V | 2047 |
Sources: family datasheets and the official rpiplc library for the Raspberry PLC. On a 0-10 V input, 4 mA with 500 Ω reads about 20 % of full scale: 205 counts of 1023, before the input impedance correction.
Scaling function
// counts: analogRead() value, adcMax: value at 10 V for your range
// rEq: 500 ohm in parallel with the input impedance (493.7 ohm on M-Duino)
float countsToMilliamps(float counts, float adcMax, float rEq) {
return counts * 10.0 / adcMax / rEq * 1000.0;
}
float scale420(float mA, float pvMin, float pvMax) {
return pvMin + (mA - 4.0) * (pvMax - pvMin) / 16.0;
}
// Below 3.6 mA: broken loop or a transmitter fault (NAMUR NE 43). Alarm, do not scale.The full sketch, tested on an M-Duino, with averaging, loop fault detection and full-scale check, is in the guide how to convert a 4-20 mA signal to 0-10 V in an Arduino PLC.
Near 0 mA is a fault, not a value
- 0 mA or close: broken wire, no loop power or reversed polarity. Raise an alarm and go to a safe state.
- Below 3.6 mA or above 21 mA: transmitters that follow NAMUR NE 43 use these values to signal a fault.
- Reading stuck at full scale: the real current can be higher than the input can show. Check the resistor value and the input range.
Commenting is not enabled on this course.