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

cannot enable/disable RTS for client and slave #33

Closed
ghost opened this issue Sep 27, 2013 · 60 comments
Closed

cannot enable/disable RTS for client and slave #33

ghost opened this issue Sep 27, 2013 · 60 comments

Comments

@ghost
Copy link

ghost commented Sep 27, 2013

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.

@bashwork
Copy link
Collaborator

What you can do is simply::

client = ModbusSerialClient(...)
client.socket.setRTS(true)
...
client.socket.setRTS(false)

Furthermore, anything that you need to do on the serial socket, you can do as well (this is actually just the pyserial socket instance).

@ghost
Copy link
Author

ghost commented Sep 27, 2013

sorry for being noob..
i know how to set that, but what does it mean,
like if i want to do a read_holding_register through just RS-485 twisted pair wires,
i setRTS(true) to send the read request.
client.read_holding_register would return the value?
do i need to setRTS(false) after doing client.read_holding_register? do i need a delay between them?
i'v been adding set RTS(True) and setRTS(false) in transaction manager's execute() method .
so before a send, i set it true, after a send i set it false.

However, the real issue is with the server,
the server should only setRTS(True) when the master sends a request right? how do i know when to set it high,
is there a way to know if a request has been sent so i can do an IF statement?

please be more detailed i'm really noob at this..

thank you very much for all the help you've given me.

@ghost
Copy link
Author

ghost commented Sep 27, 2013

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
from asyn.py import ModbusSerialClient as Client doesn't work, there's no ModbusSerialClient in Async.py ..

@bashwork
Copy link
Collaborator

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

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) # may need to delay, poll, etc here
        return self.socket.write(request)
    return 0

monkey patch ModbusSerialClient._recv

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__())
    client.socket.setRTS(false) # you shouldn't have to delay here
    return self.socket.read(size)

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.

@bashwork
Copy link
Collaborator

However after reading the pyserial documetation, it seems you can just defer to the hardware flow control by setting
rtscts=False in the ModbusSerialClient constructor.

@ghost
Copy link
Author

ghost commented Sep 27, 2013

yes but how about the server side

what can i do there, there does not seem to be a send and receive functions
in the transaction manager in the transaction.py .

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:

However after reading the pyserial documetation, it seems you can just
defer to the hardware flow control by setting
rtscts=False in the ModbusSerialClient constructor.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25224568
.

@ghost
Copy link
Author

ghost commented Sep 27, 2013

yes i'm doing half duplex.

On Thu, Sep 26, 2013 at 11:32 PM, Heming Liu hemingliu123@gmail.com wrote:

yes but how about the server side

what can i do there, there does not seem to be a send and receive
functions in the transaction manager in the transaction.py .

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:

However after reading the pyserial documetation, it seems you can just
defer to the hardware flow control by setting
rtscts=False in the ModbusSerialClient constructor.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25224568
.

@karlp
Copy link
Contributor

karlp commented Sep 27, 2013

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 :)

@ghost
Copy link
Author

ghost commented Sep 27, 2013

both of my Linux devices are the same.
and i'm using Sync client on one and Async server on the other. should i be using an Async client? but the one in the documentation code doesn't work.
i'm setting RTS high and low like this on the SYNC.PY in ModbusUdpServer

def _execute(self, request, addr):
''' Executes the request and returns the result

    :param request: The decoded request message
    '''
    try:
        context = self.store[request.unit_id]
        response = request.execute(context)
    except Exception, ex:
        _logger.debug("Datastore unable to fulfill request: %s" % ex)
        response = request.doException(merror.SlaveFailure)
    #self.framer.populateResult(response)
    response.transaction_id = request.transaction_id
    response.unit_id = request.unit_id
    self._send(response, addr)
    self.socket.setRTS(False)

def _send(self, message, addr):
''' Send a request (string) to the network

    :param message: The unencoded modbus response
    :param addr: The (host, port) to send the message to
    '''
    self.control.Counter.BusMessage += 1
    pdu = self.framer.buildPacket(message)
    if _logger.isEnabledFor(logging.DEBUG):
        _logger.debug('send: %s' % b2a_hex(pdu))
    self.socket.setRTS(True)
    return self.transport.write(pdu, addr)

Even using the modpoll simulation server, i could not get a result using the Synchronous client..
getting error like this from writing to the register
assert(rq.function_code < 0x80) # test that we are not an error
AttributeError: 'NoneType' object has no attribute 'function_code'
and i get none from reading the register..

@ghost
Copy link
Author

ghost commented Sep 28, 2013

Hi Galen,

what controller do people use, does the controller have automatic rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
    return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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__())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25224214
.

@xvart
Copy link

xvart commented Sep 28, 2013

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows will
never be able to meet the requirements of the serial spec, there is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS or any
other modem signalling system. If you want to send over RS485, get an
RS485 converter and move on this is not a modbus issue. On serial modbus
is a poll response protocol so RTS et al are meaningless, read the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25224214
.


Reply to this email directly or view it on GitHub
#33 (comment).

@ghost
Copy link
Author

ghost commented Sep 28, 2013

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
the RS-232 TO RS-485 converter then.

say if i want to connect from my master box to my slave box, how would i do
it.

i have a FTDI USB to RS485 converter like this one
https://www.sparkfun.com/products/9822
and i do have a rs-232 to rs-485 converter.

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows will
never be able to meet the requirements of the serial spec, there is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS or any
other modem signalling system. If you want to send over RS485, get an
RS485 converter and move on this is not a modbus issue. On serial modbus
is a poll response protocol so RTS et al are meaningless, read the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub
#33 (comment).


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25293550
.

@ghost
Copy link
Author

ghost commented Sep 28, 2013

on the other hand, why does Modpoll work, their simulation master and slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows will
never be able to meet the requirements of the serial spec, there is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS or any
other modem signalling system. If you want to send over RS485, get an
RS485 converter and move on this is not a modbus issue. On serial modbus
is a poll response protocol so RTS et al are meaningless, read the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub
#33 (comment).


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25293550
.

@xvart
Copy link

xvart commented Sep 28, 2013

RS422 and RS485 are ballanced lines, you can get over 1km on them with
very good data rates and they are immune to noise. RS232 will go about
20m(60ft) before you start having issues this is why we use RS422/485 in
industrial aplications.

On 28/09/13 20:40, 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
the RS-232 TO RS-485 converter then.

say if i want to connect from my master box to my slave box, how would
i do
it.

i have a FTDI USB to RS485 converter like this one
https://www.sparkfun.com/products/9822
and i do have a rs-232 to rs-485 converter.

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows
will
never be able to meet the requirements of the serial spec, there is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS or any
other modem signalling system. If you want to send over RS485, get an
RS485 converter and move on this is not a modbus issue. On serial
modbus
is a poll response protocol so RTS et al are meaningless, read the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25293550
.


Reply to this email directly or view it on GitHub
#33 (comment).

@xvart
Copy link

xvart commented Sep 28, 2013

If you need to have RTS/CTS and the other modem stuff to trigger the
direction on the RS232/RS485 converter you have then this is an issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with the
converter IC. Find out how your converter works first, then patch the
send to toggle the appropriate bits and post the patch. Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we have and
have had no issues bot serial and tcp. If your remote end decides it's
going to hold to 3.5 bits your going to have issues. Our current code
base interfaces to PLC gear and works ok, I'm moving to pymodbus as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows
will
never be able to meet the requirements of the serial spec, there is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS or any
other modem signalling system. If you want to send over RS485, get an
RS485 converter and move on this is not a modbus issue. On serial
modbus
is a poll response protocol so RTS et al are meaningless, read the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25293550
.


Reply to this email directly or view it on GitHub
#33 (comment).

@ghost
Copy link
Author

ghost commented Sep 28, 2013

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:

If you need to have RTS/CTS and the other modem stuff to trigger the
direction on the RS232/RS485 converter you have then this is an issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with the
converter IC. Find out how your converter works first, then patch the
send to toggle the appropriate bits and post the patch. Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we have and
have had no issues bot serial and tcp. If your remote end decides it's
going to hold to 3.5 bits your going to have issues. Our current code
base interfaces to PLC gear and works ok, I'm moving to pymodbus as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows
will
never be able to meet the requirements of the serial spec, there is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS or any
other modem signalling system. If you want to send over RS485, get an
RS485 converter and move on this is not a modbus issue. On serial
modbus
is a poll response protocol so RTS et al are meaningless, read the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25293550
.


Reply to this email directly or view it on GitHub
#33 (comment).


Reply to this email directly or view it on GitHub.

@xvart
Copy link

xvart commented Sep 29, 2013

Get a CRO and make sure the USB device has all the pins connected and
these are changing state when you transmit.

If nothing changes state then the pymodbus serial driver may need to
change the way it configures the serial port or your kernel driver isn't
doing what you think it is.

The RS232->RS485 device uses the modem lines to define direction and can
use them to power the converter, you need to work all this out first.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to trigger the
direction on the RS232/RS485 converter you have then this is an issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with the
converter IC. Find out how your converter works first, then patch the
send to toggle the appropriate bits and post the patch. Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we have and
have had no issues bot serial and tcp. If your remote end decides it's
going to hold to 3.5 bits your going to have issues. Our current code
base interfaces to PLC gear and works ok, I'm moving to pymodbus as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows
will
never be able to meet the requirements of the serial spec, there
is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS
or any
other modem signalling system. If you want to send over RS485,
get an
RS485 converter and move on this is not a modbus issue. On serial
modbus
is a poll response protocol so RTS et al are meaningless, read
the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS
is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHubhttps://github.com//issues/33#issuecomment-25293550

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub
#33 (comment).

@ghost
Copy link
Author

ghost commented Sep 29, 2013

what is a CRO?.

so if i use pymodbus to send out data through RS-232 port and after the
converter it becomes RS-485 and it goes to the slave's RS-48 port, that
would have auto-flow control as suppose to using just 2 wires for RS-485?

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
in pymodbus , they do it like enable RTS when send, and disable 1MS after.
that worked fine, or using auto-flow control transmitters? if i send data
serially through either RS-232 or USB port, modpoll doesn't work.. the
ports are already configured as they are on the Linux system .

On Sat, Sep 28, 2013 at 7:55 PM, xvart notifications@github.com wrote:

Get a CRO and make sure the USB device has all the pins connected and
these are changing state when you transmit.

If nothing changes state then the pymodbus serial driver may need to
change the way it configures the serial port or your kernel driver isn't
doing what you think it is.

The RS232->RS485 device uses the modem lines to define direction and can
use them to power the converter, you need to work all this out first.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to trigger the
direction on the RS232/RS485 converter you have then this is an issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with the
converter IC. Find out how your converter works first, then patch the
send to toggle the appropriate bits and post the patch. Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we have and
have had no issues bot serial and tcp. If your remote end decides it's
going to hold to 3.5 bits your going to have issues. Our current code
base interfaces to PLC gear and works ok, I'm moving to pymodbus as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows
will
never be able to meet the requirements of the serial spec, there
is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS
or any
other modem signalling system. If you want to send over RS485,
get an
RS485 converter and move on this is not a modbus issue. On serial
modbus
is a poll response protocol so RTS et al are meaningless, read
the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS
is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25293550>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub
#33 (comment).


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25313332
.

@xvart
Copy link

xvart commented Sep 29, 2013

Ok using the sync client test app talking to /dev/ttyUSB0 I get from
stty -F /dev/ttyUSB0 -a

speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt
= ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl
-ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0
vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop
-echoprt

The -crtscts says that hardware flow control is not enabled.

You can tye running the serialclient with a start up delay after it open
the port then doing a "stty -F /dev/ttyUSB0 crtscts", and see if that works.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to trigger the
direction on the RS232/RS485 converter you have then this is an issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with the
converter IC. Find out how your converter works first, then patch the
send to toggle the appropriate bits and post the patch. Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we have and
have had no issues bot serial and tcp. If your remote end decides it's
going to hold to 3.5 bits your going to have issues. Our current code
base interfaces to PLC gear and works ok, I'm moving to pymodbus as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows
will
never be able to meet the requirements of the serial spec, there
is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS
or any
other modem signalling system. If you want to send over RS485,
get an
RS485 converter and move on this is not a modbus issue. On serial
modbus
is a poll response protocol so RTS et al are meaningless, read
the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS
is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHubhttps://github.com//issues/33#issuecomment-25293550

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub
#33 (comment).

@xvart
Copy link

xvart commented Sep 29, 2013

CRO - https://en.wikipedia.org/wiki/Oscilloscope

On 29/09/13 13:09, heming277 wrote:

what is a CRO?.

so if i use pymodbus to send out data through RS-232 port and after the
converter it becomes RS-485 and it goes to the slave's RS-48 port, that
would have auto-flow control as suppose to using just 2 wires for RS-485?

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
in pymodbus , they do it like enable RTS when send, and disable 1MS
after.
that worked fine, or using auto-flow control transmitters? if i send data
serially through either RS-232 or USB port, modpoll doesn't work.. the
ports are already configured as they are on the Linux system .

On Sat, Sep 28, 2013 at 7:55 PM, xvart notifications@github.com wrote:

Get a CRO and make sure the USB device has all the pins connected and
these are changing state when you transmit.

If nothing changes state then the pymodbus serial driver may need to
change the way it configures the serial port or your kernel driver
isn't
doing what you think it is.

The RS232->RS485 device uses the modem lines to define direction and
can
use them to power the converter, you need to work all this out first.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to trigger
the
direction on the RS232/RS485 converter you have then this is an
issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with
the
converter IC. Find out how your converter works first, then
patch the
send to toggle the appropriate bits and post the patch.
Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we
have and
have had no issues bot serial and tcp. If your remote end
decides it's
going to hold to 3.5 bits your going to have issues. Our current
code
base interfaces to PLC gear and works ok, I'm moving to pymodbus
as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation
master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart
notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or
windows
will
never be able to meet the requirements of the serial spec,
there
is no
debate on this, tasking is normally 10ms so meeting 3.5us
timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no
RTS,CTS
or any
other modem signalling system. If you want to send over RS485,
get an
RS485 converter and move on this is not a modbus issue. On
serial
modbus
is a poll response protocol so RTS et al are meaningless, read
the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with
buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS
is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have
automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc
here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to
delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25293550>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25313332
.


Reply to this email directly or view it on GitHub
#33 (comment).

@xvart
Copy link

xvart commented Sep 29, 2013

You can try this for laughs and see what happens,

In the sync client, add "client.socket.rtscts=True" to your code after
you create the client.

The serial port according to this
http://pyserial.sourceforge.net/pyserial_api.html, states that rtscts is
normally set to false.

On 29/09/13 13:09, heming277 wrote:

what is a CRO?.

so if i use pymodbus to send out data through RS-232 port and after the
converter it becomes RS-485 and it goes to the slave's RS-48 port, that
would have auto-flow control as suppose to using just 2 wires for RS-485?

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
in pymodbus , they do it like enable RTS when send, and disable 1MS
after.
that worked fine, or using auto-flow control transmitters? if i send data
serially through either RS-232 or USB port, modpoll doesn't work.. the
ports are already configured as they are on the Linux system .

On Sat, Sep 28, 2013 at 7:55 PM, xvart notifications@github.com wrote:

Get a CRO and make sure the USB device has all the pins connected and
these are changing state when you transmit.

If nothing changes state then the pymodbus serial driver may need to
change the way it configures the serial port or your kernel driver
isn't
doing what you think it is.

The RS232->RS485 device uses the modem lines to define direction and
can
use them to power the converter, you need to work all this out first.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to trigger
the
direction on the RS232/RS485 converter you have then this is an
issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with
the
converter IC. Find out how your converter works first, then
patch the
send to toggle the appropriate bits and post the patch.
Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we
have and
have had no issues bot serial and tcp. If your remote end
decides it's
going to hold to 3.5 bits your going to have issues. Our current
code
base interfaces to PLC gear and works ok, I'm moving to pymodbus
as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation
master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart
notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or
windows
will
never be able to meet the requirements of the serial spec,
there
is no
debate on this, tasking is normally 10ms so meeting 3.5us
timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no
RTS,CTS
or any
other modem signalling system. If you want to send over RS485,
get an
RS485 converter and move on this is not a modbus issue. On
serial
modbus
is a poll response protocol so RTS et al are meaningless, read
the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with
buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS
is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have
automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc
here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to
delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25293550>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25313332
.


Reply to this email directly or view it on GitHub
#33 (comment).

@ghost
Copy link
Author

ghost commented Sep 29, 2013

how do i do a startup delay?..the serial client specify the paramters and
then do a client.connect(), do i put the delay between these?..

i currently do not have my test equipment with me.
but even enabling the rts/cts is not automatic flow control right, i still
have to manually turn it on or off after sending and receiving data?

thanks

On Sat, Sep 28, 2013 at 8:12 PM, xvart notifications@github.com wrote:

Ok using the sync client test app talking to /dev/ttyUSB0 I get from
stty -F /dev/ttyUSB0 -a

speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt
= ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl
-ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0
vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop
-echoprt

The -crtscts says that hardware flow control is not enabled.

