Lynn's Industrial Protocols over IP

Monday, October 09, 2006

Using Python to query Modbus slaves

I use Python ( ) at lot in my testing. It is a language designed to make a programmer's life easy and the computer sweat - in other words, it is an ideal tool for test scripts and maybe a bad tool for "constant use" tools.

Stock python has no serial support. For serial, you'll need some serial tool like pyserial - this hides details of OS and allows Linux (or Windows) style serial calls on either OS. A web search of pyserial will turn up a download site - such as . The "Vaults of parnassus" is another nice source for Python tools including pyserial.

Creating binary messages is not hard in Python, but a bit ugly. You use lots of "chr(x)" function to build up a binary string and to parse a binary response lots of "ord()". Other than that, look at the spec at for details of the actual protocol.

CRC-16 for Modbus (or DF1):
Here is my CRC16 routine including a few test cases (written with no regard for CPU speed, since that is not why one uses Python). as a ZIP file


  • Standard python struct module with pack()/unpack functions will help you to create binary messages in more elegant manner.

    By Blogger techtonik, at 4:50 AM  

  • Thanks, that's an option.

    I guess 'elegance' is in the eye of the beholder - I only use that module for reading/writing floats from a binary string since it requires "try/except" to keep it from throwing exceptions.

    It's other problem is the output of the pack isn't a real Python string, so you can't do much with it ... in fact, after I pack the float I have to convert the result to a "4-byte binary string" so it works with the rest of my code.

    By Blogger Lynn August Linse, at 7:22 AM  

  • The link to your example code no longer seems to work:

    Is there another way to get at that code?

    By Anonymous Donald, at 1:16 PM  

  • I duplicated it to:

    I guess the server was now trying to "run" the .PY as-if a server extension. The .zip format stops this.

    By Blogger Lynn August Linse, at 1:23 PM  

  • Lynn,
    Would it be possible to post a code example of a full master to slave query? I think I understand how your function works, but I just can't seem to get my slave device to respond to my queries. One example would save me an incredible amount of time.


    By Anonymous Donald, at 11:46 AM  

  • Here is a complete 'construction' which is used in one of my real-world tests - notice how the CRC16 is appended in what I'd call little-endian form.

    st = "\x03\x03\x00\x00\x00\x0A"
    crc = crc16.calcString( st, crc16.INITIAL_MODBUS)
    st += chr(crc & 0xFF) + chr(( crc >>8) & 0xFF)

    Since I moderate comments; you can just send a 'new comment' with an email address; I'll reject it (not publish) but I can send you a few complete modbus libraries 'as-is'.

    By Blogger Lynn August Linse, at 11:55 AM  

  • I need to read/write a few int/float registers in 1+ modbus slaves from an embedded device running Linux (over the serial line).

    I wrote a Python C extension module to wrap the calls I need in libmodbus (, but I'm wondering if it's possible to do what I need purely in Python.

    Is this possible with your code?


    By Blogger tobias, at 8:07 PM  

  • Hi,
    You may be interested by Modbus Test Kit which is an implementation of the Modbus protcol in Python designed with testing purpose in mind.
    I am interested by your feedback if you have a little time to play with it.

    By Blogger luc, at 1:28 PM  

Post a Comment

<< Home