代码示例
import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
def mod(PORT = "com2"):
red = []
alarm = ""
try:
# 设定串口com2的参数
master = modbus_rtu.RtuMaster(serial.Serial(port=PORT,baudrate=9600,bytesize=8,parity='N',stopbits=1))
master.set_timeout(5.0)
master.set_verbose(True)
# 读取从站为2的保持寄存器,读取0-9共10个寄存器的值,
# 各参数意义
# 2:从机地址
# cst.READ_HOLDING_REGISTERS: 即功能码,cst.READ_HOLDING_REGISTERS为03的意思
# 0:起始寄存器地址
# 9:读取寄存器个数
red = master.execute(2,cst.READ_HOLDING_REGISTERS,0,9) # 这里可以修改需要读取的功能码
print(red)
alarm= "正确"
return [red],alarm
except Exception as exc:
print(str(exc))
alarm = (str(exc))
# 如果异常就返回空列表和故障信息
return red, alarm
if __name__ == "__main__":
ret = mod()
print(ret)
解释
modbus分主机与从机,或者叫上位机与下位机,简单点理解,主机或上位机,我们可以理解为管理端,从机或下位机,我们可以理解为终端。
终端的数据有几种形式,分别为线圈、离散输入、寄存器、线圈等几种方式,其在python中的代码如下
# READ_COILS = 1 读线圈
# READ_DISCRETE_INPUTS = 2 读离散输入
# READ_HOLDING_REGISTERS = 3 【读寄存器】
# READ_INPUT_REGISTERS = 4 读输入寄存器
# WRITE_SINGLE_COIL = 5 写单一线圈
# WRITE_SINGLE_REGISTER = 6 写单一寄存器
# WRITE_MULTIPLE_COILS = 15 写多个线圈 【强制多点线圈】
# WRITE_MULTIPLE_REGISTERS = 16 写多寄存器 【写乘法寄存器】
实例2
下面是一个应用实例,并结合日志进行输出
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus_tcp as modbus_tcp
logger = modbus_tk.utils.create_logger("console")
if __name__ == "__main__":
try:
# 连接MODBUS TCP从机
master = modbus_tcp.TcpMaster(host="192.168.1.66")
master.set_timeout(5.0)
logger.info("connected")
# 读从机1保持寄存器
demo1 = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9)
print(demo1)
# 读从机3输入寄存器
logger.info(master.execute(3, cst.READ_INPUT_REGISTERS, 0, 9, output_value=1))
# 读从机2线圈寄存器
logger.info(master.execute(2, cst.READ_COILS, 0, 8))
logger.info(master.execute(2, cst.WRITE_SINGLE_COIL, 1, output_value=2))
# 读从机4离散输入寄存器
logger.info(master.execute(4, cst.READ_DISCRETE_INPUTS, 0, 8))
# 单个读写寄存器操作
# 写从机1寄存器地址为0的保持寄存器
logger.info(master.execute(1, cst.WRITE_SINGLE_REGISTER, 0, output_value=20))
logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 8))
# 写寄存器地址为0的线圈寄存器,写入内容为0(位操作)
logger.info(master.execute(2, cst.WRITE_SINGLE_COIL, 0, output_value=2))
logger.info(master.execute(2, cst.READ_COILS, 0, 1))
# # 多个寄存器读写操作
# # 写寄存器起始地址为0的保持寄存器,操作寄存器个数为4
logger.info(master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, 0, output_value=[20,21,22,23]))
logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 4))
# # 写寄存器起始地址为0的线圈寄存器
logger.info(master.execute(2, cst.WRITE_MULTIPLE_COILS, 0, output_value=[0,0,0,1]))
logger.info(master.execute(2, cst.READ_COILS, 0, 4))
except modbus_tk.modbus.ModbusError as e:
logger.error("%s- Code=%d" % (e, e.get_exception_code()))
python之modbus常见的返回值
import modbus_tk.defines
#modbus exception codes 异常代码
# 代码功能不合法
ILLEGAL_FUNCTION = 1
# 数据地址不合法
ILLEGAL_DATA_ADDRESS = 2
# 数据值不合法
ILLEGAL_DATA_VALUE = 3
# slave设备失败
SLAVE_DEVICE_FAILURE = 4
# 命令已收到
COMMAND_ACKNOWLEDGE = 5
# slave设备忙
SLAVE_DEVICE_BUSY = 6
# 内存奇偶校验差
MEMORY_PARITY_ERROR = 8
# supported modbus functions 功能代码
# 读线圈
READ_COILS = 1
# 离散读输入
READ_DISCRETE_INPUTS = 2
# 读保持寄存器
READ_HOLDING_REGISTERS = 3
# 读输入寄存器
READ_INPUT_REGISTERS = 4
# 写单一线圈
WRITE_SINGLE_COIL = 5
# 写单一寄存器
WRITE_SINGLE_REGISTER = 6
# *读例外状态
READ_EXCEPTION_STATUS = 7
DIAGNOSTIC = 8
# *报告slave的id
REPORT_SLAVE_ID = 17
# 写多个线圈
WRITE_MULTIPLE_COILS = 15
# 写多寄存器
WRITE_MULTIPLE_REGISTERS = 16
# *读写多个寄存器
READ_WRITE_MULTIPLE_REGISTERS = 23
# *设备信息
DEVICE_INFO = 43
# supported block types 支持的块类型
# 线圈
COILS = 1
# 离散输入
DISCRETE_INPUTS = 2
# 保持寄存器
HOLDING_REGISTERS = 3
# 模拟量输入
ANALOG_INPUTS = 4