mono-Modbus:

Designing an Open Framework for Modbus Access

Alejandro Fernándes Herrero, Victor Rocha Pusch, Henrique Augusto Menarin, David Caruso
April 2006



1. Introduction

Software tools known as SCADA (for Supervisory Control and Data Acquisition) are nowadays widely used around the world. This kind of software allows us to interact with electronic devices which control processes in many fields of the Industry, such as power generation, manufacturing, chemical transformations and HVAC (Heating, Ventilation and Air Conditioning) applications, among others. In order to successfully interface these electronic devices to computers, it is necessary to define standards for physical connections and which communication protocols will be used. Physical connections are available in a wide range of options (from serial lines and radio modems to satellite links). Some of the most popular communications protocols include Modbus, Hart, DF1 and Fieldbus.

Modbus is a communications protocol designed by Modicon for use with its programmable logic controllers (PLCs). It has become a de facto standard communications protocol in industry, and it is now the most commonly available means of connecting industrial electronic devices such as process controllers and data loggers.

The mono-Modbus project provides a set of open-source software tools for data acquisition and supervisory control of Modbus devices. These tools will allow for low-cost, modular development of new SCADA applications, using modern programming languages and techniques. Using the open-source development model, we can take advantage of feedback from end-users and other software developers, who can contribute with their programming skills and knowledge about SCADA systems. The software release should include: source code for the protocol implementation; dynamic-link libraries for integration with third-party applications; and stand-alone executables, which will connect to Modbus devices and provide connectivity to external systems using the Internet. The "Mono" framework was chosen, among other reasons, because of its multi-platform compatibility and its compliance to Microsoft's .NET technologies.

In this paper we define the implemented protocols, and choose international standards to which our software tools complies. The design of a System Architecture is presented, including the definition of abstraction layers and the selection of technologies, programming languages and tools.

2. Protocols and compliance to standards

2.1 The Modbus Protocol

Modbus is a communications protocol positioned at the level 7 of the OSI Model, based on master/slave or client/server architecture. Modbus allows remote administration of a network of devices, for example in a system which measures temperature and humidity and then communicates the results to a remote computer. Modbus was originally used over serial lines (RS-485 and RS-232), but today it is also available over Ethernet. There are currently the following types of Modbus protocol: Modbus ASCII, Modbus RTU and Modbus TCP. There is also a protocol called Modbus Plus, but it is proprietary technology.


one master device connected to several slaves, which connnect to one or more industrial devices

Figure 1: diagram showing basic architecture with Modbus master and slaves


In the Modbus protocol, there is one device called "Master", which is usually a PC or a PLC, and several devices called "Slaves". The master starts the communication sending a message frame across the Bus, and the addressed slave responds with another message frame. Every message frame in Modbus has the same structure, which includes a function code and data bytes. Depending on the protocol mode, error-checking is added (LRC in ASCII, CRC in RTU). Every message contains also the slave address, which is different in each protocol mode (2 characters in ASCII, 1 byte in RTU or TCP).


addressing, function, data, error-check

Figure 2: the Modbus message structure


The functions defined in Modbus Protocol are shown in the following table:

Function Description
Function Code
Read Discrete Inputs 02
Read Coils 01
Write Single Coil 05
Write Multiple Coils 15
Read Input Register 04
Read Holding Registers 03
Write Single Register 06
Write Multiple Registers 16
Read/Write Multiple Registers 23
Mask Write Register 22
Read FIFO queue 24
Read File record 20
Write File record 21
Read Exception status 07
Diagnostic 08
Get Com event counter 11
Get Com Event Log 12
Report Slave ID 17
Read device Identification 43

Our project follows the Modbus standard guidelines, as published in the MODBUS Protocol Specification. The first version of the main API implements the Master side of the Modbus RTU protocol as defined in the Modbus Serial Line Implementation Guide. We should later implement the full line of Modbus protocols, including ASCII and TCP versions. Although Modbus Slave implementations are very device-specific, mono-Modbus provides a basic implementation model as source code and a demo executable.

2.2 Connectivity to other software systems

Connectivity to other software systems will be provided through an API (Application Programming Interface), distributed as a set of dynamic-link libraries and remote object bindings. This dynamic-link libraries and remote bindings must expose access to all functions specified in the Modbus protocol. Configuration functions must also be available, so that users of mono-Modbus can programatically set operation mode, com ports, baud rates, and other configurations for the protocol.

Compatibility with commercial, "off-the-shelf" SCADA and HMI packages is highly desired. Since the international standard for software interoperability in Control and Automation is OPC, an OPC server could be built on top of the main Modbus functionality. This server can be built as a wrapper for the main API.

The original OPC-DA is based on the proprietary DCOM, which has been declared "legacy technology" by Microsoft, and still isn't fully supported using open software. The OPC Foundation has publised a DCOM-independent standard called XML-DA, based on web-services, which has been implemented in C# by the OpenDA project. OpenDA has not been succesfully tested in Linux, yet. A new set of standards is under development by OPC Foundation, and is currently known as the OPC UA (Unified Architecture). When UA gets to the market, the XML-DA will no longer be supported as a mainstream technology. Therefore, a better understanding of this issues is recommended before implementing these higher-level wrappers.

3. Review of existing software

Plenty of software has been written around the world for MODBUS communication. There are good commercial drivers available for differen Operational Systems, as well as some Open-Source alternatives.This is a list of some open-source projects which offer MODBUS support, with their descriptions extracted from Internet sites:

http://sourceforge.net/projects/mbdevconf
Modbus Device Configurator is a JAVA based PC software which let you to
read/write parameters on a MODBUS protocol based board, using HI-Level
graphical user interface SWING based fully customisable. (description from the project site)

http://sourceforge.net/projects/jamod
jamod is an object oriented implementation of the Modbus protocol, realized 100%
in Java. It allows to quickly realize master and slave applications in various
transport flavors (IP and serial).

http://modrssim.sourceforge.net/
This simulator was written to allow the testing of a MODBUS RTU serial driver
without having to get 255 little MODBUS PLCs into one office. It is not, by any
means, a full implementation of the protocol; it implements only the common
functions used in MODBUS and other protocols supported here.

http://freshmeat.net/projects/plcio/
PLCIO is a library designed to read and write data on a programmable logic
controller (PLC). It runs under Linux, HP-UX, Solaris, and QNX, and supports
the Allen-Bradley DF1, 1784-KT Data Highway Plus, PLC-5, SLC, and Control Logix
PLCs. It also supports the Modicon Ethernet, Modbus RTU, and SA-85 Modbus Plus
protocols, as well as Siemens Step5 via AS511 and Step7 via Ethernet. Its
extensibility allows the programmer to address PLC memory by their tag names
for different data types, regardless of the computer architecture, with the PLC
linked either directly or remotely. It also includes a simple CGI interface for
PLC access from a Web browser.

http://sourceforge.net/projects/libmodbus
Libmodbus is a dynamic library to use Modbus dialog protocol with GNU/Linux.
LibModbus include master, slave and also serial port configuration functions.
GModbusControl is a simple tool tu use with libmodbus

4. System Architecture

4.1. Requirements

Applications based on our software framework will communicate with popular Modbus devices like process controllers and dataloggers. Our first implementation should have the following features:

4.2. Description of Abstraction Layers

To properly allow for modular development of SCADA applications, our software should be split in abstraction layers, from the physical bus access to the development of high-level applications. Our abstraction layers are designed as shown in the following diagram:


Layer 1. Bus-level communication

In this layer we find the physical and transport subsets of the Modbus protocol, like bus configuration, assembly of message frames and error-checking (with CRC). Expected functionality should be exposed as functions (methods) such as:

bus1 = new InstrumentBus;

bus1.setfromfile("settings.xml");     //loads setting from file and applies them to the bus,
                //also selects and instantiates the needed transport (tcp or serial)

bus1.setmode("RTU"); //
bus1.setserialcomm(9600, 8, "EVEN", 1); // functions for "manually" setting the bus

bus1.sendframe(byte [] requestframe);          //sends a modbus formatted frame

response = bus1.listen(timeout);         //waits for a response on the bus


For implementation of the transport functions, specialized classes are needed, which provide the same methods from the above mentioned InstrumentBus class:

port1.sendframe(byte [] requestframe);

response = port1.listen(timeout);        // for serial transports



socket1.sendframe(byte [] requestframe);

response = socket1.listen(timeout);        // for tcp

Layer 2. Read/write access to modbus slaves' registers

This abstraction layer is related to Modbus Application protocol itself, which is positioned at layer 7 of the ISO/OSI model. When working at this abstraction level, the developer should not have to deal with transport-related issues. Expected functionality is exposed by methods like:

// access to the register using special method calls for each function
word [] registers = bus1.ReadHoldingRegisters(slave_address, starting_register, register_count);
bus1.WriteCoil(slave_address, coil, value);

// access to the slaves using the function codes directly
byte [] response = bus1.query(byte function, byte [] data);

The Modbus functions (0x03, 0x06 etc.) are all defined at this layer, whith proper methods for each function.


Layer 3. Tag management (point IDs with engineering units)

The software for Tag management translates modbus registers into "measured variables", which is usually information about physical processes (like temperature in Celsius, Pressure in bar or actuator on/off status), or information about the behavior of the controller (PID tuning, alarms, hysteresis, running program etc). Tag management must include conversion routines from binary words to integers, doubles, boolean status and so on. Tag management tipically includes scaling, in a form such as "aX + B" or some kind of polinomyal function. These parameters will vary from one application to another, so a flexible tag management system must be built. Tag management itself is not a part of the Modbus Protocol, but serves as an interface between low-level machine dialect and high-level application development. Below we show an example of how a developer would work at this abstraction level:

myControlPoints = new tagmanager();

myControlPoints.init("tags_conversion.xml");        // loads settings for tag conversion

Temperature1 = myControlPoints.Read("Temperature1");

     // reads value for "Temperature1" as described in settings

myControlPoints.Write("OutputPower", 0.50);        // sets 50% as output power for a modbus controller

Layer 4. Alarms, events, datalogging

This are typical Supervisory Control and Data Acquisition functions, and will be not implemented as part of mono-Modbus. This kind of features are commonly found in SCADA/HMI software applications, and mono-Modbus should only provide appropriate interfaces up to the 3rd layer described above. Examples of function calls in this level, implemented in a 3rd-party SCADA package, would be as following:

Temperature1.ReadAsynchronous();

Temperature1.GetHistory(starting_time, final_time);

Temperature1.ReadAlarmStatus();

Valve1.SetupLogging(samplingrate);

Layer 5. High-level application development

This is the layer where user interaction occurs, frequently using an OS-specific GUI or a web browser. Although we should not implement high-level applications in the scope of this project, we should design all previous layers in such a way that they should be easily integrated to user applications, using technologies as dynamic library linking, remote objects or Web-Services. Integration will be discussed later in this document, under "Main API" and "Remote Bindings".


4.3. Selection of frameworks and tools

[...]

object oriented programming and distributed systems
The .NET framework is suggested for deployment of our solution. The .NET framework was chosen for a number of reasons: it provides binary compatibility to many different operating systems; it has a very large base class library, including support for sockets and multi-threading; it provides uniform access to serial ports in both Windows and Linux (using Mono); and it has great support for developing language-independent, distributed applications based on Web Services.
.NET and Java
TCP remoting
C# language
mono

4.4. General Architecture

[...]

A sample configuration file is shown below:

<bus name="InstrumentBus1" type="RTU">

<port>/dev/ttyS0</port>
<baud>9600</baud>
<parity>none</parity>

<slave address="1">
<id>CT01</id>
<description>Temperature Controller 1</description>
</slave>

<slave address="2">
<id>DL02</id>
<description>Data Logger 2</description>
</slave>

</bus>


4.5. Modbus main API

[...]

An object-oriented implementation for the Modbus protocol, packaged as a set of dynamic link libraries, allowing for quick development of local SCADA application.



4.6. Modbus distributed services

[...]
A set of standards-based remote bindings for the main API, for use in a language-independent distributed programming environment.

4.7. "Osmox"

[...]
A data aqcuisition system based on the main API and the remote bindings, which will provide publish-subscribe functionality built on the OPC Foundation's XML-DA standard. This system shall be easily portable to different operating systems, and provide interoperability with existing free and comercial software.



5. Results

[...]
- download mono-modbus driver for RTU
-
-



6. Conclusions

[...]