As you can see in the mono source code, the SerialPort.GetPortNames()
method just enumerates the /dev/tty* nodes:
string[] ttys = Directory.GetFiles("/dev/", "tty*");
...
foreach (string dev in ttys) {
if (linux_style){
if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB") || dev.StartsWith("/dev/ttyACM"))
serial_ports.Add (dev);
} else {
if (dev != "/dev/tty" && dev.StartsWith ("/dev/tty") && !dev.StartsWith ("/dev/ttyC"))
serial_ports.Add (dev);
}
}
So that's why you're getting all those tty* devices in the output.
But it's not so easy to determine which of them actually correspond to a (connected) serial port on your machine.
You can take a look on this answer. They're using an Unix dmesg command there followed by a grep to find out which devices are actually serial ports. They're even trying to figure out which of the serial port is connected on the other side too.
$dmesg | grep ttyS
[ 0.872181] 00:06: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 0.892626] 00:07: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[ 0.915797] 0000:01:01.0: ttyS4 at I/O 0x9800 (irq = 19) is a ST16650V2
[ 0.936942] 0000:01:01.1: ttyS5 at I/O 0x9c00 (irq = 18) is a ST16650V2
Alternatively, you could parse the /proc/tty/drivers file, as explained in this answer.
There are a couple of similar questions about it. Perhaps you can find a solution that suits your needs best.
AFAIK there is no simple way to do this in mono directly, you have to go deeper.
UPDATE
The reason why there is only one /dev/ttyUSB0 item in case of a connected FTDI device seems to be pretty obvious.
In the same method, the linux_style
flag value is determined by a simple look-up:
if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB") || dev.StartsWith("/dev/ttyACM")) {
linux_style = true;
break;
}
So if there is a ttyUSB* device available, this flag will be set to true
. This affects the device enumeration described above which returns a single item.