Recent

Author Topic: Modbus summary thread  (Read 385 times)

bobby100

  • Sr. Member
  • ****
  • Posts: 291
    • Malzilla
Modbus summary thread
« on: June 22, 2025, 05:47:30 pm »
I'll try to make a summary thread about Modbus on Lazarus/FPC.

Short terms explanation:
Modbus/TCP - Modbus over Ethernet
Modbus/RTU - Modbus over serial connection (RS-485)
Modbus/ASCII - Modbus over serial connection, but the communication is encoded as hexadecimal ASCII text

A simple Modbus network has one master and one or more slaves. The master is the single device sending requests for read or write, and slaves are responding.
These terms/names are replaced by newer terms recently.
Master = Client = Broker
Slave = Server = Device

Back to Lazarus - there are a couple of packages/libraries for Modbus.

Native:
delphi-modbus ( https://github.com/coassoftwaresystems/delphi-modbus ) - Modbus/TCP master and slave
PascalSCADA ( https://www.pascalscada.com/ ) - Modbus/TCP master and slave, Modbus/RTU master
pascal-modbus ( https://sourceforge.net/projects/pascal-modbus/ ) - Modbus/TCP master and slave, Modbus/RTU master and slave
mbutils ( https://sourceforge.net/projects/mbutils/ ) - Modbus/TCP master and slave, Modbus/RTU master
lazarus-modbus ( https://github.com/BobanSpasic/lazarus-modbus ) - Modbus/TCP master and slave

Non-native:
SnapModbus ( https://snapmodbus.sourceforge.io ) - Modbus/TCP master and slave, Modbus/RTU master and slave
Lazarus extended demos for SnapModbus - https://github.com/BobanSpasic/lazarus-SnapModbus-demos

Support files:
untCOMPortList ( https://github.com/BobanSpasic/lazarus-SnapModbus-demos/blob/main/untCOMPortList.pas ) - cross-platform (tested on Windows and Linux) unit for listing available COM Ports. Based on code from Synapse and from this forum post: https://forum.lazarus.freepascal.org/index.php/topic,63256.0.html

Pros & Cons:
delphi-modbus - primarily developed for Delphi and there are some minor installation problems with Lazarus 4.0 on Linux. Based on Indy components. Just one example for usage in Lazarus
PascalSCADA - very good if you are working with known register addresses. Very good support and developed for Lazarus primarily. Not easy to implement a monitor/sniffer
pascal-modbus - based on synapse. Abandoned project but still usable. Complicated usage (confusing function/procedure names and some low-level settings for communication are left to user to calculate and set up)
mbutils - latest snapshot (tested on 15.06.2025)  does not compile. The fixes are relatively easy (some variables are declared twice - change the name of one variable). The example from the readme file seems to be too old - it does not match the current object structures.
SnapModbus - most complete feature set. Good example/demo projects. No support.


What next:
- I'll try to summarize the forum threads here, containing useful information on Modbus
- I've cleaned delphi-modbus from all the code that is non-relevant for Lazarus, and also fixed the installation on Linux. As Thaddy suggested, this will probably get its own repo on Github under the name lazarus-modbus. I also wrote some pretty usable example projects.
- write/collect some examples for mbutils
- I've extended the SnapModbus demos, making them more usable (open/save configurations, hide/show registers for better visibility, Linux builds, better COM-Ports selection...)
- convert ModbusEmu from CT to Lazarus, translate from Russian to English, correct English spelling in unit/function/procedure names (Chennel > Channel etc)

Any suggestions?

jamie

  • Hero Member
  • *****
  • Posts: 6995
Re: Modbus summary thread
« Reply #1 on: June 22, 2025, 07:26:32 pm »
https://github.com/stephane/libmodbus

Those files cover the ins and outs of what is needed to deal with implementation of Modbus (Monicon) .

 Its in C however, its most likely one of the good sources to get the CRC logic for RTU and also spans in using
TCP with simple examples that can be converted over using the more direct API functions instead of relying on components like Indy.

 RTU requires CRC as does some ASCII protocols. Also using ASCII there is a #1 to start and #2 to end the frames, much like what is found in serial printers when sending blocks of data.

 On top of that, timing is very important since devices need to know when to discard an assemble of a frame in case of intermitting hardware errors.

 There are apparently two styles of CRC logic used between ASCII and RTU(Binary).

 Also, the Function Codes are not written in stone, meaning, specific devices may desire to use custom values.

 Also on top of that, Register ranges for many devices have a fixed range within the categories and may not be as they are like found in the Monicon PLC time.

Jamie






 
The only true wisdom is knowing you know nothing

bobby100

  • Sr. Member
  • ****
  • Posts: 291
    • Malzilla
Re: Modbus summary thread
« Reply #2 on: June 22, 2025, 10:00:40 pm »
Opening post updated:
- lazarus-modbus
- extended demos for SnapModbus
- support unit untCOMPortList

jamie

  • Hero Member
  • *****
  • Posts: 6995
Re: Modbus summary thread
« Reply #3 on: June 22, 2025, 10:26:02 pm »
Well I don't use libraries without source code so you can count me out of this thread
The only true wisdom is knowing you know nothing

bobby100

  • Sr. Member
  • ****
  • Posts: 291
    • Malzilla
Re: Modbus summary thread
« Reply #4 on: June 22, 2025, 10:30:44 pm »
Which one is without the source code?
If you mean SnapModbus - it comes as source code to be compiled on your own, or to use precompiled libs (just the Windows dlls are distibuted in the package)
In the extended demo package, I've included the precompiled Linux 64-bit libsnapmb.so, because not everyone cares to compile it on its own, but you are free to compile it from the SnapModbus sources.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12326
  • FPC developer.
Re: Modbus summary thread
« Reply #5 on: June 22, 2025, 10:44:53 pm »
Its in C however, its most likely one of the good sources to get the CRC logic for RTU and also spans in using
TCP with simple examples that can be converted over using the more direct API functions instead of relying on components like Indy.

Why would you actually do that?  Afaik the FPC CRC unit supports custom polynomals too, and while people always whine about Indy, I haven't found much problems in practice. Performance or otherwise and I use both UDP and TCP.

I'm only starting with modbus (I've layered delphi-modbus over an own indy wrapper to isolate it a thread), but I hope to test with PLCs in the coming week.

Quote
RTU requires CRC as does some ASCII protocols. Also using ASCII there is a #1 to start and #2 to end the frames, much like what is found in serial printers when sending blocks of data.

 On top of that, timing is very important since devices need to know when to discard an assemble of a frame in case of intermitting hardware errors.

In that case you are better off with a USB device to act as intermediate and not rely on a PC at all for the deepest layer. I had a project with a serial protocols once that that heavily used BREAKs a lot, and it was a disaster on PCs.

Quote
Also on top of that, Register ranges for many devices have a fixed range within the categories and may not be as they are like found in the Monicon PLC time.

I've been warned that some PLCs have "pages" of registers to select, I assume that that customer uses Siemens.

bobby100

  • Sr. Member
  • ****
  • Posts: 291
    • Malzilla
Re: Modbus summary thread
« Reply #6 on: June 22, 2025, 11:18:35 pm »
Quote
Also on top of that, Register ranges for many devices have a fixed range within the categories and may not be as they are like found in the Monicon PLC time.

I've been warned that some PLCs have "pages" of registers to select, I assume that that customer uses Siemens.
Modicon implementation had notation like:
Coil = 00001-09999
Discrete Input = 10001-19999
Input Register = 30001-39999
Holding Register = 40001-49999
Later, the 6-digit form got into use (e.g. Holding Register 400001-465536).

So, if you see somewhere 30232, you know it is an input register because of the 3 at the beginning. At reading it, you use function 04 (read input register), with the register address 231 (this is no mistake - here is 0 the first address so you need to subtract 1).

If you think about it, from the function code (-1) and register address (-1), you could develop a simple hardware to access the inputs and outputs (mapped to addresses according to Modicon notation).

I think, jamie want to say, that not everyone respects the Modicon implementation, because today with cheap microcontrollers, you can implement a custom addressing easily.

 

TinyPortal © 2005-2018