OVMS3-idf/examples/protocols/modbus_master/README.md
Alex Lisitsyn 449d2a6367 freemodbus: Fix bug with incorrect coils read mask
Contains two different component folders per each implementation (serial_master and serial_slave) with concrete ports.
Added common public api for master and slave and common interface for master and slave implementation.
Add support of cmake system (added cmake files).
Added sdkconfig.defaults files for slave and master modbus examples.
Updated make file and KConfig for freemodbus component
Update according to review and fix doxygen warnings
Fix Doxyfile to pass documentation build
Update headers and change interface file names as per review comments
Merge  branch feature/freemodbus_move_rs485_mode_control
Update after review:
The stack modbus folder updated to support master and slave ports together and moved into freemodbus/modbus
Stack and port files updated to remove duplicated simbols
Make file, KConfig and CMakeLists.txt updated to compile master and slave stacks, common interface and concrete implementations of ports
Stack callback functions execute callbacks using interface pointer from concrete port implementation
User can instantiate any of concrete port using common API (only one concrete port at a time) and it does not require to select port by KConfig
Port pins and mode configuration moved into example files from port files to allow user select pins and port mode (customer request)
Changes tested using pymodbus, ModbusPoll and communication between two boards
Updated DoxyFile according to public include path
Fix maximum instance size for slave (merge from master of customer issue)
Fix critical section issue TW#28622 (change spin lock based critical section to semaphore)
Move serial port files into component port folder for master and slave accordingly
Fix example issue showed in the log when IO slave is not configured correctly
Fix conflicts while merging from origin/master
Fix errors handling in modbus controller interface + some final corrections according to review
Update maximum allowed number of slaves in the network segment
Fix bug with incorrect coils read mask

Closes https://github.com/espressif/esp-idf/issues/858
2019-04-16 10:21:20 +02:00

7.5 KiB

Modbus Master Example

This example demonstrates using of FreeModbus stack port implementation for ESP32 as a master device. This implementation is able to read/write values of slave devices connected into Modbus segment. All parameters to be accessed are defined in data dictionary in the files /main/device_params.h/c. The values represented as characteristics with its name and characteristic CID which are linked into registers of slave devices connected into Modbus segment.

The example implements simple control algorithm and checks humidity and temperature from two sensors and set alarm (relay in third device) when values exceeded limits.

Device parameters definition:

Slave address Characteristic ID Characteristic name Description
MB_DEVICE_ADDR1 CID_DATA_CHAN_0, Data_channel_0 Data channel 1
MB_DEVICE_ADDR1 CID_HUMIDITY_1, Humidity_1 Humidity from sensor 1
CID_TEMPERATURE_1 Temperature_1 Sensor 1 temperature
MB_DEVICE_ADDR2 CID_HUMIDITY_2, Humidity_2 Humidity from sensor 2
CID_TEMPERATURE_2 Temperature_2 Sensor 2 temperature
MB_DEVICE_ADDR3 CID_RELAY_P1 RelayP1 Alarm Relay outputs on/off

Modbus segment device connection schematic:

   MB_DEVICE_ADDR1
    -------------
    |           |   
    |  Slave 1  |---<>--+
    |           |       |
    -------------       |
   MB_DEVICE_ADDR2      |
    -------------       |        -------------
    |           |       |        |           |
    |  Slave  2 |---<>--+---<>---|  Master   |
    |           |       |        |           |
    -------------       |        -------------
   MB_DEVICE_ADDR3      |
    -------------  RS485 network
    |           |       |
    |  Slave 3  |---<>--+
    |           |
    -------------

Hardware required :

Option 1: PC (Modbus Slave app) + USB Serial adapter connected to USB port + RS485 line drivers + ESP32 WROVER-KIT board. Option 2: Three ESP32 WROVER-KIT board flashed with modbus_slave example software to represent slave device with specific slave address. The slave addresses for each board have to be configured as defined in "Device parameters definition" table above. One ESP32 WROVER-KIT board flashed with modbus_master example. All the boards require connection of RS485 line drivers (see below).

The MAX485 line driver is used as an example below but other similar chips can be used as well. RS485 example circuit schematic for connection of master and slave devices into segment:

         VCC ---------------+                               +--------------- VCC
                            |                               |
                    +-------x-------+               +-------x-------+
         RXD <------| RO            | DIFFERENTIAL  |             RO|-----> RXD
                    |              B|---------------|B              |
         TXD ------>| DI   MAX485   |    \  /       |    MAX485   DI|<----- TXD
ESP32 WROVER KIT 1  |               |   RS-485 side |               |      External PC (emulator) with USB to serial or
         RTS --+--->| DE            |    /  \       |             DE|---+  ESP32 WROVER KIT 2 (slave)     
               |    |              A|---------------|A              |   |
               +----| /RE           |    PAIR       |            /RE|---+-- RTS
                    +-------x-------+               +-------x-------+
                            |                               |
                           ---                             --- 
                    Modbus Master device             Modbus Slave device
                           

How to setup and use an example:

Configure the application

Configure the UART pins used for modbus communication using command and table below.

make menuconfig
  ------------------------------------------------------------------------------------------------
  | ESP32 Interface       | #define                      | Default ESP32 Pin | External RS485 Pin|
  | ----------------------|------------------------------|-------------------|-------------------|
  | Transmit Data (TxD)   | CONFIG_MB_UART_TXD           | GPIO23            | DI                |
  | Receive Data (RxD)    | CONFIG_MB_UART_RXD           | GPIO22            | RO                | 
  | Request To Send (RTS) | CONFIG_MB_UART_RTS           | GPIO18            | ~RE/DE            |
  |                       |                              |                   |                   |
  | Ground                | n/a                          | GND               | GND               |
  ------------------------------------------------------------------------------------------------

The communication parameters below allow to configure Modbus stack appropriately but usually it is enough to use default settings. See the help string of parameters for more information.

Setup external Modbus slave devices or emulator

Option 1: Configure the external Modbus master software according to port configuration parameters used in the example. The Modbus Slave application can be used with this example to emulate slave devices with its parameters. Use official documentation for software to setup emulation of slave devices. Option 2: Other option is to have the modbus_slave example flashed into ESP32 WROVER KIT board and connect boards together as showed in "Modbus segment connection schematic above". See the modbus slave API documentation to configure communication parameters and slave addresses as defined in "Device parameters definition" table above.

Build and flash software of master device

Build the project and flash it to the board, then run monitor tool to view serial output:

make -j4 flash monitor

(To exit the serial monitor, type Ctrl-].)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

Example Output

Example output of the application:

I (51493) SENSE_MAIN: cid: 0, Data_channel_0(Volts) = 6.00
I (51543) SENSE_MAIN: cid: 1, Humidity_1(%rH) = 22.00
I (51573) SENSE_MAIN: cid: 2, Temperature_1(C) = 0.00
I (51603) SENSE_MAIN: cid: 3, Humidity_2(%rH) = 1.00
I (51633) SENSE_MAIN: cid: 4, Temperature_2(C) = 33.00
I (51673) SENSE_MAIN: cid: 5, (RelayP1) = OFF
I (61713) SENSE_MAIN: cid: 0, Data_channel_0(Volts) = 50.00
I (61763) SENSE_MAIN: cid: 1, Humidity_1(%rH) = 22.00
I (61793) SENSE_MAIN: cid: 2, Temperature_1(C) = 0.00
I (61823) SENSE_MAIN: cid: 3, Humidity_2(%rH) = 1.00
I (61853) SENSE_MAIN: cid: 4, Temperature_2(C) = 33.00
I (61893) SENSE_MAIN: cid: 5, (RelayP1) = OFF
I (62893) SENSE_MAIN: The value exceeds limit, then set relay.
I (71953) SENSE_MAIN: cid: 0, Data_channel_0(Volts) = 50.00
I (71993) SENSE_MAIN: cid: 1, Humidity_1(%rH) = 22.00
I (72023) SENSE_MAIN: cid: 2, Temperature_1(C) = 0.00
I (72063) SENSE_MAIN: cid: 3, Humidity_2(%rH) = 1.00
I (72093) SENSE_MAIN: cid: 4, Temperature_2(C) = 33.00
I (73143) SENSE_MAIN: cid: 5, (RelayP1) = ON

The example refreshes the characteristics from devices every 10 seconds, verifies if they exceeded limits and sets alarm accordingly. The output line describes Timestamp, Cid of characteristic, Characteristic name(Units), Characteristic value.