Skip to content
🤖 AI 助手 / 自动化工具:先读 《AI 助手先读》 《Agent 开发指引》 《生成前信息采集清单》;机器可读入口 /llms.txt;技能包(SKILL)直链:SKILL.md

三、Modbus 通讯(Python) ​

本页对应 C++ 版。函数名与参数顺序与 C++ 完全一致(Python SDK 由 C++ 经 SWIG 生成),差异只在两处:

  1. 返回值形态:C++ 用引用参数回填数据;Python 的返回形态由 SWIG 绑定决定,逐接口实测,不按类型推断。
  2. 少数接口在 Python 中不可直接调用(绑定缺陷),页面内已逐个标注。

本页共 13 个接口,其中 11 个在 Python SDK 中存在。


数据结构 ​

ModbusTCPParameter ​

TCP 通讯参数。

成员类型默认值说明
IPstring"192.168.1.13"Modbus TCP 服务器 IP 地址
portint503Modbus TCP 端口号

Python 中定义:nrc_interface.ModbusTCPParameter(构造:nrc.ModbusTCPParameter())。

可用字段(共 2 个,实测 dir()):

IP、port


ModbusRTUParameter ​

RTU 通讯参数。

成员类型默认值说明
slaveIdint-从站 ID,范围 [0, 65535]
portint1串口端口号
baudrateint115200波特率
checkBitstring"None"奇偶校验位;"None"(无校验)/ "Even"(偶校验)/ "Odd"(奇校验)
dataBitint8数据位;可选 5、6、7、8
stopBitint1停止位;可选 1、2

Python 中定义:nrc_interface.ModbusRTUParameter(构造:nrc.ModbusRTUParameter())。

可用字段(共 6 个,实测 dir()):

baudrate、checkBit、dataBit、port、slaveId、stopBit


ModbusMasterParameter ​

Modbus 主站参数。

成员类型默认值说明
typestring"TCP"主站类型;"TCP" 或 "RTU"
startAddressboolfalse起始地址偏移;false 为地址自动 -1(起始为 1),true 为地址不变(起始为 0)
TCPModbusTCPParameter-TCP 通讯参数(type 为 TCP 时有效)
RTUModbusRTUParameter-RTU 通讯参数(type 为 RTU 时有效)

Python 中定义:nrc_interface.ModbusMasterParameter(构造:nrc.ModbusMasterParameter())。

可用字段(共 4 个,实测 dir()):

RTU、TCP、startAddress、type


主站配置 ​

modbus_set_master_parameter ​

设置主站参数(支持 TCP/RTU,最多 9 个工艺号)。

cpp
Result modbus_set_master_parameter(SOCKETFD socketFd, int id, const ModbusMasterParameter& param);
python
def modbus_set_master_parameter(socketFd, id, param):

返回值:int 结果码(0 成功,负数为错误码)。本接口无数据出参。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符,由 connect_robot 返回
idint工艺号,范围 [1, 9]
paramconst ModbusMasterParameter&主站参数结构体

C++ 侧返回值描述:Result 结构体,result 为 true 时表示设置成功。


modbus_open_master ​

打开主站通讯连接。

cpp
Result modbus_open_master(SOCKETFD socketFd, int id);
python
def modbus_open_master(socketFd, id):

返回值:int 结果码(0 成功,负数为错误码)。本接口无数据出参。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]

C++ 侧返回值描述:Result 结构体。


modbus_get_master_connection_status ​

获取主站连接状态。

cpp
Result modbus_get_master_connection_status(SOCKETFD socketFd, int id, int& status);
python
def modbus_get_master_connection_status(socketFd, id, status):

返回值:list,共 2 个元素,形如 [结果码, 数据...]。下标 0 是结果码,下标 1 是出参值。(实测为 list 而非 tuple,解包写法 ret, val = ... 同样可用。)

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
statusint&输出参数,连接状态;0 表示未连接,1 表示已连接

C++ 侧返回值描述:Result 结构体。

连接状态 ≠ 从站在线(现场经验,按版本复核)

