Problem Summary
The Siemens SIMATIC IoT2040 example image ships with Node-RED v1.2.1 and the intel-gpio nodeset that exposes the Arduino Uno R3 header of the gateway. When a 4–20 mA two-wire transmitter is wired to the I/O shield's I0 input (which maps to Node-RED channel A1), the analog reading often stays pinned at the bottom of the scale (raw counts 0 to 3) and does not move when the process variable changes. Three field-confirmed root causes account for nearly every instance of this fault:
- Jumper in voltage mode – the shield current-mode jumper is on the VOLT (1–2) position, or is open. The internal 250 Ω shunt is bypassed, the AI input stage sees only leakage, and the SAR returns a near-zero count.
- Polarity reversed – the two loop conductors are swapped at the I0 terminal block. Reverse polarity is not destructive on documented shields, but the differential front end resolves to a near-zero ADC code.
-
Node wired to the wrong property – the
intel-gpio innode is set to a digital pin or to the wrong analog pin, so the payload never reflects the current loop.
The fix sequence is: set the jumper to CUR, verify polarity with a multimeter, and deploy a flow that binds Pin = A1 and Type = Analog on the intel-gpio in node.
IoT2040 Hardware Reference
The IoT2040 (Siemens 6ES7647-0AA00-1YA2) is an industrial IoT gateway in the SIMATIC family, built around an Intel Quark x86 SoC with 1 GB DDR3 and 8 GB eMMC. The example image layers a Yocto Linux distribution, Node-RED v1.2.1, and the intel-gpio nodeset on top of the Quark. The Arduino Uno R3-compatible socket on the top of the enclosure is the electrical interface to the I/O shield; the pin assignment follows the standard Arduino Uno layout:
| Arduino Pin | intel-gpio Node Name | Shield Terminal | Function |
|---|---|---|---|
| A0 | A0 | I1 (AI1+) | Analog input 0 |
| A1 | A1 | I0 (AI0+) | Analog input 1, default 4–20 mA channel |
| A2 | A2 | I2 | Analog input 2 |
| A3 | A3 | I3 | Analog input 3 |
| A4 / A5 | A4 / A5 | — | I²C SDA / SCL – do not use for analog |
| D2–D9 | D2–D9 | — | Digital I/O 0–7 |
The Input/Output Shield for IoT2040 manual calls the channel on the I0 screw terminal A1 in the Node-RED node palette. This is the source of the confusion: the screw-terminal label I0 is the field-side designation, while the firmware node label A1 is the Arduino-header position. The two must be reconciled before commissioning.
I/O Shield Current-Mode Jumper
The shield front end is bipolar: each analog input pair accepts either a 0–10 V voltage signal or a 0/4–20 mA current loop. The selection is hardware-driven through a 3-pin jumper on the shield. Without the jumper placed on the CUR position the internal shunt resistor is disconnected, the AI input stage floats, and the SAR returns a near-zero count (typically 0 to 3 out of 4095 for a 12-bit SAR, or 0 to 3 out of 1023 for a 10-bit SAR – the resolution depends on the shield variant; verify against the shield bill of materials).
| Jumper Position | Mode | Input Range | Shunt Configuration |
|---|---|---|---|
| 1–2 (VOLT) | Voltage | 0–10 V | Direct to resistor divider; no shunt |
| 2–3 (CUR) | Current | 0/4–20 mA | 250 Ω precision shunt engaged |
| Open | Disabled | — | AI reads 0 counts; input floating |
Sensor Wiring and Polarity
A two-wire (loop-powered) 4–20 mA transmitter needs only two conductors: the loop supply positive and the loop return. The shield's I0 terminal block on documented shields uses + and − (or IN+ / IN−). Swapping the two will not damage the sensor or the IoT2040 (the input is reverse-polarity protected up to ±30 V on most shields), but the ADC will measure a near-zero differential and the reading will pin to 0–3.
A three-wire sensor (sensor supply, signal out, common) requires matching the shield's three-terminal strip: V+, IN+, GND. The shield documentation shows the matching to the I0 / A1 channel as follows:
-
+on the sensor →IN+on the shield (screw terminal 1 of the I0 block). -
−on the sensor →IN−on the shield (screw terminal 2 of the I0 block). - For three-wire devices, connect
V+(screw terminal 3) to the sensor's supply pin only if the shield is the loop-power source; otherwise power the sensor from a separate 24 V rail.
Node-RED Flow Configuration
The example image registers the intel-gpio nodes under the Intel IoT palette. The intel-gpio in node has the following relevant properties:
| Property | Type | Default | Notes |
|---|---|---|---|
| Pin | String | — | Use A0, A1, A2, A3 for the four analog channels. |
| Type | Enum | — |
Analog is mandatory for AI; Digital is for the eight DIO lines. |
| Interval (ms) | Integer | 1000 | Sample period. Below 100 ms the Quark SAR may report stale values. |
| Resistor mode | Enum | none | Leave none for current mode (shunt is on the shield). |
| Deadband | Integer | 0 | Suppresses noise around the last reading; set to 1 for 10-bit, 4 for 12-bit. |
Minimum flow to validate the AI:
[
{ "id": "tab1", "type": "tab", "label": "AI diagnostic" },
{ "id": "inject1", "type": "inject", "z": "tab1", "name": "tick",
"props": [{ "p": "payload" }], "repeat": "1", "crontab": "",
"once": true, "onceDelay": "0.2", "topic": "",
"payloadType": "date", "x": 150, "y": 100, "wires": [["read1"]] },
{ "id": "read1", "type": "intel-gpio in", "z": "tab1", "name": "A1 read",
"pin": "A1", "type": "Analog", "interval": "1000",
"deadband": "0", "resistor": "none", "x": 320, "y": 100,
"wires": [["scale1", "debug1"]] },
{ "id": "scale1", "type": "function", "z": "tab1", "name": "to mA",
"func": "var raw = msg.payload;\nvar counts = 4095; // change to 1023 for 10-bit SAR\nvar ma = (raw / counts) * 16 + 4;\nmsg.payload = ma.toFixed(2);\nreturn msg;",
"outputs": 1, "noerr": 0, "x": 510, "y": 80, "wires": [["debug2"]] },
{ "id": "debug1", "type": "debug", "z": "tab1", "name": "AI raw",
"active": true, "tosidebar": true, "complete": "payload",
"targetType": "msg.payload", "x": 510, "y": 120, "wires": [] },
{ "id": "debug2", "type": "debug", "z": "tab1", "name": "AI mA",
"active": true, "tosidebar": true, "complete": "payload",
"targetType": "msg.payload", "x": 680, "y": 80, "wires": [] }
]
Expected output: an integer payload that scales linearly with the loop current. On a 12-bit SAR with 1.2 V reference and 250 Ω shunt, 4 mA reads ~500 counts, 20 mA reads ~2500 counts. On a 10-bit SAR the same loop reads ~205 and ~1023 counts respectively. If msg.payload is constant at 0–3 regardless of sensor stimulus, the fault is hardware (jumper or wiring), not Node-RED.
Diagnostic Procedure
- Power down the IoT2040. Open the top cover of the gateway. Locate the I/O shield and identify the jumper block for the AI channel pair that contains the I0 terminal (label JP1 or JP2 on most shield revisions).
- Confirm the jumper is on the CUR position (2–3). If it is on VOLT (1–2) or open, the analog input cannot read a 4–20 mA loop. Move it and re-seat the gateway cover.
- Power the loop supply (typically 24 VDC). With a digital multimeter on mA, break the loop at the I0 terminal and confirm the current is between 4 mA and 20 mA. A reading of 0 mA means the sensor is unpowered or the loop is open; a reading of >20 mA indicates a short.
- Restore the loop. Measure the voltage across the I0
+and−terminals. Expect 1.0 V (4 mA) to 5.0 V (20 mA) with the jumper on CUR. Voltages outside this range indicate a wiring fault. - Check the polarity: swap the two wires and watch the Node-RED debug sidebar. The valid wiring produces a moving integer; the swapped wiring pins the value to 0–3. Reconnect correctly and re-deploy.
- Verify the
intel-gpio innode: Pin = A1, Type = Analog, Resistor = none. Deploy and observe the debug output for 30 s. The payload should track the sensor in real time.
Common Failure Modes and Signatures
| Symptom | Likely Cause | Verify | Fix |
|---|---|---|---|
| Reading 0–3, no change | Jumper on VOLT, wires swapped, or both | DMM on I0 terminals; expect 1–5 V | Set jumper to CUR; correct polarity |
| Reading full-scale (4095 or 1023) at all times | Loop supply on input, sensor shorted | Measure I0 voltage; expect < 5 V | Remove loop supply from input; check sensor wiring |
| Reading 0 at all times, loop current 4–20 mA present | Node wired to DIO, not AI | Node property Type | Change node to intel-gpio in with Type = Analog
|
| Reading noisy, ±20 counts jitter | Long unshielded cable, no 250 Ω at shield | Loop resistance < 250 Ω + cable | Use shielded twisted pair; ground shield at gateway end only |
| Reading drifts with gateway temperature | Shield reference not ratiometric | Reference value vs. data sheet | Apply single-point calibration in Node-RED function node |
| Reading collapses during relay or VFD switching | Conducted EMI on the loop | Scope across I0 with isolated probe | Add ferrite on the loop cable; separate from VFD power |
| Reading responds to digital stimulus only |
intel-gpio Pin set to D2–D9 |
Inspect deployed node JSON | Change Pin to A1 |
EMI and Industrial Noise Considerations
The IoT2040 is intended for cabinet installation. Long analog runs in plant environments pick up common-mode noise from variable-frequency drives, contactors, and resistance welders. The current loop is more immune than a voltage loop because the 4–20 mA signal is represented by current, not voltage, but the cable still acts as an antenna. Field-proven practices:
- Use shielded twisted pair (Belden 8760 or equivalent) for the loop. Ground the shield at the IoT2040 end only; never at both ends – a dual-end ground creates a ground loop that injects 50/60 Hz.
- Keep the loop cable at least 200 mm away from VFD output cables. If crossing is unavoidable, cross at 90°.
- Install a ferrite (Laird 28A2024-0A2 or equivalent) on the loop cable close to the IoT2040.
- If the sensor is a thermocouple or strain gauge bridge, add a 0.1 µF X7R cap across the input terminals at the shield to roll off RF.
- Route the loop away from DC motor commutator brushes and from any contactor coil that does not have a snubber.
Verification Tests
- Open-loop test: Disconnect the sensor. With a calibrated current source (or a 4 mA / 12 mA / 20 mA simulator like the WIKA CPP1000 or Beamex MC6), inject each setpoint into I0. The Node-RED payload should match the table below within ±1 count:
| Loop Current | Expected ADC Count (10-bit) | Expected ADC Count (12-bit) | Expected mA on Dashboard |
|---|---|---|---|
| 4.000 mA | 205 | 819 | 4.00 |
| 8.000 mA | 410 | 1638 | 8.00 |
| 12.000 mA | 614 | 2458 | 12.00 |
| 16.000 mA | 819 | 3277 | 16.00 |
| 20.000 mA | 1023 | 4095 | 20.00 |
-
Short test: With the loop supply off, place a wire link between
IN+andIN−on the shield. The ADC must read 0 counts. Any other value indicates a stuck offset on the SAR or a damaged input stage. - Polarity test: Reverse the sensor wires. The ADC should pin to 0–3 (or a near-zero value, not full scale). This confirms the polarity protection is intact and the input stage is not latched.
- Loop-supply test: With the sensor disconnected and the loop supply still on, measure the open-circuit voltage at the I0 terminals. It should equal the loop supply (typically 24 VDC). If the supply collapses, the shield's input protection has failed and the unit must be replaced.
-
Function-node scaling test: Inject 4.000 mA. The mA dashboard should read 4.00 ±0.05. Inject 20.000 mA. The dashboard should read 20.00 ±0.05. A non-linear response indicates that the
countsdivisor in the function node does not match the SAR resolution – update it to 1023 or 4095 to match the actual shield.
Spare-Part and Ordering Information
| Item | Manufacturer Part Number | Notes |
|---|---|---|
| IoT2040 gateway | Siemens 6ES7647-0AA00-1YA2 | Quark SoC, 1 GB DDR3, 8 GB eMMC |
| SIMATIC IOT2040 Input/Output Shield | Siemens 6ES7647-0KA00-0AA0 | Arduino form factor, 4 AI / 8 DIO; confirm variant with IA/DT configurator |
| Example image (Node-RED v1.2.1) | SIMATIC_IOT2040_Image_V2.6.0 | Yocto Linux + Node-RED + intel-gpio |
| 4–20 mA loop calibrator | WIKA CPP1000 / Beamex MC6 | Used for verification |
| Shielded twisted-pair loop cable | Belden 8760 / Lapp UNITRONIC LiYCY | ≥ 24 AWG, 2-core, overall foil + braid |
| Loop ferrite | Laird 28A2024-0A2 | Snap-on, 240 Ω @ 25 MHz, 5 mm bore |
intel-gpio nodeset is replaced on IoT2050 by native sysfs GPIO plus the node-red-contrib-s7 palette. Cross-check the active part number against the Siemens Industry Mall configurator before ordering; some IoT2040 shield variants have different AI front ends (10-bit vs 12-bit, isolated vs non-isolated).Related Documentation
- Siemens Industry Online Support – search "IoT2040" for operating instructions, FAQs, firmware images, and application examples.
- Node-RED official documentation – flow authoring, function node reference, dashboard.
FAQ
Why does my IoT2040 analog input read 0–3 regardless of the sensor value?
Three field-confirmed causes: the shield jumper is on VOLT instead of CUR, the two sensor wires are swapped, or the Node-RED node is bound to a digital pin. Move the jumper to the CUR position (2–3) on the channel pair, swap the wires if polarity is reversed, and confirm the intel-gpio in node has Type = Analog and Pin = A1.
Which Arduino pin maps to the I0 terminal on the I/O shield?
I0 maps to A1 in the Node-RED intel-gpio node palette. The field-side label (I0) and the firmware node label (A1) differ; refer to the shield manual to confirm before deploying the flow. I1 maps to A0, I2 to A2, I3 to A3.
Does the IoT2040 power the 4–20 mA loop?
No. The I/O shield exposes the input stage only; the loop must be powered from an external 24 VDC supply or from the sensor's own loop supply. The shield provides a 250 Ω precision shunt that converts the loop current to a 1–5 V signal for the on-board SAR; the input is reverse-polarity protected up to ±30 V on most shield variants.
Can I scale the raw ADC counts to engineering units in Node-RED?
Yes. Wire a function node after the intel-gpio in node and apply msg.payload = (raw / 4095) * 16 + 4; for a 12-bit SAR (output in mA) or msg.payload = (raw / 1023) * 16 + 4; for a 10-bit SAR. The math maps 4 mA to 4 mA and 20 mA to 20 mA, so the function node becomes a direct mA readout suitable for a dashboard gauge.
Is the IoT2040 still available, or should I move to IoT2050?
The IoT2040 is in the product phase-out window; the recommended successor is the SIMATIC IoT2050 (6ES7647-0BA00-0YA2) with an ARM Cortex-A53 SoC. The I/O shield form factor and the intel-gpio nodeset are replaced on IoT2050 by native sysfs GPIO and the node-red-contrib-s7 palette. Existing flows must be migrated; the shield is not pin-compatible across the two gateways.