Protocol Bridges (MQTT, Modbus, S7comm)

Last updated March 19, 2026


Overview

Protocol bridges let you connect hardware that speaks a different language than the Raspberry Pi's native sensors. Instead of wiring a sensor directly to the Pi, the Pi acts as a gateway — it speaks MQTT, Modbus, or S7comm to reach the remote device, then forwards the values to Firebase and your dashboard as if they were any other sensor.

LoopString supports four bridge protocols:

  • MQTT — wireless message-passing for microcontrollers like ESP32, D1 Mini, Arduino, and Tasmota devices
  • Modbus RTU — wired serial (RS-485) for industrial sensors, energy meters, and PLCs
  • Modbus TCP — Ethernet-based Modbus for networked PLCs and smart meters
  • S7comm — Siemens proprietary protocol for S7-1200 and S7-1500 PLCs

All required software (Mosquitto MQTT broker, Modbus libraries, python-snap7) is pre-installed by the Pi provisioning wizard during first-boot setup. You do not need to install anything manually.

Each bridge appears in the Configurator Parts Library under the Sensors or Actuators category and works exactly like a native sensor part — you drop it into a room, configure it, wire it to other parts, and deploy.


The Pi as Gateway

When you add a bridge part to your flow, Node-RED on the Pi handles the protocol translation:

  1. The bridge node connects to the external device (via MQTT, Modbus, or S7comm)
  2. It reads a value or receives a message from that device
  3. Node-RED forwards that value to Firebase RTDB on the standard sensor path
  4. Your dashboard reads from RTDB and displays the value in real time

For actuators, the direction reverses: a dashboard command writes to RTDB, Node-RED picks it up, and the bridge translates it into a Modbus write, MQTT publish, or S7 variable write sent to the external device.

The external device never talks to Firebase directly — the Pi manages that entire connection.


MQTT Bridges

MQTT is a lightweight publish-subscribe messaging protocol. Devices like ESP32, ESP8266, D1 Mini, Arduino (with an Ethernet or WiFi shield), and Tasmota firmware smart plugs all support MQTT natively. The Pi runs a local Mosquitto MQTT broker, so your microcontrollers publish messages directly to the Pi's IP address on port 1883 — no cloud MQTT service required.

MQTT Sensor Bridge

The MQTT Sensor Bridge subscribes to a topic on the local Mosquitto broker and forwards the received value to your dashboard.

How to add it:

  1. Open the Configurator and select or create a room
  2. Click Add Part and search for "MQTT Sensor"
  3. Give it a name and configure the settings below
  4. Wire it to a PID controller, alarm threshold, or leave it standalone
  5. Deploy to the Pi

Configuration settings:

MQTT Topic — the topic your device publishes to. Use a descriptive path such as greenhouse/bench1/temp. The default is loopstring/sensors/value. All devices on the same local network that know the Pi's IP address can publish to this broker.

Payload Format — choose Raw numeric value if your device publishes a plain number like 23.5. Choose JSON if your device publishes a JSON object like {"temperature": 23.5, "humidity": 60}.

JSON Key Path — only applies when Payload Format is JSON. Enter a dot-separated path to the value you want. For {"temperature": 23.5} use temperature. For {"readings": {"temp": 23.5}} use readings.temp.

QoS Level — Quality of Service controls message delivery guarantees. 0 (At most once) is fastest and suits most sensor readings. 1 (At least once) retries until acknowledged and is recommended for actuator commands. 2 (Exactly once) is slowest and rarely needed.

Publish Throttle — minimum time between RTDB writes. If your device publishes faster than this interval, extra messages are dropped. The default is 1000 ms (1 second). Set to 0 to forward every message.

No physical wiring is required on the Pi side. The external device must be on the same local network as the Pi and configured to publish MQTT messages to the Pi's IP address on port 1883.

MQTT Actuator Bridge

The MQTT Actuator Bridge listens for on/off commands from the dashboard and publishes them to an MQTT topic. Your external device subscribes to that topic and acts on the command.

Configuration settings:

MQTT Topic — the topic to publish commands to. Your device should subscribe to this topic. The default is loopstring/actuators/cmd.

Payload (ON) — the message to publish when the actuator is turned on. Default is 1. Common values: 1, ON, true, open.

Payload (OFF) — the message to publish when the actuator is turned off. Default is 0. Common values: 0, OFF, false, close.

QoS Level — use 1 (At least once) for actuator commands to ensure the message is delivered even if the device momentarily disconnects.

Retain Message — when enabled, the broker stores the last command and immediately delivers it to any device that subscribes. This ensures the device knows the correct state when it reconnects. Enabled by default.

Common MQTT Use Cases

ESP32 or D1 Mini temperature sensor — Program the microcontroller with the Arduino IDE or MicroPython to read a DHT22 and publish {"temperature": 24.1, "humidity": 58} to greenhouse/sensor1. Add an MQTT Sensor Bridge in the Configurator, set the topic to greenhouse/sensor1, payload format to JSON, and JSON Key Path to temperature.

iSpindel digital hydrometer — The iSpindel publishes fermentation data (gravity, temperature, tilt, battery) over MQTT. See the iSpindel sensor documentation for a dedicated part that handles the full payload automatically.

Tasmota smart plug (power monitoring) — Tasmota devices publish power readings to topics like tele/tasmota-plug/SENSOR. Use an MQTT Sensor Bridge pointed at that topic with the correct JSON key path for energy or watts.

ESP32 relay (remote switch) — Add an MQTT Actuator Bridge. Configure your ESP32 to subscribe to the command topic and toggle a relay when it receives 1 or 0.


Modbus RTU Bridges (RS-485 Serial)

Modbus RTU is the standard serial protocol for industrial equipment — energy meters, VFDs (variable-frequency drives), PLCs, flow meters, pressure transmitters, and countless other devices. Communication happens over a two-wire RS-485 bus, which you connect to the Pi via a USB-to-RS485 adapter (available for about $6).

Physical Wiring

Before adding a Modbus RTU part in the Configurator, wire the hardware:

  1. Plug a USB-to-RS485 adapter into any USB port on the Pi. It appears as /dev/ttyUSB0.
  2. Connect the A+ (also labeled D+) screw terminal on the adapter to the A+ terminal on your Modbus device.
  3. Connect B- (D-) on the adapter to B- on the device.
  4. For cable runs longer than 10 meters, add a common ground wire and 120-ohm termination resistors at each end of the bus.
  5. If you have multiple devices, daisy-chain them in a line — do not wire them in a star pattern.
  6. Set the slave address on each device using its DIP switches or configuration software. Each device on the same bus must have a unique address (1 to 247).

Modbus RTU Sensor

The Modbus RTU Sensor polls a register on a serial Modbus device and sends the value to your dashboard.

Configuration settings:

Serial Port — the device path for your USB-to-RS485 adapter. The first adapter is /dev/ttyUSB0. A second adapter is /dev/ttyUSB1. If you use the Pi's GPIO UART pins instead, select /dev/ttyAMA0.

Baud Rate — the serial communication speed. This must match the setting on your Modbus device exactly. The default is 9600. Check your device's manual or DIP switch labels. Common values: 9600, 19200, 38400, 115200.

Slave ID — the Modbus device address (1 to 247). Must match the address configured on the device.

Register Address — the zero-based address of the register to read. Device manuals often list register numbers starting from 1 (e.g., "Register 30001") — subtract 1 to get the zero-based address (30000).

Function Code — FC03 (Read Holding Registers) is the most common and reads writable registers. FC04 (Read Input Registers) reads read-only measurement registers. Check your device's documentation.

Data Type — the format of the value stored in the register. UINT16 is an unsigned 16-bit integer (most common). INT16 is signed. FLOAT32 reads two consecutive registers and decodes them as a 32-bit floating-point number (IEEE 754). BOOL reads a single coil or discrete input.

Poll Interval — how often to read the device. The default is 1000 ms (1 second). Set higher values (5000 ms or more) for slow-changing measurements like temperature to reduce bus traffic.

Scaling Factor — a multiplier applied to the raw register value before sending to the dashboard. Many industrial sensors store values multiplied by 10 or 100 to avoid decimals — use 0.1 or 0.01 to convert back. Example: a temperature sensor returning 245 with a scaling factor of 0.1 shows 24.5 on the dashboard.

Modbus RTU Actuator

The Modbus RTU Actuator receives on/off commands from the dashboard and writes them to a coil or register on a Modbus device.

Configuration settings:

Serial Port, Baud Rate, Slave ID — same as the sensor, must match the device.

Register Address — the address of the coil or register to write.

Function Code — FC05 (Write Single Coil) writes a boolean (on/off) to a coil output. FC06 (Write Single Register) writes a 16-bit value to a holding register.

Data Type — BOOL for coil writes (FC05). UINT16 or INT16 for register writes (FC06).

Common Modbus RTU Use Cases

Energy meter — Most DIN-rail energy meters (e.g., EASTRON SDM120, EASTRON SDM630) expose power, voltage, and current via Modbus RTU. Connect via USB-to-RS485. Check the device manual for register addresses and set the baud rate and slave ID to match.

VFD speed control — Variable-frequency drives often accept speed setpoints via Modbus register writes. Use the Modbus RTU Actuator with FC06 and wire it to a setpoint in your Configurator flow.

Industrial pressure transmitter — Many 4-20 mA pressure sensors with RS-485 output use Modbus RTU. Read the measurement register and apply a scaling factor to convert raw counts to pressure units.


