Python的网络编程[6] -> Modbus 协议 -> Modbus 的基本理论与 Python 实现
Modbus协议 / Modbus Protocol
目录
1 Modbus 协议简介
Modbus协议MODICON公司1979年开发的一种通信协议,是一种工业现场总线协议标准,1996年施耐德公司推出了基于以太网TCP/IP的Modbus协议—ModbusTCP。
Modbus协议是一项应用层报文传输协议,包括ASCII / RTU / TCP三种报文类型,协议本身不定义物理层,只定义了控制器能够认识和使用的消息结构,而不管消息是经过何种网络进行通信的。
标准的Modbus协议物理层接口主要有RS232 / RS422 / RS485和以太网。采用Master/Slave主从方式通信。
2 Modbus RTU协议 / Modbus RTU Protocol
Modbus RTU协议报文格式主要如下,
名称 字节数 位号 描述
------------ --------- ------ ------
设备地址 1 1
功能码 1 2 03H读寄存器/06H写单个寄存器/10H写多个寄存器
寄存器地址 2 3-4 高位在前
数据长度 2 5-6 传送数据总长度
CRC校验 2 7-8
下面是不同操作时使用的报文格式


3 Modbus TCP协议 / Modbus TCP Protocol
3.1 Modbus TCP协议格式
Modbus TCP协议报文格式主要可分为两段,MBAP和PDU,
MBAP:
名称 字节数 位号 描述
------------ --------- ------ ------
事物标识符 2 1-2 由服务器复制返回,通常为\x00\x00
协议表示符 2 3-4 通常为\x00\x00
数据长度 2 5-6 传送数据总长度,高位通常\x00(数据不超过256),低位为后续字节长度
单元标识符 1 7 通常为\x00
PDU:
名称 字节数 位号 描述
------------ --------- ------ ------
功能码 1 8 定义功能
起始寄存器 2 9-10 操作的寄存器起始位
寄存器/数据 2 11-12 读/多个写模式下,为寄存器数量,单个写模式为写入数据



3.2 Modbus TCP 加解码的 Python 实现 / Modbus TCP Encode and Decode by Python
import struct class ModbusCodeC():
"""
This CodeC class implement partly of Modbus encode and decode
The chamber only offer 03H and 06H function-code for using
""" @staticmethod
def MBAP_encode():
transFlagHi = b'\x00'
transFlagLo = b'\x00'
protoFlag = b'\x00\x00'
length = b'\x00\x06'
unitFlag = b'\x00'
mbap = transFlagHi + transFlagLo + protoFlag + length + unitFlag
return mbap @staticmethod
def PDU_encode(func, regi, num=1, data=None):
funcList = {'r': b'\x03',
'w': b'\x06'}
funcCode = funcList[func]
registerStart = struct.pack('!H', regi)
registerNum = struct.pack('!H', num)
if data and func == 'w':
dataCode = struct.pack('!H', data)
pdu = funcCode + registerStart + dataCode
return pdu
pdu = funcCode + registerStart + registerNum
return pdu @staticmethod
def encode(func, regi, num, data=None):
return ModbusCodeC.MBAP_encode() + ModbusCodeC.PDU_encode(func, regi, num, data) @staticmethod
def MBAP_decode(s):
m = {}
m['transFlagHi'] = s[:1]
m['transFlagLo'] = s[1:2]
m['protoFlag'] = s[2:4]
m['length'] = s[4:6]
m['unitFlag'] = s[6:]
return m @staticmethod
def PDU_decode(s):
p = {}
'''
p['funcCode'] = s[:1]
p['registerStart'] = s[1:3]
p['registerNum'] = s[3:5]
p['data'] = s[5:]
'''
# TODO: Add bit number and data length check here
p['funcCode'] = s[:1]
p['bitNum'] = s[1:2]
p['data'] = s[2:]
return p @staticmethod
def decode(msg):
msg_de = {}
mbap, pdu = msg[:7], msg[7:]
msg_de['MBAP'] = ModbusCodeC.MBAP_decode(mbap)
msg_de['PDU'] = ModbusCodeC.PDU_decode(pdu)
return msg_de if __name__ == '__main__':
print(ModbusCodeC.encode('r', 5, 3))
print(ModbusCodeC.encode('w', 5, 1, 8))
4 Modbus 功能码/ Modbus Function Code
在Modbus功能码中,1-65位为公共功能码,定义了一些通用的功能


5 Modbus TCP/RTU对比 / Modbus TCP/RTU Comparison
5.1 Modbus RTU与Modbus TCP读指令对比
|
MBAP报文头 |
地址码 |
功能码 |
寄存器地址 |
寄存器数量 |
CRC校验 |
|
|
Modbus RTU |
无 |
01 |
03 |
01 8E |
00 04 |
25 DE |
|
Modbus TCP |
00 00 00 00 00 06 00 |
无 |
03 |
01 8E |
00 04 |
无 |
指令的涵义:从地址码为01(TCP协议单元标志为00)的模块0x18E(01 8E)寄存器地址开始读(03)四个(00 04)寄存器。
5.2 Modbus RTU与Modbus TCP写指令对比
|
MBAP报文头 |
地址码 |
功能码 |
寄存器地址 |
寄存器数量 |
数据长度 |
正文 |
CRC校验 |
|
|
RTU |
无 |
01 |
10 |
01 8E |
00 01 |
02 |
00 00 |
A8 7E |
|
TCP |
00 00 00 00 00 09 00 |
无 |
10 |
01 8E |
00 01 |
02 |
00 00 |
无 |
指令的涵义:从地址码为01(TCP协议单元标志为00)的模块0x18E(01 8E)寄存器地址开始写(10)一个(00 01)寄存器,具体数据长度为2个字节(02),数据正文内容为00 00(00 00)。
参考链接
http://blog.csdn.net/yangbingzhou/article/details/39504015
http://www.485-can-tcp.com/technology/232485/Modbus.htm
Python的网络编程[6] -> Modbus 协议 -> Modbus 的基本理论与 Python 实现的更多相关文章
- Python的网络编程[3] -> BOOTP 协议[0] -> BOOTP 的基本理论
BOOTP协议 / BOOTP Protocol 目录 基本理论 BOOTP 与 DHCP 通信流程 数据报文格式 报文加解码实现 1. 基本理论 / Basic Theory BOOTP(Boots ...
- Python的网络编程[4] -> DHCP 协议[0] -> DHCP 的基本理论
DHCP协议 / DHCP Protocol 目录 DHCP 基本理论 DHCP 通信流程 DHCP 完整报文 DHCP 的 Optional 字段 DHCP 的报文类型 1 DHCP 基本理论 DH ...
- Python的网络编程[1] -> FTP 协议[0] -> FTP 的基本理论
FTP协议 / FTP Protocol FTP全称为File Transfer Protocol(文件传输协议),常用于Internet上控制文件的双向传输,常用的操作有上传和下载.基于TCP/IP ...
- Python的网络编程[2] -> TFTP 协议[0] -> TFTP 的基本理论
TFTP 的基本理论 目录 通信流程 数据报文格式 传输终结 异常处理 数据丢失和超时 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是UDP协议族中的一个 ...
- Python的网络编程[1] -> FTP 协议[2] -> 使用 ftplib 建立 FTP 客户端
使用 ftplib 建立 FTP 客户端 用于建立FTP Client,与 pyftplib 建立的 Server 进行通信. 快速导航 1. 模块信息 2. 建立 FTP 客户端 1. 模块信息 1 ...
- Python的网络编程[3] -> BOOTP 协议[1] -> BOOTP 的 Python 实现
BOOTP实现 / BOOTP Implement 目录 BOOTP 的服务器建立过程 BOOTP 的客户端建立过程 Note: 理论部分请参考文末相关阅读链接 1 BOOTP 的服务器建立过程 服务 ...
- Python的网络编程[1] -> FTP 协议[1] -> 使用 pyftplib 建立 FTP 服务器
使用 pyftplib 建立 FTP 服务器 pyftplib 主要用于建立 FTP Server,与 ftplib 建立的 Client 进行通信. 快速导航 1. 模块信息 2. 建立 FTP 服 ...
- Python的网络编程[2] -> TFTP 协议[1] -> TFTP 的 Python 实现
TFTP实现 / TFTP Implement 目录 TFTP 的服务器建立过程 TFTP 的客户端建立过程 1 TFTP 的服务器建立过程 服务器建立步骤主要有: (1) 设定服务器IP和 ...
- Python的网络编程[4] -> DHCP 协议[1] -> DHCP 的 Python 实现
DHCP实现 / DHCP Implement 目录 DHCP 服务器建立过程 DHCP 报文加码实现过程 下面介绍建立一个简单的DHCP服务器,主要用于对基本的DHCP请求进行响应,目前只提供一个I ...
随机推荐
- 《Cracking the Coding Interview》——第9章:递归和动态规划——题目8
2014-03-20 04:04 题目:给你不限量的1分钱.5分钱.10分钱.25分钱硬币,凑成n分钱总共有多少种方法? 解法:理论上来说应该是有排列组合的公式解的,但推导起来太麻烦而且换个数据就又得 ...
- Jmeter获取Cookie并传递到下一个线程---跨线程后cookie找不到了
网上找了一堆文章没有一个是实际操作的,自己边试边查边摸索终于找到了一个全套的办法. 原创文章,转载请说明出处. 1.取得cookie 直接这样写就可以了${COOKIE_JSESSIONID},当然具 ...
- diskimage-builder-command
yum -y install python-virtualenv.noarch virtualenv ~/dib-virtualenv . ~/dib-virtualenv/bin/activate ...
- 【Python】重定向 Stream 到文件
Python 系统模块 sys 中有三个变量 stdin . stdout 与 stderr ,分别对应标准输入流.输出流与错误流.stdin 默认指向键盘, stdout 与 stderr 默认指向 ...
- CLion 的 Debug 模式是怎么回事
我对这个问题产生兴趣的起因是 Codeoforces Avito Challenges 2018 的 E 题,我想到了正解,但写得太慢,最后一刻才提交.有个地方写错,结果是 Runtime error ...
- [CF1036C]Classy Numbers
题目大意:多个询问,每个询问问$[l,r](1\leqslant l\leqslant r\leqslant10^{18})$内有多少个数满足非零数位小于等于$3$. 题解:数位$DP$,$f_{i, ...
- JZOJ 5279 香港记者
一句话题意:一个带点权边权的无向图,输出从1号点到n号点的最短路中字典序最小的一条路径 样例输入: 8 9 1 2 3 4 5 6 7 8 1 2 2 2 3 3 3 8 3 1 4 3 4 5 2 ...
- Codeforces Round #281 (Div. 2) B 模拟
B. Vasya and Wrestling time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- 手动编写一个简单的loadrunner脚本
loadrunner除了自动录制脚本外,还可以手动编写脚本,通过右键+inset step添加步骤,还可以手动添加事务,集合点等 下面是一个简单的Action脚本,服务是运行在本机的flask服务: ...
- Vue props父组件向子组件传值详解
vue官网上可以说有我们想要的一切,先贴上通过prop传值的官网地址:通过prop向子组件传递数据 Prop是什么? Prop是你可以在组件上注册的一些自定义特性.当一个值传递给一个prop特性的时候 ...