You can tye running the serialclient with a start up delay after it open
the port then doing a "stty -F /dev/ttyUSB0 crtscts", and see if that
works.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to trigger the
direction on the RS232/RS485 converter you have then this is an issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with the
converter IC. Find out how your converter works first, then patch the
send to toggle the appropriate bits and post the patch. Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we have and
have had no issues bot serial and tcp. If your remote end decides it's
going to hold to 3.5 bits your going to have issues. Our current code
base interfaces to PLC gear and works ok, I'm moving to pymodbus as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or windows
will
never be able to meet the requirements of the serial spec, there
is no
debate on this, tasking is normally 10ms so meeting 3.5us timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no RTS,CTS
or any
other modem signalling system. If you want to send over RS485,
get an
RS485 converter and move on this is not a modbus issue. On serial
modbus
is a poll response protocol so RTS et al are meaningless, read
the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS
is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25293550>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub
#33 (comment).


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25313523
.

@xvart
Copy link

xvart commented Sep 29, 2013

In your client after,
"client = ModbusClient(method='rtu', port='/dev/ttyUSB0', timeout=1)"
*
insert the line,
*"client.socket.rtscts=True
"

this enables hardware handshaking, the "crtscts" parameter shown with stty.
*

*On 29/09/13 14:08, heming277 wrote:

how do i do a startup delay?..the serial client specify the paramters and
then do a client.connect(), do i put the delay between these?..

i currently do not have my test equipment with me.
but even enabling the rts/cts is not automatic flow control right, i
still
have to manually turn it on or off after sending and receiving data?

thanks

On Sat, Sep 28, 2013 at 8:12 PM, xvart notifications@github.com wrote:

Ok using the sync client test app talking to /dev/ttyUSB0 I get from
stty -F /dev/ttyUSB0 -a

speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z;
rprnt
= ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl
-ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0
bs0
vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase
-tostop
-echoprt

The -crtscts says that hardware flow control is not enabled.

You can tye running the serialclient with a start up delay after it
open
the port then doing a "stty -F /dev/ttyUSB0 crtscts", and see if that
works.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to trigger
the
direction on the RS232/RS485 converter you have then this is an
issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with
the
converter IC. Find out how your converter works first, then
patch the
send to toggle the appropriate bits and post the patch.
Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we
have and
have had no issues bot serial and tcp. If your remote end
decides it's
going to hold to 3.5 bits your going to have issues. Our current
code
base interfaces to PLC gear and works ok, I'm moving to pymodbus
as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation
master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart
notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or
windows
will
never be able to meet the requirements of the serial spec,
there
is no
debate on this, tasking is normally 10ms so meeting 3.5us
timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no
RTS,CTS
or any
other modem signalling system. If you want to send over RS485,
get an
RS485 converter and move on this is not a modbus issue. On
serial
modbus
is a poll response protocol so RTS et al are meaningless, read
the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with
buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS
is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have
automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc
here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to
delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25224214>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25293550>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25313523
.


Reply to this email directly or view it on GitHub
#33 (comment).

@ghost
Copy link
Author

ghost commented Sep 29, 2013

i did that
the question i was trying to understand is , is it automatic? like when
master sends data its rts is high, after it sends it needs to be low
immediately..
also using ansynchronous server or synchrounous server from pymodbus, how
do you set the rts? do you just do server.setRTS?
and how do you know when to set it high or low..

thanks for the help you've given me

On Sat, Sep 28, 2013 at 10:29 PM, xvart notifications@github.com wrote:

In your client after,
"client = ModbusClient(method='rtu', port='/dev/ttyUSB0', timeout=1)"
*
insert the line,
*"client.socket.rtscts=True
"

this enables hardware handshaking, the "crtscts" parameter shown with stty.
*

*On 29/09/13 14:08, heming277 wrote:

how do i do a startup delay?..the serial client specify the paramters and
then do a client.connect(), do i put the delay between these?..

i currently do not have my test equipment with me.
but even enabling the rts/cts is not automatic flow control right, i
still
have to manually turn it on or off after sending and receiving data?

thanks

On Sat, Sep 28, 2013 at 8:12 PM, xvart notifications@github.com wrote:

Ok using the sync client test app talking to /dev/ttyUSB0 I get from
stty -F /dev/ttyUSB0 -a

speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z;
rprnt
= ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl
-ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0
bs0
vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase
-tostop
-echoprt

The -crtscts says that hardware flow control is not enabled.

You can tye running the serialclient with a start up delay after it
open
the port then doing a "stty -F /dev/ttyUSB0 crtscts", and see if that
works.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to trigger
the
direction on the RS232/RS485 converter you have then this is an
issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky with
the
converter IC. Find out how your converter works first, then
patch the
send to toggle the appropriate bits and post the patch.
Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we
have and
have had no issues bot serial and tcp. If your remote end
decides it's
going to hold to 3.5 bits your going to have issues. Our current
code
base interfaces to PLC gear and works ok, I'm moving to pymodbus
as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation
master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart
notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or
windows
will
never be able to meet the requirements of the serial spec,
there
is no
debate on this, tasking is normally 10ms so meeting 3.5us
timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no
RTS,CTS
or any
other modem signalling system. If you want to send over RS485,
get an
RS485 converter and move on this is not a modbus issue. On
serial
modbus
is a poll response protocol so RTS et al are meaningless, read
the spec
it was designed for embedded systems probably bit bashing IO.

It is even probable that with a modern RS232 chip with
buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a multitasking OS
is at
the mercy of the external equipment.

see here for converters
http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have
automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc
here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to
delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

#33 (comment)

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25293550>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25313523>

.


Reply to this email directly or view it on GitHub
#33 (comment).


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25314760
.

@xvart
Copy link

xvart commented Sep 29, 2013

RTS/CTS/DTR/CD etc are old modem hardware signal control lines and
normally controlled by the RS232 IC, normally something that looks like
a 16550, on whatever your computer is. With the correct drivers you can
pull the line high but it's the IC's job to do this in the real world.
Setting the client.socket.rtscts=True (in this instance socket is a
serial object) tells serial.py to turn on hardware handshaking in the
seral IC so after that it should be automatic magic.

From what I can tell the async/sync in pymodbus has nothing to do with
the serial IO, it's about how pymodbus handles incoming packets.

Did the change work???

On 29/09/13 17:41, heming277 wrote:

i did that
the question i was trying to understand is , is it automatic? like when
master sends data its rts is high, after it sends it needs to be low
immediately..
also using ansynchronous server or synchrounous server from pymodbus, how
do you set the rts? do you just do server.setRTS?
and how do you know when to set it high or low..

thanks for the help you've given me

On Sat, Sep 28, 2013 at 10:29 PM, xvart notifications@github.com wrote:

In your client after,
"client = ModbusClient(method='rtu', port='/dev/ttyUSB0', timeout=1)"
*
insert the line,
*"client.socket.rtscts=True
"

this enables hardware handshaking, the "crtscts" parameter shown
with stty.
*

*On 29/09/13 14:08, heming277 wrote:

how do i do a startup delay?..the serial client specify the
paramters and
then do a client.connect(), do i put the delay between these?..

i currently do not have my test equipment with me.
but even enabling the rts/cts is not automatic flow control right, i
still
have to manually turn it on or off after sending and receiving data?

thanks

On Sat, Sep 28, 2013 at 8:12 PM, xvart notifications@github.com
wrote:

Ok using the sync client test app talking to /dev/ttyUSB0 I get
from
stty -F /dev/ttyUSB0 -a

speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol =
;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z;
rprnt
= ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl
-ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0
tab0
bs0
vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase
-tostop
-echoprt

The -crtscts says that hardware flow control is not enabled.

You can tye running the serialclient with a start up delay after it
open
the port then doing a "stty -F /dev/ttyUSB0 crtscts", and see if
that
works.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to
trigger
the
direction on the RS232/RS485 converter you have then this is an
issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they switch
disrection, the one shown uses DTR and RTS to do some funky
with
the
converter IC. Find out how your converter works first, then
patch the
send to toggle the appropriate bits and post the patch.
Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we
have and
have had no issues bot serial and tcp. If your remote end
decides it's
going to hold to 3.5 bits your going to have issues. Our
current
code
base interfaces to PLC gear and works ok, I'm moving to
pymodbus
as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation
master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart
notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or
windows
will
never be able to meet the requirements of the serial spec,
there
is no
debate on this, tasking is normally 10ms so meeting 3.5us
timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no
RTS,CTS
or any
other modem signalling system. If you want to send over
RS485,
get an
RS485 converter and move on this is not a modbus issue. On
serial
modbus
is a poll response protocol so RTS et al are
meaningless, read
the spec
it was designed for embedded systems probably bit
bashing IO.

It is even probable that with a modern RS232 chip with
buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a
multitasking OS
is at
the mercy of the external equipment.

see here for converters

http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have
automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc
here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to
delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

#33 (comment)

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25293550>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25313523>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25314760
.


Reply to this email directly or view it on GitHub
#33 (comment).

@bashwork bashwork reopened this Sep 29, 2013
@ghost
Copy link
Author

ghost commented Sep 30, 2013

well using the

client.socket.rtscts =True returned an error with nonetype object doesn't
not have rtscts
so i did client.socket = serial.Serial(port='/dev/ttyUSB0', rtscts=True)
and then i ran synclient.py

then i run stty -F /dev/usb0 -crstcts
doesn't return anything , the code compiles and that's it..
so i don't know if it worked or not?

like i just want to know if there's a way to turn on auto flow control on
both the master and slave side, like synchronous client and asynchronous
server.
and do i need an asynchronous client as well?

thanks

On Sun, Sep 29, 2013 at 1:52 AM, xvart notifications@github.com wrote:

RTS/CTS/DTR/CD etc are old modem hardware signal control lines and
normally controlled by the RS232 IC, normally something that looks like
a 16550, on whatever your computer is. With the correct drivers you can
pull the line high but it's the IC's job to do this in the real world.
Setting the client.socket.rtscts=True (in this instance socket is a
serial object) tells serial.py to turn on hardware handshaking in the
seral IC so after that it should be automatic magic.

From what I can tell the async/sync in pymodbus has nothing to do with
the serial IO, it's about how pymodbus handles incoming packets.

Did the change work???

On 29/09/13 17:41, heming277 wrote:

i did that
the question i was trying to understand is , is it automatic? like when
master sends data its rts is high, after it sends it needs to be low
immediately..
also using ansynchronous server or synchrounous server from pymodbus, how
do you set the rts? do you just do server.setRTS?
and how do you know when to set it high or low..

thanks for the help you've given me

On Sat, Sep 28, 2013 at 10:29 PM, xvart notifications@github.com
wrote:

In your client after,
"client = ModbusClient(method='rtu', port='/dev/ttyUSB0', timeout=1)"
*
insert the line,
*"client.socket.rtscts=True
"

this enables hardware handshaking, the "crtscts" parameter shown
with stty.
*

*On 29/09/13 14:08, heming277 wrote:

how do i do a startup delay?..the serial client specify the
paramters and
then do a client.connect(), do i put the delay between these?..

i currently do not have my test equipment with me.
but even enabling the rts/cts is not automatic flow control right, i
still
have to manually turn it on or off after sending and receiving data?

thanks

On Sat, Sep 28, 2013 at 8:12 PM, xvart notifications@github.com
wrote:

Ok using the sync client test app talking to /dev/ttyUSB0 I get
from
stty -F /dev/ttyUSB0 -a

speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol =
;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z;
rprnt
= ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl
-ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0
tab0
bs0
vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase
-tostop
-echoprt

The -crtscts says that hardware flow control is not enabled.

You can tye running the serialclient with a start up delay after it
open
the port then doing a "stty -F /dev/ttyUSB0 crtscts", and see if
that
works.

On 29/09/13 06:45, 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:

If you need to have RTS/CTS and the other modem stuff to
trigger
the
direction on the RS232/RS485 converter you have then this is an
issue
with your hardware implementation. You may want to check
http://www.rs232-to-rs485.com/ for circuits and how they
switch
disrection, the one shown uses DTR and RTS to do some funky
with
the
converter IC. Find out how your converter works first, then
patch the
send to toggle the appropriate bits and post the patch.
Unfortunately
nothing says they will all work the same.

I have used modpoll and simplymodbus to test applications we
have and
have had no issues bot serial and tcp. If your remote end
decides it's
going to hold to 3.5 bits your going to have issues. Our
current
code
base interfaces to PLC gear and works ok, I'm moving to
pymodbus
as I'm
sick of maintaining the current code written in C.

On 28/09/13 20:44, heming277 wrote:

on the other hand, why does Modpoll work, their simulation
master and
slave
runs fine over serial RS-485 ..

On Sat, Sep 28, 2013 at 12:30 AM, xvart
notifications@github.com
wrote:

Sorry but I have to dive in here,

Anyone running modbus on a multitasking OS such as linux or
windows
will
never be able to meet the requirements of the serial spec,
there
is no
debate on this, tasking is normally 10ms so meeting 3.5us
timing
requirement just doesn't fit and never will.

RS485 is balanced 2 wire coms like RS422 and there is no
RTS,CTS
or any
other modem signalling system. If you want to send over
RS485,
get an
RS485 converter and move on this is not a modbus issue. On
serial
modbus
is a poll response protocol so RTS et al are
meaningless, read
the spec
it was designed for embedded systems probably bit
bashing IO.

It is even probable that with a modern RS232 chip with
buffering
meeting
the 3.5us in the spec is not possible.

Sorry but anyone trying modbus over serial on a
multitasking OS
is at
the mercy of the external equipment.

see here for converters

http://www.usconverters.com/index.php?main_page=index&cPath=65

On 28/09/13 14:33, heming277 wrote:

Hi Galen,

what controller do people use, does the controller have
automatic
rs-485
half-duplex enable/disable flow control?

thanks

Heming

On Thu, Sep 26, 2013 at 10:43 PM, Galen Collins
notifications@github.comwrote:

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 to the following

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) # may need to delay, poll, etc
here
return self.socket.write(request)
return 0

monkey patch ModbusSerialClient._recv to the following

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())
client.socket.setRTS(false) # you shouldn't have to
delay here
return self.socket.read(size)

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.


Reply to this email directly or view it on
GitHub<

#33 (comment)

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on

GitHub<

https://github.com/bashwork/pymodbus/issues/33#issuecomment-25293550>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25313523>

.


Reply to this email directly or view it on GitHub

#33 (comment).


Reply to this email directly or view it on
GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-25314760>

.


Reply to this email directly or view it on GitHub
#33 (comment).


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25316775
.

@bashwork
Copy link
Collaborator

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:

  1. async uses the twisted framework to run a high performance event based service. This basically tries to remove all blocking operations from your code (io) and have the kernel do them for you, and let you know when they are finished. You can think of it like:

while (running):
io_events = get_io_events() # kernel code
distribute(io_events) # your non-blocking code

  1. sync uses python threads to simply do everything in one go. The problem with this is that python is really bad at threading as the whole interpreter has to stop to switch threads.

The decision to use one over the other is basically asking the following questions:

  1. Do I need high performance (say monitoring a data center for devices). If so, use the async client.
  2. Do I need to quickly script a modbus solution. If so, use the sync client.
  3. Do I need to run on a platform where twisted isn't available. If so, use the sync client/server.
  4. Do I need to run a modbus server. Ideally use the async server.

@ghost
Copy link
Author

ghost commented Sep 30, 2013

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
doesn't show anything in terminal.

does that mean it succeeded?

thanks

On Mon, Sep 30, 2013 at 1:04 PM, Galen Collins notifications@github.comwrote:

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:

  1. async uses the twisted framework to run a high performance event
    based service. This basically tries to remove all blocking operations from
    your code (io) and have the kernel do them for you, and let you know when
    they are finished. You can think of it like:

while (running):
io_events = get_io_events() # kernel code
distribute(io_events) # your non-blocking code

  1. sync uses python threads to simply do everything in one go. The
    problem with this is that python is really bad at threading as the
    whole interpreter has to stop to switch threads.

The decision to use one over the other is basically asking the following
questions:

  1. Do I need high performance (say monitoring a data center for
    devices). If so, use the async client.
  2. Do I need to quickly script a modbus solution. If so, use the sync
    client.
  3. Do I need to run on a platform where twisted isn't available. If
    so, use the sync client/server.
  4. Do I need to run a modbus server. Ideally use the async server.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25399872
.

@bashwork
Copy link
Collaborator

bashwork commented Oct 1, 2013

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):

import serial, sys

def server(socket):
    while (true):        
        ping = socket.read(4)
        print "ponging a ping"
        if ping == "pong":
            socket.write("pong")

def client(socket):
     while True:
         count = socket.write("ping")
         if count < 4:
             print "failed to ping"
             continue
         pong = socket.read(4)
         if pong == "pong": print "ping was ponged"

if __name__ == "__main__":
    socket = serial.Serial(...)
    if sys.argv[1] == "server":
        server(socket)
    else: client(socket)

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.

@xvart
Copy link

xvart commented Oct 2, 2013

The "crtscts" stands for rts cts lines, this says it is being used,
when showing as "-crtscts" it is disabled.

The printout says hardware flow control is on.

On 02/10/13 05:55, heming277 wrote:

yes it does show me the baudrate..
stty --all -F /dev/ttyS2
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z;
rprnt =
^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread clocal crtscts -cdtrdsr
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon
-ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0
vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop
-echoprt

i see this, where does this show me the status of RTS

On Tue, Oct 1, 2013 at 9:51 AM, Galen Collins
notifications@github.comwrote:

stty --all -F /dev/usb0

Should show you the current settings for the device.