Modbus TCP Bridges (Ethernet)

Modbus TCP carries the same Modbus register model over a standard Ethernet connection. Any device with a LAN port and Modbus TCP firmware can be reached by the Pi over your local network — no serial adapter needed.

Modbus TCP Sensor

The Modbus TCP Sensor connects to a Modbus TCP device by IP address and polls a register at a regular interval.

Before configuring, assign a static IP to the device. If the device's IP address changes (e.g., after a power cycle), Node-RED will lose the connection. Configure a static IP directly on the device, or create a DHCP reservation in your router.

Configuration settings:

IP Address — the IPv4 address of the Modbus TCP device (e.g., 192.168.1.100).

TCP Port — the Modbus TCP port. The standard is 502. Some devices use a different port — check the device documentation.

Unit ID — equivalent to Slave ID in RTU. Most standalone Modbus TCP devices use Unit ID 1. Gateways that bridge multiple RTU devices to TCP may use higher unit IDs to address each downstream device.

Register Address, Function Code, Data Type, Poll Interval, Scaling Factor — these work identically to the Modbus RTU Sensor settings described above.

Modbus TCP Actuator

The Modbus TCP Actuator sends write commands to a Modbus TCP device over Ethernet.

Configuration settings:

IP Address and TCP Port — same as the sensor, must match the device.

Unit ID, Register Address, Function Code, Data Type — same as the Modbus RTU Actuator.

Common Modbus TCP Use Cases

Networked smart meter — Electricity, gas, and water meters with Ethernet ports often expose readings via Modbus TCP on port 502. No serial adapter needed — just connect the meter to your LAN.

HVAC controller — Many rooftop unit controllers support Modbus TCP for setpoint adjustment and status monitoring. Use a Modbus TCP Sensor for temperature or pressure readings and an Actuator for setpoint writes.

Modbus RTU-to-TCP gateway — If you already have RS-485 Modbus devices but want Ethernet access, a gateway device (e.g., Waveshare RS485 to ETH converter) bridges them. Connect the Pi to the gateway's IP; each RTU device has its own Unit ID.


S7comm Bridges (Siemens PLCs)

The S7comm protocol is Siemens' proprietary communication protocol used by S7-1200 and S7-1500 series PLCs. It runs over ISO-on-TCP on port 102. LoopString integrates via the node-red-contrib-s7 package, which is pre-installed on provisioned Pis.

TIA Portal Prerequisites

Before adding an S7comm bridge in the Configurator, two settings must be enabled in TIA Portal:

Enable PUT/GET access — In TIA Portal, open the CPU Properties, go to Protection & Security, then Connection mechanisms, and check "Permit access with PUT/GET communication from remote partner". This is disabled by default on S7-1200/1500 CPUs and must be turned on for external tools to read from or write to the PLC.

Disable Optimized Block Access — Open the properties of the data block you want to read from or write to, and uncheck "Optimized block access". Optimized blocks use internal symbolic addresses that are incompatible with the absolute byte-offset format used here. After disabling, recompile the project and download it to the PLC. The "Offset" column will now appear in the data block editor, showing the byte address of each variable.

S7comm Sensor

The S7comm Sensor Bridge polls a variable in a Siemens PLC data block and forwards the value to your dashboard.

Configuration settings:

PLC IP Address — the local network IP address of the Siemens PLC. Assign a static IP in TIA Portal (under Device Properties, PROFINET interface) or via your router's DHCP reservation feature.

Rack — the rack number of the CPU module. For standalone S7-1200 and S7-1500 PLCs this is always 0.

Slot — the slot number of the CPU module. S7-1200 and S7-1500 CPUs typically use slot 1.

DB Number — the data block number containing the variable you want to read. Visible in TIA Portal's project tree (e.g., "Data block 1" is DB1).

Byte Offset — the position of the variable within the data block. For numeric types (INT, DINT, REAL), enter the byte address shown in the Offset column (e.g., 0, 2, 4). For BOOL variables, enter byte.bit notation (e.g., 0.0 for byte 0 bit 0, 1.7 for byte 1 bit 7).

S7 Data Type — the PLC type of the variable. REAL is a 32-bit float and is most common for sensor measurements. INT is a 16-bit signed integer. DINT is a 32-bit signed integer. BOOL maps to 0 or 1 on the dashboard.

Poll Interval — how often Node-RED reads the PLC variable. 1000 ms (1 second) suits most sensors. Reduce to 100 ms for fast process variables; increase to 5000 ms for slow-changing environmental readings to reduce network traffic.

S7comm Actuator

The S7comm Actuator Bridge writes a boolean (on/off) command from the dashboard to a BOOL variable in a Siemens PLC data block.

Configuration settings:

