基础知识

硬件层协议:解决0和1的可靠传输,常有RS232、RS485、CAN、IIC、SPI …

软件层协议:解决传输目的,常有Modbus、TCP/IP、CANopen …

协议优点:

  • Modbus协议标准开放、公开发表且无版权要求
  • Modbus协议支持多种电气接口,包括RS232、RS485、TCP/IP等,还可以在各种介质上传输,如双绞线、光纤、红外、无线等
  • Modbus协议消息帧格式简单、紧凑、通俗易懂。用户理解和使用简单,厂商容易开发和集成,方便形成工业控制网络

Modbus是一主多从的通信协议

Modbus通信中只有一个设备可以发送请求。其他从设备接收主机发送的数据来进行响应,从机是任何外围设备,如I/O传感器,阀门,网络驱动器,或其他测量类型的设备,从站处理信息和使用Modbus将其数据发送给主站。不能Modbus同步进行通信,主机在同一时间内只能向一个从机发送请求,总线上每次只有一个数据进行传输,即主机发送,从机应答,主机不发送,总线上就没有数据通信。 从机不会自己发送消息给主站,只能回复从主机发送的消息请求。

RTU协议

Modbus报文是指主机发送给从机的一帧数据,其中包含着从机的地址,主机想执行的操作,校验码等内容

Modbus协议在串行链路上的报文格式如下所示:

  • 从机地址: 每个从机都有唯一地址,占用一个字节,范围0-255,其中有效范围是1-247,其中255是广播地址(广播就是对所有从机发送应答)
  • 功能码: 占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改从机的数据,所以不同功能码对应不同功能.
  • 数据: 根据功能码不同,有不同功能,比方说功能码是查询从机的数据,这里就是查询数据的地址和查询字节数等。
  • 校验: 在数据传输过程中可能数据会发生错误,CRC检验检测接收的数据是否正确

Modbus功能码

Modbus协议同时规定了二十几种功能码,但是常用的只有8种,用于对存储区的读写,如下表所示:

功能码 功能说明
01H 读取输出线圈
02H 读取输入线圈
03H 读取保持寄存器
04H 读取输入寄存器
05H 写入单线圈
06H 写入单寄存器
0FH 写入多线圈
10H 写入多寄存器

当然我们用的最多的就是03和06 一个是读取数据,一个是修改数据。

1、主机对从机读数据操作

主机发送报文格式如下:

从站地址 功能码 起始(高) 起始(低) 数量(高) 数量(低) 校验
0x01 0x03 0x00 0x01 0x00 0x01 0xD5 0xCA

含义:

0x01:从机的地址

0x03:查询功能,读取从机寄存器的数据

0x00 0x01: 代表读取的起始寄存器地址.说明从0x0001开始读取.

0x00 0x01: 查询的寄存器数量为0x0001个 Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据; 寄存器地址对应着从机实际的存储地址

0xD5 0xCA: 循环冗余校验 CRC

从机回复报文格式如下:

从站地址 功能码 字节计数 字节1 字节2 校验
0x01 0x03 0x02 0x00 0x00 0xB8 0x44

含义:

0x01:从机的地址

0x03:查询功能,读取从机寄存器的数据

0x02: 返回字节数为2个 一个寄存器2个字节

0x00 0x00:寄存器的值是0000

0xB8 0x44: 循环冗余校验 CRC

2、主机对从机写数据操作

主机发送报文格式如下:

从站地址 功能码 数据地址(高) 数据地址(低) 数据(高) 数据(低) 校验
0x01 0x06 0x00 0x01 0x00 0x17 0x98 0x04

含义:

0x01:从机的地址

0x06:修改功能,修改从机寄存器的数据

0x00 0x01: 代表修改的起始寄存器地址.说明修改0x0001-0x0003的存储内容

0x00 0x17: 要修改的数据值为0017

0x98 0x04: 循环冗余校验 CRC

从机回复报文格式如下:

从站地址 功能码 数据地址(高) 数据地址(低) 数据(高) 数据(低) 校验
0x01 0x06 0x00 0x01 0x00 0x17 0x98 0x04

含义:

0x01:从机的地址

0x06:修改功能,修改从机寄存器的数据

0x00 0x01: 代表修改的起始寄存器地址.说明是0x0000

0x00 0x17:修改的值为0017

0x98 0x04: 循环冗余校验 CRC

从机的回复和主机的发送是一样的,如果不一样说明出现了错误

python库 modbus_tk

import serial
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu class Modbus:
def __init__(self, port: str, baud: int):
"""
初始化modbus
默认的slave_id为1
:param port: 串口号
:param baud: 波特率
"""
self.port = port
self.baud = int(baud)
self.master = None def open(self):
try:
self.master = modbus_rtu.RtuMaster(
serial.Serial(port=self.port, baudrate=self.baud, bytesize=8, parity='N', stopbits=1))
self.master.set_timeout(5.0)
except Exception as err:
print("---异常---", err) def master_write_single_coil(self, slave_id: int, register_address: int, output_value: int) -> tuple:
"""
05指令
向slave从机中写寄存器
:param slave_id: 从机id
:param register_address: 从机寄存器的地址 十进制
:param output_value: 要写入的数值 十进制
:return: (0, 32762) 类似元组(写入的从机寄存器地址,写入的值)
"""
result = self.master.execute(slave_id, cst.WRITE_SINGLE_COIL, register_address, output_value=output_value)
return result def master_write_single_register(self, slave_id: int, register_address: int, output_value: int) -> tuple:
"""
06指令
向slave从机中写寄存器
:param slave_id: 从机id
:param register_address: 从机寄存器的地址 十进制
:param output_value: 要写入的数值 十
:return: (0, 32762) 类似元组(写入的从机寄存器地址,写入的值)
"""
# 写入操作当对动作指令寄存器写入对应动作参数,就会立刻进行执行动作
# 站点号;cst.WRITE_SINGLE_REGISTER写入单个寄存器;寄存器写入地址;output_value写入的值
result = self.master.execute(slave_id, cst.WRITE_SINGLE_REGISTER, register_address, output_value=output_value)
return result

