Modbus-tk on Linux ?

1,662 views
Skip to first unread message

achiosso

unread,
Feb 6, 2013, 5:28:55 AM2/6/13
to modb...@googlegroups.com
Hi people.
One question .... Is there any way to port modbus-tk working on a Linux PC ?

Regards

Alessandro Chiosso

Luc JEAN

unread,
Feb 6, 2013, 5:33:17 AM2/6/13
to modb...@googlegroups.com
Hello Allessandro,
modbus_tk should run on every platform with Python. I've used modbus-tk on a Ubuntu machine without any problem.
Best
luc

2013/2/6 achiosso <achi...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "modbus-tk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modbus-tk+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

achiosso

unread,
Feb 6, 2013, 5:51:37 AM2/6/13
to modb...@googlegroups.com
Hello Luc,
I'm happy to read you.
I'm not so familiar with Linux so please how can I install the modbus-tk on Linux (Ubuntu 8.04 at the moment) pc?

Thanks

Alessandro

Luc JEAN

unread,
Feb 6, 2013, 5:54:38 AM2/6/13
to modb...@googlegroups.com
Not very different from Windows. Download the project and run setup.py install. Then run your script. It should work "out of the box".

achiosso

unread,
Feb 6, 2013, 6:02:55 AM2/6/13
to modb...@googlegroups.com
I will try .

Thanks a lot.

Alessandro

achiosso

unread,
Feb 19, 2013, 9:08:15 AM2/19/13
to modb...@googlegroups.com

Hello Luc,
I have some problems during the installation under Ubuntu 8.04 and Python 2.5.
I downloaded the package and ran setup.py script but at first I have a message that no setuptools module is not installed.
So I downloaded setuptools from here and installed it as per instructions.
I ran the setup.py script again but I got another message as the image above.
I'm new about linux so please can you give me some advice an this issue ?

Thanks

Alessandro

Luc JEAN

unread,
Feb 19, 2013, 9:25:05 AM2/19/13
to modb...@googlegroups.com
Hello Alessandro,

Did you run the following command : python setup.py install

Best
luc

2013/2/19 achiosso <achi...@gmail.com>

achiosso

unread,
Feb 19, 2013, 9:37:52 AM2/19/13
to modb...@googlegroups.com
Hi Luc,
thank you so much for the quick reply.
I did as you suggested and seems to be ok.
I opened the python interpreter and the modbus_tk module is present.
So now I will go forward and see.
I think you did a great job on this project.
Thank you for share this .

Regards

Alessandro

Luc JEAN

unread,
Mar 25, 2013, 4:41:08 AM3/25/13
to modb...@googlegroups.com
Hello Denis,

It is difficult to answer. I would say that there is a communication issue. Did you try to compare the way your are opening the port with what is done by pymodbus?

I hope it helps
luc


2013/3/25 Denis Štogl <denis...@gmail.com>
Hello,

I'm writing in this thema because I have a problem with modbus-tk lib on linux. So I have the same program to communicate with motor controllers that I'm using on window machne and it working good. But since we want to transfer everything on linux machine i found a problem.

As i said program is working good on Windows XP, but on debian 6 it does not. The error traceback is:

Traceback (most recent call last):
  File "modbus_test.py", line 17, in <module>
    first_motor_comm.enable_motor()
  File "/home/dagor/workspace/modbus_test_ziherica/modbus_communication.py", line 111, in enable_motor
    self.protocol.write_registers(self.address, MotorCommunication.DGTINSET.register_number, [1])
  File "/home/dagor/workspace/modbus_test_ziherica/modbus_communication.py", line 58, in write_registers
    self.master.execute(motor_address, cst.WRITE_MULTIPLE_REGISTERS, start_registar, output_value=data)
  File "build/bdist.linux-i686/egg/modbus_tk/utils.py", line 26, in new
modbus_tk.modbus.ModbusInvalidResponseError: Response length is invalid 0

Both operating systems are on the same phisical computer with pyhon2.7.3 and modbus-tk-0.4.2. I don't think that problem is with controllers or hardware because it's working with pymodbus library which also use pyserial. If you want to see code you can find it here: http://marvin.kset.org/~denis/code/

I like your library a lot and would really like to use it in the future!

Thanks for any help!

Denis Štogl

unread,
Mar 25, 2013, 12:27:09 PM3/25/13
to modb...@googlegroups.com
Hello Luc,