Reply to this email directly or view it on
GitHubhttps://github.com//issues/33#issuecomment-25467800
.


Reply to this email directly or view it on GitHub
#33 (comment).

@ghost
Copy link
Author

ghost commented Oct 3, 2013

ok so i think i found the reason

using client.socket = serial.Serial(rtscts=True) doesn't send anything or
recive anything for some reason

i have to set RTS using client.socket.setRTS(True) and False

in the ping pong example, i used socket.setRTS(True) and
socket.setRTS(False) and it worked

the problem is. with Modbus it doesn't work

the modifications i made to Sync.py under ModbusSerialClient source code is
this

def _send(self, request):
''' Sends data on the underlying socket

    :param request: The encoded request to send
    :return: The number of bytes written
    '''
    #self.socket = serial.Serial(port='/dev/ttyS2', timeout=1,

baudrate=192
00, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_EVEN,
bytesize=serial.EI
GHTBITS) (Not sure if i need this line or not, seems to be no
help, it also resets baudrate and everything to be what's declared here)
if not self.socket:
raise ConnectionException(self.str())

    if request:
       self.socket.setRTS(True)
       return self.socket.write(request)
       time.sleep(0.0025)
       self.socket.setRTS(False)
    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)
    return self.socket.read(size)

and the modification i made to the server's Sync.py the
SingleRequestHandler codes are below

def send(self, message):
''' Send a request (string) to the network

    :param message: The unencoded modbus response
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
if message.should_respond:
#self.server.control.Counter.BusMessage += 1
pdu = self.framer.buildPacket(message)
if _logger.isEnabledFor(logging.DEBUG):
_logger.debug('send: %s' % b2a_hex(pdu))
self.socket.setRTS(True)
return self.request.send(pdu)
time.sleep(0.0025)
self.socket.setRTS(False)

and i made modification to Asyn Server's UDP server's execute method, not
sure if UDP server is used for serial

def _execute(self, request, addr):
''' Executes the request and returns the result

    :param request: The decoded request message
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
try:
context = self.store[request.unit_id]
response = request.execute(context)
except Exception, ex:
_logger.debug("Datastore unable to fulfill request: %s" % ex)
response = request.doException(merror.SlaveFailure)
#self.framer.populateResult(response)
response.transaction_id = request.transaction_id
response.unit_id = request.unit_id
self.socket.setRTS(True)
self._send(response, addr)
time.sleep(0.0025)
self.socket.setRTS(False)

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:

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:

  1. async uses the twisted framework to run a high performance event
    based service. This basically tries to remove all blocking operations from
    your code (io) and have the kernel do them for you, and let you know when
    they are finished. You can think of it like:

while (running):
io_events = get_io_events() # kernel code
distribute(io_events) # your non-blocking code

  1. sync uses python threads to simply do everything in one go. The
    problem with this is that python is really bad at threading as the
    whole interpreter has to stop to switch threads.

The decision to use one over the other is basically asking the following
questions:

  1. Do I need high performance (say monitoring a data center for
    devices). If so, use the async client.
  2. Do I need to quickly script a modbus solution. If so, use the sync
    client.
  3. Do I need to run on a platform where twisted isn't available. If
    so, use the sync client/server.
  4. Do I need to run a modbus server. Ideally use the async server.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25399872
.

@ghost
Copy link
Author

ghost commented Oct 3, 2013

the error it gives me right now is that it is still getting None
same errors as before..

On Wed, Oct 2, 2013 at 5:55 PM, Heming Liu hemingliu123@gmail.com wrote:

ok so i think i found the reason

using client.socket = serial.Serial(rtscts=True) doesn't send anything or
recive anything for some reason

i have to set RTS using client.socket.setRTS(True) and False

in the ping pong example, i used socket.setRTS(True) and
socket.setRTS(False) and it worked

the problem is. with Modbus it doesn't work

the modifications i made to Sync.py under ModbusSerialClient source code
is this

def _send(self, request):
''' Sends data on the underlying socket

    :param request: The encoded request to send
    :return: The number of bytes written
    '''
    #self.socket = serial.Serial(port='/dev/ttyS2', timeout=1,

baudrate=192
00, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_EVEN,
bytesize=serial.EI
GHTBITS) (Not sure if i need this line or not, seems to be no
help, it also resets baudrate and everything to be what's declared here)

    if not self.socket:
        raise ConnectionException(self.__str__())

    if request:
       self.socket.setRTS(True)
       return self.socket.write(request)
       time.sleep(0.0025)
       self.socket.setRTS(False)
    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)
    return self.socket.read(size)

and the modification i made to the server's Sync.py the
SingleRequestHandler codes are below

def send(self, message):
''' Send a request (string) to the network

    :param message: The unencoded modbus response
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
if message.should_respond:
#self.server.control.Counter.BusMessage += 1
pdu = self.framer.buildPacket(message)
if _logger.isEnabledFor(logging.DEBUG):
_logger.debug('send: %s' % b2a_hex(pdu))
self.socket.setRTS(True)
return self.request.send(pdu)
time.sleep(0.0025)
self.socket.setRTS(False)

and i made modification to Asyn Server's UDP server's execute method, not
sure if UDP server is used for serial

def _execute(self, request, addr):
''' Executes the request and returns the result

    :param request: The decoded request message
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
try:
context = self.store[request.unit_id]
response = request.execute(context)
except Exception, ex:
_logger.debug("Datastore unable to fulfill request: %s" % ex)
response = request.doException(merror.SlaveFailure)
#self.framer.populateResult(response)
response.transaction_id = request.transaction_id
response.unit_id = request.unit_id
self.socket.setRTS(True)
self._send(response, addr)
time.sleep(0.0025)
self.socket.setRTS(False)

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:

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:

  1. async uses the twisted framework to run a high performance event
    based service. This basically tries to remove all blocking operations from
    your code (io) and have the kernel do them for you, and let you know when
    they are finished. You can think of it like:

while (running):
io_events = get_io_events() # kernel code
distribute(io_events) # your non-blocking code

  1. sync uses python threads to simply do everything in one go. The
    problem with this is that python is really bad at threading as the
    whole interpreter has to stop to switch threads.

The decision to use one over the other is basically asking the following
questions:

  1. Do I need high performance (say monitoring a data center for
    devices). If so, use the async client.
  2. Do I need to quickly script a modbus solution. If so, use the sync
    client.
  3. Do I need to run on a platform where twisted isn't available. If
    so, use the sync client/server.
  4. Do I need to run a modbus server. Ideally use the async server.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25399872
.

@ghost
Copy link
Author

ghost commented Oct 3, 2013

here's my master code from ping pong code.
import serial, sys, time

def server(socket):
while True:
ping = socket.read(4)
print "ponging a ping"
if ping == "ping":
socket.write("pong")

def client(socket):
while True:
socket.setRTS(True)
count = socket.write("ping")
if count < 4:
print "failed to ping"
continue
time.sleep(0.0025)
socket.setRTS(False)
pong = socket.read(4)
if pong == "pong": print "ping was ponged"
if name == "main":
socket = serial.Serial(port='/dev/ttyS2', baudrate=19200, timeout=1,
parit
y=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
if sys.argv[1] == "server":
server(socket)
else: client(socket)

and my slave code from ping pong

import serial, sys, time

def server(socket):
while (True):
socket.setRTS(False)
ping = socket.read(4)
print ping
print "ponging a ping"
if ping == "ping":
socket.setRTS(True)
socket.write("pong")
time.sleep(0.0025)

def client(socket):
while (True):
count = socket.write("ping")
if count < 4:
print "failed to ping"
continue
pong = socket.read(4)
if pong == "pong": print "ping was ponged"
if name == "main":
socket = serial.Serial(port='/dev/ttyS2', baudrate=19200, timeout=1,
stopbi
ts=serial.STOPBITS_ONE, parity=serial.PARITY_EVEN,
bytesize=serial.EIGHTBITS)
if sys.argv[1] == "server":
server(socket)
else: 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:

ok so i think i found the reason

using client.socket = serial.Serial(rtscts=True) doesn't send anything or
recive anything for some reason

i have to set RTS using client.socket.setRTS(True) and False

in the ping pong example, i used socket.setRTS(True) and
socket.setRTS(False) and it worked

the problem is. with Modbus it doesn't work

the modifications i made to Sync.py under ModbusSerialClient source code
is this

def _send(self, request):
''' Sends data on the underlying socket

    :param request: The encoded request to send
    :return: The number of bytes written
    '''
    #self.socket = serial.Serial(port='/dev/ttyS2', timeout=1,

baudrate=192
00, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_EVEN,
bytesize=serial.EI
GHTBITS) (Not sure if i need this line or not, seems to be no
help, it also resets baudrate and everything to be what's declared here)

    if not self.socket:
        raise ConnectionException(self.__str__())

    if request:
       self.socket.setRTS(True)
       return self.socket.write(request)
       time.sleep(0.0025)
       self.socket.setRTS(False)
    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)
    return self.socket.read(size)

and the modification i made to the server's Sync.py the
SingleRequestHandler codes are below

def send(self, message):
''' Send a request (string) to the network

    :param message: The unencoded modbus response
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
if message.should_respond:
#self.server.control.Counter.BusMessage += 1
pdu = self.framer.buildPacket(message)
if _logger.isEnabledFor(logging.DEBUG):
_logger.debug('send: %s' % b2a_hex(pdu))
self.socket.setRTS(True)
return self.request.send(pdu)
time.sleep(0.0025)
self.socket.setRTS(False)

and i made modification to Asyn Server's UDP server's execute method, not
sure if UDP server is used for serial

def _execute(self, request, addr):
''' Executes the request and returns the result

    :param request: The decoded request message
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
try:
context = self.store[request.unit_id]
response = request.execute(context)
except Exception, ex:
_logger.debug("Datastore unable to fulfill request: %s" % ex)
response = request.doException(merror.SlaveFailure)
#self.framer.populateResult(response)
response.transaction_id = request.transaction_id
response.unit_id = request.unit_id
self.socket.setRTS(True)
self._send(response, addr)
time.sleep(0.0025)
self.socket.setRTS(False)

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:

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:

  1. async uses the twisted framework to run a high performance event
    based service. This basically tries to remove all blocking operations from
    your code (io) and have the kernel do them for you, and let you know when
    they are finished. You can think of it like:

while (running):
io_events = get_io_events() # kernel code
distribute(io_events) # your non-blocking code

  1. sync uses python threads to simply do everything in one go. The
    problem with this is that python is really bad at threading as the
    whole interpreter has to stop to switch threads.

The decision to use one over the other is basically asking the following
questions:

  1. Do I need high performance (say monitoring a data center for
    devices). If so, use the async client.
  2. Do I need to quickly script a modbus solution. If so, use the sync
    client.
  3. Do I need to run on a platform where twisted isn't available. If
    so, use the sync client/server.
  4. Do I need to run a modbus server. Ideally use the async server.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25399872
.

@ghost
Copy link
Author

ghost commented Oct 7, 2013

anyone knows what i'm doing wrong?
..
thanks

On Thu, Oct 3, 2013 at 11:34 AM, Heming Liu hemingliu123@gmail.com wrote:

here's my master code from ping pong code.
import serial, sys, time

def server(socket):
while True:

    ping = socket.read(4)
    print "ponging a ping"
    if ping == "ping":

        socket.write("pong")

def client(socket):
while True:
socket.setRTS(True)

    count = socket.write("ping")
    if count < 4:
        print "failed to ping"
        continue
    time.sleep(0.0025)
    socket.setRTS(False)

    pong = socket.read(4)
    if pong == "pong": print "ping was ponged"

if name == "main":
socket = serial.Serial(port='/dev/ttyS2', baudrate=19200, timeout=1,
parit
y=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)

if sys.argv[1] == "server":
    server(socket)
else: client(socket)

and my slave code from ping pong

import serial, sys, time

def server(socket):
while (True):
socket.setRTS(False)
ping = socket.read(4)
print ping
print "ponging a ping"
if ping == "ping":
socket.setRTS(True)
socket.write("pong")
time.sleep(0.0025)

def client(socket):
while (True):

    count = socket.write("ping")
    if count < 4:
        print "failed to ping"
        continue
    pong = socket.read(4)
    if pong == "pong": print "ping was ponged"

if name == "main":
socket = serial.Serial(port='/dev/ttyS2', baudrate=19200, timeout=1,
stopbi
ts=serial.STOPBITS_ONE, parity=serial.PARITY_EVEN,
bytesize=serial.EIGHTBITS)

if sys.argv[1] == "server":
    server(socket)
else: 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:

ok so i think i found the reason

using client.socket = serial.Serial(rtscts=True) doesn't send anything or
recive anything for some reason

i have to set RTS using client.socket.setRTS(True) and False

in the ping pong example, i used socket.setRTS(True) and
socket.setRTS(False) and it worked

the problem is. with Modbus it doesn't work

the modifications i made to Sync.py under ModbusSerialClient source code
is this

def _send(self, request):
''' Sends data on the underlying socket

    :param request: The encoded request to send
    :return: The number of bytes written
    '''
     #self.socket = serial.Serial(port='/dev/ttyS2', timeout=1,

baudrate=192
00, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_EVEN,
bytesize=serial.EI
GHTBITS) (Not sure if i need this line or not, seems to be
no help, it also resets baudrate and everything to be what's declared here)

    if not self.socket:
        raise ConnectionException(self.__str__())

    if request:
       self.socket.setRTS(True)
       return self.socket.write(request)
       time.sleep(0.0025)
       self.socket.setRTS(False)
    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)
    return self.socket.read(size)

and the modification i made to the server's Sync.py the
SingleRequestHandler codes are below

def send(self, message):
''' Send a request (string) to the network

    :param message: The unencoded modbus response
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
if message.should_respond:
#self.server.control.Counter.BusMessage += 1
pdu = self.framer.buildPacket(message)
if _logger.isEnabledFor(logging.DEBUG):
_logger.debug('send: %s' % b2a_hex(pdu))
self.socket.setRTS(True)
return self.request.send(pdu)
time.sleep(0.0025)
self.socket.setRTS(False)

and i made modification to Asyn Server's UDP server's execute method, not
sure if UDP server is used for serial

def _execute(self, request, addr):
''' Executes the request and returns the result

    :param request: The decoded request message
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
try:
context = self.store[request.unit_id]
response = request.execute(context)
except Exception, ex:
_logger.debug("Datastore unable to fulfill request: %s" % ex)
response = request.doException(merror.SlaveFailure)
#self.framer.populateResult(response)
response.transaction_id = request.transaction_id
response.unit_id = request.unit_id
self.socket.setRTS(True)
self._send(response, addr)
time.sleep(0.0025)
self.socket.setRTS(False)

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:

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:

  1. async uses the twisted framework to run a high performance event
    based service. This basically tries to remove all blocking operations from
    your code (io) and have the kernel do them for you, and let you know when
    they are finished. You can think of it like:

while (running):
io_events = get_io_events() # kernel code
distribute(io_events) # your non-blocking code

  1. sync uses python threads to simply do everything in one go. The
    problem with this is that python is really bad at threading as the
    whole interpreter has to stop to switch threads.

The decision to use one over the other is basically asking the following
questions:

  1. Do I need high performance (say monitoring a data center for
    devices). If so, use the async client.
  2. Do I need to quickly script a modbus solution. If so, use the
    sync client.
  3. Do I need to run on a platform where twisted isn't available. If
    so, use the sync client/server.
  4. Do I need to run a modbus server. Ideally use the async server.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25399872
.

@ghost
Copy link
Author

ghost commented Oct 9, 2013

please help! any suggestion is helpful!

thanks

On Mon, Oct 7, 2013 at 12:47 AM, Heming Liu hemingliu123@gmail.com wrote:

anyone knows what i'm doing wrong?
..
thanks

On Thu, Oct 3, 2013 at 11:34 AM, Heming Liu hemingliu123@gmail.comwrote:

here's my master code from ping pong code.
import serial, sys, time

def server(socket):
while True:

    ping = socket.read(4)
    print "ponging a ping"
    if ping == "ping":

        socket.write("pong")

def client(socket):
while True:
socket.setRTS(True)

    count = socket.write("ping")
    if count < 4:
        print "failed to ping"
        continue
    time.sleep(0.0025)
    socket.setRTS(False)

    pong = socket.read(4)
    if pong == "pong": print "ping was ponged"

if name == "main":
socket = serial.Serial(port='/dev/ttyS2', baudrate=19200, timeout=1,
parit
y=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)

if sys.argv[1] == "server":
    server(socket)
else: client(socket)

and my slave code from ping pong

import serial, sys, time

def server(socket):
while (True):
socket.setRTS(False)
ping = socket.read(4)
print ping
print "ponging a ping"
if ping == "ping":
socket.setRTS(True)
socket.write("pong")
time.sleep(0.0025)

def client(socket):
while (True):

    count = socket.write("ping")
    if count < 4:
        print "failed to ping"
        continue
    pong = socket.read(4)
    if pong == "pong": print "ping was ponged"

if name == "main":
socket = serial.Serial(port='/dev/ttyS2', baudrate=19200, timeout=1,
stopbi
ts=serial.STOPBITS_ONE, parity=serial.PARITY_EVEN,
bytesize=serial.EIGHTBITS)

if sys.argv[1] == "server":
    server(socket)
else: 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.comwrote:

ok so i think i found the reason

using client.socket = serial.Serial(rtscts=True) doesn't send anything
or recive anything for some reason

i have to set RTS using client.socket.setRTS(True) and False

in the ping pong example, i used socket.setRTS(True) and
socket.setRTS(False) and it worked

the problem is. with Modbus it doesn't work

the modifications i made to Sync.py under ModbusSerialClient source code
is this

def _send(self, request):
''' Sends data on the underlying socket

    :param request: The encoded request to send
    :return: The number of bytes written
    '''
     #self.socket = serial.Serial(port='/dev/ttyS2', timeout=1,

baudrate=192
00, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_EVEN,
bytesize=serial.EI
GHTBITS) (Not sure if i need this line or not, seems to be
no help, it also resets baudrate and everything to be what's declared here)

    if not self.socket:
        raise ConnectionException(self.__str__())

    if request:
       self.socket.setRTS(True)
       return self.socket.write(request)
       time.sleep(0.0025)
       self.socket.setRTS(False)
    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)
    return self.socket.read(size)

and the modification i made to the server's Sync.py the
SingleRequestHandler codes are below

def send(self, message):
''' Send a request (string) to the network

    :param message: The unencoded modbus response
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
if message.should_respond:
#self.server.control.Counter.BusMessage += 1
pdu = self.framer.buildPacket(message)
if _logger.isEnabledFor(logging.DEBUG):
_logger.debug('send: %s' % b2a_hex(pdu))
self.socket.setRTS(True)
return self.request.send(pdu)
time.sleep(0.0025)
self.socket.setRTS(False)

and i made modification to Asyn Server's UDP server's execute method,
not sure if UDP server is used for serial

def _execute(self, request, addr):
''' Executes the request and returns the result

    :param request: The decoded request message
    '''
    self.socket = serial.Serial(port='/dev/ttyS2', baudrate=19200,

timeout=
1, parity=serial.PARITY_EVEN, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIG
HTBITS)
try:
context = self.store[request.unit_id]
response = request.execute(context)
except Exception, ex:
_logger.debug("Datastore unable to fulfill request: %s" % ex)
response = request.doException(merror.SlaveFailure)
#self.framer.populateResult(response)
response.transaction_id = request.transaction_id
response.unit_id = request.unit_id
self.socket.setRTS(True)
self._send(response, addr)
time.sleep(0.0025)
self.socket.setRTS(False)

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.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:

  1. async uses the twisted framework to run a high performance event
    based service. This basically tries to remove all blocking operations from
    your code (io) and have the kernel do them for you, and let you know when
    they are finished. You can think of it like:

while (running):
io_events = get_io_events() # kernel code
distribute(io_events) # your non-blocking code

  1. sync uses python threads to simply do everything in one go. The
    problem with this is that python is really bad at threading as
    the whole interpreter has to stop to switch threads.

The decision to use one over the other is basically asking the
following questions:

  1. Do I need high performance (say monitoring a data center for
    devices). If so, use the async client.
  2. Do I need to quickly script a modbus solution. If so, use the
    sync client.
  3. Do I need to run on a platform where twisted isn't available. If
    so, use the sync client/server.
  4. Do I need to run a modbus server. Ideally use the async server.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-25399872
.

@bashwork
Copy link
Collaborator

bashwork commented Oct 9, 2013

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.

@ghost
Copy link
Author

ghost commented Oct 9, 2013

yes i did modify the code for it to work.
if you look at the code i sent u before.
if i just to client.socket = serial.Serial( rtscts=True....)
this doesn't work
whereas if i do
socket.setRTS(True)
it works..
doesn't make any sense.

On Wed, Oct 9, 2013 at 3:05 PM, Galen Collins notifications@github.comwrote:

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.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-26013128
.

@ghost
Copy link
Author

ghost commented Oct 15, 2013

is there any advancement regarding this issue?

thanks

heming

On Wed, Oct 9, 2013 at 3:05 PM, Galen Collins notifications@github.comwrote:

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.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-26013128
.

@ghost
Copy link
Author

ghost commented Oct 23, 2013

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:

is there any advancement regarding this issue?

thanks

heming

On Wed, Oct 9, 2013 at 3:05 PM, Galen Collins notifications@github.comwrote:

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.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-26013128
.

@bashwork
Copy link
Collaborator

What is the modpoll command that works correctly?

@ghost
Copy link
Author

ghost commented Oct 28, 2013

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
previous replies

thank you very much for any help

On Fri, Oct 25, 2013 at 11:06 PM, Galen Collins notifications@github.comwrote:

What is the modpoll command that works correctly?


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-27140334
.

@bashwork
Copy link
Collaborator

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 serial.Serial( rtscts=True....), that was trying to enable automatic RTS handling by your driver (which it apparently doesn't support) while, socket.setRTS(True) is actually just forcing the line high. What you are going to have to do is have a simple wrapper around the serial client that will controll the RTS line for you. Something like::

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!

@ghost
Copy link
Author

ghost commented Oct 28, 2013

Hi Galen,

i did do what u suggested in the client's source code, under modbus serial
client,
but i could not find send and recv from the server side source code!

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.
like synclient.py and syncserver.py
thanks

On Mon, Oct 28, 2013 at 1:44 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 serial.Serial(
rtscts=True....), that was trying to enable automatic RTS handling by
your driver (which it apparently doesn't support) while,
socket.setRTS(True) is actually just forcing the line high. What you are
going to have to do is have a simple wrapper around the serial client that
will controll the RTS line for you. Something like::

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!


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-27254472
.

@bashwork
Copy link
Collaborator

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

@ghost
Copy link
Author

ghost commented Oct 30, 2013

so if i understand correctly i should add this class into the sync.py in
both master and slave sync.py?

thanks

Heming

On Tue, Oct 29, 2013 at 4:11 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


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-27352576
.

@bashwork
Copy link
Collaborator

No, you can overload classes in your own code. If you want to modify the
source that is fine, bit it is harder for me to know how to help you when
problems arise if I can't see your whole code base. If you can send me a
single file with your subclassing it is much easier for me to help.

So just add those two blocks to the top of your library along with the
necessary imports.
On Oct 29, 2013 5:12 PM, "heming277" notifications@github.com wrote:

so if i understand correctly i should add this class into the sync.py in
both master and slave sync.py?

thanks

Heming

On Tue, Oct 29, 2013 at 4:11 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


Reply to this email directly or view it on GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-27352576>
.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-27355550
.

@ghost
Copy link
Author

ghost commented Oct 30, 2013

ok so it still doesn't work.
i have my codes below. would you kindly check if i did anything wrong?
thanks very much
i've noticed that when using sync client it can only work with async
server? but async.py in the library code doesn't have ModbusSerialClient.
does Sync server work with sync client?

here's my client code:
#!/usr/bin/python2.4
#from pymodbus.client.sync import ModbusTcpClient as ModbusClient
#from pymodbus.client.sync import ModbusUdpClient as ModbusClient
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
from pymodbus.client.sync import ModbusSerialClient
import serial,time

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)
        time.sleep(0.0022)
        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)
    return result

#---------------------------------------------------------------------------#

configure the client logging

#---------------------------------------------------------------------------#
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

#client = ModbusClient('localhost', port=502)
#client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1)
client = ModbusClient(method='rtu', retry_on_empty=True, retries=10,
port='/dev
/ttyS2', timeout=1, bytesize=8, baudrate=19200, stopbits=1, parity='E')
#client.socket = serial.Serial(port='/dev/ttyS2')
#client.socket.setRTS(True)
client.connect()

#dw = client.write_coil(1, True)
#dr = client.read_coils(1,1)
#assert(dw.function_code < 0x80)
#assert(dr.bits[0] == True)

rq = client.write_register(1, 10, unit = 1)
rr = client.read_holding_registers(1, count = 1, unit = 1)
print rr.registers[0]
assert(rq.function_code < 0x80) # test that we are not an error
assert(rr.registers[0] == 10) # test the expected value

#---------------------------------------------------------------------------#

close the client

#---------------------------------------------------------------------------#
client.close()

And my Server code:

      #!/usr/bin/python2.4

'''

#from pymodbus.server.async import StartTcpServer
#from pymodbus.server.async import StartUdpServer
from pymodbus.server.sync import StartSerialServer
from pymodbus.server.sync import ModbusSerialServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer
import serial,time

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)
        time.sleep(0.0022)
        self.socket.setRTS(False)
        return result

    def rts_recv(count):
        self.socket.setRTS(False)
        result = self.socket.read(count)
        return result

    request = self.socket
    request.send = rts_send
    request.recv = rts_recv
    handler = ModbusSingleRequestHandler(request,
        (self.device, self.device), self)
    return handler

#---------------------------------------------------------------------------#

configure the service logging

#---------------------------------------------------------------------------#
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

slaves = {
1: ModbusSlaveContext(
di = ModbusSequentialDataBlock(1, [17,18,19,20,21,22])),
2: ModbusSlaveContext(
dd = ModbusSequentialDataBlock(1, [17]*100)),
}

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()
identity.VendorName = 'Pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
identity.ProductName = 'Pymodbus Server'
identity.ModelName = 'Pymodbus Server'
identity.MajorMinorRevision = '1.0'

#---------------------------------------------------------------------------#

run the server you want

#---------------------------------------------------------------------------#
#server = ModbusServer(context,identity=identity, port='/dev/ttyS2',
timeout=1,
#bytesize=8, baudrate=9600, stopbits=1, parity='E')
#StartTcpServer(context, identity=identity, address=("localhost", 5020))
#StartUdpServer(context, identity=identity, address=("localhost", 502))
StartSerialServer(context, identity=identity, port='/dev/ttyS2', timeout=1,
byt
esize=8, baudrate=19200, stopbits=1, parity='E')
#StartSerialServer(context, identity=identity, port='/dev/pts/3',
framer=Modbus
AsciiFramer)

the output after i ran the server and client is :
python synclient.py
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:getting transaction 1
DEBUG:pymodbus.transaction:Running transaction 2
DEBUG:pymodbus.transaction:getting transaction 2
Traceback (most recent call last):
File "synclient.py", line 73, in ?
print rr.registers[0]
AttributeError: 'NoneType' object has no attribute 'registers

On Tue, Oct 29, 2013 at 5:30 PM, Galen Collins notifications@github.comwrote:

No, you can overload classes in your own code. If you want to modify the
source that is fine, bit it is harder for me to know how to help you when
problems arise if I can't see your whole code base. If you can send me a
single file with your subclassing it is much easier for me to help.

So just add those two blocks to the top of your library along with the
necessary imports.
On Oct 29, 2013 5:12 PM, "heming277" notifications@github.com wrote:

so if i understand correctly i should add this class into the sync.py in
both master and slave sync.py?

thanks

Heming

On Tue, Oct 29, 2013 at 4:11 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


Reply to this email directly or view it on GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-27352576>
.


Reply to this email directly or view it on GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-27355550>
.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-27356341
.

@ghost
Copy link
Author

ghost commented Nov 8, 2013

sorry i need to ask again,

if Modpoll works without any converters, how come my code using pymodbus
doesn't work?

is it because it is synchronous and not asynchronous?
or is there a bug in my code?

thanks ..

On Wed, Oct 30, 2013 at 1:35 PM, Heming Liu hemingliu123@gmail.com wrote:

ok so it still doesn't work.
i have my codes below. would you kindly check if i did anything wrong?
thanks very much
i've noticed that when using sync client it can only work with async
server? but async.py in the library code doesn't have ModbusSerialClient.
does Sync server work with sync client?

here's my client code:
#!/usr/bin/python2.4

#from pymodbus.client.sync import ModbusTcpClient as ModbusClient
#from pymodbus.client.sync import ModbusUdpClient as ModbusClient
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
from pymodbus.client.sync import ModbusSerialClient
import serial,time

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)
        time.sleep(0.0022)

        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)
    return result

#---------------------------------------------------------------------------#

configure the client logging

#---------------------------------------------------------------------------#
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

#client = ModbusClient('localhost', port=502)
#client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1)
client = ModbusClient(method='rtu', retry_on_empty=True, retries=10,
port='/dev
/ttyS2', timeout=1, bytesize=8, baudrate=19200, stopbits=1, parity='E')
#client.socket = serial.Serial(port='/dev/ttyS2')
#client.socket.setRTS(True)
client.connect()

#dw = client.write_coil(1, True)
#dr = client.read_coils(1,1)
#assert(dw.function_code < 0x80)
#assert(dr.bits[0] == True)

rq = client.write_register(1, 10, unit = 1)
rr = client.read_holding_registers(1, count = 1, unit = 1)
print rr.registers[0]

assert(rq.function_code < 0x80) # test that we are not an error
assert(rr.registers[0] == 10) # test the expected value

#---------------------------------------------------------------------------#

close the client

#---------------------------------------------------------------------------#
client.close()

And my Server code:

      #!/usr/bin/python2.4

'''

#from pymodbus.server.async import StartTcpServer
#from pymodbus.server.async import StartUdpServer

from pymodbus.server.sync import StartSerialServer
from pymodbus.server.sync import ModbusSerialServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer
import serial,time

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)
        time.sleep(0.0022)

        self.socket.setRTS(False)
        return result

    def rts_recv(count):
        self.socket.setRTS(False)
        result = self.socket.read(count)
        return result

    request = self.socket
    request.send = rts_send
    request.recv = rts_recv
    handler = ModbusSingleRequestHandler(request,
        (self.device, self.device), self)
    return handler

#---------------------------------------------------------------------------#

configure the service logging

#---------------------------------------------------------------------------#
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

slaves = {

1:   ModbusSlaveContext(
        di = ModbusSequentialDataBlock(1, [17,18,19,20,21,22])),
2:   ModbusSlaveContext(
        dd = ModbusSequentialDataBlock(1, [17]*100)),

}

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()
identity.VendorName = 'Pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
identity.ProductName = 'Pymodbus Server'
identity.ModelName = 'Pymodbus Server'
identity.MajorMinorRevision = '1.0'

#---------------------------------------------------------------------------#

run the server you want

#---------------------------------------------------------------------------#
#server = ModbusServer(context,identity=identity, port='/dev/ttyS2',
timeout=1,
#bytesize=8, baudrate=9600, stopbits=1, parity='E')

#StartTcpServer(context, identity=identity, address=("localhost", 5020))
#StartUdpServer(context, identity=identity, address=("localhost", 502))
StartSerialServer(context, identity=identity, port='/dev/ttyS2',
timeout=1, byt
esize=8, baudrate=19200, stopbits=1, parity='E')

#StartSerialServer(context, identity=identity, port='/dev/pts/3',
framer=Modbus
AsciiFramer)

the output after i ran the server and client is :

python synclient.py
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:getting transaction 1
DEBUG:pymodbus.transaction:Running transaction 2
DEBUG:pymodbus.transaction:getting transaction 2

Traceback (most recent call last):
File "synclient.py", line 73, in ?
print rr.registers[0]
AttributeError: 'NoneType' object has no attribute 'registers

On Tue, Oct 29, 2013 at 5:30 PM, Galen Collins notifications@github.comwrote:

No, you can overload classes in your own code. If you want to modify the
source that is fine, bit it is harder for me to know how to help you when
problems arise if I can't see your whole code base. If you can send me a
single file with your subclassing it is much easier for me to help.

So just add those two blocks to the top of your library along with the
necessary imports.
On Oct 29, 2013 5:12 PM, "heming277" notifications@github.com wrote:

so if i understand correctly i should add this class into the sync.py
in
both master and slave sync.py?

thanks

Heming

On Tue, Oct 29, 2013 at 4:11 PM, Galen Collins <
notifications@github.com>wrote:

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


Reply to this email directly or view it on GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-27352576>
.


Reply to this email directly or view it on GitHub<
https://github.com/bashwork/pymodbus/issues/33#issuecomment-27355550>
.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-27356341
.

@bashwork
Copy link
Collaborator

bashwork commented Nov 8, 2013

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.

@ghost
Copy link
Author

ghost commented Nov 8, 2013

but does my code look correct?

thanks

On Thu, Nov 7, 2013 at 11:34 PM, Galen Collins notifications@github.comwrote:

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.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-28042549
.

@bashwork
Copy link
Collaborator

bashwork commented Nov 8, 2013

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.

@ghost
Copy link
Author

ghost commented Nov 11, 2013

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:

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.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-28107935
.

@ghost
Copy link
Author

ghost commented Nov 12, 2013

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:

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:

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.


Reply to this email directly or view it on GitHubhttps://github.com//issues/33#issuecomment-28107935
.

@dhoomakethu
Copy link
Contributor

closing stale issue

@mjm987
Copy link

mjm987 commented Oct 9, 2021

I know this is is old thread but following works for me like a charm by ..
a) overloading ModbusSerialClient and
b) calculate the correct RTS delay time

class MyModbusSerialClient(ModbusSerialClient):
  def __init__(self, **args):
    super(MyModbusSerialClient, self).__init__(**args)

  def _send(self, request):
    if not self.socket:
        raise ConnectionException(self.__str__())
    if request:
        print("in _send")
        txtime = (len(request)+1) * (10.0 / self.baudrate)
        self.socket.setRTS(False)
        time.sleep(0.001)
        rc = self.socket.write(request)
        time.sleep(txtime)
        self.socket.setRTS(True)
        return rc
    return 0

client = MyModbusSerialClient(method='rtu', port='/dev/ttyUSB0', baudrate=4800)
...

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants