Build your own serial-to-ethernet server with a Raspberry Pi
28 Oct 2016.
A Serial Terminal Server makes a serial connection available over the network, so that your application can access your devices without a direct serial connection. Typically this is used to establish a bi-directional connection between networked applications and older industrial equipment. In this article we will focus on a much simpler use case: Capturing serial logs, where we only need communication in one direction — a common use case when testing set-top boxes.
First the complete solution, for the impatient:
DEVICE=/dev/serial/by-path/platform-3f980000.usb-usb-0:126.96.36.199:1.0-port0 PORT=4953 socat -b 2048 -u "\"$DEVICE\",b115200,crnl,raw,ignoreeof,echo=0" - </dev/null \ | ts %Y-%m-%dT%H:%M:%S%z \ | gst-launch-1.0 fdsrc ! text/plain ! queue \ ! tcpserversink sync=false host=0.0.0.0 port=$PORT
The above socat command transfers data from the serial device to standard output. The two layers of quoting are necessary so that socat doesn’t treat the “:” in the device path as separators. See the socat manual for details on the other parameters.
Then we pipe socat’s output to
ts, which prepends an ISO 8601 timestamp to
gst-launch runs a GStreamer pipeline that reads the text data from
its standard input, starts up a server listening on the specified TCP port, and
sends the data to any clients that connect. GStreamer is perhaps overkill for
this but it gets the job done, and it supports multiple clients
connecting/disconnecting and reading the same data simultaneously.
You’ll want to configure your init system to start the above service automatically on startup. I’ll leave that as an exercise to the reader.
You can test this using netcat. This should print your set-top box’s serial output to the console:
nc $serial_server_address 4953
Or using socat:
socat TCP:$serial_server_address:4953 -
Installing the dependencies
Assuming you’re using Raspbian on a Raspberry Pi, here’s how to install these tools:
apt-get update && apt-get install \ gstreamer1.0-plugins-base \ gstreamer1.0-tools \ moreutils \ socat
Specifying the serial device
On a single server you can have multiple versions of the above script serving different serial devices, as long as each one uses a different TCP port.
/dev/serial/by-path/... (instead of
/dev/ttyUSBx) because it won’t
change across reboots. It refers to the physical USB port that your serial
adapter is plugged into.
To find the path of your serial device, just run
before and after plugging it in.
USB serial adapters
For out-of-the-box Linux support and good reliability, you only have two options: