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.
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
- Windows 10/11, Linux, or macOS workstation with at least 8 GB RAM (Eclipse Photon or later).
- Oracle Java JRE 8 or 11 - Eclipse Oxygen and newer require a 64-bit JRE.
- Eclipse IDE for C/C++ Developers (Photon 2018-09 or 2019-06).
- 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.
- 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
- 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-cppor/opt/eclipse-cpp. - 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&. - Confirm the GNU toolchain from the SDK is on the
PATHby opening Window > Preferences > C/C++ > Build > Environment and verifying${IOT2000_SDK}/sysroots/x86_64-pokysdk-linux/usr/binis included. - 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:
-
SCP / SFTP - copy the binary to
/home/iot/iot2000_helloon the gateway using WinSCP, FileZilla, orscp iot2000_hello [email protected]:/home/iot/. Mark it executable withchmod +x /home/iot/iot2000_helloand run with./iot2000_hello test. -
RSync over SSH - more efficient for repeated builds:
rsync -avz -e ssh ./Debug/iot2000_hello [email protected]:/home/iot/. -
Remote System Explorer (RSE) - the Eclipse RSE plugin lets you drag the binary into the gateway's
/home/iotfolder directly from the Project Explorer.
3.5 Remote Debugging with gdbserver
- On the gateway, start gdbserver on the binary:
gdbserver :2345 /home/iot/iot2000_hello. - 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 to2345. - Set breakpoints in
main(), click Debug, and Eclipse will push the binary, attach gdbserver, and stop atmain.
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
- Install Arduino IDE 1.8.x on the workstation.
- Open File > Preferences and add the IOT2000 board manager URL:
https://raw.githubusercontent.com/siemens/iot2000-arduino/main/package_arduino_iot2000_index.json. - Open Tools > Board > Boards Manager, search for SIMATIC IOT2000, and click Install.
- Select SIMATIC IOT2020 in the Tools > Board menu, set the programmer to iot2000ip (for Ethernet deploy) or iot2000usb (for the Siemens USB cable).
- Configure the IP address under Tools > Port:
192.168.200.1for 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
- Download CODESYS V3.5 SP19 or later from the CODESYS online installer.
- 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.
- 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
- Copy the runtime package
codesys-control-for-iot2000-sl_*.debto the gateway with SCP. - SSH into the gateway and install:
dpkg -i codesys-control-for-iot2000-sl_*.deb. - Enable the systemd service:
systemctl enable codesyscontrol.service && systemctl start codesyscontrol.service. - Verify the runtime is listening:
ss -tlnp | grep 11740. Port 11740 is the CODESYS communication port.
5.3 First CODESYS Project for the IOT2000
- In CODESYS, choose File > New Project > Standard project and pick CODESYS Control for IOT2000 SL as the device.
- Select the IEC 61131-3 language for the first POU, typically Structured Text (ST) or Ladder Diagram (LD).
- In Device > Communication Settings, set the gateway IP (default
192.168.200.1) and the port (11740). - Click Online > Login. The IDE downloads the running program, displays the actual values, and supports online change without stopping the PLC.
- 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
- Compile the application on the workstation using the matching SDK.
- Run
file iot2000_helloand confirm the output isELF 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. - SCP the binary into
/home/iot/andchmod +xthe file. - Run the binary under
nohup ./iot2000_hello > /var/log/iot2000_hello.log 2>&1 &for a quick smoke test. - Once the behavior is stable, register the binary as a systemd service in
/etc/systemd/system/iot2000_hello.serviceso 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.
-
Confirm the process is running:
ps -ef | grep iot2000_hello. If the process is missing, inspect the journal withjournalctl -u iot2000_hello.service -n 50. -
Verify the system log:
tail -f /var/log/iot2000_hello.logandtail -f /var/log/messagesfor kernel-side events. -
Check resource headroom:
free -manddf -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. -
Network sanity:
ip addr showandip route show. The default IP is192.168.200.1/24; if you change it, record the new IP on the cabinet label. - 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).imgon 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
- Verify the gateway image and SDK version are aligned (use System > About on the gateway and the SDK release notes).
- Confirm
pingfrom workstation to192.168.200.1succeeds; otherwise re-check the Ethernet cable and the host IP. - 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.
- For Eclipse, deploy the hello program, start the systemd service, and confirm active (running) status with
systemctl status. - For Arduino on the IOT2020, upload the blink sketch, confirm the on-board LED toggles, and verify the sketch survives a reboot.
- 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.