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
cannot enable/disable RTS for client and slave #33
Comments
What you can do is simply:: client = ModbusSerialClient(...) Furthermore, anything that you need to do on the serial socket, you can do as well (this is actually just the pyserial socket instance). |
sorry for being noob.. However, the real issue is with the server, please be more detailed i'm really noob at this.. thank you very much for all the help you've given me. |
i'm using the synchronous client and asynchronous server examples.. cannot really understand the asynchronous client example, and from the documentation's library Asynchronous server example |
Okay, so I haven't actually implemented a rs-485 solution with pymodbus. Are you stuck using the half duplex mode? Is there any chance you can just use a full duplex (4 wire) configuration? Otherwise, everyone I have been in contact with has simply used a controller that does the control line detection for them. I guess you can try to implement it yourself, but it may be a little flakey (I have no clue if this is going to work or not):: monkey patch ModbusSerialClient._send
monkey patch ModbusSerialClient._recv
There may be other serial flags that you have to set for the master to give/take control over the line, but this is a quick idea. |
However after reading the pyserial documetation, it seems you can just defer to the hardware flow control by setting |
yes but how about the server side what can i do there, there does not seem to be a send and receive functions where would i enable rts high or low for that thanks On Thu, Sep 26, 2013 at 10:58 PM, Galen Collins notifications@github.comwrote:
|
yes i'm doing half duplex. On Thu, Sep 26, 2013 at 11:32 PM, Heming Liu hemingliu123@gmail.com wrote:
|
Trying to do the toggling from userspace is fraught with danger. Lots of devices will reply before you have had time to drop the tx-enable line, and it will not work. The right way of doing this, is to ask the kernel to open the serial port in rs-485 mode, so it will take care of that for you. Of course, that's not always possible, but it's how you should do it. monkey patching send is the first attempt is ... maybe ok. You can definitely set the tx-enable line there, but you want to be dropping it again as soon as the transmission is complete. Which, unfortunately, is not when socket.write() returns! (You can get lucky with some rs485 devices by putting a delay there and dropping the signal manually, but it will not work with lots of devices that reply when the message has been received without waiting) (Also, please remember that just because you are using the RTS line repurposed as a rs485 driver enable line doesn't meant that's the right name for it :) |
both of my Linux devices are the same. def _execute(self, request, addr):
def _send(self, message, addr):
Even using the modpoll simulation server, i could not get a result using the Synchronous client.. |
Hi Galen, what controller do people use, does the controller have automatic rs-485 thanks Heming On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins notifications@github.comwrote:
|
Sorry but I have to dive in here, Anyone running modbus on a multitasking OS such as linux or windows will RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS or any It is even probable that with a modern RS232 chip with buffering meeting Sorry but anyone trying modbus over serial on a multitasking OS is at see here for converters On 28/09/13 14:33, heming277 wrote:
|
ok thanks for the informative reply! this helps very much i've been struggling for a long time. However as you said even RS-232 is not possible, what's the point of using say if i want to connect from my master box to my slave box, how would i do i have a FTDI USB to RS485 converter like this one On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com wrote:
|
on the other hand, why does Modpoll work, their simulation master and slave On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com wrote:
|
RS422 and RS485 are ballanced lines, you can get over 1km on them with On 28/09/13 20:40, heming277 wrote:
|
If you need to have RTS/CTS and the other modem stuff to trigger the I have used modpoll and simplymodbus to test applications we have and On 28/09/13 20:44, heming277 wrote:
|
Before I tried a USB to rs232 to rs485 connection, which is connecting USB to master and the A and B data wires to slave device. Then modpoll didn't work. If I simply connect 2 wires from rs485 port to the other rs485 port it works.. I'm confuse as to what is the right thing to do here. Sent from my iPhone On Sep 28, 2013, at 4:17 AM, xvart notifications@github.com wrote:
|
Get a CRO and make sure the USB device has all the pins connected and If nothing changes state then the pymodbus serial driver may need to The RS232->RS485 device uses the modem lines to define direction and can On 29/09/13 06:45, heming277 wrote:
|
what is a CRO?. so if i use pymodbus to send out data through RS-232 port and after the i'm sorry but i'm really noob .. had no experience in these kind of systems. i just want to know if there's a way to do the way Modpoll is enabling RTS On Sat, Sep 28, 2013 at 7:55 PM, xvart notifications@github.com wrote:
|
Ok using the sync client test app talking to /dev/ttyUSB0 I get from speed 19200 baud; rows 0; columns 0; line = 0; The -crtscts says that hardware flow control is not enabled. You can tye running the serialclient with a start up delay after it open On 29/09/13 06:45, heming277 wrote:
|
CRO - https://en.wikipedia.org/wiki/Oscilloscope On 29/09/13 13:09, heming277 wrote:
|
You can try this for laughs and see what happens, In the sync client, add "client.socket.rtscts=True" to your code after The serial port according to this On 29/09/13 13:09, heming277 wrote:
|
how do i do a startup delay?..the serial client specify the paramters and i currently do not have my test equipment with me. thanks On Sat, Sep 28, 2013 at 8:12 PM, xvart notifications@github.com wrote:
|
In your client after, this enables hardware handshaking, the "crtscts" parameter shown with stty. *On 29/09/13 14:08, heming277 wrote:
|
i did that thanks for the help you've given me On Sat, Sep 28, 2013 at 10:29 PM, xvart notifications@github.com wrote:
|
RTS/CTS/DTR/CD etc are old modem hardware signal control lines and From what I can tell the async/sync in pymodbus has nothing to do with Did the change work??? On 29/09/13 17:41, heming277 wrote:
|
well using the client.socket.rtscts =True returned an error with nonetype object doesn't then i run stty -F /dev/usb0 -crstcts like i just want to know if there's a way to turn on auto flow control on thanks On Sun, Sep 29, 2013 at 1:52 AM, xvart notifications@github.com wrote:
|
Right now you will have to do the second assignment you did (client.socket = serial.Socket) as I don't currently pass all the configuration flags to the Serial constructor. I will make a fix for this. When you set rtscts = True, pyserial is effectively going to set the ioctl that enables that in the serial driver. So if this is supported by your device driver/device (it should be), then you should be good to go. As for the master side, you should be able to set that as well in just the same manner. If you want to play with various settings on a single box (say to emulate various serial servers), use http://www.modbusdriver.com/diagslave.html or start a synchronous/asynchronous pymodbus server with the options you care to test with. If you need to set up null modem support (if you don't have a cable), here are some options that you can use to set up a software loopback: https://github.com/bashwork/pymodbus/tree/master/examples/tools/nullmodem The synchronous and asynchronous servers/clients are for two different purposes:
while (running):
The decision to use one over the other is basically asking the following questions:
|
is there a way i can check that RTS is enabled or not? using the STTY method it just takes me to a new command line does that mean it succeeded? thanks On Mon, Sep 30, 2013 at 1:04 PM, Galen Collins notifications@github.comwrote:
|
Here is what I would recommend that you do, write a simple serial program for your server and client that simply ping pong with each other (something like this):
Then play with your serial connection settings until you can get this to work. Don't worry about modbus for now. When you get this working, simply replace the serial socket settings you used in the modbus code and you should be good to go. |
The "crtscts" stands for rts cts lines, this says it is being used, The printout says hardware flow control is on. On 02/10/13 05:55, heming277 wrote:
|
ok so i think i found the reason using client.socket = serial.Serial(rtscts=True) doesn't send anything or i have to set RTS using client.socket.setRTS(True) and False in the ping pong example, i used socket.setRTS(True) and the problem is. with Modbus it doesn't work the modifications i made to Sync.py under ModbusSerialClient source code is def _send(self, request):
baudrate=192
def _recv(self, size):
and the modification i made to the server's Sync.py the def send(self, message):
timeout= and i made modification to Asyn Server's UDP server's execute method, not def _execute(self, request, addr):
timeout= Could anyone help me out? i think i'm getting close thank you guys very much On Mon, Sep 30, 2013 at 1:04 PM, Galen Collins notifications@github.comwrote:
|
the error it gives me right now is that it is still getting None On Wed, Oct 2, 2013 at 5:55 PM, Heming Liu hemingliu123@gmail.com wrote:
|
here's my master code from ping pong code. def server(socket): def client(socket): and my slave code from ping pong import serial, sys, time def server(socket): def client(socket): the only problem i have now is when using modbus, it doesn't work.. On Wed, Oct 2, 2013 at 5:55 PM, Heming Liu hemingliu123@gmail.com wrote:
|
anyone knows what i'm doing wrong? On Thu, Oct 3, 2013 at 11:34 AM, Heming Liu hemingliu123@gmail.com wrote:
|
please help! any suggestion is helpful! thanks On Mon, Oct 7, 2013 at 12:47 AM, Heming Liu hemingliu123@gmail.com wrote:
|
So you shouldn't have had to modify the code I provided to get that example to work. If so, you are going to have to modify the pymodbus code everywhere and resort to bit-banging to get a functioning client/server. I don't have too much more that I can offer aside from working with the pyserial module more to figure out how to get it working without pymodbus. When that works consistently, you should just be able to create the socket just as you would from an example and it will work with pymodbus. It should be noted that the library doesn't do anything directly with the hardware layer directly (i.e. it doesn't manually do anything special based on TCP, UDP, Serial, etc), it just sends data to an opened socket. So once the socket is working correctly, the library will work correctly. |
yes i did modify the code for it to work. On Wed, Oct 9, 2013 at 3:05 PM, Galen Collins notifications@github.comwrote:
|
is there any advancement regarding this issue? thanks heming On Wed, Oct 9, 2013 at 3:05 PM, Galen Collins notifications@github.comwrote:
|
i still have no luck.. it works fine with Modpoll, just doesn't work with pymodbus. On Tue, Oct 15, 2013 at 11:07 AM, Heming Liu hemingliu123@gmail.com wrote:
|
What is the modpoll command that works correctly? |
for the modpoll master it was just ./modpoll -a 1 -b 19200 -4 1 /dev/ttyS2 and for diagslave it was just ./diagslave -b 19200 -a 1 -4 1 /dev/ttyS2 the outputs are -- Polling slave... (Ctrl-C to stop) -- Polling slave... (Ctrl-C to stop) -- Polling slave... (Ctrl-C to stop) -- Polling slave... (Ctrl-C to stop) all other parameters just default to the RTU method, might it be that my Pymodbus scripts are wrong? i've attached them in the thank you very much for any help On Fri, Oct 25, 2013 at 11:06 PM, Galen Collins notifications@github.comwrote:
|
Okay so since your device does not offer any RTS capabilities, you are going to have to bit bang the line and hope for the best (that is what the -4 parameter does for modpoll). Earlier when you did class RtsModbusSerialClient(ModbusSerialClient):
def _send(self, request):
''' Sends data on the underlying socket
:param request: The encoded request to send
:return: The number of bytes written
'''
if not self.socket:
raise ConnectionException(self.__str__())
if request:
self.socket.setRTS(True)
result = self.socket.write(request)
self.socket.setRTS(False)
return result
return 0
def _recv(self, size):
''' Reads data from the underlying descriptor
:param size: The number of bytes to read
:return: The bytes read
'''
if not self.socket:
raise ConnectionException(self.__str__())
self.socket.setRTS(False)
result = self.socket.read(size)
self.socket.setRTS(True)
return result There may be some timing issues that you have to deal with for this to work correctly (the lines might need to be held for longer than the read/write; say 25ms). But generally this is what you are going to have to play around with until it works. I don't have a device to test against so I cannot really help you besides offering advice, however, if I ever get a tested solution, I will gladly add it to the contrib package so future users will not have to go through as much grief as you. Thanks for keeping at it! |
Hi Galen, i did do what u suggested in the client's source code, under modbus serial could u suggest what i should do for the server's side? or do i just put this code directly into my client and server's codes. On Mon, Oct 28, 2013 at 1:44 PM, Galen Collins notifications@github.comwrote:
|
Right, so in server/sync.py, there is the ModbusSerialServer. What you will have to do is something like:: class RtsModbusSerialServer(object):
def _build_handler(self):
''' A helper method to create and monkeypatch
a serial handler.
:returns: A patched handler
'''
def rts_send(message):
self.socket.setRTS(True)
result = self.socket.write(message)
self.socket.setRTS(False)
return result
def rts_recv(count):
self.socket.setRTS(False)
result = self.socket.read(count)
self.socket.setRTS(True)
return result
request = self.socket
request.send = rts_send
request.recv = rts_recv
handler = ModbusSingleRequestHandler(request,
(self.device, self.device), self)
return handler |
so if i understand correctly i should add this class into the sync.py in thanks Heming On Tue, Oct 29, 2013 at 4:11 PM, Galen Collins notifications@github.comwrote:
|
No, you can overload classes in your own code. If you want to modify the So just add those two blocks to the top of your library along with the
|
ok so it still doesn't work. here's my client code: class RtsModbusSerialClient(ModbusSerialClient):
#---------------------------------------------------------------------------# configure the client logging#---------------------------------------------------------------------------# #client = ModbusClient('localhost', port=502) #dw = client.write_coil(1, True) rq = client.write_register(1, 10, unit = 1) #---------------------------------------------------------------------------# close the client#---------------------------------------------------------------------------# And my Server code:
''' #from pymodbus.server.async import StartTcpServer class RtsModbusSerialServer(object):
#---------------------------------------------------------------------------# configure the service logging#---------------------------------------------------------------------------# slaves = { context = ModbusServerContext(slaves=slaves, single=False) #---------------------------------------------------------------------------# initialize the server information#---------------------------------------------------------------------------# If you don't set this or any fields, they are defaulted to empty strings.#---------------------------------------------------------------------------# identity = ModbusDeviceIdentification() #---------------------------------------------------------------------------# run the server you want#---------------------------------------------------------------------------# the output after i ran the server and client is : On Tue, Oct 29, 2013 at 5:30 PM, Galen Collins notifications@github.comwrote:
|
sorry i need to ask again, if Modpoll works without any converters, how come my code using pymodbus is it because it is synchronous and not asynchronous? thanks .. On Wed, Oct 30, 2013 at 1:35 PM, Heming Liu hemingliu123@gmail.com wrote:
|
They are doing the bit banging just like you would be doing (the -4 flag). It doesn't really matter if you use sync or async. I just don't know the timing of how long the flags should be held and how much time it takes to move between the python interpreter and the OS (to bring the serial lines high and low). It really is a duct tape solution and may require a bit of hacking to get it working correctly. As I don't have any devices, I really cannot do much to help you with debugging, sorry. |
but does my code look correct? thanks On Thu, Nov 7, 2013 at 11:34 PM, Galen Collins notifications@github.comwrote:
|
Looks okay, but I would really need to play with the code while looking at a wire trace of the serial line to see how things are actually working. |
seems like it just won't work.. do anyone has other suggestions? thanks On Fri, Nov 8, 2013 at 3:54 PM, Galen Collins notifications@github.comwrote:
|
when i'm getting transcations from the client side, the server side doesn't have any output after i start the sync server. does that mean my client's request never got to the server? On Mon, Nov 11, 2013 at 3:51 PM, Heming Liu hemingliu123@gmail.com wrote:
|
closing stale issue |
I know this is is old thread but following works for me like a charm by ..
|
when i use serial RTU and RS-485 wires, how do i set set RTS high and low.
i know i gotta to do it in the source codes, like for read_holding_register request , i need to set it high to send the request and low to receive the response from slave.
and for the slave Linux box, i need to set RTS high to send a reponse back to master and set it low right after that.
where do i do that ?
i know i can setRTS using pyserial.
The text was updated successfully, but these errors were encountered: