ARCS Modbus 使用指南

1. Modbus 协议介绍

  1. Modbus是一种串行通信协议,最初由Modicon公司(现在的施耐德电气)在1979年为使用可编程逻辑控制器(PLC)的自动化设备设计。Modbus已经成为工业领域通信协议的事实标准。Modbus协议包括Modbus RTU和Modbus TCP两种形式。

  2. Modbus RTU(Remote Terminal Unit):这是一种基于串行线(例如RS-485、RS-422、RS-232)的二进制通信协议。在Modbus RTU中,数据以二进制形式传输,每个字节由两个十六进制字符表示。Modbus RTU主要用于工业和系统自动化应用,其中设备之间的通信距离较长。

  3. Modbus TCP(Transmission Control Protocol):这是一种基于以太网的通信协议。Modbus TCP使用TCP/IP协议进行通信,因此可以利用现有的以太网基础设施。与Modbus RTU相比,Modbus TCP可以支持更多的设备连接,并且通信速度更快。

  4. Modbus RTU 与 Modbus TCP 两者的主要区别: Modbus RTU 基于串行通信的方式,如 RS-485 接口,其传输速率受限于串行接口的性能; Modbus TCP 基于 TCP/IP 协议栈,在网络上进行数据传输,支持更高的传输速率。

2. Modbus主站

2.1 主站介绍

在 Modbus 通信网络中,主站(Master Station)是发起通信的设备,它负责控制和协调与从站(Slave Station)之间的通信过程。主站就像是一个指挥者,主动向从站请求数据或者向从站发送命令,以实现对整个网络的有效管理和数据交互

2.2 主站用途

在焊接、搬运、装配等操作中作为主站,它需要根据自身的任务流程和工作状态,有针对性地向 PLC 从站请求数据或发送指令。例如,在汽车零部件组装过程中,机器人可能需要从 PLC 获取零部件的位置信息,以便准确地抓取和安装。

机器人主站往往具有较高的智能化程度,能够对获取的数据进行分析和处理,以做出合理的决策。比如,根据 PLC 提供的生产线上的设备状态信息,机器人可以调整自己的工作节奏和动作顺序,实现与其他设备的协同工作。

2.3 快速入门

  1. 打开ARCS软件,Modbus位于 配置--现场总线--Modbus

2.4 Modbus TCP

  1. 单元页面,依次点击添加Modbus单元--TCP模式

  2. Modbus TCP:使用 TCP/IP 连接,不需要校验和计算,可配置设备名称、从站编号、 IP 地址(与目标设备在同一网段),端口号参数。配置IP地址后可点击测试,弹出测试成功表示可以与目标设备通讯,反之则与目标设备不可进行通讯,需检查与目标设备是否在同一网段,防火墙是否关闭等。

  3. 信号页面,选择添加Modbus信号

​ 01:COIL STATUS(线圈状态):用于读取和控制远程设备的开关状态,通常用于控制继电器等开关设备。
​ 02:INPUT STATUS(输入状态):用于读取远程设备的输入状态,通常用于读取传感器等输入设备的状态。
​ 03:HOLDING REGISTER(保持寄存器):用于存储和读取远程设备的数据,通常用于存储控制参数、设备状态等信息。
​ 04:INPUT REGISTER(输入寄存器):用于存储远程设备的输入数据,通常用于存储传感器等输入设备的数据。

对应红色响应代码如下所示:

E1: 非法函数(0x01)查询中接收到的函数代码不是服务器(或从服务器)允许的操作,

E2: 非法数据地址(0x02)在查询中收到的功能代码不是服务器(或从站)允许的操作,请检查输入的信号地址对应于远程MODBUS服务器的设置。

E3: 非法数据值(0x03)查询数据字段中包含的值对于服务器(或从服务器)是不允许的值,请检查信号值对于远程MODBUS服务器上的指定地址是有效的

E4: 从属设备故障(0x04)当服务器(或从服务器)试图执行请求的操作时,发生了一个不可恢复的错误,请检查设备与接线是否损坏,尝试重启设备

E5: 应答(0x05)与发送到远程MODBUS单元的编程命令结合使用的专用功能,

