Week 40: Rewritting Device::Modbus
After an extremely long wait, the rewriting of Device::Modbus and its sub-classes Device::Modbus::TCP and Device::Modbus::RTU are in a (seemingly) working state and up at Github.
The TCP distribution is untested, as opposed to Device::Modbus and the RTU version which have a nice test coverage*. However, it is capable of implementing a pre-forking server which answers to a client at least in my laptop. The client is capable of talking to a Python-based, third-party server, so it is not just Device::Modbus talking to itself.
What are the next steps for Device::Modbus::TCP? I would really like to install the server in a Raspberry Pi and talk to it from my lap with the Python client. It would be neat as well to have the client talk to a PLC, or have an HMI talk to a Raspberry Pi server.
And then, there is the documentation for the whole thing. As a start, I am updating the articles of this blog to reflect the changes to the API.
That's it about the distribution update, but let's make room for a little story.
This week, like the whole month of September, was horrible at work. I am under a lot of pressure to finish a machine which is taking forever. Not the spot I enjoy. While most of the details are finished, there are still tons of simple things that need to be accomplished before it can be taken over by production. And some really important parts required to fine-tune production parameters from the HMI are still open.
Among the things that were done this week, there are the temperature controllers. These are simple PID boxes which talk via Modbus RTU. Our PLC needs to read the current temperature and eventually, to write a new set point. And, like usual, communication did not work at the first try.
The error reported by the PLC was simply a time-out. The controllers were not responding. First thing to check? Addressing parameters.
I connected the laptop with the software from the supplier. Everything was fine: addresses were configured as I needed them and the information I was trying to write was indeed writable from their software.
What did I get wrong?
Instead of fiddling with the PLC program, Device::Modbus::RTU came to the rescue. With a very simple program it became clear that the controller was responsive, that the configuration was what I expected, and that it worked as I wanted. Therefore, the problem was in the PLC side. And sure enough, instead of using a SINGLE_WRITE instruction I had a probably mis-configured WRITE_VAR. The difference between them is that the former issues a write_singe_register request; the later implements write_multiple_registers. The PLC is now talking to the temperature controller.
What really made me happy, though, was using Device::Modbus::RTU once again to solve a problem.
* The problem about my coverage metrics is that it measures the extent of the code that is exercised in my test suite, which probably leaves out many real-world potential problems. It simply means that the code behaves like I thought, and not that it was conceived correctly.