Thank you! Actually you helped me a lot! :)

I found the Error. I just commented line "self._serial.timeout = interchar_multiplier * self._t0" (line 86) from file modbus_rtu.py. I don't understand why you set again timeout parameter on serial port, becuse i set it already in serial object in constructor. And also this is very, very short time for timeout and I think that any hardware will hardly work. Also don't understand why works on Windows, but it is possible that windows doesn't respect that timeout time.

And again there is the same error from time to time, but this can be hardware problem, because when I make retray than I get an answer. So you can add that it works with Magnum 400 motor motion controller from Axor Industries (http://www.axorindustries.com/Products.aspx?id=20&new=true)

Thanks for good library!

Luc JEAN

unread,
Mar 25, 2013, 4:39:55 PM3/25/13
to modb...@googlegroups.com
Hi Denis,

Thanks for feedback. I'll check this timing issue.
I've added your contrller to the list

Best
luc

achiosso

unread,
Mar 26, 2013, 7:22:35 AM3/26/13
to modb...@googlegroups.com
Hello to everybody.
I want to inform you that I am running an ARM embedded pc (MK808 - RK3066 based Picuntu Linux) and I tried using modbus-tk
in TCP/IP master mode with positive result with Schneider Electric Twido PLC and Zelio Smart Relay .

Regards

Alessandro Chiosso
Message has been deleted
Message has been deleted

luc

unread,
Mar 26, 2013, 7:29:25 AM3/26/13
to modb...@googlegroups.com
Hi Alessandro,

Congratulations and thanks for feedback. 

Best
luc

alex chiosso

unread,
Mar 27, 2013, 10:45:30 AM3/27/13
to modb...@googlegroups.com
Hi Luc.

I'm having a problem like mentioned before by Denis.

In my case I'm using the TCP/IP connection but the error message seems to be the same.
So the timeout I've preset is 5 seconds.
The message rate is one request per second.
See the attached image to be clear.

Regards

Alessandro
Modbus_problem.png

Vinod Kumar

unread,
May 6, 2015, 9:05:18 AM5/6/15
to modb...@googlegroups.com


Hi Luc,

We  run RTU Server on serial line at high speed (115000 baud). We observed that the serial line handler had difficulty in detecting frames and so had to estimate the message length from the header and look out for those many number of bytes. This was done for the Write-multiple-registers message and not for others. Today I looked at the Modbus Serial line standard and the Modbus-tk code. I have some questions and suggestions please.

Modbus Serial line specs sheet is inline. For high speed serial line, the fixed time values for intercharacter-timeout  (t1.5)  is 750 microsecs and inter-frame delay (t3.5) is  1.750 ms. Modbus-Tk calculates these from 1) utils.calculate_rtu_inter_char(baudrate): as 0.0005 and 2) in RtuServer (modbus_rtu.py) __init__  with:
        self._t0 = utils.calculate_rtu_inter_char(self._serial.baudrate)      # 0.0005
        self._serial.interCharTimeout = 1.5 * self._t0      #  0.00075
        self._serial.timeout = 10 * self._t0      # 0.005. 5 ms much longer than the allowed 1.75 ms.
       
       Why is there a magic number 10. It should have been 3.5. Better to avoid magic numbers but use:
      #  modbus_rtu.py class -> RtuServer(Server):->  def __init__(self, serial, databank=None):
       interframe_multiplier = 3.5
       interchar_multiplier = 1.5
       self._serial.interCharTimeout = interchar_multiplier * self._t0  #       0.00075 s = 750 microsec
       self._serial.timeout = interchar_multiplier * self._t0                    #       0.00175  s =  1.75 ms


 The unusually long interframe delay of 5 ms can explain why frames were getting mixed up in the serial receive at the server.  I have not yet tested the serial receiver with the 1.75 ms delay, but am fairly confident it will work. Will let you know after testing.

Similar issue is present in RtuMaster.
 
