Serial Bridge
Route data from microcontrollers that output serial/UART data through a Raspberry Pi gateway to Plexus. This pattern works with any MCU that can print to a serial port — no networking stack required on the device side.
When to Use This
- MCU without WiFi — bare-metal STM32, Arduino Uno, or other boards with no network interface
- MCU with WiFi, but you want a Pi as aggregator — offload connectivity, logging, and buffering to a gateway
- Legacy serial equipment — RS-232 lab instruments, CNC controllers, industrial sensors
- Multiple serial devices into one gateway — fan out several USB-serial adapters from a single Pi
Architecture
┌─────────────┐ UART ┌──────────────┐ HTTPS ┌─────────────┐
│ ESP32 / │──────TX/RX──▶│ Raspberry │─────────────▶│ Plexus │
│ STM32 MCU │ │ Pi Gateway │ │ Cloud │
└─────────────┘ │ │ └─────────────┘
│ plexus-python│
┌─────────────┐ UART │ + pyserial │
│ Arduino / │──────TX/RX──▶│ │
│ Other MCU │ └──────────────┘
└─────────────┘The gateway:
- Opens one or more serial ports
- Parses incoming lines into metric name/value pairs
- Sends metrics to Plexus using the Python agent
Wiring
| MCU Pin | Pi Pin | Notes |
|---|---|---|
| TX | RX (GPIO 15/RXD) | MCU transmit → Pi receive |
| RX | TX (GPIO 14/TXD) | Pi transmit → MCU receive (optional) |
| GND | GND | Common ground required |
Voltage levels: Both ESP32 and Raspberry Pi use 3.3V logic — safe to connect directly. Arduino Uno is 5V — use a level shifter or voltage divider on the TX line to avoid damaging the Pi.
Device Side (the MCU)
The SerialAdapter supports three parser modes. Pick the one that matches your firmware's output format.
Line mode (simplest)
Print one key:value pair per line. This is the easiest way to get started — no libraries needed.
// On your ESP32/STM32/Arduino — just printf over UART
while (1) {
float temp = read_temperature();
float hum = read_humidity();
printf("temperature:%.1f\n", temp);
printf("humidity:%.1f\n", hum);
sleep(1);
}JSON mode
Print a JSON object per line. Good when you want to send multiple metrics atomically.
printf("{\"temperature\":%.1f,\"humidity\":%.1f}\n", temp, hum);CSV mode
Print a header line once, then data lines. Useful for high-throughput logging.
// First line = headers (sent once)
printf("temperature,humidity,pressure\n");
// Then data lines
printf("%.1f,%.1f,%.1f\n", temp, hum, press);Gateway Side (the Pi)
1. Install the agent with serial support
pip install plexus-python[serial]2. Set your API key
export PLEXUS_API_KEY="plx_your_key_here"3. Run the bridge
import os
import time
from plexus import Plexus
from plexus.adapters import SerialAdapter
px = Plexus(
api_key=os.environ["PLEXUS_API_KEY"],
source_id="serial-gateway",
)
adapter = SerialAdapter(
port="/dev/ttyUSB0",
baudrate=115200,
parser="line", # "line", "json", or "csv"
)
adapter.connect()
while True:
metrics = adapter.poll()
for m in metrics:
px.send(m.name, m.value, timestamp=m.timestamp)
if metrics:
px.flush()
time.sleep(0.1)Switching parser modes
For JSON output from the MCU, change the parser argument:
adapter = SerialAdapter(
port="/dev/ttyUSB0",
baudrate=115200,
parser="json",
)For CSV output:
adapter = SerialAdapter(
port="/dev/ttyUSB0",
baudrate=115200,
parser="csv",
)The poll loop stays the same — adapter.poll() returns Metric objects regardless of parser mode.
Multiple Devices
To bridge several serial devices through one Pi, create a separate adapter for each port and prefix the source ID so metrics stay organized in Plexus:
import os
import time
from plexus import Plexus
from plexus.adapters import SerialAdapter
px = Plexus(
api_key=os.environ["PLEXUS_API_KEY"],
source_id="serial-gateway",
)
adapters = [
("mcu-engine", SerialAdapter(port="/dev/ttyUSB0", baudrate=115200, parser="line")),
("mcu-cabin", SerialAdapter(port="/dev/ttyUSB1", baudrate=9600, parser="json")),
("mcu-gps", SerialAdapter(port="/dev/ttyACM0", baudrate=38400, parser="csv")),
]
for _, adapter in adapters:
adapter.connect()
while True:
for prefix, adapter in adapters:
metrics = adapter.poll()
for m in metrics:
px.send(f"{prefix}/{m.name}", m.value, timestamp=m.timestamp)
px.flush()
time.sleep(0.1)Running as a Service
For production gateways, run as a systemd service:
# /etc/systemd/system/plexus-serial-bridge.service
[Unit]
Description=Plexus Serial Bridge
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=pi
Environment=PLEXUS_API_KEY=plx_your_key_here
ExecStart=/usr/bin/python3 /home/pi/serial_bridge.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetsudo systemctl enable plexus-serial-bridge
sudo systemctl start plexus-serial-bridgeNext Steps
- Gateway Pattern for BLE and other protocols
- C SDK Quickstart for WiFi-enabled devices
- Serial/GPS Adapter for GPS-specific serial