Alberto Schiabel
Alberto Schiabel

Reputation: 1139

Simulate serial port device using stdin and stdout

Currently, I have a desktop app that I used to read and write data to a proprietary hardware device via a serial port interface. The app starts by listing the serial COM devices connected to the computer, and once a device is selected, one can interact with the app to communicate with the corresponding device. I no longer have such a device at hand, but I would still like to use the app nonetheless.

I have already developed a command-line utility that, given a binary message in stdin, emits the corresponding binary reply (the same reply that the proprietary hardware device would send via serial port) to stdout. Let's call this utility a simulator.

How do I set up a virtual serial port such that the app can detect it, and that whenever the app sends a message using the serial port protocol, such message is forwarded to the simulator, and the simulator's reply is returned back to the desktop app?

I'm on Mac OS 12 with an M1 CPU. I'm also open to solutions on Windows 10 (with less priority).

I have looked at previous questions on StackOverflow that might be similar to this one, but they were either incomplete or slightly different, with no obvious way to infer the solution for my actual problem.

Upvotes: 3

Views: 3026

Answers (2)

rafaello
rafaello

Reputation: 2435

Creating a virtual serial port on Mac OS 13 with an apple silicon M1 CPU.

Open a terminal and execute it:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

The code above returns something like:

2023/08/18 23:12:40 socat[98468] N PTY is /dev/ttys002
2023/08/18 23:12:40 socat[98468] N PTY is /dev/ttys003
2023/08/18 23:12:40 socat[98468] N starting data transfer loop with FDs 
[5,5] and [7,7]

In essence, it creates two virtual serial ports and connect them, enabling bidirectional communication between them (/dev/ttys002 and /dev/ttys003). For example, I used this command to allow an Arduino simulator to communicate via serial port with a Processing app.

*All credits to https://stackoverflow.com/a/19733677/953287

Upvotes: 3

Codo
Codo

Reputation: 78825

Serial ports are unlike other channels. That's why separate system calls exist for them.

Normally, serial ports are created by physical devices (an old-fashioned serial port or a newer USB-based one) and the associated driver. Since writing a driver is quite difficult, a pragmatic and possibly unexpected approach would be to use hardware, specifically two USB-to-serial adapters. That way, a serial port is created by the drivers of the USB-to-serial adapter.

hardware setup

The two USB-to-serial adapters are wired to each other (RX to TX and vice versa). The will appear as two serial ports on macOS (/dev/cu.usb...).

The legacy application then connects to one of the serial ports. And your command line utility (acting as a device emulation) connects to the other serial port. All data send by the command line utility will go to the legacy application, and vice versa.

The remaining issue is how to connect your command line utility to the serial port. If you are lucky, you can use the screen command. But more likely, you will need to modify it to read and write from the serial port (instead of stdin and stdout).

Upvotes: 2

Related Questions