PLC IP Address, Rack, Slot — same as the sensor.

DB Number — the data block containing the output BOOL variable.

Byte Offset — the byte.bit offset of the BOOL variable (e.g., 0.0). The actuator bridge only supports writing BOOL values. For writing INT or REAL outputs, connect the dashboard to a custom Node-RED function node after deployment.

Common S7comm Use Cases

Legacy factory PLC monitoring — Read production counts, temperatures, or alarm bits from a Siemens S7-1200 without modifying the PLC program. Any numeric DB variable becomes a sensor on your dashboard.

Automated setpoint writing — Use an S7comm Actuator to write a boolean enable/disable flag to the PLC, combined with a scheduled automation rule that turns a process on and off at set times.

Process integration — Bridge an entire production cell by reading multiple DB variables as separate sensor parts (one per Configurator room sensor), each wired to its own alarm threshold.


Troubleshooting

MQTT: The sensor shows no data after deploy

Check that the external device is publishing to the correct broker address and topic. On the Pi, you can verify messages are arriving by running mosquitto_sub -h localhost -t 'your/topic' -v from an SSH session. If no messages appear, the device is not reaching the Pi's broker. Common causes: the device has the wrong IP address for the Pi, a firewall is blocking port 1883, or the device is on a different network segment.

Modbus RTU: Frequent read errors or stale values on the dashboard

RS-485 is sensitive to wiring quality. Check that A+ connects to A+ and B- connects to B- on both ends. Reversed polarity causes consistent failures. For cable runs over 10 meters, verify that 120-ohm termination resistors are fitted at each physical end of the bus (not at intermediate devices). A floating ground — missing common ground wire — causes intermittent errors, especially on longer runs. Also confirm the baud rate, slave ID, and parity settings in the Configurator match the device's DIP switch configuration exactly.

Modbus TCP: The sensor shows "connection refused" or times out

The device IP address may have changed if it uses DHCP. Check your router's ARP table for the device's current IP and update the Configurator config. Verify the Modbus TCP server is enabled in the device firmware — some meters ship with it disabled. Also confirm no firewall on the Pi or your network is blocking TCP port 502 (or whichever port the device uses).

S7comm: The connection is rejected immediately after deploy

The most common cause is that PUT/GET access is not enabled in TIA Portal. Open the CPU Properties, navigate to Protection & Security, and verify the checkbox is ticked for "Permit access with PUT/GET communication from remote partner". Recompile and download the PLC project after enabling it. Also confirm the Pi can reach TCP port 102 on the PLC IP — use nc -zv 192.168.1.100 102 from an SSH session to test connectivity.

S7comm: The sensor connects but returns wrong values or NaN

The byte offset is likely incorrect. In TIA Portal, enable the "Offset" column in the data block editor (only visible when Optimized Block Access is disabled). Confirm the byte address matches the Byte Offset configured in the Configurator. For BOOL variables, confirm you are using byte.bit notation (e.g., 2.3) not just a plain byte number. Also verify the S7 Data Type matches the PLC variable type exactly — reading a REAL variable with the INT type produces garbage values.

General: The bridge part shows a yellow warning badge in the Configurator

The pre-deploy validator detected a configuration issue. Common causes: a required field is empty (such as MQTT topic or Modbus IP address), the register address is out of range, or an IP address does not match the required format. Click the badge to see the specific message and correct the field before deploying.


Known Issues and Limitations

MQTT Sensor Bridge only reads numeric values. If your device publishes string values (e.g., "on" or "off"), they are dropped. The sensor expects a value that can be parsed as a number. For string-based commands, use the MQTT Actuator Bridge in reverse — or add a custom function node in Node-RED after deployment to convert strings.

Modbus RTU parts share the serial port. If you add multiple Modbus RTU parts pointing to the same serial port, they share the bus through the node-red-contrib-modbus queue. This works correctly as long as each part has a unique Slave ID. Do not use the same serial port for a Modbus RTU part and a native UART sensor (such as a CO2 sensor on /dev/ttyAMA0) at the same time.

S7comm Actuator only writes BOOL variables. Writing INT, DINT, or REAL values from the dashboard to a PLC requires a custom Node-RED function node added to the flow after deployment. The Configurator does not generate this automatically.

Modbus TCP requires a static IP. Dynamic DHCP addresses will break Node-RED polling after a power cycle or lease renewal. Always assign a static IP to Modbus TCP devices, either in the device firmware or as a DHCP reservation in your router.

S7comm is not compatible with S7-300 or S7-400 PLCs using older firmware. The node-red-contrib-s7 package targets S7-1200 and S7-1500 with modern firmware. For older Siemens hardware, use a Modbus TCP gateway device as an intermediary.


mqttmodbuss7commplcesp32industrialprotocolbridge