goburrow / modbus

Fault-tolerant implementation of modbus protocol in Go (golang)
BSD 3-Clause "New" or "Revised" License
947 stars 369 forks source link

Serial connection timing out #10

Closed brianfoshee closed 8 years ago

brianfoshee commented 8 years ago

I am trying to port some existing C code over to Go using this package but keep getting a serial: timeout error on reading registers. I've tried with both ReadHoldingRegisters and ReadInputRegisters, and with timeouts up to 60s.

I have a solar charge controller with RS232 MODBUS port (spec here) connected to a Raspberry Pi running arch linux, through a USB to RS232 converter. I'm on go version go1.6 linux/arm.

The C program is here, and essentially does:

#define SUNSAVER_ADDR    0x01
#define SERIALPORT      "/dev/ttyUSB0"
ctx = modbus_new_rtu(SERIALPORT, 9600, 'N', 8, 2);
modbus_set_slave(ctx, SUNSAVER_ADDR);
rc = modbus_read_registers(ctx, 0x08, 22, data);

(new rtu call here, read registers call here. Uses libmodbus.)

However, when I perform the same setup with this package I see the timeout:

handler := modbus.NewRTUClientHandler("/dev/ttyUSB0")
handler.BaudRate = 9600
handler.DataBits = 8
handler.Parity = "N"
handler.StopBits = 2
handler.SlaveId = 1
handler.Timeout = 5 * time.Second
handler.Logger = log.New(os.Stdout, "mb: ", log.Lshortfile)

if err := handler.Connect(); err != nil {
        fmt.Println("error conecting: ", err)
        return
}

defer handler.Close()

client := modbus.NewClient(handler)

results, err := client.ReadHoldingRegisters(8, 22)
if err != nil {
        fmt.Println("error reading registers:", err)
        return
}

Output:

mb: rtuclient.go:120: modbus: sending 01 03 00 08 00 16 45 c6
error reading registers: serial: timeout

Is there any debugging info I can provide to help track down the culprit?

nqv commented 8 years ago

Did it actually wait for 5 seconds before returning ErrTimeout? if set timeout to 0 (infinity), do you still get the error?

brianfoshee commented 8 years ago

It does wait. If I set the timeout to 0 it hangs until I stop it.

nqv commented 8 years ago

To be honest, I have never tried running this on RPi but I'm willing to fix this issue so I'd be grateful if you can help me this:

brianfoshee commented 8 years ago

I'd be happy to help you fix it.

I unfortunately am not physically at the location where the RPi and solar charger are, so I won't be able to plug my computer into either of them to verify operation.

Here is the output with the C program's debugging turned on:

Opening /dev/ttyUSB0 at 9600 bauds (N, 8, 2)
[01][03][00][08][00][16][45][C6]
Waiting for a confirmation...
<01><03><2C><0F><FD><00><00><0F><EF><00><00><00><DC><00><10><00><11><00><11><00><19><00><03><00><00><0F><FD><00><00><00><00><99><ED><00><00><99><ED><02><1B><00><01><00><00><0E><B6><00><00><94><76>

I installed kermit, but I've never used it before and I'm not sure how to send that binary data to it. I ran:

ckermit -l /dev/ttyUSB0 
set carrier-watch off
set speed 9600
set stop-bits 2
set parity none
connect

but from there it didn't seem like anything I was typing was going through. If you can point me in the right direction I would appreciate it.

Thanks for helping out with this.

brianfoshee commented 8 years ago

I will also add that, although I am not in the same location as the RPi/solar setup mentioned above, I do have a raspberry pi, arduino, and USB FTDI chip where I am now. I could probably hack something together with that if necessary.

nqv commented 8 years ago

So the frame data is similar [01][03][00][08][00][16][45][C6] I'm wondering if this is the problem with fd select with serial port. Would you please go to $GOPATH/src/github.com/goburrow/serial/serial_linux.go and comment out line 125 to 129 and rebuild it (https://github.com/goburrow/serial/blob/master/serial_linux.go#L125)

    if !fdIsSet(fd, &rfds) {
        // Timeout
        err = ErrTimeout
        return
    }

I'd like to see if it can read any data at all.

brianfoshee commented 8 years ago

With that commented out I get:

mb: rtuclient.go:120: modbus: sending 01 03 00 08 00 16 45 c6
error reading registers: EOF
brianfoshee commented 8 years ago

Is there a test I could do with the serial package and the raspberry pi and arduino I have on hand to see if there's an issue at the serial communications layer?

nqv commented 8 years ago

I have got a RPi2, will install ArchLinux and test with my usb-serial port this weekend.

brianfoshee commented 8 years ago

Great, thank you!

nqv commented 8 years ago

Hi @brianfoshee

It seems the problem has been fixed in github.com/goburrow/serial package. Would you please reset any changes made to the serial package in local and pull the latest:

go get -u github.com/goburrow/serial

Let me know if the fix does (not) work for you.

Thank you.

brianfoshee commented 8 years ago

It is working now! Thank you very much @nqv, I appreciate it!