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
LED 1 - called Led_RUN which is blinking at 200 mSec rate to indicate that the controller is active and alive.
LED 2 - called Led_ON is activated when the Run switched is closed
LED 3 - called M1_ON is activated when the DC motor is running or switched on
The DC motor(Fan) is speed controlled by supplying PWM signals to the Driver IC DRV8871 and the Motor Current for current control is measured by the INA219 Current sense IC.
The temperature is measured by a LM75 sensor and the sensor supply an analog signal corresponding to temperature
Note: the schematic was done to show the operation of the Modbus component and are not designed to be a high level hardware this is a very basic design.
The slave is equipped with a serial port connector (P1) which we link to a virtual comport Emulator (VSPE) this allows us to send and receive the Modbus request and responses from the slave(PIC16F1938) in simulation as it would be in the real hardware.
The PC master Software we use the Profi-lab client which we also connect to the virtual comport and we have a full closed connection mater and slave in simulation as we would have in the real world .
As you can see we have a slave and master all in Simulation and simulating with the real code (Flowcode generated hex file ) of the salve hardware.
What are we actually simulating now?
We simulate the operation of the intended electronic components such as the DRV8871,the INA 219 current sense etc
We simulate our slave controller firmware(software written)
We simulate the complete salve hardware and software for operation and functionality
We simulate the complete Modbus communication
After our simulation is done and all is working as expected we can build this system/hardware and program it and our first build will work just as it did in our simulation.
Clearly this method has great advantages for Engineers and makers as all is done and tested in PC which makes it easy to correct bugs and operation issue with building a number of proto-type units.
In our slave device we use the following Modbus functions
Coils - 3 Led indicators
Inputs - Run Switch
Analog Register - ADC value from the temperature
Holding Register - DC Motor Current

In the below picture the slave is running in Simulation and executing the the Flowcode generated hex file
The LED's are switched on and the motor (Fan) rotating the as the Run switch is closed.
The temperature is above 40°C and the Software is activating the PWM signals to the DC motor driver DRV8871
The Serial Port is active indicated by the green terminals.
We can now send requests from the PL PC software and request some data

This is an extract of the Modbus code in Flowcode.

We send the following 2 request to the slave
Read Coil 1
Read Holding register for the speed of the motor

The slave responce is shown in the PL Terminal window($ = Hex values)
(all is done over Virtual Serial port and Simulation (SPICE 3F5 and Mix mode)

Below shown the motor running with speed indication

Here are the Requests and Responses when logged on the Logic Analyser


The Led's and Motor running in Simulation

Conclusion
Modus devices can easily be developed using Flowcode as the programming Language and using Simulation tools the devices can be developed and tested in the design cycle with out having to build various proto-type units once a acceptable Hardware and Software status is achieved a first proto-type unit can/should be build and real world functionality should then be tested and verified
Using simulation in the development cycle allows for easy and cheap correction to be done.
FlowcodeXchange can support any one that needs help in development of Modus devices or Firmware for Modbus devices.Contact us by using one of the various contact pages on our web page.
Sources: