iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python使用pymodbus库进行modbus tcp通信
  • 551
分享到

python使用pymodbus库进行modbus tcp通信

python开发语言制造 2023-09-04 09:09:24 551人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

使用pymodbus库进行modbus tcp通信 使用python解决工业通信问题是一个非常好的选择,Python具有丰富的生态,可以轻松解决工业通信的各种问题。本篇主要介绍使用pymodbus

使用pymodbus库进行modbus tcp通信

使用python解决工业通信问题是一个非常好的选择,Python具有丰富的生态,可以轻松解决工业通信的各种问题。本篇主要介绍使用pymodbus库进行modbus tcp仿真,实现pc端读取plc或工业设备modbus变量。

安装pymodbus:

pip install -U pymodbus

1 创建modbus tcp server

这里我们先创建一个虚拟的modbus设备,如果你手里有一个plc或者工业设备,可以直接跳过本节。

modbus_server.py

''' * @Author: liuzhao  * @Last Modified time: 2022-10-05 09:56:13 '''from pymodbus.server.sync import (    StartTcpServer,)from pymodbus.datastore import (    ModbusSequentialDataBlock,    ModbusServerContext,    ModbusSlaveContext,)from pymodbus.version import versiondatablock = ModbusSequentialDataBlock.create()context = ModbusSlaveContext(    di=datablock,    co=datablock,    hr=datablock,    ir=datablock,    )single = True# Build data storagestore = ModbusServerContext(slaves=context, single=single)if __name__ == '__main__':address = ("0.0.0.0", 503)StartTcpServer(    context=store,  # Data storage    address=address,  # listen address  allow_reuse_address=True,  # allow the reuse of an address)

直接运行该脚本,就可以在本机的503端口创建一台modbus设备了,具体实现暂不深追,我们学习的重点是客户端对modbus变量的读写。

2 读写modbus变量

modbus变量类型以及地址

Object typeAccessSizeAddress
CoilRead-write1 bit00001 – 09999
Discrete inputRead-only1 bit10001 – 19999
Input reGISterRead-only16 bits30001 – 39999
Holding registerRead-write16 bits40001 – 49999

coil是线圈,Discrete input是数字量输入,Input register是模拟量输入,Holding register是保持寄存器。一般地址范围是0-65535 [wiki]

2.1 读取常规变量

读写线圈 | 读取输入变量 | 读写保持寄存器

from pymodbus.client.sync import ModbusTcpClientfrom pymodbus.bit_read_message import ReadCoilsResponsefrom pymodbus.register_read_message import ReadInputRegistersResponsefrom pymodbus.exceptions import ConnectionException      # 连接失败,用于异常处理host = '127.0.0.1'port = 503client = ModbusTcpClient(host,port)# 写入线圈client.write_coil(1, True)client.write_coil(2, False)client.write_coil(3, True)# 读取线圈    注意对于离散量的读取,第二个参数cout是有坑的,必须为8的倍数个result:ReadCoilsResponse = client.read_coils(address=1,cout=8)     # 从地址1开始读,读取8个线圈,一次读8的倍数个线圈,不设置为8的倍数可能会出现问题print(result.isError())# 不建议使用print(result.getBit(7))            # 这里的参数address不是plc里的地址,而是python列表的address,print('read_coils ')# 建议使用print(result.bits)        # 打印读取结果,一共8位# 读取其中的位print(                       result.bits[0],    result.bits[1],    result.bits[2]    )         # 相当于result.getBit(0)# 读取数字输入result = client.read_discrete_inputs(address=10001,count=8)    # 从10001开始读,读取8位print(result.bits)# 读取模拟输入寄存器input_register_result:ReadInputRegistersResponse = client.read_input_registers(1,count=8)# print(f'is_error:{input_register_result.isError()}')print('read_input_registers ')print(input_register_result.registers)   print(input_register_result.getRegister(0))   # 读写保持寄存器client.write_register(address=40001,value=100)result:ReadInputRegistersResponse = client.read_holding_registers(address=40001,count=1)print('read_holding_registers ')print(result.registers)# 关闭连接client.close()

2.2 读取复杂变量

字符串、浮点数、负数等
这里需要注意modbus设备的存储结构是低位低字节还是低位高字节,也就是设备内存的字节、字的排列顺序。

  根据不同的设备,对照下表调整正确的组合方式。
Word OrderByte orderWord1Word2
BigBig0x12340x5678
BigLittle0x34120x7856
LittleBig0x56780x1234
LittleLittle0x78560x3412
# 复杂数据类型from collections import OrderedDictimport loggingfrom pymodbus.client.sync import ModbusTcpClient as ModbusClientfrom pymodbus.constants import Endianfrom pymodbus.payload import BinaryPayloadBuilder, BinaryPayloadDecoderORDER_DICT = {"<": "LITTLE", ">": "BIG"}def run_binary_payload_client(host:str,port:int):      for word_endian, byte_endian in (        (Endian.Big, Endian.Big),        (Endian.Big, Endian.Little),        (Endian.Little, Endian.Big),        (Endian.Little, Endian.Little),    ):        print("-" * 60)        print(f"Word Order: {ORDER_DICT[word_endian]}")        print(f"Byte Order: {ORDER_DICT[byte_endian]}")        print()            builder = BinaryPayloadBuilder(            wordorder=word_endian,            byteorder=byte_endian,        )# 写入的变量        my_string = "abcd-efgh123345765432"        builder.add_string(my_string)        builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])        builder.add_8bit_int(-0x12)        builder.add_8bit_uint(0x12)        builder.add_16bit_int(-0x5678)        builder.add_16bit_uint(0x1234)        builder.add_32bit_int(-0x1234)        builder.add_32bit_uint(0x12345678)        builder.add_16bit_float(12.34)        builder.add_16bit_float(-12.34)        builder.add_32bit_float(22.34)        builder.add_32bit_float(-22.34)        builder.add_64bit_int(-0xDEADBEEF)        builder.add_64bit_uint(0x12345678DEADBEEF)        builder.add_64bit_uint(0x12345678DEADBEEF)        builder.add_64bit_float(123.45)        builder.add_64bit_float(-123.45)        registers = builder.to_registers()        print("Writing Registers:")        print(registers)        print("\n")        payload = builder.build()        address = 40001          # 从40001开始写入        # We can write registers        client.write_registers(address, registers, unit=1)    # 写入          # 读取复杂变量        print("Reading Registers:")        address = 40001        count = len(payload)        print(f"payload_len {count}")        result = client.read_holding_registers(address, count, slave=1)        print(result.registers)        print("\n")        decoder = BinaryPayloadDecoder.fromRegisters(            result.registers, byteorder=byte_endian, wordorder=word_endian        )        # Make sure word/byte order is consistent between BinaryPayloadBuilder and BinaryPayloadDecoder        assert (            decoder._byteorder == builder._byteorder  # pylint: disable=protected-access        )  # nosec        assert (            decoder._wordorder == builder._wordorder  # pylint: disable=protected-access        )  # nosec        decoded = OrderedDict(            [                ("string", decoder.decode_string(len(my_string))),                ("bits", decoder.decode_bits()),                ("8int", decoder.decode_8bit_int()),                ("8uint", decoder.decode_8bit_uint()),                ("16int", decoder.decode_16bit_int()),                ("16uint", decoder.decode_16bit_uint()),                ("32int", decoder.decode_32bit_int()),                ("32uint", decoder.decode_32bit_uint()),                ("16float", decoder.decode_16bit_float()),                ("16float2", decoder.decode_16bit_float()),                ("32float", decoder.decode_32bit_float()),                ("32float2", decoder.decode_32bit_float()),                ("64int", decoder.decode_64bit_int()),                ("64uint", decoder.decode_64bit_uint()),                ("ignore", decoder.skip_bytes(8)),                ("64float", decoder.decode_64bit_float()),                ("64float2", decoder.decode_64bit_float()),            ]        )        print("Decoded Data")        for name, value in iter(decoded.items()):            print(                "%s\t" % name,  # pylint: disable=consider-using-f-string                hex(value) if isinstance(value, int) else value,            )        print("\n")# 关闭连接    client.close()if __name__ == "__main__":    run_binary_payload_client("127.0.0.1", 503)    

相关资料

modbus tcp 通信协议
2、modbus tcp 通信协议2
3、pymodbus官方文档
4、pymodbus仓库

欢迎转载

来源地址:https://blog.csdn.net/brandon_l/article/details/127169641

--结束END--

本文标题: python使用pymodbus库进行modbus tcp通信

本文链接: https://www.lsjlt.com/news/393287.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python使用pymodbus库进行modbus tcp通信
    使用pymodbus库进行modbus tcp通信 使用python解决工业通信问题是一个非常好的选择,python具有丰富的生态,可以轻松解决工业通信的各种问题。本篇主要介绍使用pymodbus...
    99+
    2023-09-04
    python 开发语言 制造
  • 如何使用Node.js进行TCP网络通信
    这篇文章给大家介绍如何使用Node.js进行TCP网络通信,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。摘要: 网络是通信互联的基础,Node.js提供了...
    99+
    2024-04-02
  • 如何进行TCP通信实现
    本篇文章给大家分享的是有关如何进行TCP通信实现,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。TCP是底层通讯协议,定义的是数据传输和连接方式的规范。TCP协议,传输控制协议(...
    99+
    2023-06-05
  • TIA博途中S7-1200进行MODBUS TCP通信(作为服务器)的具体方法演示
    TIA博途中S7-1200进行MODBUS TCP通信(作为服务器)的具体方法演示 如下图所示,打开TIA博途软件,添加一个1200的PLC,并设置该PLC的IP地址,这里以192.168.0.2...
    99+
    2023-09-21
    服务器 网络 MODBUS TCP 具体方法演示 TIA博途
  • 用 Python 进行 MQTT 通信
    用 Python 进行 MQTT 通信 简介 MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,常用于物联网设备之间的通信。Python 提...
    99+
    2023-09-14
    python 网络
  • 使用TCP协议在Go语言中进行网络通信
    目前编程网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《使用TCP协议在Go语言中进行网络通信》,也希望能帮助到大家,如果阅读完后真的对你学习Go...
    99+
    2024-04-04
  • 利用TCP进行通信出现丢包如何解决
    这篇文章给大家介绍利用TCP进行通信出现丢包如何解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。如果通信中发现缺少数据或者丢包,那么,最大的可能在于程序发送的过程或者接收的过程出现问题。例如服务器给客户端发大量数据,...
    99+
    2023-05-31
    tcp tc
  • Android进程间使用Intent进行通信
    安卓使用Intent来封装程序的“调用意图”,使用Intent可以让程序看起来更规范,更易于维护。 除此之外,使用Intent还有一个好处:有些时候我们只是想...
    99+
    2023-02-28
    Android Intent通信 Android进程通信
  • Android怎么使用GRPC进行通信
    这篇文章主要介绍“Android怎么使用GRPC进行通信”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android怎么使用GRPC进行通信”文章能帮助大家解决问题。引言Android作为一个开发平...
    99+
    2023-07-05
  • Android进程间如何使用Intent进行通信
    这篇文章主要介绍“Android进程间如何使用Intent进行通信”,在日常操作中,相信很多人在Android进程间如何使用Intent进行通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android进程...
    99+
    2023-07-05
  • Vue3.x使用mitt.js进行组件通信
    目录快速开始使用方式核心原理Vue2.x 使用 EventBus 进行组件通信,而 Vue3.x 推荐使用 mitt.js。 比起 Vue 实例上的 EventBus,mitt.j...
    99+
    2024-04-02
  • 如何使用 Golang 协程进行通信?
    非常抱歉,由于您没有提供文章标题,我无法为您生成一篇高质量的文章。请您提供文章标题,我将尽快为您生成一篇优质的文章。...
    99+
    2024-05-21
  • 如何使用Python中的socket编程进行数据通信
    标题:Python中的socket编程及代码示例引言:在现代互联网时代,数据通信无处不在。而Python中的socket编程提供了一种简单而有效的方式来实现网络上的数据传输。本文将介绍如何使用Python的socket模块来进行数据通信,并...
    99+
    2023-10-22
    Python Socket编程 数据通信
  • Android使用GRPC进行通信过程解析
    目录引言环境搭建修改项目的setting.gradle信息修改项目的build.gralde信息修改gradle版本号修改模块的build.gradle信息在main目录下创建pro...
    99+
    2023-02-28
    Android使用GRPC Android GRPC通信
  • golang函数如何使用管道进行通信
    在 go 中,管道是用于 goroutine 之间通信的 fifo 队列。创建一个管道:使用 make(chan t) 函数,其中 t 是管道中数据类型。发送数据:使用 ch Go ...
    99+
    2024-04-30
    golang 管道
  • 如何使用Golang与RabbitMQ进行高效通信?
    要使用Golang与RabbitMQ进行高效通信,可以按照以下步骤进行操作:1. 安装RabbitMQ:首先需要安装RabbitMQ...
    99+
    2023-10-08
    Golang
  • Vue3使用mitt进行组件通信的步骤
    目录1. 安装 2. 引入到项目并挂载 3. 使用 Vue2.x使用EventBus进行组件通信,而Vue3.x推荐使用mitt.js。 比起Vue实例上的Even...
    99+
    2024-04-02
  • 如何使用Python中的进程间通信
    如何使用Python中的进程间通信进程间通信(IPC,Inter-Process Communication)是计算机科学中一个重要的概念,它允许不同的进程在同一个计算机系统中进行数据交换和共享资源。在Python中,有多种方式可以实现进程...
    99+
    2023-10-22
    Python 进程通信 IPC
  • 如何使用Linux命令行与其他用户进行通信
    这篇文章主要介绍了如何使用Linux命令行与其他用户进行通信,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。wallwall(“Write ALL” 的简称)命令允许你向所有系...
    99+
    2023-06-16
  • 使用 python 进行微信好友分析
    使用 python 进行微信好友分析 1. 使用到的库 ① wxpy:初始化微信机器人 ② openpyxl:保存微信好友数据为Excel表格 ③ pyecharts:生成可视化的地图 ④ wordcloud、matplotlib、jie...
    99+
    2023-01-31
    好友 python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作