Search

Flowcode and Modbus.

Modbus is still one of the most commonly used protocols for field communications. It’s relative simplicity and robustness and openness made it a protocol of choice for many automation hardware and software vendors. Because of this, Modbus is a safe choice for organization to commit to as there are always devices that support it.

Flowcode has support for Modbus and we will take a look at it in our short introduction of Modbus.


Another major benefit of Modbus is that it does not prescribe a specific physical layer. Instead, Modbus can work on top of RS-232, RS-485 or TCP/IP over Ethernet. Those are all cheap and already commonly used in enterprises. This means there is no need to invest into expensive protocol-specific network infrastructure.

There are different types of Modbus implementation depending on data encoding format, the transport layer and some other considerations. The most popular protocol types are:

  • Modbus RTU (binary over serial link)

  • Modbus ASCII (text-based over serial link)

  • Modbus TCP (binary over TCP/IP transport)

Modbus RTU Protocol Overview

Modbus RTU is a master-slave protocol. This means that only one device, the master, is allowed to initiate communication. The other devices on the network are called slaves and they may only respond to the requests. Modbus RTU can support up to 247 devices on the same physical network.

Modbus RTU encodes data as binary and uses big-endian encoding for 16-bit values. This means that the most significant byte of a 16-bit word is sent first.


Below is an example of Modbus RTU Request and Response messages with explanation of each item. First, a master sends a request telling the slave 1 to return the value of one register starting at address 3.



slave id (1 byte)
|  function code (read holding registers)
|  |      address of first register to read (2 bytes)
|  |      |     number of registers to read (1 byte)
|  |      |     |  checksum (2 bytes)
|  |      |     |  | 
01 03 00 03 00 02 xx xx
The request also includes a checksum which is used to make sure the messaged is not corrupted on the way to the slave. All slaves except for 1 must ignore the message. Slave 1 is expected to send a response message similar to the following:


All slaves except for Slave with ID = 1 must ignore the message. Slave 1 is expected to send a response message similar to the following:

Slave ID (repeats own id)
|  function code (repeats requested code)
|  |   number of bytes of data (4)
|  |   |     the value of the register (0x07FF)
|  |   |     |     checksum
|  |   |     |     |
01 03 04 07 FF   XX XX

Modbus ASCII

Modbus ASCII works similar to Modbus RTU, however it uses text-based encoding of data. This make requests and responses human-readable, it’s much less efficient because the messages become longer. Because of this, Modbus ASCII is only used for testing inmost cases


Modbus TCP

Modbus TCP is an adaptation of Modbus to be used on top of modern TCP/IP networks. There are two types of Modbus TCP implementation:

  • Modbus RTU over TCP, which simply uses TCP as a transport layer for RTU messages

  • Normal Modbus TCP which has some changes in the message format.


Because Modbus TCP uses Ethernet networks, the data transmission speeds is much higher than in RTU using serial links.


Modbus RTU Data Frame

A Modbus data frame is a message transmitted over Modbus network. There are Request and Response frames. A request is a message from the master to a slave. A response is a message from the slave to the master.

The length and the contents of the data frame vary based on the type of read/write operation being performed.


A basic request frame:

01 03 02 00 02 25 CA

They are 8-bit hexadecimal numbers that are sent over Modbus RTU network. The whole message in this case is seven bytes long. Let’s see what’s inside the frame:


01         03        02 00 01                 25 CA
-----------------------------------------------------
slave id   function  function-specific data   CRC
1 byte     1 byte                             2 bytes

The first byte of every Modbus message is a slave id. The master specifies the id of the slave to which the request message is addressed. Slaves must specify their own id in every response message:

01 03 02 00 01 25 CA
|
slave id (1 byte)  

The second byte of every Modbus message is a function code. This code determines the type of operation to be performed by the slave. We’ll cover function codes in a moment.


01 03 02 00 01 25 CA
   |
   function code (1 byte)

The last two bytes of every Modbus message are CRC bytes. These are computed based on the preceding bytes of the frame and allow both master and slave to verify the integrity of the received message.CRC is automatically handled my Flowcode Modbus Component.


01 03 02 00 01 25 CA
               -----
                 |
                 CRC (2 bytes)
                

Below is a Modbus message in general form,

[ID][FC][DATA][CRC]

ID corresponds to the slave id, FC is function code, data is function-specific variable length sequence of characters, and CRC is a 2-byte checksum.



Modbus Addresses

Modbus devices have 4 types of addresses:

  • Coil

  • Discrete Input

  • Input Register - (Analog Inputs in Flowcode)

  • Holding Register

Coils are 1-bit (boolean) read/write devices. Each coil can be in either on or off state. Discrete inputs are similar to coils, but they are read-only - it’s impossible to set the value of a discrete input.

Holding registers are like memory(locations). They are 16-bit words which you can both read and write via Modbus protocol. Input Registers are also 16-bit words, but they are read-only, like readings of a sensor.

A Modbus address is a 16-bit unsigned integer that is transmitted with every request to indicate which data should be read or written. Address occupies two characters in the Modbus message and the most significant byte is sent first (big-endian).


Function Codes

In this section we go through Modbus function codes and explain the specifics of data frame construction for each one of them.


Read Coils - 0x01

This function code allows the master to query the state of slave’s coils.


Request

[ID][FC][ADDR][NUM][CRC]
  • ADDR - the address of the first coil (2 bytes)

  • NUM - the number of coils to read (2 bytes)


A read coils request is always 8 bytes long. Here is example request to read 2 coils starting at address 0xA:

 ID   FC   ADDR     NUM    CRC
[01] [01] [00 0A] [00 02] [9D C9]

Response

[ID][FC][BC][DATA(1+)][CRC]
  • BC - the nubmer of bytes of DATA in the response (1 byte)

  • DATA - a sequence of bytes that contains the state of coils (1 byte per 8 coils)


A read coils response is at least 6 bytes long. In our example we have only one byte of DATA because we requested only two coils, so all data fits into a single byte:

 ID   FC   BC   DATA  CRC
[01] [01] [01]  [03] [11 89]


Read Discrete Inputs - 0x02

This function code allows the master to query the state of slave’s discrete inputs.

Request

[ID][FC][ADDR][NUM][CRC]
  • ADDR - the address of the first discrete input (2 bytes)

  • NUM - the number of inputs to read (2 bytes)

A read discrete inputs request is always 8 bytes long. Here is example request to read 2 discrete inputs starting at address 0x00:

 ID   FC   ADDR     NUM     CRC
[01] [02] [00 00] [00 02] [F9 CB]

Response

[ID][FC][BC][DATA(1+)][CRC]
  • BC - the number of bytes of DATA in the response (1 byte)

  • DATA - a sequence of bytes that contains the state of discrete inputs (1 byte per 8 inputs)


A read discrete inputs response is at least 6 bytes long. Example:

 ID   FC   BC  DATA   CRC
[01] [02] [01] [02] [20 49]


Read Holding Registers - 0x03

This function code allows the master to query the state of slave’s holding registers.


Request

[ID][FC][ADDR][NUM][CRC]
  • ADDR - the address of the first register (2 bytes)

  • NUM - the number of registers to read (2 bytes)

A read holding registers request is always 8 bytes long. In the request below we read 1 holding register at address 0x02:

 ID   FC   ADDR     NUM    CRC
[01] [03] [00 02] [00 01] [25 CA]

Response

[ID][FC][BC][DATA(2+)][CRC]
  • BC - the number of bytes of DATA in the response (1 byte)

  • DATA a sequence of bytes that contains the values of holding registers (2 bytes per register)


A read holding registers response is at least 7 bytes long. Example:

 ID   FC   BC   DATA     CRC
[01] [03] [02] [07 FF] [FA 34]


Write Single Coil - 0x05

Sets the value of a single slave’s coil.


Request

[ID][FC][ADDR][VAL][CRC]
  • ADDR - the address of the coil to write (2 bytes)

  • VAL - the value of the coil to write (2 bytes), 0xFF00 sets coil to ON, 0x0000 sets coil to OFF

A write single coil request is always 8 bytes long. Example:

 ID   FC   ADDR     NUM    CRC
[01] [05] [00 0A] [00 00] [ED C8]

Response

A successful response to write single coil repeats the request exactly:

 ID   FC   ADDR     NUM    CRC
[01] [05] [00 0A] [00 00] [ED C8]


Write Single Register - 0x06

Sets the value of a single slave’s holding register.

Request

[ID][FC][ADDR][VAL][CRC]
  • ADDR - the address of the register to write (2 bytes)

  • VAL - the value of the register to write (2 bytes)

A write single register request is always 8 bytes long. Example:

 ID   FC   ADDR     VAL    CRC
[01] [06] [00 02] [0C 00] [2D 0A]

Response

A successful response to write single register is exacly like the request:

 ID   FC   ADDR     VAL    CRC
[01] [06] [00 02] [0C 00] [2D 0A]

Write Multiple Coils - 0x0F

Sets the value of a consecutive range of slave’s coils.


Request

[ID][FC][ADDR][NUM][BC][DATA(1+)][CRC]
  • ADDR - the address of the first coil to write (2 bytes)

  • NUM - the number of the coils to write (2 bytes)

  • BC - the number of bytes of data in the request (1 byte)

  • DATA - the values of coils to set (1 bytes per 8 coils)

In this example we set values of 10 (0x0A) coils starting at 0x01 to ON:

 ID   FC   ADDR    NUM     BC   DATA     CRC
[01] [0F] [00 01] [00 0A] [0F] [FF 03] [AB CD]

Response

 ID   FC   ADDR    NUM     CRC
[01] [0F] [00 01] [00 0A] [AB CD]
  • ADDR - the address of the first updated coil (2 bytes)

  • NUM - the number of updated coils (2 bytes)


Write Multiple Registers - 0x10

Sets the value of a consecutive range of slave’s holding registers.


Request

[ID][FC][ADDR][NUM][BC][DATA(2+)][CRC]
  • ADDR - the address of the first register to write (2 bytes)

  • NUM - the number of the registers to write (2 bytes)

  • BC - the number of bytes of data in the request (1 byte)

  • DATA - the values of registers to set (2 bytes per register)

In this example where we write 2 registers starting at 0x0A:

 ID   FC   ADDR    NUM     BC      DATA        CRC
[01] [10] [00 0A] [00 02] [04] [00 0A 01 02] [AB CD]

Response

 ID   FC   ADDR    NUM     CRC
[01] [10] [00 0A] [00 02] [AB CD]
  • ADDR - the address of the first updated register (2 bytes)

  • NUM - the number of updated registers (2 bytes)

Exception Response

In some cases a slave might be unable to process a master request. For such occasions Modbus defines an Exception Response Frame:

[ID][FC][EC][CRC]
  • FC - the function code of the request that led to the exception with the most significant bit set to 1 (1 byte)

  • EC - an exception code explaining what happened (1 byte)

Example of an exception response to a read coils request:

 ID   FC   EC    CRC
[01] [81] [02] [C1 91]

The function code of read coils is 0x01, but in the exception response the most significant bit has been set to 1, so the code becomes 0x81:

0000 0001 => 1000 0001
 (0x01)       (0x81)

We took a look here at the basics of Modbus RTU as explained in the this article and the

reader is advised to take a look at it.We acknowledge the information used from this article.



Flowcode Modbus Component.


As shown below the Flowcode component supports Modbus RTU and TCP/IP in master and slave modes.








The components consists of the below macros to handle the various Modus functions,which allows the user to build Master or slave devices.




Example Project.

Modbus Slave Simulation in Proteus with Virtual Comport (VSPE)


We have build a Modbus slave controller in Proteus Mix Mode Simulator as shown in the below schematic.


Just a brief introduction to Proteus ,Proteus is a CAD Software that allows for drawing schematics and also creating PCB production files from the schematic,the benefit of Proteus

is its Mix mode simulator which combines the SPICE analog simulation features with Digital Simulation i.a.w it can run generated hex files from code for a microprocessor as if it is running on the real micro processor.This allows to test code and electronic Hardware design

in your PC with out having any real Hardware build .


Our Slave device consist of a PIC16F1938 which reads the temperature of a system and controls a DC motor (Fan) in close loop Temperature Control ,it reports the temperature and system status to the master (Modus) which in out case is a PC.


The slave has 3 led indicators

  1. LED 1 - called Led_RUN which is blinking at 200 mSec rate to indicate that the controller is active and alive.