modbus_rtu.py -> class RtuMaster(Master): -> def __init__(self, serial, interchar_multiplier=1.5):
        ....
        Master.__init__(self, self._serial.timeout# Master.__init only after calculating timeout
        self._t0 = utils.calculate_rtu_inter_char(self._serial.baudrate)
        self._serial.interCharTimeout = interchar_multiplier * self._t0
        self._serial.timeout = interchar_multiplier * self._t0    # should use inter_frame_multiplier (3.5)

Should we correct the routine as:
modbus_rtu.py -> class RtuMaster(Master): -> def __init__(self, serial, interchar_multiplier=1.5):
def __init__(self, serial, interchar_multiplier=1.5, interframe_multiplier=3.5);
        """Constructor. Pass the pyserial.Serial object"""
        self._serial = serial
        LOGGER.info("RtuMaster %s is %s" % (self._serial.portstr, "opened" if self._serial.isOpen() else "closed"))
        self._t0 = utils.calculate_rtu_inter_char(self._serial.baudrate)
        self._serial.interCharTimeout = interchar_multiplier * self._t0
        self._serial.timeout = interframe_multiplier * self._t0

        Master.__init__(self, self._serial.timeout)

Lastly the magic number 3.5 occuring elsewhere has to be replaced with interframe_multiplier eg:
modbus_rtu.py -> class RtuServer(Server): ->
def _do_run(self): ->
                   ...
                    time.sleep(3.5 * self._t0
def _send(self, request):->
       ...
        time.sleep(3.5 * self._t0)

Cheers,
k vinod kumar

Vinod Kumar

unread,
May 6, 2015, 9:13:45 AM5/6/15
to modb...@googlegroups.com
Corrected earlier message. Pl ignore the earlier one.


On Wednesday, 6 May 2015 18:35:18 UTC+5:30, Vinod Kumar wrote:



Hi Luc,

We  run RTU Server on serial line at high speed (115000 baud). We observed that the serial line handler had difficulty in detecting frames and so had to estimate the message length from the header and look out for those many number of bytes. This was done for the Write-multiple-registers message and not for others. Today I looked at the Modbus Serial line standard and the Modbus-tk code. I have some questions and suggestions please.

Modbus Serial line specs sheet is inline. For high speed serial line, the fixed time values for intercharacter-timeout  (t1.5)  is 750 microsecs and inter-frame delay (t3.5) is  1.750 ms. Modbus-Tk calculates these from 1) utils.calculate_rtu_inter_char(baudrate): as 0.0005 and 2) in RtuServer (modbus_rtu.py) __init__  with:
        self._t0 = utils.calculate_rtu_inter_char(self._serial.baudrate)      # 0.0005
        self._serial.interCharTimeout = 1.5 * self._t0      #  0.00075
        self._serial.timeout = 10 * self._t0      # 0.005. 5 ms much longer than the allowed 1.75 ms.
       
       Why is there a magic number 10. It should have been 3.5. Better to avoid magic numbers but use:
      #  modbus_rtu.py class -> RtuServer(Server):->  def __init__(self, serial, databank=None):
       interframe_multiplier = 3.5
       interchar_multiplier = 1.5
       self._serial.interCharTimeout = interchar_multiplier * self._t0  #       0.00075 s = 750 microsec
       self._serial.timeout = interframe_multiplier * self._t0                    #       0.00175  s =  1.75 ms

Vinod Kumar

unread,
May 6, 2015, 4:23:08 PM5/6/15
to modb...@googlegroups.com

Hi Luc,
Downloaded modbus_tk-0.4.3.tar.gz, unpacked it, renamed as modbus_tk-0.4.4 and then made modifications in defines.py, utils.py and modbus_rtu.py. All modifications have been tagged with # MELabs. The modifiactionbs are with respect to serial line inter char and frame timeout and for checking for a 0 byte receive from the serial line.

The bzipped tar is attached. The version is not tested!

Cheers,
k vinod kumar

modbus_tk-0.4.4.tar.bz2

Luc JEAN

unread,
May 7, 2015, 1:32:27 AM5/7/15
to modb...@googlegroups.com
Hello Vinod,

Thanks for your message and your contribution. I've integrated your changes on the future 0.5.0 that you can clone/download/fork at the new github repository https://github.com/ljean/modbus-tk

All,

I'll be interested by feedback on this version before pushing it to PyPi. Please let me know if it is ok for some of you.

I've put a contributor list in the __init__.py of modes-tk. Please let me know if your name is missing or if you want to add more info (link, name, ...)

Best
luc



--
You received this message because you are subscribed to the Google Groups "modbus-tk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modbus-tk+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Vinod Kumar

unread,
May 8, 2015, 4:17:20 AM5/8/15
to modb...@googlegroups.com