status = 1 只说明主站这一侧的会话已建立。现场多次遇到:从站未上电或网线未插,本接口仍返回 1,随后的读写也不报错、只是数据不更新。 所以不要把它当成从站在线判据,建议:

  • 周期读一个已知寄存器,用数据是否更新判断从站在线;
  • 读写超时/失败在业务层累计计数,连续 N 次失败即判离线并重连;
  • 恢复后重新确认该 id 的配方参数没有被重置。

功能码 01H - 读线圈 ​

modbus_read_coil_status ​

读取从站线圈状态(位操作,可读可写)。

cpp
Result modbus_read_coil_status(SOCKETFD socketFd, int id, int address, int quantity, std::vector<int>& data);
python
def modbus_read_coil_status(socketFd, id, address, quantity, data):

返回值:int 结果码(0 成功,负数为错误码)。数据通过出参容器原地填充——先创建 nrc.VectorInt() 传入,调用成功后用 list(obj) 读取。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
addressint起始地址
quantityint读取数量;范围 [1, 2000]
datastd::vector<int>&输出参数,读取到的线圈状态数组;每个元素为 0 或 1

C++ 侧返回值描述:Result 结构体。


功能码 02H - 读输入状态 ​

modbus_read_input_status ​

读取从站离散输入状态(位操作,只读)。

cpp
Result modbus_read_input_status(SOCKETFD socketFd, int id, int address, int quantity, std::vector<int>& data);
python
def modbus_read_input_status(socketFd, id, address, quantity, data):

返回值:int 结果码(0 成功,负数为错误码)。数据通过出参容器原地填充——先创建 nrc.VectorInt() 传入,调用成功后用 list(obj) 读取。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
addressint起始地址
quantityint读取数量;范围 [1, 2000]
datastd::vector<int>&输出参数,读取到的输入状态数组;每个元素为 0 或 1

C++ 侧返回值描述:Result 结构体。


功能码 03H - 读保持寄存器 ​

modbus_read_holding_registers ​

读取从站保持寄存器(16 位操作,可读可写)。

cpp
Result modbus_read_holding_registers(SOCKETFD socketFd, int id, int address, int quantity, std::vector<int>& data);
python
def modbus_read_holding_registers(socketFd, id, address, quantity, data):

返回值:int 结果码(0 成功,负数为错误码)。数据通过出参容器原地填充——先创建 nrc.VectorInt() 传入,调用成功后用 list(obj) 读取。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
addressint起始地址
quantityint读取数量;范围 [1, 125]
datastd::vector<int>&输出参数,读取到的保持寄存器值数组;每个元素范围 [0, 65535]

C++ 侧返回值描述:Result 结构体。


功能码 04H - 读输入寄存器 ​

modbus_read_input_registers ​

读取从站输入寄存器(16 位操作,只读)。

cpp
Result modbus_read_input_registers(SOCKETFD socketFd, int id, int address, int quantity, std::vector<int>& data);
python
def modbus_read_input_registers(socketFd, id, address, quantity, data):

返回值:int 结果码(0 成功,负数为错误码)。数据通过出参容器原地填充——先创建 nrc.VectorInt() 传入,调用成功后用 list(obj) 读取。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
addressint起始地址
quantityint读取数量;范围 [1, 125]
datastd::vector<int>&输出参数,读取到的输入寄存器值数组;每个元素范围 [0, 65535]

C++ 侧返回值描述:Result 结构体。


功能码 05H - 写单个线圈 ​

modbus_write_signal_coil_status ​

写单个线圈状态。

cpp
Result modbus_write_signal_coil_status(SOCKETFD socketFd, int id, int address, int data);
python
def modbus_write_signal_coil_status(socketFd, id, address, data):

返回值:int 结果码(0 成功,负数为错误码)。本接口无数据出参。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
addressint线圈地址
dataint写入值;0 或 1

C++ 侧返回值描述:Result 结构体。


功能码 06H - 写单个保持寄存器 ​

modbus_write_signal_holding_registers ​

写单个保持寄存器。

cpp
Result modbus_write_signal_holding_registers(SOCKETFD socketFd, int id, int address, int data);
python
def modbus_write_signal_holding_registers(socketFd, id, address, data):

返回值:int 结果码(0 成功,负数为错误码)。本接口无数据出参。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
addressint寄存器地址
dataint写入值;范围 [0, 65535]

C++ 侧返回值描述:Result 结构体。


功能码 0FH - 写多个线圈 ​

modbus_write_multiple_coil_status ​

批量写入多个线圈状态。

cpp
Result modbus_write_multiple_coil_status(SOCKETFD socketFd, int id, int address, const std::vector<int>& data);
python
def modbus_write_multiple_coil_status(socketFd, id, address, data):

返回值:int 结果码(0 成功,负数为错误码)。本接口无数据出参。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
addressint起始地址
dataconst std::vector<int>&写入的线圈值数组;每个元素为 0 或 1

C++ 侧返回值描述:Result 结构体。


功能码 10H - 写多个保持寄存器 ​

modbus_write_multiple_holding_registers ​

批量写入多个保持寄存器。

cpp
Result modbus_write_multiple_holding_registers(SOCKETFD socketFd, int id, int address, const std::vector<int>& data);
python
def modbus_write_multiple_holding_registers(socketFd, id, address, data):

返回值:int 结果码(0 成功,负数为错误码)。本接口无数据出参。

参数说明(与 C++ 一致):

参数类型说明
socketFdSOCKETFD套接字文件描述符
idint工艺号,范围 [1, 9]
addressint起始地址
dataconst std::vector<int>&写入的寄存器值数组;每个元素范围 [0, 65535]

C++ 侧返回值描述:Result 结构体。


完整使用示例 ​

TCP 主站读写完整流程 ​

cpp
#include "nrc_modbus.h"

void modbus_tcp_example(SOCKETFD socketFd) {
    // 1. 设置主站参数(TCP 模式)
    ModbusMasterParameter masterParam;
    masterParam.type = "TCP";
    masterParam.startAddress = false;  // 起始地址为 1
    masterParam.TCP.IP = "192.168.1.14";
    masterParam.TCP.port = 503;

    Result ret = modbus_set_master_parameter(socketFd, 1, masterParam);
    if (!ret.result) {
        printf("设置主站参数失败\n");
        return;
    }

    // 2. 打开主站
    ret = modbus_open_master(socketFd, 1);
    if (!ret.result) {
        printf("打开主站失败\n");
        return;
    }

    // 3. 检查连接状态
    int status = 0;
    ret = modbus_get_master_connection_status(socketFd, 1, status);
    if (ret.result && status == 1) {
        printf("Modbus TCP 连接成功\n");
    }

    // 4. 读线圈(功能码 01H)
    std::vector<int> coilData;
    ret = modbus_read_coil_status(socketFd, 1, 0, 10, coilData);
    if (ret.result) {
        printf("读取线圈成功: ");
        for (int v : coilData) printf("%d ", v);
        printf("\n");
    }

    // 5. 写单个线圈(功能码 05H)
    ret = modbus_write_signal_coil_status(socketFd, 1, 3, 1);

    // 6. 读保持寄存器(功能码 03H)
    std::vector<int> holdingReg;
    ret = modbus_read_holding_registers(socketFd, 1, 200, 5, holdingReg);
    if (ret.result) {
        printf("读取保持寄存器成功: ");
        for (int v : holdingReg) printf("%d ", v);
        printf("\n");
    }

    // 7. 写多个保持寄存器(功能码 10H)
    std::vector<int> writeReg = {1000, 2000, 3000};
    ret = modbus_write_multiple_holding_registers(socketFd, 1, 400, writeReg);
}

⚠️ 该接口在 Python SDK 中不存在。nrc_interface 中没有同名函数,调用会抛 AttributeError。请使用 C++ SDK,或联系纳博特确认后续版本是否支持。


RTU 主站配置示例 ​

cpp
ModbusMasterParameter rtuParam;
rtuParam.type = "RTU";
rtuParam.startAddress = false;
rtuParam.RTU.slaveId = 1;
rtuParam.RTU.port = 2;
rtuParam.RTU.baudrate = 115200;
rtuParam.RTU.checkBit = "Even";
rtuParam.RTU.dataBit = 8;
rtuParam.RTU.stopBit = 1;

Result ret = modbus_set_master_parameter(socketFd, 2, rtuParam);

⚠️ 该接口在 Python SDK 中不存在。nrc_interface 中没有同名函数,调用会抛 AttributeError。请使用 C++ SDK,或联系纳博特确认后续版本是否支持。


Modbus 功能码汇总 ​

注意事项 ​