Modbus协议及python库实现的更多相关文章

  1. Python的网络编程[6] -> Modbus 协议 -> Modbus 的基本理论与 Python 实现

    Modbus协议 / Modbus Protocol 目录 Modbus 协议简介 Modbus RTU协议 Modbus TCP协议与 Python 实现 Modbus 功能码 Modbus TCP ...

  2. Python爬虫:HTTP协议、Requests库(爬虫学习第一天)

    HTTP协议: HTTP(Hypertext Transfer Protocol):即超文本传输协议.URL是通过HTTP协议存取资源的Internet路径,一个URL对应一个数据资源. HTTP协议 ...

  3. Python爬虫:HTTP协议、Requests库

    HTTP协议: HTTP(Hypertext Transfer Protocol):即超文本传输协议.URL是通过HTTP协议存取资源的Internet路径,一个URL对应一个数据资源. HTTP协议 ...

  4. Python 库大全

    作者:Lingfeng Ai链接:http://www.zhihu.com/question/24590883/answer/92420471来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非 ...

  5. 【阿里聚安全·安全周刊】Python库现后门 可窃取用户SSH信息|Facebook再曝300万用户数据泄露

    本周七个关键词:Python库现后门丨Facebook再曝数据泄露丨加密协议被曝严重漏洞丨英国报摊将出售"色情通行证"丨HTTPS的绿色锁图标丨机器学习和预测应用的API丨Ecli ...

  6. 哪些 Python 库让你相见恨晚?【转】

    原文链接:https://www.zhihu.com/question/24590883/answer/92420471 原文链接:Python 资源大全 ---------------- 这又是一个 ...

  7. Python库资源大全

    转载地址:https://zhuanlan.zhihu.com/p/27350980 本文是一个精心设计的Python框架.库.软件和资源列表,是一个Awesome XXX系列的资源整理,由BigQu ...

  8. Python 库/模块/工具收集

    1 算法 1.1 字符串处理 re 正则表达式的标准库. StringIO / cStringIO 以读写文件的方式来操作字符串(有点类似于内存文件). cStringIO 是 C 语言实现的,提供高 ...

  9. Python库,让你相见恨晚的第三方库

    环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具.pyenv – 简单的 Python 版本管理工具.Vex – 可以在虚拟环境中执行命令.virt ...

随机推荐

  1. JCEF 初体验,window系统构建jar包

    前言 本文记录如何通过jcef源代码去构建自己所需要的jar包,此文章构建的为windows64位jcef 的 jar 包,若需要构建 32 位的 jar 包,则需要按照文章将相关准备软件设置为 32 ...

  2. Android的Handler线程切换原理

    Handler是我们在开发中经常会接触到的类,因为在Android中,子线程一般是不能更新UI的. 所以我们会使用Handler切换到主线程来更新UI,那Handler是如何做到实现不同线程之间的切换 ...

  3. 典型C内存空间分布图

    下图是一个典型的C内存空间分布图 这是Linux下32位环境的用户空间内存分布情况 内核空间 :一部分核心软件独立于普通应用程序,运行在较高的特权级别上,驻留在被保护的内存空间上,拥有访问硬件设备的所 ...

  4. linux中awk命令详解(最全面秒懂)

    一:linux中awk命令 1.awk命令简介 AWK 是一种处理文本文件的语言,是一个强大的文本分析工具. 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinber ...

  5. .NET 反向代理-YARP 部署Https(SSL)

    YARP 作为反向代理中间件,那就无可避免需要使用到 Https 去部署项目,那 YARP 要怎么去实现呢,本来以为 YARP 会有一套自己的实现,在翻阅了资料后发现,根本不是我想的那样,按照 YAR ...

  6. Nginx反代服务器进阶学习最佳配置实践指南

    转载自:https://www.bilibili.com/read/cv16150010?spm_id_from=333.999.0.0 0x00 编译实践 描述:在企业线上生产环境中推荐进行Ngin ...

  7. 常用的清理 Kubernetes 集群资源命令

    1. Kubernetes 基础对象清理 清理 Evicted 状态的 Pod kubectl get pods --all-namespaces -o wide | grep Evicted | a ...

  8. 天翼云主机某一IP多次登录失败导致IP被锁无法登录,天翼云主机莫名其妙无法远程登陆

    情况说明: 直接使用该IP通过ssh远程连接失败,但是先通过ssh远程连接其他主机上,然后在这个主机上再ssh刚才连接失败的主机,就能登陆上. 说明,root用户不是被锁了, 而是远程登陆IP被锁了 ...

  9. a += 20 和 a = a+20前者不报错,后者报错的原因

    我们在使用a += 20 和 a = a+20两种不同方式的赋值运算是发现尽然前者不报错,后者报错 代码示例: shot s = 5; s += 5; s = s+5; 很明显我们可以看出s = s+ ...

  10. .Net 7 C#11 原始字符串

    .Net7 的到来的同时,也带来了 C# 11,而令我最期待的就是 C# 11 的 原始字符串了,当我知道这个的时候,简直比过年还要开心. 非原始字符串 首先我们看看现在写字符串的方式 var str ...