Overview
Industrial IoT (IIoT) Gateway is a critical component in modern automation and telemetry systems. This article demonstrates how to build a Field-to-Cloud Gateway using the dual-Ethernet SP2302, with:
- eth0 for cloud connectivity (Internet-facing)
- eth1 for Modbus TCP data collection (W5500 via SPI)
This physical and logical separation enhances security, performance, and fault isolation — making it ideal for manufacturing, energy, and infrastructure applications.
Why Use Dual-Port SP2302?
In many industrial environments, Modbus controllers, PLCs, and legacy field devices are built for local, deterministic communication and have no native support for IoT protocols, cloud APIs, or secure Internet access. These devices are often critical to operations but lack the capability to communicate beyond their local network.
This is where the dual-port SP2302 becomes invaluable.
By integrating a W5500-based Ethernet port (eth1) via SPI alongside the SP2302’s native Ethernet (eth0), you can safely isolate and connect local-only machines to the cloud — without compromising network security or device integrity.
This architecture allowseth1
to interface with local Modbus TCP devices, PLCs, or proprietary machine controllers, while eth0
manages communication with cloud services like Adafruit IO, AWS IoT, or private MQTT brokers.
Here’s how the dual-port configuration supports this secure and efficient data bridge:
Feature | eth0 (Main Ethernet) | eth1 (W5500 via SPI) |
---|---|---|
Primary Role | Connect to IoT/cloud platforms | Interface with local Modbus/PLC devices |
Designed for | Internet, MQTT, REST, dashboards | Field protocols like Modbus TCP, SCADA, custom |
Network Isolation | Public or enterprise network | Local, air-gapped OT/machine network |
Security Advantage | Protects field devices from external access | Prevents reverse traffic from Internet to machine |
Use Case Example | Publish to Adafruit IO | Read from industrial PLC at 192.168.2.x |
Data Flow Direction | Outbound to the cloud | Inbound from sensors/machines |
Why It Matters | Enables cloud integration | Connects legacy systems with modern workflows |
With this setup, devices that were never designed for the Internet — like PLCs and Modbus sensors — can now participate in modern IoT platforms. The SP2302 ensures that all communication is stable, secure, and structured, acting as a translation and transport layer between industrial equipment and scalable cloud infrastructure.
The field-to-cloud gateway architecture is not only practical but also essential for evolving legacy operations into connected, intelligent systems without requiring expensive retrofitting or risking security exposure.
System Architecture
Roles for Each Ethernet Port
Interface | Device | Role |
---|---|---|
eth0 | SP2302 native | Cloud uplink (Internet) |
eth1 | WIZ850io (W5500 via SPI) | Field bus (Modbus TCP or SCADA) |
System Diagram
Setup Instructions
1. Prepare the Hardware
- Connect WIZ850io to SP2302 via SPI
- Assign IPs:
eth0
: via DHCP or static (e.g.,192.168.1.50
)eth1
: static (e.g.,192.168.2.50
) for talking to local Modbus devices
2. Configure Netplan
yaml network: version: 2 ethernets: eth0: dhcp4: true eth1: dhcp4: false addresses: [192.168.2.50/24] bash 複製編輯 sudo netplan apply
Demo: Modbus TCP to MQTT Gateway (Field-to-Cloud)
This example reads a simulated Modbus register from a device on `eth1`, and sends it to **Adafruit IO** using MQTT over `eth0`.
Install Required Packages
bash pip3 install pymodbus paho-mqtt
Python Demo Code
python # iot_gateway_demo.py import time import paho.mqtt.client as mqtt from pymodbus.client.sync import ModbusTcpClient # --- Modbus TCP Config (eth1 interface) --- MODBUS_IP = '192.168.2.100' MODBUS_PORT = 502 UNIT_ID = 1 # --- Adafruit IO MQTT Config (eth0 interface) --- AIO_USER = 'your_adafruit_username' AIO_KEY = 'your_aio_key' AIO_FEED = 'sensor1' BROKER = 'io.adafruit.com' TOPIC = f"{AIO_USER}/feeds/{AIO_FEED}" ETH0_IP = '192.168.1.50' # Bind MQTT to this IP # Setup MQTT mqtt_client = mqtt.Client() mqtt_client.username_pw_set(AIO_USER, AIO_KEY) mqtt_client.bind_address = ETH0_IP mqtt_client.connect(BROKER, 1883, 60) mqtt_client.loop_start() def read_modbus(): client = ModbusTcpClient(MODBUS_IP, port=MODBUS_PORT) if not client.connect(): print("[X] Modbus connect failed") return None result = client.read_holding_registers(0, 1, unit=UNIT_ID) client.close() if not result.isError(): return result.registers[0] return None def main(): print("[✓] Gateway running (Modbus ➜ MQTT)") while True: val = read_modbus() if val is not None: mqtt_client.publish(TOPIC, val) print(f"[>] Published to cloud: {val}") time.sleep(5) if __name__ == "__main__": main()
Test Scenario
- SP2302 talks to a Modbus TCP device at
192.168.2.100
viaeth1
- Data is read every 5 seconds
- Value is sent to Adafruit IO over
eth0
via MQTT
Result

Bonus: Secure Routing
Use firewall rules to isolate eth0
and eth1
traffic:
bashsudo ufw allow out on eth0 sudo ufw allow in on eth1 from 192.168.2.0/24
Summary
Layer | Role |
---|---|
Hardware | SP2302 + WIZ850io (W5500) |
Interface | eth0 = Internet / MQTT, eth1 = Modbus TCP |
Software | pymodbus , paho-mqtt |
Cloud | Adafruit IO |
Field | Modbus TCP |
This setup enables reliable and secure field-to-cloud communication
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.