E6: 从设备忙(0x06)与发送到远程MODBUS单元的编程命令一起使用,从设备(服务器)现在无法响应,请等待或尝试重新连接,并排查机器人IP地址是否与同一局域网下其他设备IP地址一致,产生了冲突

2.5 Modbus RTU

  1. 单元页面,依次点击添加Modbus单元--RTU模式

  2. 选择串口号,波特率,奇偶校验,数据位,停止位

注意:Modbus RTU 基于串行通信的方式,其传输速率受限于 RS-485 串行接口的性能;若通信不稳定,信号状态闪烁,可将波特率值调小,若不通讯时排查选择选择的串口是否符合,可使用Modbus串口助手进行排查,参考文档:

17 RS485测试流程 · AUBO Wiki

19 Modbus RTU 串口通信测试 · AUBO Wiki

  1. Modbus RTU 通讯依赖于控制柜或机械臂末端的RS-485串口通讯,在Modbus的串口选择可以参考如下

  2. 控制RS-485串口号,控制RS-485包括末端RS485及USB485

  3. 信号页面,选择添加Modbus信号,信号类型如图中标号1所示

    01:COIL STATUS(线圈状态):用于读取和控制远程设备的开关状态,通常用于控制继电器等开关设备。
    02:INPUT STATUS(输入状态):用于读取远程设备的输入状态,通常用于读取传感器等输入设备的状态。
    03:HOLDING REGISTER(保持寄存器):用于存储和读取远程设备的数据,通常用于存储控制参数、设备状态等信息。
    04:INPUT REGISTER(输入寄存器):用于存储远程设备的输入数据,通常用于存储传感器等输入设备的数据。

绿色表示为正常通讯,灰色,红色为不通讯,对应红色响应代码如下所示:

E1: 非法函数(0x01)查询中接收到的函数代码不是服务器(或从服务器)允许的操作,请检查从站是否存在对应信号类型

E2: 非法数据地址(0x02)在查询中收到的功能代码不是服务器(或从站)允许的操作,请检查输入的信号地址对应于远程MODBUS服务器的设置

E3: 非法数据值(0x03)查询数据字段中包含的值对于服务器(或从服务器)是不允许的值,请检查信号值对于远程MODBUS服务器上的指定地址是有效的

E4: 从属设备故障(0x04)当服务器(或从服务器)试图执行请求的操作时,发生了一个不可恢复的错误,请检查设备与接线是否损坏,尝试重启设备

E5: 应答(0x05)与发送到远程MODBUS单元的编程命令结合使用的专用功能,

E6: 从设备忙(0x06)与发送到远程MODBUS单元的编程命令一起使用,从设备(服务器)现在无法响应,请等待或尝试重新连接,并排查机器人IP地址是否与同一局域网下其他设备IP地址一致,产生了冲突

2.6 Modbus信号在配置中作为IO使用

在“配置 -> 现场总线 -> Modbus -> 信号”中添加信号类型为寄存器/数字输入,在“配置 -> 一般 -> I/O”设置可配置其 I/O 输入动作,除拖动示教外其余信号需要在联动模式下触发信号执行(也可通过OEM定制功能使其在手动模式或自动模式生效)

  1. 配置--一般--I/O设置

  2. 为对应的Modbus 信号配置输入动作

  3. 为对应的Modbus 信号配置输出动作

  4. 可在IO-Modbus中可查看信号寄存器和数字信号的变化

2.7 modbus信号在程序中使用

1.设置节点: 可以设置Modbus数字和寄存器输出,设置数字信号的单脉冲,常与等待信号一起用做为校验确保信号设置成功才往下执行

2.等待节点: 可以使用Modbus信号做为判断,等待满足此信号程序才继续运行,常与设置信号一起使用,

3.赋值节点: 可将Modbus信号值赋值给变量进行使用

4.如果节点: 可将Modbus信号做为判断使用,满足此信号条件程序进入这个判断中

5.循环节点: 可将Modbus信号做为进入循环的条件,满足此信号条件进入循环

可在IO-Modbus中可查看信号寄存器和数字信号的变化

3. Modbus 从站

3.1 从站介绍

Modbus 从站的主要作用是响应主站(Master)的请求并执行相应的操作。实际应用中它可以用于连接和控制生产线上的各种设备,实现设备之间的信息交换和控制指令传递。

3.2 ARCS从站的用途

  1. 响应主站(Master)的请求,将机器臂的状态信息实时发送给主站;

  2. 响应主站(Master)的请求,将控制器的信息发送给主站;

  3. 测试调试时作为数据中转站,将机器臂 I/O 信号的变化实时传递给主站;

  4. 测试调试时作为数据中转站,将主站自定义信号实时传递给机器臂;

    注意:通过ARCS的主站连接从站的方式,可能会存在信号延时,仅在调试时候使用,不可在程序中使用,若需要在程序中对从站进行寄存器的读写可以参考下文 3.4通用寄存器的读写示例

3.3 从站地址表更新位置

Modbus从站地址表位于钉盘-团队文件-ARCS-对外文件夹-Modbus从站中进行更新,若您是使用客户,可联系本公司技术服务部技术人员获取,若您是技术服务人员可自行获取

3.4 Modbus TCP

  1. 开启 Modbus TCP

  2. 开启从站之后,就可以使用其它的主站列如PLC或modscan来连接该从站,从站地址请参考 Modbus 从站协议中的定义;

3.5 Modbus RTU

  1. 开启Modbus从站

    注意:Modbus RTU从站需要先将串口串口参数配置完成,开启后不可修改,需关闭后进行修改

  2. Modbus RTU 通讯依赖于控制柜或机械臂末端的RS-485串口通讯,在Modbus的串口选择可以参考如下

    注意:Modbus RTU 基于串行通信的方式,其传输速率受限于 RS-485 串行接口的性能;若通信不稳定,信号状态闪烁,可将波特率值调小,若不通讯时排查选择选择的串口是否符合,可使用Modbus串口助手进行排查,参考文档:

    17 RS485测试流程 · AUBO Wiki

    19 Modbus RTU 串口通信测试 · AUBO Wiki

  3. 控制RS-485串口号,控制RS-485包括末端RS485及USB485

3.6 Modbus 从站通用寄存器读写接口应用示例

3.6.1 Modbus 从站通用寄存器介绍

为了方便用户使用自定义信号实现PLC(主站)跟控制器通信,Modbus 从站提供了专用的可读写的通用寄存器,通用寄存器的地址为300~525;

通用寄存器读写示例,两种典型的通用寄存器读写示例:

  • 使用 SDK 调用接口读写对应地址的通用寄存器信号;
  • 使用工程(Lua)脚本读写对应地址的通用寄存器信号;

测试环境描述:

现使用 Modbus 调试助手(Modbus Poll)来模拟 PLC 主站与 Modbus 从站进行通信;Modbus 调试助手的相关地址信号设置如下:

3.6.2 SDK 读写通用寄存器

(1) 读通用寄存器:

使用 SDK 调用 modbusAddSignal 添加对应地址的信号,然后使用 modbusGetSignalStatus 获取对应地址的信号值,最后使用 modbusDeleteSignal 删除该信号;下面使用 SDK 读 Modbus 从站里地址为300、301、303的通用寄存器,具体代码逻辑如下:

// 读通用寄存器
void exampleModbusSlaveRead(RpcClientPtr impl)
{
    // 根据从站地址新建对应地址的保持寄存器信号
    impl->getRegisterControl()->modbusAddSignal(
        MODBUS_SLAVE_IP, 1, 300, 0x03, "READ_HOLDING_REGISTER_300", true);
    impl->getRegisterControl()->modbusSetSignalUpdateFrequency(
        "READ_HOLDING_REGISTER_300", 10);

    impl->getRegisterControl()->modbusAddSignal(
        MODBUS_SLAVE_IP, 1, 301, 0x03, "READ_HOLDING_REGISTER_301", true);
    impl->getRegisterControl()->modbusSetSignalUpdateFrequency(
        "READ_HOLDING_REGISTER_301", 10);

    impl->getRegisterControl()->modbusAddSignal(
        MODBUS_SLAVE_IP, 1, 303, 0x03, "READ_HOLDING_REGISTER_303", true);
    impl->getRegisterControl()->modbusSetSignalUpdateFrequency(
        "READ_HOLDING_REGISTER_303", 10);

    std::this_thread::sleep_for(std::chrono::seconds(1));

    int i = 30;
    while (i--) {
         // 获取对应地址的保持寄存器信号的值
        auto ret0 = impl->getRegisterControl()->modbusGetSignalStatus(
            "READ_HOLDING_REGISTER_300");
        std::cout << "READ_HOLDING_REGISTER_300:" << ret0 << std::endl;

        auto ret1 = impl->getRegisterControl()->modbusGetSignalStatus(
            "READ_HOLDING_REGISTER_301");
        std::cout << "READ_HOLDING_REGISTER_301:" << ret1 << std::endl;

        auto ret3 = impl->getRegisterControl()->modbusGetSignalStatus(
            "READ_HOLDING_REGISTER_303");
        std::cout << "READ_HOLDING_REGISTER_303:" << ret3 << std::endl;

        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    // 结束后删除信号
    impl->getRegisterControl()->modbusDeleteSignal("READ_HOLDING_REGISTER_300");
    impl->getRegisterControl()->modbusDeleteSignal("READ_HOLDING_REGISTER_301");
    impl->getRegisterControl()->modbusDeleteSignal("READ_HOLDING_REGISTER_303");
}

读取的结果如下:

(2) 写通用寄存器:

使用 SDK 调用 modbusAddSignal 添加对应地址的信号,然后使用 modbusSetOutputSignal 写入对应地址的信号值,最后使用 modbusDeleteSignal 删除该信号;下面使用 SDK 写 Modbus 从站里地址为 302 的通用寄存器,具体代码逻辑如下:

// 写保持寄存器
void exampleModbusSlaveWrite(RpcClientPtr impl)
{
    // 根据从站地址新建对应地址的保持寄存器信号
    impl->getRegisterControl()->modbusAddSignal(
        MODBUS_SLAVE_IP, 1, 302, 0x03, "WRITE_HOLDING_REGISTER_302", true);

    std::this_thread::sleep_for(std::chrono::seconds(1));

    // 写入对应地址保持寄存器的值
    impl->getRegisterControl()->modbusSetOutputSignal(
        "WRITE_HOLDING_REGISTER_302", 25);

    std::this_thread::sleep_for(std::chrono::seconds(1));

    // 结束后删除信号
    impl->getRegisterControl()->modbusDeleteSignal(
        "WRITE_HOLDING_REGISTER_302");
}

写入成功的结果如下:

3.6.3 工程脚本读写通用寄存器

(1) 读通用寄存器:

使用 Modbus 调试助手,设置 Modbus 从站里地址为 300 的通用寄存器值为10;

在示教器中通过编写脚本,获取地址为300的信号值,可以看到获取的值 tmp0 为10;

--建立modbus信号,(ip,站号,寄存器起始地址,功能码名,字)     
modbusAddSignal("127.0.0.1,502",1,300,0x03,"READ_HOLDING_REGISTER_300",true)   
-- 获取modbus的寄存器的值,并赋值给变量,赋值给变量是为了方便在示教器上查看   
tmp0=modbusGetSignalStatus("READ_HOLDING_REGISTER_300")   
-- 删除指定名称的信号      
modbusDeleteSignal("READ_HOLDING_REGISTER_300")

(2) 写通用寄存器:

--建立modbus信号,(ip,站号,寄存器起始地址,功能码名,字)
modbusAddSignal("127.0.0.1,502",1,300,0x03,"WRITE_HOLDING_REGISTER_300",true)   
--写入modbus的值,并赋值给变量,赋值给变量是为了方便在示教器上查看
tmp0 = modbusSetOutputSignal("WRITE_HOLDING_REGISTER_300",88)
--删除指定名称的信号
modbusDeleteSignal("WRITE_HOLDING_REGISTER_300")

在示教器中通过编写脚本,将地址为302的信号值设置为88;

使用 Modbus 调试助手可以看到地址为 302 的通用寄存器值为88;

4. 接口应用

5.1 modbusSendCustomCommand接口功能说明&注意事项

  • 将用户指定的命令发送到指定IP地址上的Modbus单元。
  • 由于不会接收到响应,因此不能用于请求数据,读数据的功能码暂不可用。
  • 用户负责提供对所提供的功能码有意义的数据。
  • 内置函数负责构建Modbus帧,因此用户不需要关心命令的长度,不需要输入CRC格式的数据。

5.2 参数定义及格式

// 接口定义
int modbusSendCustomCommand(const std::string &device_info,int slave_number, int function_code, const std::vector<uint8_t> &data);

// device_info: 设备信息
     * 设备信息是RTU格式,
     * 例如:"serial_port,baud,parity,data_bit,stop_bit" 
     * (1)serial_port参数指定串口的名称,
     * 例如,在Linux上为"/dev/ttyS0""/dev/ttyUSB0",在Windows上为"\.\COM10"
     * (2)baud参数指定通信的波特率,例如96001920057600115200等 
     * (3)parity参数指定奇偶校验方式,N表示无校验,E表示偶校验,O表示奇校验 
     * (4)data_bit参数指定数据位数,允许的值为5678 
     * (5)stop_bit参数指定停止位数,允许的值为12
     *
     * 设备信息是TCP格式,例如:"ip address,port" 
     * (1)ip address参数指定服务器的IP地址 
     * (2)port参数指定服务器监听的端口号

// slave_number: 指定用于自定义命令的从站号

// function_code: 指定自定义命令的功能码
     * MODBUS_FC_READ_COILS                0x01   // 读线圈寄存器
     * MODBUS_FC_READ_DISCRETE_INPUTS      0x02   // 读离散输入状态
     * MODBUS_FC_READ_HOLDING_REGISTERS    0x03   // 读保持寄存器
     * MODBUS_FC_READ_INPUT_REGISTERS      0x04   // 读输入寄存器
     * MODBUS_FC_WRITE_SINGLE_COIL         0x05   // 写单线圈
     * MODBUS_FC_WRITE_SINGLE_REGISTER     0x06   // 写单寄存器
     * MODBUS_FC_READ_EXCEPTION_STATUS     0x07   // 读异常状态(限串行线)
     * MODBUS_FC_WRITE_MULTIPLE_COILS      0x0F   // 写多线圈
     * MODBUS_FC_WRITE_MULTIPLE_REGISTERS  0x10   // 写多个寄存器
     * MODBUS_FC_REPORT_SLAVE_ID           0x11   // 报告丛机ID(限串行线)
     * MODBUS_FC_MASK_WRITE_REGISTER       0x16   // 带屏蔽字写入寄存器
     * MODBUS_FC_WRITE_AND_READ_REGISTERS  0x17   // 读&写寄存器

// data: 必须是有效的字节值(0-255)
     * { 0x00, 0x02, 0x00, 0x0F }
     * { 0x06, 0x0A, 0x0F, 0x08, 0x00, 0x0F }

5.3 调用示例

// 定义IP
#define MODBUS_IP          "172.16.3.111,502"    
// 建立对象
RpcClientPtr impl;
// 发送自定义数据
impl->getRegisterControl()->modbusSendCustomCommand(MODBUS_IP, 1, 0x06, { 0x00, 0x02, 0x00, 0x0F });

5. 问题处理

Modbus TCP信号通信失败

  • 排查设备与机器人之间网络是否能正常通信,首先查看是否关闭设备的防火墙,然后使用ping命令检查网络是否能正常通信;
  • 排查主站建立的信号地址在从站中是否存在,主站新建的信号对应地址在从站中必须存在,信号才能正常通信;
  • 排查机器人IP地址是否与同一局域网下其他设备IP地址一致,是否产生了冲突

Modbus RTU信号通信失败

  • 排查设备与机器人之间串口通信是否正常, 可以使用设备与机器人中的串口调试助手来测试串口通信状态;
  • 排查主站建立的信号地址在从站中是否存在,主站新建的信号对应地址在从站中必须存在,信号才能正常通信;

操作步骤:

​ 在机器人控制柜中使用命令安装 cutecom

​ 打开cutecom,并设置串口号,波特率,奇偶校验,数据位,停止位

​ 若设备端是PLC,则用 cutecom 直接连接PLC测试,若设备是本机电脑,可在电脑中安装串口调试助手,例如:XCOM

​ 如果 cutecomPLC/XCOM 能够相互发送数据,表示能正常通信,串口通信线路没有问题,反之,需要检查通信线路连接情况;

results matching ""

    No results matching ""