Connecting to serial port (com port) over network
(Serial port or com port? - Serial ports are often refered as COM ports. It is the same to be short. You can read abut it in the Wiki article )
- The problem
- The solution in theory
- Connect over the internet
Suppose we have an application that works with some device using serial port (com port or comport - the same thing). It could be GPS reader, IRDA, whatever. So it looks like this:
+--------+ serial +--------------+ | DEVICE | ~~~~~~~~~~ | PC with APP | +--------+ +--------------+
Now what we want, is to have the device connected to one machine (server), and run the application on the remote machine (client) over the network. Real life example: a device is connected to raspberry pi (very small single-board machine) that is connected to a local network, and read the data on a desktop.
Since the application (APP on diagrams) knows only how to communicate with the device by serial port (we suppose), the client machine has to have some virtual serial port that is used by the application. It is called "virtual serial port" or "virtual comport" as this is a software emulated bridge between a client and your application. So the diagram is:
+--------+ comport +--------+ network +--------+ virtual comport +---+ | DEVICE | ~~~~~~~~~~ | SERVER |========....==========| CLIENT |~~~~~~~~~~~~~~~~~~|APP| +--------+ +--------+ +--------+ +---+
Thus we need:
- SERVER that communicates with the DEVICE through physical serial port and then serves the data over network
- Client that connects to the server
- Virtual comport that mimics physical serial port and interface with the APP
So now the application just works with serial port on the client machine, and doesn't even know that data is actually transmitted over the network.
The solution in theory
One of the solutions is using telnet with RFC2217 - Telnet Com Port Control Option. Is solves exactly the problem above. There are a lot of software that supports telnet+RFC2217 serial port forwarding. It allows you to run the server and the client on linux or windows machines (and MACs I suppose, but haven't tested it). This allows one to run linux server and windows client. Both would use completely different software, but because of RFC2217 standard they 'know' how to communicate.
More over you can multiplex the com ports and encrypt the data. Whatever you want.
The solution in practice
There is an absolutely brilliant free opensoure solution that can be used for comport forwarding, client and server for windows. It is called com0com. It actually consists of two parts a HUB (hub4com) and kernel-mode virtual serial port driver (com0com) - explained further.
For the server you need only hub4com.
Configuration (I just cite the documentation):
You have a server computer with phisical COM1 port and you'd like to share it through the network by the RFC 2217 "Telnet Com Port Control Option" protocol:
Start the com2tcp-rfc2217.bat on COM1 port. For example:
com2tcp-rfc2217 COM1 7000
It will listen TCP/IP port 7000 for incaming connections and redirect them to COM1 port.
To be a windows client you have to install com0com virtual comport driver and hub4com (provided as 2 separate files).
Create a PAIR of virtual comports where one is used for RFC2217 and the other is the port for your application will use.
(documentation citation) for RFC 2217 client :
You have a server computer your.comport.server with physical serial port shared through the network by the RFC 2217 protocol (see above example) and you'd like to use it on the client computer like a virtual serial port.
With the com0com's Setup Command Prompt create COM19<->COM20 virtual COM port pair (see com0com's ReadMe.txt for more info). For example:
>setupc.exe command> install PortName=COM19,EmuBR=yes PortName=COM20
Example. Start the com2tcp-rfc2217.bat on COM19 port:
com2tcp-rfc2217 \\.\COM19 192.168.123.30 7000
It will redirect virtual serial port COM20 on the second computer to the physical serial port on the first computer.
(!) TL;DR; Your Application should connect to COM20.
TL;DR; We have a virtual serial port pair COM19<->COM20, we connect com2tcp to one of the ports (COM19) and your application connects to the other (COM20)
It is bit counter intuitive why a virtual pair is created. To explain what happens, imagine we create a virtual comport pair: COM19<->COM20 as in the example above. The reason one needs a pair is that only one thing can be connected to a COM port. If hub4com binds network data to COM19, then the port is taken and your application can't connect to it. So virtual comport pair mirrors everything from COM19 to COM20, which is free and your application can connect to it.
So, the more detailed client diagram looks like this now:
network +---------+ +-------+-------+ +---+ ....==========| hub4com |~~~| COM19 = COM20 |~~~~~~~~~~~~|APP| +---------+ +-------+-------+ +---+ virtual pair
Deprecated part - com0com 3.0.0 comes with driver signarure. Unfortunately on newer windows (since 2018) this doesn't help.
According to Windows Driver Signing Policy "Starting with Windows 10, version 1607, Windows will not load any new kernel-mode drivers which are not signed by the Dev Portal." (link)[https://sourceforge.net/p/com0com/discussion/440109/thread/c4d52f1b/?limit=25]
There are 3 solutions:
- Disable driver signature verification (bad)
- Use version 2.2 (it works)
- Use DSEO
(older problem) According to this bug report on Windows 8x64 you may get problem with driver installation if you don't have the driver signature verification turned off. To enable driver test mode and sign a driver for windows, one may download DSEO
The linux app I've got working pretty easy is ser2net
It has configuration file located at /etc/ser2net.conf.
sudo apt-get ser2net #install sudo vim /etc/ser2net.conf #configure ser2net #run service
The configuration line (for /etc/ser2net.conf) that corresponds to windows setup above
7000:telnet:0:/dev/ttyUSB0:1000000 8DATABITS NONE 1STOPBIT remctl
- 7000 - port
- /dev/ttyUSB0 - name of serial port
- 1000000 ... - baud rate etc (actually you can skip it because of remctl)
- remctl - means using remote port configuration as of RFC2217
That is it. Read ser2net docs for more
socat can be used as a linux client. Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them.
socat /dev/ttyS2,b115200,raw,echo=0 TCP:192.168.123.30:7000
- 192.168.123.30 - your server IP
- 7000 server port
- your app should connect to /dev/ttyS2
- 115200 - port baud rate
Connect over the internet
All the above solutions basically describe how to forward data from com-port (serial port) to network port and then how to bind a network IP with port to a virtual com-port. It is streight forward for a local network but how to connect the devices over the internet? If you are an experiecned IT person, you may think of tons of solutions here, starting from fixed IPs and counting up to infinity.
For me one of the versatile easy to configure ways was to use ZeroTier VPN services. It is free for up to 100 devices and have a good interface for easy configuration, good manuals, etc. In the end you have a network interface on each of the machines which acts as a single local network (basically what VPN is).
I'm NOT connected anyhow with Zerotier co. Just share the solution which was optimal for me. "As is".