Hello luc,
Suspect problem in Serial Rtu receive:


modbus_rtu.py -> class RtuServer(Server): -> def _do_run(self):
            ...
            request = ""
            read_bytes = "dummy"
            while read_bytes:
                read_bytes = self._serial.read(128)
                request += read_bytes

            #parse the request
            if request:
            ...

Suppose two messages with the required interframe gap are sent
on the serial line.
<message1_20bytes><gap><message2_24bytes>

The server issues a serial read for 128 bytes. As it receives
message1_20bytes and a gap, the serial device returns with
message1_20bytes. Since the read_bytes has 20 chars, the serial.read
will again be issued for 128 bytes. Now the message2_24bytes
will be received and returned. The do_run will append the
message2 to request. Thus the request will contain multiple messages.

The 'request' should contain only one modbus message. If
it contained many modbus messages, the parsing and handling
would be delayed till an interframe gap of twice the normal gap
is detected. Then  a zero 'read_bytes' would be returned and
the request passed on to parsing.
So for timely parsing the 'request' should contain only one
modbus message. So the  present code can be modified to:


modbus_rtu.py -> class RtuServer(Server): -> def _do_run(self):
            request = ""
            read_bytes = "dummy"
            while read_bytes:
                read_bytes = self._serial.read(128)
                request += read_bytes
                if len(read_bytes) < 128:
                    break

            #parse the request
            if request:
            ...

If a frame is of 128 bytes, then the above code will break down.
It will append the
next message to the message with 128 bytes. To overcome this
problem the code can be simplified to:
------------------------------------------------------

modbus_rtu.py -> class RtuServer(Server): -> def _do_run(self):
    def _do_run(self):
        """main function of the server"""
        MAX_ASCII_FRAME_SIZE = 513 #Modbus_over_serial_line spec 2.5.2.1
        try:
            #check the status of every socket
            response = ""
            request = ""
            request = self._serial.read(MAX_ASCII_FRAME_SIZE)

            #parse the request
            if request:
            ...
                              
We dont have to assemble a message from multiple serial.read
as the maximum possible size is given to the read. A shorter
message will return due to the interframe timeout.


Cheers
k vinod kumar

Vinod Kumar

unread,
May 8, 2015, 11:00:31 PM5/8/15
to modb...@googlegroups.com
Hi Luc,

While testing the Serial RTU with  MAX_ASCII_FRAME_SIZE = 513, the serial line returned 1 char, and the request with 1 byte failed in the subsequent processing (request should be minimum of 3 chars). Please dont include the 513 code,  pending further testing.

Am wondering whether there is a gap of more than InterFrameTimeout between the first char on the RTU Serial line (Salve Id) and the rest of the modbus PDU.. Currently we go back to test with the 128 char serial receive with break if the received count is less than 128.

Cheers
k vinod kumar

Luc JEAN

unread,
May 12, 2015, 1:23:49 AM5/12/15
to modb...@googlegroups.com
Hello Vinod,

Thanks for this feedback. I'll let you do more testing and let me know what is the best implementation. I admit that the current implementation will ignore a second request in the same frame. 

The interframe timeout should avoid this situation but maybe not in all cases, especially for high speed communication rate.

I don't have any rtu device currently (and I am missing time too) to investigate more.

One  possible fix would be to improve the way the request are handling and to detect if there is more than one request in the read bytes. (Pre-parsing the request in the RtuQuery class?)

What do you think about it?

Best
luc








--

Vinod Kumar

unread,
May 12, 2015, 5:26:17 AM5/12/15
to modb...@googlegroups.com
Hi Luc,
I was not sure whether the request handler can handle multiple modbus PDUs. That is why I mentioned only the delay problem if the serial line assembles multiple PDUs. The same problem will occur even if we segment the received buffer in a pre-parser and hand over PDUs to the parser one by one. So I would vote against a pre-parser.

During Testing with the 128 buffer scheme with break on messages with less than 128, 129 char modbus messages were detected and also 20 and 29 char ones.

Will post results and recommendations.

Cheers

--
You received this message because you are subscribed to a topic in the Google Groups "modbus-tk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/modbus-tk/cCLt2TVXoSg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to modbus-tk+...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
पृथिवी सस्यशालिनी
the earth be green
Reply all
Reply to author
Forward
0 new messages