modbus icon indicating copy to clipboard operation
modbus copied to clipboard

Fail on 2 digit com #'s in Windows

Open pstlabdev opened this issue 1 year ago • 6 comments

COM1 - 9 work as expected, however COM10, 11, etc. give an open fail. I haven't had a chance to search the code for the reason. My work around was to change COM10 to COM1 and COM11 to COM2 in Device Manager port settings/advanced for those two ports.

pstlabdev avatar Sep 18 '24 16:09 pstlabdev

Hi there,

thanks for the report. I'll try to see if I can reproduce this, but I'm not using windows that much, so don't hold your breath :) In any case, the client would be passing COM10 in about the same way as it passes COM1, so I'm wondering what might be causing the issue. Maybe something with the serial library I'm using ? I'll take a look there as well.

simonvetter avatar Sep 22 '24 11:09 simonvetter

How would you path it? I use windows but cannot get how to set a port?

URL: "rtu:///COM7"

Like this?

Serhioromano avatar Dec 27 '24 07:12 Serhioromano

Try with two forward slashes instead of three? i.e. rtu://COM7

simonvetter avatar Dec 27 '24 09:12 simonvetter

Thank you. It works fine.

Serhioromano avatar Dec 27 '24 11:12 Serhioromano

Just ran in to this same issue FYI, it seems that ports larger than COM9 are indeed special and need to be prefixed with a \\.\ string to work with the windows.CreateFile API. See https://support.microsoft.com/en-us/topic/howto-specify-serial-ports-larger-than-com9-db9078a5-b7b6-bf00-240f-f749ebfd913e.

The underlying serial library doesn't do this automatically (https://github.com/goburrow/serial/blob/bfb69110f8dd407add15aa6de3a7b6b31c9aa4a7/serial_windows.go#L160) whereas other better maintained libraries do (https://github.com/bugst/go-serial/blob/f0e4a45720a879803364f829e5e633e6f8f1be9b/serial_windows.go#L356)

A workaround for me when creating the RTU client:

const windowsPortPrefix = `\\.\`

serialPortName := os.Getenv("SERIAL_PORT")

if runtime.GOOS == "windows" && !strings.HasPrefix(serialPortName, windowsPortPrefix) {
    serialPortName = windowsPortPrefix + serialPortName
}

client, err := mb.NewClient(&mb.ClientConfiguration{
	URL:      "rtu://" + serialPortName,
	// etc...
})
// handle err, use client etc.

lhopcroft123 avatar Jul 08 '25 13:07 lhopcroft123

Huh, interesting. So it's all down to windows.CreateFile wonkiness. The MS article you linked to says

This syntax also works for ports COM1 through COM9. Certain boards will let you choose the port names yourself. This syntax works for those names as well.

so I may implement a fix in the same vein as yours in the client. I have a test setup I sometimes have access to with more than 10 Windows COM ports, so once I get around to play with it again I'll try and push a fix.

Thanks for taking the time to investigate!

simonvetter avatar Nov 26 '25 09:11 simonvetter