利用 python modbus工具实现modbus从站的数据采集,很方便简单。Python Modbus 协议工具目前有下面三种:
pymodbus
MinimalModbus
Modbus-tk
modbus_tk :完整modbus协议栈的实现,支持modbus tcp/rtu{1.提供slave模拟器,即模拟modbus server:502), web-based hmi master支持}
pymodbus:使用twisted实现的modbus完整协议(支持异步通讯)
MinimalModbus :只支持modbusrtu
至于那个更好,可以参考stack overflaw上的一个回答http://stackoverflow.com/questions/17081442/python-modbus-library
Modbus_tk是很简单易用的工具。相关资料查看:https://pypi.python.org/pypi/modbus_tk
Modbsu_tk库使用
execute(slave,功能代码,开始地址,quantity_of_x=0,output_value=0,data_format="",指定长度=-1)
实现数据读与写,用功能码很容易实现。
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 写多寄存器 【写乘法寄存器】
master.execute(1,cst.READ_HOLDING_REGISTERS, 0, 3)
1—从设备地址
cst.READ_HOLDING_REGISTERS—读保持寄存器
0—开始地址
3—读三个字节
下面来一个简单的例子。
#!/usr/bin/env python
# -*- coding: utf_8 -*-
"""
Modbus TestKit: Implementation of Modbus protocol in python
(C)2009 - Luc Jean - [email protected]
(C)2009 - Apidev - http://www.apidev.fr
This is distributed under GNU LGPL license, see license.txt
"""
import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
#PORT = 1
PORT = "/dev/ttyUSB0"
def main():
"""main"""
logger = modbus_tk.utils.create_logger("console")
try:
#Connect to the slave
master = modbus_rtu.RtuMaster(
serial.Serial(port=PORT, baudrate=9600, bytesize=8, parity='N', stopbits=1, xonxoff=0)
)
master.set_timeout(5.0)
master.set_verbose(True)
logger.info("connected")
logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 1, 1))
#send some queries
#logger.info(master.execute(1, cst.READ_COILS, 0, 10))
#logger.info(master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 8))
#logger.info(master.execute(1, cst.READ_INPUT_REGISTERS, 100, 3))
#logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 100, 12))
#logger.info(master.execute(1, cst.WRITE_SINGLE_COIL, 7, output_value=1))
#logger.info(master.execute(1, cst.WRITE_SINGLE_REGISTER, 100, output_value=54))
#logger.info(master.execute(1, cst.WRITE_MULTIPLE_COILS, 0, output_value=[1, 1, 0, 1, 1, 0, 1, 1]))
#logger.info(master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, 100, output_value=xrange(12)))
except modbus_tk.modbus.ModbusError as exc:
logger.error("%s- Code=%d", exc, exc.get_exception_code())
if __name__ == "__main__":
main()
用modsim在window下充当slave设置如下:
在树莓派下运行结果如下: