Skip to main content

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
    1. RS485/RS232 Serial (Modbus-RTU)
    2. 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.
    1. Coil (Discrete Output)
    2. Discrete Input (or Status Input)
    3. Holding Register
    4. 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

  1. Read data stored in PLC/SCADA.
  2. Write data stored in PLC/SCADA.

Using Modbus Shunya stack

Requirements to use Modbus Shunya stack

  1. Shunya OS installed (supported Arm devices) or Shunya OS docker container (X86 based windows/linux devices)
  2. PLC/SCADA with Modbus support.

Steps to use Modbus Shunya stack

  1. Set PLC Modbus settings in Shunya.
  2. Load Modbus settings.
  3. Read from Modbus server.
  4. 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.

ConfigDescription
modbusTypeModbus is available in 2 variants RTU and TCP. Select the mode that you want to communicate.
modbusServerIpModbus server IP address (only for Modbus TCP type)
modbusSerialBaudrateModbus server Port (only for Modbus TCP type)
modbusSerialDeviceModbus server Device node (only for Modbus RTU type)
modbusSerialBaudrateModbus server Baud rate (only for Modbus RTU type)

Example configuration:

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",
},

Step 2: Load Modbus settings.

  1. 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-registers
  2. Open the read-modbus-registers.c in an text editor and modify as per your use case.

  3. 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 is modbusTcpSettings.

Step 3: Read data stored in PLC/SCADA registers via Modbus.

  1. 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:

    1. PLC coil status is stored in coil register at address 0x01
    2. Analog sensor data is stored in holding register at address 0x02
    NameRegister TypeRegister AddressData type of the value stored in the register
    PLC coilCoil register0x01int16
    Analog sensorHolding Register0x02int16
  2. Open the read-modbus-registers.c in an text editor and modify as per your use case.

  3. 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);
  4. Read Analog sensor data stored in PLC at 0x02 address, 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 */

    uint16_t sensorValue = modbusRead(&plc, MODBUS_READ_HOLDING_REG, 0x02); /* Read Modbus Holding register at 0x02 */

    /* Disconnect from the Modbus server */
    modbusDisconnect(&plc);
  5. Once you are done editing, save and compile the code , by running

    mkdir build && cd build
    cmake ../
    make
  6. Run the code

    sudo ./read-modbus-registers
  7. More examples to read data from PLC via Modbus using shunya stack

    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 */

Step 4: Change values in PLC/SCADA registers via Modbus.

  1. 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:

    1. PLC coil status is stored in coil register at address 0x01
    NameRegister TypeRegister AddressData type of the value stored in the register
    PLC coilCoil register0x01int16
  1. 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-registers
  2. Open the write-modbus.c in an text editor and modify as per your use case.

  3. 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);
  4. Once you are done editing, save and compile the code , by running

    mkdir build && cd build
    cmake ../
    make
  5. Run the code

    sudo ./write-modbus
  6. More examples to change data stored in PLC via Modbus using shunya stack

    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 */

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 :

  1. 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:

    1. PLC coil status is stored in coil register at address 0x01
    2. Analog sensor data is stored in holding register at address 0x02
    NameRegister TypeRegister AddressData type of the value stored in the register
    PLC coilCoil register0x01int16
    Analog sensorHolding Register0x02int16
  2. 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-registers
  3. Open the read-modbus-registers.c in an text editor and modify as per your use case.

  4. 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);
  5. Read Analog sensor data stored in PLC at 0x02 address, add the highlighted code in your main() function

    /* Read Modbus Holding register at 0x02 */
    uint16_t sensorValue = modbusRead(&plc, MODBUS_READ_HOLDING_REG, 0x02);
  6. 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);
  7. Once you are done editing, save and compile the code , by running

    mkdir build && cd build
    cmake ../
    make
  8. Run the code

    sudo ./read-modbus-registers

Facing errors with the component?