ESP-IDF Modbus 主站示例程序

支持的芯片型号 ESP32 ESP32-C2 ESP32-C3 ESP32-C6 ESP32-H2 ESP32-S2 ESP32-S3

Modbus主站例子

这个示例展示了使用FreeModbus协议栈来实现ESP32作为主站设备来进行通信,
该示例能读取和写入连接到Modbus线路从站设备的属性值。所有需要访问的参数都在在Modbus主站示例源文件的数据字典中定义。
这些参数以属性的形式表示,每个属性都有其名称和属性ID ,这些属性与连接到Modbus线路的从站设备的寄存器相关联。
此外,该示例实现了一个简单的控制算法,用于检查从设备的参数。如果holding_data0参数的值超出限制,则会发出警报(在从设备中的继电器上)。
值得注意的是,modbus参数的实例对于主站和从站示例是通用的,它们都位于examples/protocols/modbus/mb_example_common文件夹中。

参数定义示例:

从站地址 属性ID 属性名称 描述
MB_DEVICE_ADDR1 CID_INP_DATA_0, Data_channel_0 数据通道 1
MB_DEVICE_ADDR1 CID_HOLD_DATA_0, Humidity_1 湿度1
MB_DEVICE_ADDR1 CID_INP_DATA_1 Temperature_1 传感器温度
MB_DEVICE_ADDR1 CID_HOLD_DATA_1, Humidity_2 湿度2
MB_DEVICE_ADDR1 CID_INP_DATA_2 Temperature_2 环境温度
MB_DEVICE_ADDR1 CID_HOLD_DATA_2 Humidity_3 湿度3
MB_DEVICE_ADDR1 CID_RELAY_P1 RelayP1 报警继电器输出 on/off
MB_DEVICE_ADDR1 CID_RELAY_P2 RelayP2 报警继电器输出 on/off

注意:
从站地址对于测试示例的所有参数都是相同的,但它可以在主站示例的“示例数据(对象)字典”表中更改,以寻址来自其他从站的参数。
从站示例中的 Kconfig Modbus slave address- CONFIG_MB_SLAVE_ADDR参数可创建多个Modbus从站设备。

简单的Modbus连接示意图:

   MB_DEVICE_ADDR1
   -------------                -------------
   |           | RS485 network  |           |
   |  Slave  1 |---<>--+---<>---|  Master   |
   |           |                |           |
   -------------                -------------

一主多从Modbus连接示意图:

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

所需硬件 :

选项1:
PC (Modbus从站应用软件) + 连接到USB端口的USB串行适配器 + RS485线路驱动器 + ESP32开发板

选项2:
首先,我们需要为几个ESP32开发板烧写modbus_slave示例,并确保它们具有独特的从站地址,以符合“连接示意图”中的定义。
其次,为了实现主从通信,我们需要将一个ESP32开发板烧写modbus_master示例。
此外,所有这些开发板都需要通过RS485线路进行连接,具体信息参见下文。

以下使用MAX485驱动芯片作为示例,但也可以使用其他类似的芯片。
主站设备和从站设备连接到RS485部分电路示意图:

         VCC ---------------+                               +--------------- VCC
                            |                               |
                    +-------x-------+               +-------x-------+
         RXD <------| RO            | DIFFERENTIAL  |             RO|-----> RXD
                    |              B|---------------|B              |
         TXD ------>| DI   MAX485   |      /       |    MAX485   DI|<----- TXD
ESP32 板子           |               |   RS-485 side |               |      外置PC(仿真器)USB转串口 或者
         RTS --+--->| DE            |    /         |             DE|---+  ESP32 从站板子
               |    |              A|---------------|A              |   |
               +----| /RE           |    PAIR       |            /RE|---+-- RTS
                    +-------x-------+               +-------x-------+
                            |                               |
                           ---                             --- 
                      Modbus 主站设备                  Modbus 从站设备
                           

如何设置和使用示例:

配置软件

输入下面的命令开始配置:

idf.py menuconfig
  1. 使用下表用于modbus通信的UART引脚
  2. 在Kconfig中定义主站设备和从站设备的通信模式参数 - CONFIG_MB_COMM_MODE(主站设备和从站设备的模式必须相同)
  3. 为每个从站配置从站地址(Kconfig 中的 CONFIG_MB_SLAVE_ADDR)
  ------------------------------------------------------------------------------------------------------------------------------
  |  UART Interface       | #define            | Default pins for      | Default pins for          | External RS485 Driver Pin |
  |                       |                    | ESP32 (C6)            | ESP32-S2 (S3, C3, C2, H2) |                           |
  | ----------------------|--------------------|-----------------------|---------------------------|---------------------------|
  | Transmit Data (TxD)   | CONFIG_MB_UART_TXD | GPIO23                | GPIO9                     | DI                        |
  | Receive Data (RxD)    | CONFIG_MB_UART_RXD | GPIO22                | GPIO8                     | RO                        |
  | Request To Send (RTS) | CONFIG_MB_UART_RTS | GPIO18                | GPIO10                    | ~RE/DE                    |
  | Ground                | n/a                | GND                   | GND                       | GND                       |
  ------------------------------------------------------------------------------------------------------------------------------

注意: 每个目标芯片都有不同的GPIO引脚可用于UART连接。有关更多信息,请参阅所选目标的UART文档。
将USB转RS485适配器连接到计算机,然后将适配器的A/B输出线与连接到ESP32芯片的RS485线路的相应A/B输出线连接(见图)。
Modbus协议栈的通信参数允许对其进行适当配置,但通常使用默认设置就足够了。
有关详细信息,请参阅参数的帮助字符串。

设置外部Modbus从站设备或仿真器

选项1:
根据示例中使用的端口配置参数配置外部Modbus主软件。Modbus Slave应用程序可与此示例一起使用,以通过其参数模拟从属设备。使用软件的官方文档来设置从属设备的仿真。

选项2:
另一种选择是将modbus_slave示例应用程序闪存到基于ESP32的板中,并将板连接在一起,如上面的modbus连接示意图所示。请参阅Modbus从API文件,以配置上面“示例参数定义”表中定义的通信参数和从地址。

主站设备的应用编译和烧写

构建项目并烧写程序到板上,然后运行监视器工具查看串行输出:

idf.py -p PORT flash monitor

(退出串行监视器, 输入 Ctrl-].)

有关配置和使用ESP-IDF构建项目的完整步骤,请参阅《Getting Started Guide》

示例输出

应用程序的示例输出:

I (9035) MASTER_TEST: Characteristic #0 Data_channel_0 (Volts) value = 1.120000 (0x3f8f5c29) read successful.
I (9045) MASTER_TEST: Characteristic #1 Humidity_1 (%rH) value = 5.539999 (0x40b147ac) read successful.
I (9045) MASTER_TEST: Characteristic #2 Temperature_1 (C) value = 2.340000 (0x4015c28f) read successful.
I (9055) MASTER_TEST: Characteristic #3 Humidity_2 (%rH) value = 2.560000 (0x4023d70a) read successful.
I (9065) MASTER_TEST: Characteristic #4 Temperature_2 (C) value = 3.560000 (0x4063d70a) read successful.
I (9075) MASTER_TEST: Characteristic #5 Humidity_3 (%rH) value = 3.780000 (0x4071eb85) read successful.
I (9085) MASTER_TEST: Characteristic #6 RelayP1 (on/off) value = OFF (0x55) read successful.
I (9095) MASTER_TEST: Characteristic #7 RelayP2 (on/off) value = OFF (0xaa) read successful.
I (9605) MASTER_TEST: Characteristic #0 Data_channel_0 (Volts) value = 1.120000 (0x3f8f5c29) read successful.
I (9615) MASTER_TEST: Characteristic #1 Humidity_1 (%rH) value = 5.739999 (0x40b7ae12) read successful.
I (9615) MASTER_TEST: Characteristic #2 Temperature_1 (C) value = 2.340000 (0x4015c28f) read successful.
I (9625) MASTER_TEST: Characteristic #3 Humidity_2 (%rH) value = 2.560000 (0x4023d70a) read successful.
I (9635) MASTER_TEST: Characteristic #4 Temperature_2 (C) value = 3.560000 (0x4063d70a) read successful.
I (9645) MASTER_TEST: Characteristic #5 Humidity_3 (%rH) value = 3.780000 (0x4071eb85) read successful.
I (9655) MASTER_TEST: Characteristic #6 RelayP1 (on/off) value = OFF (0x55) read successful.
I (9665) MASTER_TEST: Characteristic #7 RelayP2 (on/off) value = ON (0xff) read successful.
I (10175) MASTER_TEST: Alarm triggered by cid #7.
I (10175) MASTER_TEST: Destroy master...

这个例子演示了当从站设备没有触发报警时,会读取其属性(请参阅“示例参数定义”)。输出行包括时间戳、属性ID、属性名称(单位)和属性值(十六进制)。