Problem: WiFi Dongle Connects but IOT2020 Disappears from Network
After installing a USB WiFi dongle (typically a Raspberry Pi compatible adapter based on Realtek or Ralink silicon) on a Siemens SIMATIC IOT2020 and applying the standard WiFi configuration procedure, the wlan0 interface acquires an IP address and the ifconfig output appears normal. The interface is UP, BROADCAST is set, and an inet address is shown. As soon as the Ethernet cable is disconnected from eth0, however, the device becomes unreachable on the network. The IOT2020 no longer responds to ping, does not appear in the router's DHCP lease table, and is invisible to network discovery tools such as nmap or the router's connected-clients page.
This is the single most common WiFi deployment failure on the SIMATIC IOT2000 series and is almost always caused by an interface routing conflict, not by a dongle defect, a driver issue, or a signal-strength problem. The dongle is functioning correctly; it is the IP layer that is broken. The same failure mode applies to the SIMATIC IOT2040 (dual-Ethernet variant) and to the newer IOT2050 when both wired and wireless interfaces are left in the same subnet.
Root Cause: eth0 and wlan0 Configured in the Same Subnet
The Linux kernel maintains a single routing table by default. When two interfaces are configured with IP addresses in the same subnet — for example, eth0 = 192.168.1.3/24 and wlan0 = 192.168.1.4/24 — the kernel installs two equal-cost directly-connected routes pointing at different interfaces for the same destination prefix. This creates a deterministic failure cascade:
- Outbound packets destined for the gateway (typically
192.168.1.1) may be transmitted out of eth0 even when the LAN cable is unplugged, because route lookup for a same-subnet destination is interface-agnostic at L3. - The kernel performs ARP resolution through both interfaces, producing duplicate ARP replies on the wired segment and CAM-table instability on managed switches.
- When the eth0 link state drops (cable removed), the kernel deletes the route associated with eth0. If wlan0 was never the primary egress for that subnet, the host's TCP/IP stack loses its route to the gateway and stops responding to inbound traffic.
- DHCP renewals sent over WiFi may be dropped by the router because the router already holds a stale lease for the same MAC or detects a duplicate IP address on the LAN segment.
The fundamental requirement for any Linux host with two L3 interfaces is that each interface belongs to a distinct IP network. There is no kernel version, iptables rule, ip rule configuration, or sysctl parameter that allows two interfaces to share a subnet and route correctly. Attempting to do so produces undefined behavior that varies by kernel release and wireless driver.
Diagnostic Verification Before Making Changes
Before editing any configuration file, confirm four facts in sequence: the dongle is enumerated by USB, the driver loaded successfully, the wireless interface exists, and the two interfaces are on distinct subnets.
Step 1 — Confirm USB enumeration with lsusb
Run lsusb on the IOT2020 shell. A healthy WiFi dongle appears as a new line with its USB vendor and product ID:
Bus 001 Device 004: ID 0bda:8179 Realtek Semiconductor Corp. RTL8188EUS 802.11n Wireless Network Adapter
If no wireless device appears, the dongle is not receiving enough power (the IOT2020 USB-A port supplies 500 mA), is not supported by the IOT2000 image, or has a hardware fault. Move the dongle to a powered USB hub, try a different dongle, or verify the firmware image version.
Step 2 — Confirm the kernel driver bound
Run dmesg | grep -i usb and dmesg | grep -i wlan immediately after inserting the dongle. Expected output includes a line such as usb 1-1: new high-speed USB device number 4 using ehci-pci followed by r8188eu 1-1:1.0 wlan0: renamed from wlan1. If the kernel prints device descriptor read/all, error -71, the dongle is being reset — power-budget issue. If it prints module verification failed: signature and/or required key missing, Secure Boot is rejecting the out-of-tree driver.
Step 3 — Confirm the interface exists
Run ifconfig -a or ip link show. Look for wlan0 in addition to eth0 and lo. If only eth0 and lo are present, the driver did not bind to the dongle.
Step 4 — Confirm the subnet conflict
Run ifconfig and compare the inet addresses of eth0 and wlan0:
eth0 Link encap:Ethernet HWaddr B8:27:EB:11:22:33
inet addr:192.168.1.3 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500
wlan0 Link encap:Ethernet HWaddr 7c:dd:90:aa:bb:cc
inet addr:192.168.1.4 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500
If both interfaces carry a 192.168.1.x address with a /24 (255.255.255.0) mask, the configuration is broken. This is the root cause of the unreachable-when-LAN-unplugged symptom.
Solution: Place wlan0 in a Distinct Subnet
Reconfigure the WiFi interface to a different network than the LAN interface. Three deployment patterns cover the vast majority of industrial use cases:
| Scenario | eth0 address | wlan0 address | Gateway | Notes |
|---|---|---|---|---|
| Home/office single router | 192.168.1.3/24 | 192.168.2.4/24 | 192.168.2.1 | Requires a router with a second SSID on a separate VLAN, or a second physical access point |
| Dual-NIC isolation | 192.168.1.3/24 (LAN to plant) | 10.0.0.4/24 (WiFi to maintenance laptop) | None on wlan0 | wlan0 used only for direct peer-to-peer access; remove the gateway directive to prevent default-route conflicts |
| WiFi as primary uplink | 192.168.1.3/24 (diagnostic only) | 192.168.10.4/24 | 192.168.10.1 | Default route moved to wlan0 in /etc/network/interfaces |
| Field service tablet pairing | 192.168.1.3/24 | 192.168.50.4/24 (ad-hoc or AP mode) | None | wlan0 runs in AP mode for a single service tablet; static address only |
Configuration: /etc/network/interfaces
Edit /etc/network/interfaces on the IOT2020. The SIMATIC IOT2000 image ships with a minimal interfaces file that brings up eth0 via DHCP. Add a wlan0 stanza that uses a distinct subnet, and remove any duplicate gateway directive from the interface that should NOT be the default route.
Example 1 — eth0 stays on the plant LAN (DHCP), wlan0 is a static WiFi link to a maintenance network:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
auto wlan0
iface wlan0 inet static
address 192.168.2.4
netmask 255.255.255.0
gateway 192.168.2.1
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
wireless-power off
Example 2 — wlan0 DHCP, eth0 static on the plant network:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.3
netmask 255.255.255.0
# No gateway here — wlan0 owns the default route
auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
wireless-power off
After saving the file, bring the interfaces up in order:
sudo ifdown eth0
sudo ifdown wlan0
sudo ifup eth0
sudo ifup wlan0
Or reboot the IOT2020 with sudo reboot for a clean state.
Configuration: wpa_supplicant.conf for WPA2-PSK
The wpa_supplicant.conf file must contain the SSID and pre-shared key for the WiFi network. For WPA2-PSK (the most common case in plant deployments):
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=DE
network={
ssid="PlantWiFi"
psk="correct-horse-battery-staple"
key_mgmt=WPA-PSK
proto=RSN
pairwise=CCMP
group=CCMP
scan_ssid=1
}
For enterprise WPA2-EAP (PEAP/MSCHAPv2 against a RADIUS server common in OT environments):
network={
ssid="PlantWiFi"
key_mgmt=WPA-EAP
eap=PEAP
identity="iot2020"
password="radius-password"
phase2="auth=MSCHAPV2"
ca_cert="/etc/ssl/certs/ca-certificates.crt"
}
Lock the file permissions so wpa_supplicant does not refuse to read it (wpa_supplicant refuses world-readable or group-writable config files):
sudo chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
sudo chown root:root /etc/wpa_supplicant/wpa_supplicant.conf
wpa_passphrase "PlantWiFi" "cleartext-password" to generate a pre-hashed 256-bit PSK and paste the resulting hex string into the file instead of the cleartext password.Verification
After reconfiguration, verify five conditions in sequence before declaring the fix complete.
-
Interface state:
ifconfig wlan0shows an inet address in the new subnet and theUP BROADCAST RUNNING MULTICASTflags are set. -
Association:
iwconfig wlan0reports the SSID under "ESSID" and a non-zero link quality. The modern equivalent isiw dev wlan0 link, which printsSSID,freq, andtx bitrate. -
Default route:
ip route showshows exactly one default route, and it points through the correct interface. The presence of two default routes is itself a configuration error. -
DHCP lease:
cat /var/lib/dhcp/dhclient.wlan0.leasesshows a valid lease from the WiFi subnet, withrenewandrebindtimestamps in the future. -
L3 reachability: With the LAN cable unplugged,
ping -c 4 8.8.8.8from the IOT2020 succeeds, and from a workstation on the WiFi network,ping 192.168.2.4succeeds with latency under 10 ms on a local segment.
If the workstation can ping the IOT2020 but cannot open a web service on port 80, 443, or 22, the issue is no longer networking — inspect iptables -L -n on the IOT2020 and the Windows Firewall or iptables on the workstation.
Supported USB WiFi Dongles for SIMATIC IOT2020
The IOT2020 ships with the Intel Quark SoC x1000 and runs the Siemens-supplied Yocto-based SIMATIC Industrial OS. Not every RTL- or Atheros-based dongle ships with an in-tree driver on that image. The following adapters are field-validated against the iot2000-image-v2.4.0 and later releases:
| Chipset | Vendor:Product ID | Driver (kernel module) | Band | Notes |
|---|---|---|---|---|
| Realtek RTL8188EUS | 0bda:8179 | r8188eu | 2.4 GHz | Low power, common in Raspberry Pi kits, in-tree on v2.6.3+ |
| Realtek RTL8188CUS | 0bda:8176 | r8712u / 8192cu | 2.4 GHz | May require blacklist rtl8192cu on newer kernels |
| Realtek RTL8812AU | 0bda:8812 | 8812au (out-of-tree) | 2.4 / 5 GHz | Required for 5 GHz WiFi; compile against the Yocto SDK |
| Realtek RTL8811AU | 0bda:0811 | 8812au (out-of-tree) | 2.4 / 5 GHz | Smaller form factor than 8812AU dongles |
| Ralink RT5370 | 148f:5370 | rt2800usb | 2.4 GHz | In-tree driver, supports AP mode for service-tablet pairing |
| MediaTek MT7610U | 148f:761a | mt76x0u | 2.4 / 5 GHz | In-tree on kernel 4.9+, dual-band support |
| Atheros AR9271 | 0cf3:9271 | ath9k_htc | 2.4 GHz | Best Linux compatibility, supports monitor mode for diagnostics |
| Broadcom BCM4323 | 0a5c:bd1e | wl (proprietary) | 2.4 GHz | Avoid for industrial use — proprietary blob, no in-tree support |
dmesg shows over-current events.Firmware Image and Driver Notes
The SIMATIC IOT2000 uses the Siemens-supplied Yocto image. Reference releases include iot2000-image-v2.4.0, iot2000-image-v2.6.3, and the Example Image V2.6.3 published on the Siemens support portal. The kernel is built with a slim wireless stack — only the modules listed above are guaranteed present. If the dongle does not enumerate after lsusb shows the device:
- Confirm the image is at least v2.4.0. Earlier images lack
cfg80211userspace tools (iw,iwconfigmay be missing). - Run
sudo depmod -aandsudo modprobe <driver-name>to force-load the expected module from/lib/modules/$(uname -r)/. - For RTL8812AU and similar out-of-tree chipsets, compile the driver against the Yocto SDK using the Siemens-provided toolchain; do not assume the kernel headers from a Raspberry Pi image are compatible.
- Verify the firmware blob is present in
/lib/firmware/rtlwifi/for Realtek adapters and/lib/firmware/for the specific chipset directory.
Refer to the SIMATIC IOT2020 / IOT2040 operating instructions on the Siemens support portal for the exact image checksum, signed-driver policy, and known-good dongle list for the installed firmware version.
Why the Same-Subnet Failure Is Not Fixable With iptables or Policy Routing
Engineers familiar with Linux policy routing sometimes attempt to resolve the conflict with ip rule and a per-interface routing table. While policy routing is a legitimate technique for advanced setups (VRF, MPLS, multi-homing), it does not help in this scenario because the problem is not route selection — it is route installation. The kernel refuses to install two equal-cost directly-connected routes for the same prefix through different interfaces, and even when forced with ip route replace, ARP resolution for the gateway address becomes interface-ambiguous, producing the duplicate-ARP symptom described above.
The clean, supported, documented fix is to use different subnets. If the requirement is truly to keep both interfaces on 192.168.1.0/24 (for example, to satisfy a fixed router configuration in an existing plant where the WiFi SSID is bridged onto the same VLAN as the wired LAN), the only Linux-supported path is to bridge the interfaces with brctl or ip link add and assign the bridge a single IP. This trades the routing problem for a bridging problem and is not recommended on the IOT2020 without explicit Siemens guidance and without disabling the wireless driver's station-mode logic.
Power Management and Roaming Pitfalls
A second common cause of intermittent drops on a working WiFi link is the wireless driver's power-saving feature. The IOT2020 USB power budget is tight, and the default Linux power-save behavior (especially for Realtek out-of-tree drivers) aggressively parks the radio after 200 ms of idle. Disable power management in two places:
# Disable iwlevel power save
sudo iw dev wlan0 set power_save off
# Disable interface-level power management (in /etc/network/interfaces)
iface wlan0 inet static
wireless-power off
iwconfig wlan0 power off
Roaming between access points with the same SSID is also aggressive on some drivers. If the IOT2020 walks between two APs and drops association, set ap_scan=1 in wpa_supplicant.conf and lock the BSSID explicitly:
network={
ssid="PlantWiFi"
bssid=00:11:22:33:44:55
psk="correct-horse-battery-staple"
key_mgmt=WPA-PSK
}
Troubleshooting Matrix
| Symptom | Likely Cause | Fix |
|---|---|---|
| wlan0 does not appear in ifconfig -a | Dongle not enumerated or driver missing |
lsusb; dmesg | grep -i usb; check powered hub |
| wlan0 appears but stays DOWN | rfkill blocked or interface not configured |
rfkill list; sudo rfkill unblock wifi; ifup wlan0
|
| wlan0 UP but no association | wpa_supplicant.conf has wrong SSID, PSK, or country code |
wpa_cli status; check /var/log/wpa_supplicant.log
|
| Associated but no IP | DHCP server unreachable on WiFi subnet | Verify router serves 192.168.2.x; set static address as fallback |
| IP acquired but device unreachable when eth0 unplugged | Same-subnet conflict (this article) | Move wlan0 to a different subnet than eth0; reboot |
| Reachable on WiFi but cannot reach Internet | Default route still points to eth0 gateway | Edit /etc/network/interfaces so only one interface has a gateway directive, or use metric 100 on the preferred uplink |
| Works for 5 minutes then drops | Power management or roaming | Add wireless-power off and iw dev wlan0 set power_save off; lock BSSID |
| SSH works but HTTP/HTTPS blocked | Host firewall on IOT2020 or workstation |
iptables -L -n; check workstation firewall rules |
| Slow throughput (< 5 Mbps on 802.11n) | USB 1.1 hub in path or driver rate-limit | Move to a USB 2.0 port; check lsusb -t for 480 Mbps link |
| wpa_supplicant fails with "failed to read config" | File permissions too open | chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf |
Field-Commissioning Checklist
- Document the planned subnet for wlan0 before powering on the IOT2020. Confirm the WiFi router or access point serves DHCP on that subnet.
- Insert the USB WiFi dongle while the IOT2020 is powered off. Boot the device.
- Run
lsusband confirm enumeration. Record the vendor:product ID in the plant asset record. - Edit
/etc/network/interfacesand/etc/wpa_supplicant/wpa_supplicant.confwith a distinct subnet and the correct SSID/PSK. - Set file permissions (
chmod 600) on the wpa_supplicant file and verify ownership isroot:root. - Reboot, then run the five-step verification sequence (interface state, association, route, DHCP lease, ping).
- Disconnect the LAN cable and confirm the device is still reachable on the WiFi subnet for at least 30 minutes.
- Reconnect the LAN cable and confirm the device is reachable on the wired subnet without rebooting.
- Run a sustained ping test (
ping -i 1 192.168.2.4) for 10 minutes to validate stability. - Record the configuration (subnets, SSID, BSSID, dongle part number) in the plant network documentation.
Integration With TIA Portal and S7 Communication
When the IOT2020 is used as an edge gateway between plant equipment and a TIA Portal HMI or SCADA, the WiFi link typically carries the S7 communication or OPC UA traffic while the wired link carries PROFINET or plant-bus traffic. In this dual-role configuration, the subnet separation is even more critical because PROFINET discovery (DCP) and S7 routing use broadcast frames that flood both interfaces if they share a subnet, producing multicast storms on the WiFi segment.
Recommended pattern:
-
eth0: PROFINET / plant bus —
192.168.1.3/24, no default gateway, IGMP snooping enabled on the switch. -
wlan0: TIA Portal / SCADA traffic —
192.168.10.4/24, default gateway192.168.10.1, firewall rules innftablesrestricting inbound to TCP 102 (S7) and TCP 4840 (OPC UA) only.
wlan0 when not in active maintenance using a systemd timer or a physical switch wired to a GPIO. The IOT2020 should never sit on WiFi with an open S7 port in a production plant without an explicit allow-list on the access point.Switching to systemd-networkd (Alternative Network Manager)
Newer SIMATIC IOT2000 example images use systemd-networkd instead of the legacy /etc/network/interfaces script. If the IOT2020 image is based on Yocto Pyro or later, the configuration files are /etc/systemd/network/eth0.network and /etc/systemd/network/wlan0.network. The same distinct-subnet rule applies:
# /etc/systemd/network/eth0.network
[Match]
Name=eth0
[Network]
DHCP=yes
# /etc/systemd/network/wlan0.network
[Match]
Name=wlan0
[Network]
Address=192.168.2.4/24
Gateway=192.168.2.1
[DHCP]
UseDNS=yes
Then enable and start the service:
sudo systemctl enable systemd-networkd
sudo systemctl start systemd-networkd
sudo systemctl restart wpa_supplicant
Use networkctl status to verify the configuration and resolvectl status to confirm DNS is correctly assigned to the WiFi interface, not the wired one.
Why does my IOT2020 stop responding when I unplug the LAN cable even though WiFi is configured?
eth0 and wlan0 are on the same subnet (for example, both 192.168.1.x/24). The Linux kernel cannot route correctly when two interfaces share a network because both directly-connected routes are installed with equal cost and the kernel cannot determine which interface should carry traffic to the gateway. Move wlan0 to a distinct subnet such as 192.168.2.4/24 and reboot.
How do I confirm the USB WiFi dongle is detected by the IOT2020?
Run lsusb from the IOT2020 shell. A healthy dongle appears as a new line with its vendor:product ID, e.g. 0bda:8179 Realtek RTL8188EUS. If nothing appears, the dongle is unpowered, defective, or unsupported by the installed image — try a powered USB hub or a dongle from the field-validated list.
Can I use policy routing with ip rule to keep both interfaces on 192.168.1.0/24?
No. The kernel refuses to install two equal-cost directly-connected routes for the same prefix through different interfaces, and ARP resolution for the gateway becomes interface-ambiguous. The only Linux-supported configurations are distinct subnets or a bridge interface. Use distinct subnets for each interface.
Which WiFi dongles work reliably with the SIMATIC IOT2020?
Realtek RTL8188EUS (2.4 GHz), RTL8188CUS (2.4 GHz), RTL8812AU (dual-band), Ralink RT5370 (2.4 GHz with AP-mode support), MediaTek MT7610U (dual-band), and Atheros AR9271 adapters are field-validated with the SIMATIC Industrial OS Yocto image. Avoid Broadcom chipsets that require the proprietary wl driver.
Do I need to change /etc/network/interfaces if I only use WiFi and never connect an Ethernet cable?
Yes. Even with no cable attached, the kernel still installs a route for the configured eth0 subnet. Leave eth0 disabled by removing the auto eth0 stanza, or remove the iface eth0 inet block entirely, to prevent the routing conflict at boot.