Modbus
warning
The document is a continuation of the previous document, if you have landed directly on this page then, Please read from page Get started.
What is Modbus?
- PLC's and SCADA are Industrial computers that control factories and factory equipment.
- Modbus is a communication protocol used to communicate with PLC and SCADA.
- Modbus protocol can be used with 2 physical Interfaces
- RS485/RS232 Serial (Modbus-RTU)
- Ethernet/Wifi (Modbus-TCP)
Modbus Registers
- PLC's and SCADA store the data for monitor and control into 16-bit memory blocks called as registers.
- Each register has its unique address that allows us to read or write into the registers, called as Register address.
- There are 4 different types of registers in a PLC with Modbus.
- Coil (Discrete Output)
- Discrete Input (or Status Input)
- Holding Register
- Input Register
List of Modbus features implemented in Shunya stack
With Shunya stack you can make IoT device to act as a Modbus client i.e you can
- Read data stored in PLC/SCADA.
- Write data stored in PLC/SCADA.
Using Modbus Shunya stack
Requirements to use Modbus Shunya stack
- Shunya OS installed (supported Arm devices) or Shunya OS docker container (X86 based windows/linux devices)
- PLC/SCADA with Modbus support.
Steps to use Modbus Shunya stack
- Set PLC Modbus settings in Shunya.
- Load Modbus settings.
- Read from Modbus server.
- Write to Modbus server.
note
Run the steps given below inside Shunya OS installed (supported Arm devices) or Shunya OS docker container (X86 based windows/linux devices) terminals.
Step 1: Set PLC Modbus settings in Shunya
Set PLC Modbus settings, by editing the config file /etc/shunya/config.json
inside Shunya OS.
A simple configuration should contain these parameters.
Config | Description |
---|---|
modbusType | Modbus is available in 2 variants RTU and TCP. Select the mode that you want to communicate. |
modbusServerIp | Modbus server IP address (only for Modbus TCP type) |
modbusSerialBaudrate | Modbus server Port (only for Modbus TCP type) |
modbusSerialDevice | Modbus server Device node (only for Modbus RTU type) |
modbusSerialBaudrate | Modbus server Baud rate (only for Modbus RTU type) |
Example configuration:
- Modbus over Ethernet/Wifi
- Modbus over Serial
Writing the below json in /etc/shunya/config.json
file, will tell the Shunya stack to
connect to PLC over Ethernet/Wifi interface with IP 192.168.0.101
and port 5059
.
"modbusTcpSettings": {
"modbusType": "tcp",
"modbusServerIp": "192.168.0.101",
"modbusServerPort": "5059",
},
Writing the below json in /etc/shunya/config.json
file, will tell the Shunya stack to
connect to PLC over serial interface with device /dev/ttyS1
and with baudrate 9600
.
"modbusRtuSettings": {
"modbusType": "rtu",
"modbusSerialDevice": "/dev/ttyS1",
"modbusSerialBaudrate": 9600,
},
Step 2: Load Modbus settings.
Start with an ready to use template for reading data stored in PLC/SCADA via Modbus
git clone https://gitlab.iotiot.in/repo-public/examples.git
cd examples/simple-examples/read-modbus-registersOpen the
read-modbus-registers.c
in an text editor and modify as per your use case.To load the json configuration set in Step 1, we ned to add below line.
/* Loads json settings for modbus */
modbusObj plc = newModbusClient("modbusTcpSettings"); /* Argument = JSON Title */info
The argument to the function
newModbusClient()
should match the JSON title in the configuration, in our case it ismodbusTcpSettings
.
Step 3: Read data stored in PLC/SCADA registers via Modbus.
Get Modbus adresses for PLC registers which store the data that we want to read, these Modbus addresses are available on the PLC's software.
For example:
- PLC coil status is stored in
coil register
at address0x01
- Analog sensor data is stored in
holding register
at address0x02
Name Register Type Register Address Data type of the value stored in the register PLC coil Coil register 0x01 int16 Analog sensor Holding Register 0x02 int16 - PLC coil status is stored in
Open the
read-modbus-registers.c
in an text editor and modify as per your use case.For our example, we need to first read PLC coil status, add the highlighted code in your
main()
function/* Create the modbus instance */
modbusObj plc = newModbusClient("modbusTcpSettings"); /* Argument = JSON Title, Load settings from JSON file */
/* Connect to the Modbus Slave/Server*/
modbusConnect(&plc);
/* --- Read the values from the PLC --- */
int status = modbusRead(&plc, MODBUS_READ_COILS, 0x01); /* Read Modbus Coil register at 0x01 */
/* Disconnect from the Modbus server */
modbusDisconnect(&plc);Read Analog sensor data stored in PLC at
0x02
address, add the highlighted code in yourmain()
function/* Create the modbus instance */
modbusObj plc = newModbusClient("modbusTcpSettings"); /* Argument = JSON Title, Load settings from JSON file */
/* Connect to the Modbus Slave/Server*/
modbusConnect(&plc);
/* --- Read the values from the PLC --- */
int status = modbusRead(&plc, MODBUS_READ_COILS, 0x01); /* Read Modbus Coil register at 0x01 */
uint16_t sensorValue = modbusRead(&plc, MODBUS_READ_HOLDING_REG, 0x02); /* Read Modbus Holding register at 0x02 */
/* Disconnect from the Modbus server */
modbusDisconnect(&plc);Once you are done editing, save and compile the code , by running
mkdir build && cd build
cmake ../
makeRun the code
sudo ./read-modbus-registers
More examples to read data from PLC via Modbus using shunya stack
- Read Coil Registers
- Read Input Registers
- Read Holding Register (Integer)
- Read Holding Register (Float)
For reading data from PLC coil register, change code in step 4. with the example given below.
/* --- Read the values from the PLC --- */
uint16_t value1 = modbusRead(&plc, MODBUS_READ_COILS, 0x01); /* Read Modbus Coil register 0x01 */For reading data from PLC Input register, change code in step 4. with the example given below.
uint16_t value5 = modbusRead(&plc, MODBUS_READ_INPUT_REG, 0x06); /* Read Modbus Holding register 0x06 */
For reading
integer
data from PLC Holding register, change code in step 4. with the example given below.uint16_t value3 = modbusRead(&plc, MODBUS_READ_HOLDING_REG, 0x03); /* Read Modbus Holding register 0x03 */
For reading
floating point
data from PLC Holding register, change code in step 4. with the example given below.float value4 = modbusReadFloat(&plc, MODBUS_READ_HOLDING_REG, 0x04); /* Read Modbus Holding register 0x04 */
Step 4: Change values in PLC/SCADA registers via Modbus.
Get Modbus adresses for PLC registers which store the data that we want to change, these Modbus addresses are available on the PLC's software.
For example:
- PLC coil status is stored in
coil register
at address0x01
Name Register Type Register Address Data type of the value stored in the register PLC coil Coil register 0x01 int16 - PLC coil status is stored in
Start with an ready to use template for reading data stored in PLC/SCADA via Modbus
git clone https://gitlab.iotiot.in/repo-public/examples.git
cd examples/simple-examples/write-modbus-registersOpen the
write-modbus.c
in an text editor and modify as per your use case.For our example, we need to change PLC coil status to on, add the highlighted code in your
main()
function/* Create the modbus instance */
modbusObj plc = newModbusClient("modbusTcpSettings"); /* Argument = JSON Title, Load settings from JSON file */
/* Connect to the Modbus Slave/Server*/
modbusConnect(&plc);
/* --- Write the values to the PLC --- */
modbusWrite(&plc, MODBUS_WRITE_COIL, 0x01, 1); /* Write value 1 to Modbus Coil register */
/* Disconnect from the Modbus server */
modbusDisconnect(&plc);Once you are done editing, save and compile the code , by running
mkdir build && cd build
cmake ../
makeRun the code
sudo ./write-modbus
More examples to change data stored in PLC via Modbus using shunya stack
- Read Coil Registers
- Read Input Registers
For changing data in PLC coil register, change code in step 4. with the example given below.
/* --- Write the values to the PLC --- */
modbusWrite(&plc, MODBUS_WRITE_COIL, 0x01, 1); /* Write value 1 to Modbus Coil register */For changing data in PLC Input register, change code in step 4. with the example given below.
/* --- Write the values to the PLC --- */
modbusWrite(&plc, MODBUS_WRITE_REG, 0x02, 1); /* Write value 1 to Modbus Input register */
Understand this component with an example (ready to use code)
Let's take an example use case: Say we need to
- Read status of PLC coil and check if it is on/off.
- Read data from the analog sensor connected to PLC.
- Change status of PLC coil to on.
Steps are :
Get Modbus adresses for PLC registers which store the data that we want to read, these Modbus addresses are available on the PLC's software.
For example:
- PLC coil status is stored in
coil register
at address0x01
- Analog sensor data is stored in
holding register
at address0x02
Name Register Type Register Address Data type of the value stored in the register PLC coil Coil register 0x01 int16 Analog sensor Holding Register 0x02 int16 - PLC coil status is stored in
Start with an ready to use template for reading data stored in PLC/SCADA via Modbus
git clone https://gitlab.iotiot.in/repo-public/examples.git
cd examples/simple-examples/read-modbus-registersOpen the
read-modbus-registers.c
in an text editor and modify as per your use case.For our example, we need to first read PLC coil status, add the highlighted code in your
main()
function/* Read Modbus Coil register at 0x01 */
int status = modbusRead(&plc, MODBUS_READ_COILS, 0x01);Read Analog sensor data stored in PLC at
0x02
address, add the highlighted code in yourmain()
function/* Read Modbus Holding register at 0x02 */
uint16_t sensorValue = modbusRead(&plc, MODBUS_READ_HOLDING_REG, 0x02);For our example, we need to change PLC coil status to on, add the highlighted code in your
main()
function/* Write value 1 to Modbus Coil register */
modbusWrite(&plc, MODBUS_WRITE_COIL, 0x01, 1);Once you are done editing, save and compile the code , by running
mkdir build && cd build
cmake ../
makeRun the code
sudo ./read-modbus-registers