SIMATIC IOT2000 Programming Eclipse, Arduino IDE, and CODESYS

David Krause16 min read
Other TopicSiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

SIMATIC IOT2000 Programming: Eclipse, Arduino IDE, and CODESYS Setup

The SIMATIC IOT2000 is Siemens' industrial-grade IoT gateway family built on an Intel x86-compatible processor. It bridges shop-floor automation protocols with higher-level IT and cloud systems, and it is shipped with a customized Yocto Linux image. Engineers developing on this platform must select a programming toolchain early in the project because the supported toolchains determine which libraries, debugging options, and field-replacement procedures are available. This reference covers the three primary toolchains - Eclipse with CDT, the Arduino IDE, and CODESYS Control for IOT2000 SL - and shows how to install, configure, build, and deploy applications on each.

Engineer field note: The IOT2000 is not a PLC in the SIMATIC S7 sense. Although CODESYS allows you to program it with IEC 61131-3 languages, the runtime is a soft-PLC on a Linux gateway, not the deterministic firmware of a SIMATIC S7-1200 or ET 200SP CPU. Treat it as an edge device, not a safety controller.

1. SIMATIC IOT2000 Platform Overview

The SIMATIC IOT2000 line was introduced by Siemens as a programmable IoT gateway that accepts the same physical environment (24 V DC, DIN-rail mounting, industrial EMC) as a SIMATIC PLC but exposes a Linux programming model. Two hardware variants are commonly deployed:

Model CPU Memory Arduino Shield I/O Ethernet USB / Serial
SIMATIC IOT2020 Intel Quark x86 (single core) 512 MB RAM / 8 GB flash Yes (Uno R3 compatible) 1 x RJ45 10/100 USB 2.0, RS232/485
SIMATIC IOT2040 Intel Quark x86 (single core) 1 GB RAM / 8 GB flash No 2 x RJ45 10/100 (switched) USB 2.0, RS232/485

Both variants ship with a Siemens-customized Yocto Linux image (Poky) that includes the SSH server, the Eclipse GNU toolchain, and a SDK package. The full operating instructions and SDK documentation are available in the Siemens Industry Online Support portal under entry ID 109741656 (IOT2020) and 109741657 (IOT2040). The SDK is the foundation for native C/C++ development, the Arduino integration, and the CODESYS runtime.

2. Toolchain Selection Strategy

Before installing anything, classify your application by three criteria. The first criterion is skill set: if your team is fluent in C/C++ and Qt, Eclipse is the natural fit; if your team comes from PLC backgrounds, CODESYS is faster to adopt; if your team is from maker/embedded backgrounds, the Arduino IDE offers the shortest ramp-up. The second criterion is determinism: deterministic cyclic IEC 61131-3 tasks require CODESYS Control for IOT2000 SL; soft-real-time scripts and C daemons run fine under Linux. The third criterion is field service: SD-card image swap, SSH-based firmware update, and OTA image deployment are supported uniformly, but CODESYS and Eclipse both expect a specific project layout on the gateway.

Use Case Recommended Tool Why
Custom Linux daemon, MQTT bridge, S7 / Modbus / OPC UA client Eclipse + C/C++ (CDT) Direct access to POSIX, sockets, libmodbus, open62541
Skid-mounted I/O acquisition with Arduino shields Arduino IDE on IOT2020 Native shield pin mapping, fast sketch iteration
Replacing a SIMATIC S7-1200 edge aggregator with IEC 61131-3 logic CODESYS Control for IOT2000 SL ST, FBD, LD, CFC, SFC with built-in fieldbus configurators
Drag-and-drop dashboards, REST connectors, low-code flow logic Node-RED (Linux service) Visual flow programming, JSON over MQTT / HTTP
Data-science glue, machine learning inference, JSON parsing Python 3 (preinstalled) Available out of the box on the Yocto image

3. Eclipse IDE with CDT for Native C/C++ Development

Eclipse is the toolchain Siemens documents in the IOT2000 starter guide as the canonical development environment for native C/C++ programs. The CDT (C/C++ Development Tooling) plugin set turns Eclipse into a cross-development IDE that pulls in the GNU compiler and debugger from the Siemens SDK.

3.1 Prerequisites

  1. Windows 10/11, Linux, or macOS workstation with at least 8 GB RAM (Eclipse Photon or later).
  2. Oracle Java JRE 8 or 11 - Eclipse Oxygen and newer require a 64-bit JRE.
  3. Eclipse IDE for C/C++ Developers (Photon 2018-09 or 2019-06).
  4. SIMATIC IOT2000 SDK installed on the workstation - download the archive that matches the firmware on the gateway. Siemens keeps the SDK aligned with the Yocto image; mismatched versions cause GLIBC errors on deploy.
  5. Ethernet or USB connectivity between the workstation and the IOT2000. The default IP is 192.168.200.1 (host) / 192.168.200.2 (gateway) when using the Siemens configuration cable.

3.2 Install Eclipse and CDT

  1. Download the Eclipse IDE for C/C++ Developers archive from the Eclipse Foundation downloads page and extract it to a writable path such as C:\eclipse-cpp or /opt/eclipse-cpp.
  2. Start Eclipse and select a fresh workspace, for example C:\iot2000-ws\iot2040. Avoid workspaces with spaces in the path; the CDT indexer can fail on long paths or paths containing &.
  3. Confirm the GNU toolchain from the SDK is on the PATH by opening Window > Preferences > C/C++ > Build > Environment and verifying ${IOT2000_SDK}/sysroots/x86_64-pokysdk-linux/usr/bin is included.
  4. Create a new C/C++ project with File > New > C/C++ Project > C Managed Build > Cross GCC. Enter a project name, then set the toolchain prefix to i586-poky-linux- (Quark is i586) and the path to the cross compiler ${IOT2000_SDK}/sysroots/x86_64-pokysdk-linux/usr/bin/i586-poky-linux-.

3.3 A Minimal C Hello-IOT Program

/* iot2000_hello.c - minimal cross-build sample */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    printf("SIMATIC IOT2000 build=%s %s\n", __DATE__, __TIME__);
    if (argc > 1) {
        printf("arg[1] = %s\n", argv[1]);
    }
    return EXIT_SUCCESS;
}

Build the project. Eclipse will produce an ELF binary linked against the i586-poky-linux libc. The SDK sysroot ensures glibc symbols match the gateway.

3.4 Deploying to the Gateway

Deployment options, in order of convenience:

  1. SCP / SFTP - copy the binary to /home/iot/iot2000_hello on the gateway using WinSCP, FileZilla, or scp iot2000_hello [email protected]:/home/iot/. Mark it executable with chmod +x /home/iot/iot2000_hello and run with ./iot2000_hello test.
  2. RSync over SSH - more efficient for repeated builds: rsync -avz -e ssh ./Debug/iot2000_hello [email protected]:/home/iot/.
  3. Remote System Explorer (RSE) - the Eclipse RSE plugin lets you drag the binary into the gateway's /home/iot folder directly from the Project Explorer.

3.5 Remote Debugging with gdbserver

  1. On the gateway, start gdbserver on the binary: gdbserver :2345 /home/iot/iot2000_hello.
  2. In Eclipse, create a C/C++ Remote Application debug configuration. Set the connection to the gateway IP, the remote path to /home/iot/iot2000_hello, and the gdbserver port to 2345.
  3. Set breakpoints in main(), click Debug, and Eclipse will push the binary, attach gdbserver, and stop at main.
Tip: The Quark core has no hardware single-step assist. Avoid placing breakpoints in tight loops; stepping through large arrays is slow because gdbserver has to single-step across every iteration. Use watchpoints and conditional breakpoints instead.

4. Arduino IDE Integration for the IOT2020

The IOT2020 carries a 100-mil spaced header that follows the Arduino Uno R3 pinout for the digital and analog channels, and the Yocto image ships with a compatibility shim that allows the Arduino IDE to program the gateway over USB or Ethernet. This is the only IOT2000 variant that supports Arduino-style shield I/O. The IOT2040 does not have the Arduino header; do not waste time trying to flash an Arduino sketch to it.

4.1 Arduino IDE Setup

  1. Install Arduino IDE 1.8.x on the workstation.
  2. Open File > Preferences and add the IOT2000 board manager URL: https://raw.githubusercontent.com/siemens/iot2000-arduino/main/package_arduino_iot2000_index.json.
  3. Open Tools > Board > Boards Manager, search for SIMATIC IOT2000, and click Install.
  4. Select SIMATIC IOT2020 in the Tools > Board menu, set the programmer to iot2000ip (for Ethernet deploy) or iot2000usb (for the Siemens USB cable).
  5. Configure the IP address under Tools > Port: 192.168.200.1 for the default gateway IP.

4.2 A Minimal Arduino Sketch for IOT2020

/* iot2020_blink.ino */
#define LED_PIN 13

void setup() {
    pinMode(LED_PIN, OUTPUT);
    Serial.begin(115200);
    while (!Serial) { ; }   // wait for serial on USB
    Serial.println("IOT2020 sketch started");
}

void loop() {
    digitalWrite(LED_PIN, HIGH);
    delay(500);
    digitalWrite(LED_PIN, LOW);
    delay(500);
}

Hit upload. The Arduino IDE compiles the sketch on the workstation, then pushes the resulting ELF binary to the gateway over SSH. The gateway's Yocto image launches it as a regular Linux process. The on-board LED is mapped to Arduino pin 13 by the Siemens shield definition file.

4.3 Limits of the Arduino Toolchain

The Arduino sketch runs on top of Linux, not on a bare-metal AVR/ARM core. The startup latency from power-on to sketch execution is on the order of 5-10 seconds, and you do not get deterministic loop timing because the Linux scheduler can preempt the sketch. For non-deterministic I/O expansion, this is fine; for safety or motion, it is not.

5. CODESYS Control for IOT2000 SL

CODESYS Control for IOT2000 SL is a single-seat, site-licensed runtime that turns the SIMATIC IOT2000 into a soft-PLC programmable with the CODESYS Development System V3 (free download from the CODESYS store). The runtime installs as a Linux service on the Yocto image and exposes the standard CODESYS fieldbus configurators: Modbus TCP master/slave, Modbus RTU master/slave, EtherNet/IP scanner/adapter, OPC UA server/client, and CANopen. The runtime supports all IEC 61131-3 languages plus CFC and the object-oriented extensions introduced in CODESYS V3.5.

5.1 Install the CODESYS Development System

  1. Download CODESYS V3.5 SP19 or later from the CODESYS online installer.
  2. Install the CODESYS Control for IOT2000 SL package from Tools > Package Manager. This adds the IOT2000 device description and the appropriate fieldbus configurator plug-ins.
  3. Activate the license. Single-seat licenses bind to the workstation; multi-seat and site licenses are available from the CODESYS store.

5.2 Install the CODESYS Runtime on the Gateway

  1. Copy the runtime package codesys-control-for-iot2000-sl_*.deb to the gateway with SCP.
  2. SSH into the gateway and install: dpkg -i codesys-control-for-iot2000-sl_*.deb.
  3. Enable the systemd service: systemctl enable codesyscontrol.service && systemctl start codesyscontrol.service.
  4. Verify the runtime is listening: ss -tlnp | grep 11740. Port 11740 is the CODESYS communication port.

5.3 First CODESYS Project for the IOT2000

  1. In CODESYS, choose File > New Project > Standard project and pick CODESYS Control for IOT2000 SL as the device.
  2. Select the IEC 61131-3 language for the first POU, typically Structured Text (ST) or Ladder Diagram (LD).
  3. In Device > Communication Settings, set the gateway IP (default 192.168.200.1) and the port (11740).
  4. Click Online > Login. The IDE downloads the running program, displays the actual values, and supports online change without stopping the PLC.
  5. Click Online > Start to put the runtime in RUN mode.

5.4 A Minimal ST Program for the IOT2000

PROGRAM PLC_PRG
VAR
    iCounter : INT := 0;
    xToggle  : BOOL;
END_VAR

IF iCounter < 1000 THEN
    iCounter := iCounter + 1;
ELSE
    iCounter := 0;
    xToggle := NOT xToggle;
END_IF;

Compile, download, and start. The cyclic task default is 10 ms, configurable under Task Configuration > PlcTask. For motion or high-speed acquisition, set the task interval to 1 ms; for slow process I/O, 50-100 ms is sufficient and reduces CPU load on the Quark core.

5.5 Fieldbus Configuration

Right-click Device > Add Device and select the desired fieldbus. The CODESYS configurator generates the cyclic I/O image automatically. For Modbus TCP, for example, add a Modbus TCP Master device, assign a slave IP and unit ID, and the configurator exposes the holding registers as MB_Holding_Registers arrays in the program.

6. Node-RED and Python Scripting Options

For teams that do not need compiled binaries, two additional toolchains are available on the standard Yocto image.

6.1 Node-RED

Node-RED is a flow-based development tool that runs as a Linux service. Install it via the Yocto package manager: opkg install nodejs node-red. Once running, Node-RED listens on port 1880 by default. The CODESYS OPC UA server and the S7-1500 / S7-1200 OPC UA servers can be reached with the built-in opcua node. S7 communication is possible through the node-red-contrib-s7 contribution package.

6.2 Python 3

Python 3.5 is preinstalled on the standard IOT2000 Yocto image. Common libraries - paho-mqtt, requests, opcua, pyModbusTCP, snap7 - can be added with the pip3 installer if the gateway has Internet access. Python is best for glue code, data analysis, and ML inference at the edge, not for hard-real-time control.

7. Programming Toolchain Comparison

Criterion Eclipse + CDT Arduino IDE CODESYS Control for IOT2000 SL Node-RED Python 3
Language C / C++ C / C++ (Arduino dialect) IEC 61131-3 (ST, LD, FBD, SFC, CFC) JavaScript flows Python
Skill Required Linux / C / C++ Embedded C / Arduino PLC / IEC 61131-3 Web / IT Scripting / data
Determinism Soft real-time Soft real-time Hard real-time (cyclic task) Non-deterministic Non-deterministic
Supported Models IOT2020, IOT2040 IOT2020 only IOT2020, IOT2040 IOT2020, IOT2040 IOT2020, IOT2040
Debugging gdbserver / RSE Serial.print + IDE monitor Online mode, watch tables, breakpoints Debug sidebar pdb, logging
Fieldbus Stacks 3rd-party libs Limited Modbus, EtherNet/IP, CANopen, OPC UA built in Node packages pip packages
License Cost Free Free Single-seat site license (paid) Free Free

8. Project Structure, Build, and Deployment Workflow

Regardless of toolchain, the gateway expects a small set of standard locations. Familiarize yourself with them before the first build.

Path on the IOT2000 Owner Purpose
/home/iot/ root:iot User programs and shared scripts
/etc/codesyscontrol/ root:root CODESYS runtime configuration and license
/opt/codesys/ root:root CODESYS runtime binaries
/usr/bin/ root:root Cross-built user binaries installed by Yocto packages
/media/sd/ root:root Auto-mounted SD card; recommended for swap and large data logs
/var/log/ root:root System and application logs

8.1 Recommended Build and Deploy Sequence

  1. Compile the application on the workstation using the matching SDK.
  2. Run file iot2000_hello and confirm the output is ELF 32-bit LSB executable, Intel 80386. The Quark core is i586-compatible, so i686 binaries also execute but waste a few hundred bytes of memory on alignment traps.
  3. SCP the binary into /home/iot/ and chmod +x the file.
  4. Run the binary under nohup ./iot2000_hello > /var/log/iot2000_hello.log 2>&1 & for a quick smoke test.
  5. Once the behavior is stable, register the binary as a systemd service in /etc/systemd/system/iot2000_hello.service so the program auto-starts on boot.

8.2 Sample systemd Unit File

[Unit]
Description=SIMATIC IOT2000 Hello Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/iot
ExecStart=/home/iot/iot2000_hello --production
Restart=on-failure
RestartSec=5
StandardOutput=append:/var/log/iot2000_hello.log
StandardError=append:/var/log/iot2000_hello.err

[Install]
WantedBy=multi-user.target

Enable and start: systemctl daemon-reload && systemctl enable iot2000_hello.service && systemctl start iot2000_hello.service.

9. Debugging, Logging, and Field Verification

Once the application is deployed, follow this verification sequence to confirm the build is healthy before commissioning.

  1. Confirm the process is running: ps -ef | grep iot2000_hello. If the process is missing, inspect the journal with journalctl -u iot2000_hello.service -n 50.
  2. Verify the system log: tail -f /var/log/iot2000_hello.log and tail -f /var/log/messages for kernel-side events.
  3. Check resource headroom: free -m and df -h /home/iot. The IOT2020 has 512 MB RAM, leaving very little headroom for memory-hungry daemons; the IOT2040 has 1 GB and is the preferred model for larger builds.
  4. Network sanity: ip addr show and ip route show. The default IP is 192.168.200.1/24; if you change it, record the new IP on the cabinet label.
  5. Fieldbus liveness: for CODESYS, open the I/O Mapping view and confirm the cyclic task is reporting current values within the configured task interval. For native C, drive a Modbus loopback and verify round-trip latency stays below 50 ms.

9.1 Capturing a Field Trace

For intermittent issues, capture a network trace with tcpdump -i eth0 -w /media/sd/trace.pcap port 502 (Modbus) or port 4840 (OPC UA). Copy the .pcap to the workstation and inspect it with Wireshark. The opcua and modbus dissectors in Wireshark decode the payloads automatically.

10. Common Errors and Troubleshooting Matrix

Symptom Likely Cause Toolchain Affected Remediation
Arduino IDE shows Board not found at 192.168.200.1 SSH service on gateway is down or firewall blocks port 22 Arduino IDE SSH into the gateway with PuTTY, verify systemctl status sshd; if down, systemctl start sshd
Eclipse Cannot run program /lib/ld-linux.so.2: No such file SDK sysroot mismatch with runtime Eclipse + CDT Reinstall the SDK that matches the Yocto image version listed under System > About
CODESYS Device is not responding on login Runtime not running, port 11740 blocked, or wrong IP CODESYS Control for IOT2000 SL Check systemctl status codesyscontrol; on workstation, telnet 192.168.200.1 11740; confirm gateway IP in the device
Sketch runs once then disappears after reboot Sketch not registered as a systemd service Arduino IDE Create a systemd unit pointing at /home/iot/sketch/sketch.elf and enable it
Cyclic task overruns (CODESYS warning Task time exceeded) Task interval too short for program complexity CODESYS Increase task interval from 1 ms to 5 ms; profile with the built-in task monitor; move heavy work to a slower background task
Out-of-memory (OOM) killer terminates the binary Memory leak or IOT2020 limit (512 MB) Eclipse, Python, Node-RED Profile with valgrind; cap heap size; upgrade to IOT2040 if sustained headroom is required
SD card not auto-mounted Filesystem type not supported or partition not labeled All Use ext4 and label the partition sd; add to /etc/fstab with noatime
OPC UA server certificate rejected by S7-1500 Self-signed certificate not trusted in TIA Portal CODESYS, Python Export the CODESYS OPC UA certificate and import it into the TIA Portal trust list

10.1 Safety and Operational Notes

  • The IOT2000 has no SIL rating. Do not implement safety functions in any of the three toolchains. Use a certified SIMATIC F-CPU or a Sirius safety relay for emergency-stop and protective-door logic.
  • Always back up the SD card image before deploying a new application. Use dd if=/dev/mmcblk0 of=/media/sd/backup-$(date +%F).img on the gateway, or remove the SD card and image it on a workstation.
  • Disable the development SSH keys before shipping to a production environment. Siemens ships the image with a default key embedded in the documentation; rotate it.

11. Commissioning Checklist

  1. Verify the gateway image and SDK version are aligned (use System > About on the gateway and the SDK release notes).
  2. Confirm ping from workstation to 192.168.200.1 succeeds; otherwise re-check the Ethernet cable and the host IP.
  3. For CODESYS, install the runtime, start the service, log in from the IDE, and run a minimal blink-equivalent program to confirm online change works.
  4. For Eclipse, deploy the hello program, start the systemd service, and confirm active (running) status with systemctl status.
  5. For Arduino on the IOT2020, upload the blink sketch, confirm the on-board LED toggles, and verify the sketch survives a reboot.
  6. Capture the final image, label the gateway with its IP and the installed runtime versions, and file the project archive in the project documentation.

Which programming tool is easiest for a PLC engineer on the SIMATIC IOT2000?

CODESYS Control for IOT2000 SL is the most natural fit because it uses the IEC 61131-3 languages (ST, LD, FBD, SFC, CFC) that PLC engineers already know. Eclipse CDT requires C/C++ skills, and the Arduino IDE requires embedded-programming experience, so the learning curve is steeper from a PLC background.

Can the SIMATIC IOT2040 run Arduino sketches?

No. The Arduino shield header is present only on the IOT2020. The IOT2040 has no Arduino-compatible I/O pinout, and the Arduino board package does not list the IOT2040 as a target. Use Eclipse or CODESYS on the IOT2040.

How do I match the SDK version on the workstation to the gateway image?

Open System > About on the gateway's web configuration page and note the Yocto image version. Download the SDK archive with the same version from the Siemens Industry Online Support entry ID 109741656 (IOT2020) or 109741657 (IOT2040). Mismatched SDK and image versions cause GLIBC symbol errors at deploy time.

Is the SIMATIC IOT2000 suitable for safety functions up to SIL 3?

No. The IOT2000 is a non-safety gateway and has no SIL rating. Implement safety functions on a SIMATIC F-CPU (such as the S7-1500F or ET 200SP F-CPU) or a certified safety relay. The IOT2000 can read non-safety process data and forward it to a higher-level system.

How do I deploy a new CODESYS program without stopping production?

Use the CODESYS Online Change feature. With the project open, click Online > Login, then Online > Download > Online Change. The runtime updates the running program in place; the cyclic task continues without a full restart, preserving state variables and I/O image.

Back to blog