Is there a better Modbus library?

Hi folks. I'm trying to implement an application to read and write using the Modbus protocol and I'm feeling a bit discouraged.

I've been able to implement my application on an Uno Wifi Rev 2, using the ArduinoModbus library. However, I'd like to get it working on some other boards. The R2 is no longer current, and it's kind of expensive ($55 from Amazon).

I tried running my code on an original Uno. I had to modify the library code to get it to compile and load, but it won't run. I think it runs out of memory, it just quits on startup. I tried running it on a R4 Wifi Uno. At first the library code wouldn't compile at all, I made a bunch more changes to the library to get it to compile and run. It runs, but it times out on every communications call.

So I thought maybe I should try a different library, so I moved on to Modbus-Arduino, but it lacked the functionality I needed. Then ModbusMaster. Then YAAJ_ModbusMaster, which claimed to fix the problems with ModbusMaster.

All of these libraries pretty much follow the same pattern: I copy the example program, and it doesn't compile. I spend a while rooting around in the source code fixing the compiler errors until I get it to compile and load. Then it doesn't run. At that point I give up, there's a limit to how much I can do with someone else's decade old code.

It seems a lot of people have gone down this road, ArduionModbus has 108 forks, ModbusMaster has 331. Has anyone gone down this path and found a solution that works?

I did find this thread from a few years ago that discusses the problem and pretty much comes to the same conclusion:

Thanks.

Hi,

I'm the OP of the post you linked so I got tagged (I don't mind).

If you're interested in the final (working but might be ugly) code from that post, you can find it here:

Other than that, I agree with the statement of 'too many damn things that don't work as intended', but I'm unable to do much more for you than to provide the final code, I'm sorry.

I don't think there is anything magic about Modbus, but it is easy for me to say that because I spent nearly a decade writing code for Modbus devices, and even longer on comms in general.

However, there are sufficient wrinkles in the Modbus spec which make it hard to be play and play, and easy to get wrong. For example, an address of 30007 means input register address 7, but the address sent in the message is 0-based, so ends up being 6. Then throw in all the issues with character framing, slave address, RS485 port control etc.

Treating the Modbus library as a black box, it can be hard to find the right config by trial and error, there are too many variables. And if it either works or it doesn't, you need some understanding of Modbus and how to debug comms. It doesn't help that the standard serial port used for debug is also the one you want to use for Modbus.

Modbus is a less popular application than say addressable LEDs or servo motors, so it is not surprising that the libraries are less well maintained and supported.

So I don't think Modbus is ever likely to reach the "just works" level for people who may be novices to Modbus and also not experienced coders. I guess I could write a library which had an auto "config option" and suggests a setup, but I probably wouldn't have the time to support or maintain it.

So the whole idea of a layered protocol is that each layer is independent of the other layers. Modbus is supposed to be an application layer protocol, it can run over RS485 or RS232 or TCP/IP, if implemented properly it shouldn't have to know anything about the layers below it. So an implementation that abstracts the communication layer should be quite portable to different boards.

Having looked at a handful of implementations, what I've seen is that many don't abstract the communication layer below them. Some do, they just have a Stream object that can read and write bytes, but for the most part they tear into the Serial object, which causes problems when you switch to a different board that implements Serial differently.

There also seem to be problems with architecture-specific code. ArduinoModbus in particular is littered with #ifdef statements, even a fair number of "#if defined(_WIN32)" statements (gasp!). Byte ordering is always important when you're communicating with another computer, the default data type in Modbus is a two-byte short integer, so byte order matters. And every packet has a CRC checksum, which depends on byte-level manipulations.

Timing seems to matter a lot to Modbus, I've found that if a Modbus call fails unexpectedly the most common fix is to insert a delay() statement before the statement. Timing is going to be processor-speed dependent, which makes it hard for code to be portable.

ArduinoModbus seems to have been ported from Unix via Windows. I mean, it's full of statements like:
`fprintf(stderr, "Sending request using RTS signal\n");

It allocates and frees a lot of memory, which isn't going to work in a lot of Arduino environments.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.