Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modbus-RTU: Only first byte of answer is read from my device #4

Closed
gonium opened this issue Apr 17, 2015 · 10 comments
Closed

Modbus-RTU: Only first byte of answer is read from my device #4

gonium opened this issue Apr 17, 2015 · 10 comments

Comments

@gonium
Copy link

gonium commented Apr 17, 2015

I'm implementing a client for a Eastron SDM630 electricity meter using your library. The aduRequest ist composed and send correctly, but your library only reads one byte back. I suspect that this relates to the handling of the select call in serial_linux.go, but I'm not sure.

My setup consists of a RS485-USB-dongle that shows up as /dev/ttyUSB0 under my Ubuntu 14.04-box. I can successfully read the device using the minimalmodbus python library and the following script:

#!/usr/bin/env python
import minimalmodbus

instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1) # port name, slave address (in decimal)
instrument.serial.baudrate = 9600
instrument.serial.bytesize = 8
instrument.serial.parity = minimalmodbus.serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 1
instrument.debug = True
instrument.mode = minimalmodbus.MODE_RTU
print instrument

l1_voltage = instrument.read_float(0, functioncode=4,
    numberOfRegisters=2)
print "L1 voltage: ", l1_voltage

The output of this script looks like this:

$ python test.py
minimalmodbus.Instrument<id=0xb7322b2c, address=1, mode=rtu, close_port_after_each_call=False, precalculate_read_size=True, debug=True, serial=Serial<id=0xb7322b6c, open=True>(port='/dev/ttyUSB0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=1, xonxoff=False, rtscts=False, dsrdtr=False)>

MinimalModbus debug mode. Writing to instrument (expecting 9 bytes back): '\x01\x04\x00\x00\x00\x02q\xcb'
MinimalModbus debug mode. No sleep required before write. Time since previous read: 1429260650749.2 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Response from instrument: '\x01\x04\x04Cj\xcf\x17\xdb\xe2' (9 bytes), roundtrip time: 31.6 ms. Timeout setting: 1000.0 ms.

L1 voltage:  234.808944702

So, in order to query the SDM630, the library generates the following ADU request (in python syntax):
'\x01\x04\x00\x00\x00\x02q\xcb' and the device responds with '\x01\x04\x04Cj\xcf\x17\xdb\xe2'.

BUT: My program creates the correct ADU request []byte{0x1, 0x4, 0x0, 0x0, 0x0, 0x2, 0x71, 0xcb} (go syntax). It fails to read the answer correctly, it just receives the first byte of the answer: []byte{0x1}. The output of the program is here:

$ go run main.go  
Connecting to RTU via /dev/ttyUSB0
test: 2015/04/17 11:07:40 modbus: connecting '/dev/ttyUSB0'
test: 2015/04/17 11:07:40 modbus: sending []byte{0x1, 0x4, 0x0, 0x0, 0x0, 0x2, 0x71, 0xcb}
test: 2015/04/17 11:07:40 modbus: received []byte{0x1}
Failed to read from SDM630 device modbus: response length '1' does not meet minimum '4'
test: 2015/04/17 11:07:40 modbus: closing '/dev/ttyUSB0'

Any ideas?

Best regards,
-Mathias

@nqv
Copy link
Member

nqv commented Apr 17, 2015

I should provide expected length to read from serial port for each command.
What if you put time.Sleep(300 * time.Millisecond) before syscall.Select (serial_linux.go:123), will you have full response data?

@gonium
Copy link
Author

gonium commented Apr 17, 2015

@nqv: Thank you very much. If I insert a sleep time, I can correctly receive the data (and the data is also correctly decoded, see my last commit). I guess that you can determine the sleep time from the baudrate and the expected response length.

@nqv
Copy link
Member

nqv commented Apr 17, 2015

@gonium Thanks. I'll fix this issue as you have suggested.

gonium added a commit to gonium/modbus that referenced this issue Apr 20, 2015
@nqv
Copy link
Member

nqv commented Apr 20, 2015

@gonium Thanks for your pull request, I believe the issue has been fixed. I'd be grateful if you can test and let me know if it works with your device.

You also need to run go get -u github.com/goburrow/modbus to also download github.com/goburrow/serial as I move the serial part to another repository.

Thanks

@gonium
Copy link
Author

gonium commented Apr 20, 2015

@nqv I just switched from my temporary fork back to your master - now everything works as expected. Please note that I am currently using the SDM630 device in its factory settings: 9600 8N1. I didn't test higher baud rates.

Thank you very much for your help! Closing this for now.

@gonium gonium closed this as completed Apr 20, 2015
@arnavbansal95
Copy link

@gonium How to connect Pi to TTL to 485 Converter?

@gonium
Copy link
Author

gonium commented Aug 28, 2015

Hi @arnavbansal95, I prefer using cheap (as in 3 USD) USB-to-RS485 converters. If you really need to connect directly to the extension header of your RPi you can have a look at the schematics of this Sparkfun RS485 shield.

@arnavbansal95
Copy link

@gonium Thanks ....I also got a Usb to 485 converter....but I don't know how to install its driver on raspian as I am new to linux....could you help me with that?

@NilanjPatel
Copy link

@gonium how you did sleep thing to to read energy meter??

@surbhigup
Copy link

@gonium i am also working on it but didn't get the result. Can you give me some help that how you send query?

Ryanyntc2013 pushed a commit to Ryanyntc2013/modbus that referenced this issue Aug 23, 2019
Ryanyntc2013 pushed a commit to Ryanyntc2013/modbus that referenced this issue Aug 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants