We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you've provided to them or that they've collected from your use of their services.

MODBUS - introduction

Once you understand how the PLC's memory is structured and how the variable addresses work to store their values in a desired place (see previous article), you can try to use the MODBUS protocol.  It is an industry standard for a communication between various systems.  It can be used for connecting a HMI panel to your PLC, connecting a 1-wire module or connecting the PLC to your PC...

WARNING! All that you find here is an amateur attempt to cover a complex subject with a simple mind.  I ask the experts to have understanding.  Unfortunately none of the 'professional' descriptions of the protocol was understandable to me.  What you see below is a composition of bits an pieces found on random sites.

The MODBUS communication is done by executing 'functions'.  They can be split into two main categories: 1st for bit (BOOL) variables and the 2nd for WORD.  Then that distinction can be split again into variables, which are read-only and those which can be overwritten.

Here is a table which shows the split of the main MODBUS functions:

  Read/Write Read only
BIT/BOOL

FC1 - Read Coil
FC5 - Write Coil
FC15 - Write Multiple Coils

 FC2 - Read Discrete Input
WORD

FC3 - Read Holding Register
FC6 - Write Single Register
FC16 - Write Multiple Registers
FC23 - Read/Write multiple registers

FC4 - Read Input Registers

 

To be honest, I do not like those function names.  I do not know why a 'coil' or a 'discrete input'.  What matters is that in order to read a single bit I can use FC1 or FC2, to write it - FC5 or FC15; for WORD values the functions are: FC3, FC4 for reading and FC6, FC16 or FC23 to write.  That's all.

To clarify - MODBUS can let you read or modify some areas of your PLC's memory.  It does not accept commands like "turn on the lights" or "show me the temperature".  To do that you need to reach for a specific part of the PLC's memory and interpret it.  

Now it is time to understand how the addresses of MODBUS protocol fit the map of addresses in PLC's memory.  In the PLC manual one can find a whole chapter titled "MODBUS Register Mapping".  You can find there tables showing the link between MODBUS and WAGO controllers.  

In case of reading/writing single bits (functions FC1, FC2 and FC5) the following values need to be used.  In case of digital ins or outs (DI or DO) one need to know their consecutive number, not their address in PLC's memory:

Address MODBUS [dec] Memory range Description
0...511

Physical inputs

First 512 digital inputs
512...1023

Physical outputs

First 512 digital outputs
12288...32767

%MX0...%MX1279.15

NOVRAM
retain memory

 For WORD variables (functions FC3 i FC4):

Adres MODBUS  [dec] Memory range Description
0...255

%IW0...%IW255

Physical input area
512...767

%QW0...%QW255

Physical output area
12288...24575

%MW0...%MW12287

NOVRAM 
retain memory

So, let's look at some examples:

  • in order to read the status on input 0 use function FC1 and address 0
  • in order to read the status of output 3 use function FC1 and address 514
  • in order to read the BOOL value stored at %MX0.3, use function FC1 and address 12 291
  • in order to read the first word of the table holding statuses of inputs, use function FC3 and address 0
  • in order to read the first word of the table holding statuses of outputs, use function FC3 and address 512
  • in order to read a WORD variable stored at %MW0, use function FC3 and address 12288,

Writing values is very similar.  One just has to remember that PLC's inputs are read-only.

Now it is time for a specific example from my PLC:

Modbus 11 Modbus 1 204

The input IN4 is the 4th physical input in my PLC, while the OUT 3 is the third.  Quite distant addresses in the memory (%IX11.2 i QX3.2) are the consequence of additional modules using the first areas of the memory - in my case the analog sensors and RS232 communication module.

Example MODBUS commands:

MODBUS equivalent to WAGO WebServer Reply
FC2 3 (to get the 4th input)

READPI?ADR=IX11.3&FORMAT=%x

TRUE
FC1 514 (to get the 3rd output)

READPI?ADR=QX3.2&FORMAT=%x

TRUE

FC4 11

READPI?ADR1=IW11&FORMAT=%d

8
(00000000 00001000)

FC5 515

READPI?ADR1=QW3&FORMAT=%d

204
(00000000 11001100)

How to check it all?  One possibility is to use a phpmodbus library available at https://code.google.com/p/phpmodbus/.  It integrates MODBUS functionality into PHP.

Here is an example of reading values of the 4th word of output table (address 515, the last example in the table above):

<?php

require_once dirname(__FILE__) . '/Phpmodbus/ModbusMaster.php';

// Create Modbus object
$modbus = new ModbusMaster("192.168.1.3", "UDP");

try {
    // FC 1
    $recData = $modbus->readMultipleRegisters(0, 515, 1);
}
catch (Exception $e) {
    // Print error information if any
    echo $modbus;
    echo $e;
    exit;
}

// Print read data
echo "Data:";
var_dump($recData);

The script returns the following on execution:

Data:
array(2) { [0]=> int(0) [1]=> int(204) }

What do those number mean?  We read a WORD built of 2 bytes.  The first is 0, the second is 204.  204 in binary system is 11001100.  Reading from the end we have two first bits = false, two following bits = true (those are %QX3.2 and %QX3.3), 2 further bits = false and 2 final bits = true.  All fits the screenshot shown at the beginning of this article.

All I need now is to find a device which will let me use the protocol, prepare PHP scripts, which would be an intermediation between that device and the PLC.... ...or maybe talking directly from the PLC via ethernet or RS485 module?