modbus-tk学习笔记
对于modbus ASCII 模式,使用的是高位字节在前,低位字节在后。使用LRC校验。
对于modbus rtu 模式,使用的是低位字节在前,高位字节在后。使用CRC校验。
参考博客:
modbus 入门篇,不冗长,很好理解!
MODBUS学习笔记——modbus tk modbus TCP主机实现_物联网 IoT 经验分享-CSDN博客_modbus_tk
modbus协议中的寄存器理解
0.前言
modbus是一种古老但是高效的应用层协议。在嵌入式和PC机领域有多种方法实现modbus协议栈,modbus又分为从机和主机,从机和主机在协议栈的实现上存在不同。在不能运行linux的嵌入式系统中,freemodbus是一个完善的从机协议栈,在能够运行linux的嵌入式系统中存在多种选择,而modbus tk是使用python语言实现的modbus协议栈, 该函数库即支持主机也支持从机,即支持RTU也支持TCP。
有了modbus TK,那么在树莓派中加入一个modbus TCP实现从机功能,也就是分分钟的事情。
官方源码:git clone https://github.com/ljean/modbus-tk.git
用到的软件:
链接:https://pan.baidu.com/s/1iCfk3c_eRQlzY5cEDJa-cA
提取码:2g3l
1、名词解释
功能码:用于表示信息帧的功能
参考博客:modbus功能码定义和样例
0x01: 读线圈寄存器
0x02: 读离散输入寄存器
0x03: 读保持寄存器
0x04: 读输入寄存器
0x05: 写单个线圈寄存器
0x06: 写单个保持寄存器
0x0f: 写多个线圈寄存器
0x10: 写多个保持寄存器
线圈寄存器:实际上就可以类比为开关量,每个bit都对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。对应上面的功能码也就是:0x01 0x05 0x0f
离散输入寄存器:如果线圈寄存器理解了这个自然也明白了。离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。所以功能码也简单就一个读的 0x02
保持寄存器:这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写,所以功能码有对应的三个:0x03 0x06 0x10
输入寄存器:只剩下这最后一个了,这个和保持寄存器类似,但是也是只支持读而不能写。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值。对应的功能码也就一个 0x04
报文:一个报文就是一帧数据,一个数据帧就一个报文: 指的是一串完整的指令数据,就像下面的一串数据。
01 06 00 01 00 17 98 04
01 | 06 | 00 01 | 00 17 | 98 04 |
---|---|---|---|---|
从机地址 | 功能码 | 数据地址 | 数据 | CRC校验 |
这一串数据的意思是:把数据 0x0017(十进制23) 写入1号从机地址 0x0001数据地址。
ADU: 应用数据单元
PDU: 协议数据单元
CRC校验:上面的 98 04 是它前面的数据(01 06 00 01 00 17)通过一算法计算出来的。
作用:在数据传输过程中可能数据会发生错误,CRC检验检测接收的数据是否正确。比如主机发出01 06 00 01 00 17 98 04,那么从机接收到后要根据01 06 00 01 00 17 再计算CRC校验值,从机判断自己计算出来的CRC校验是否与接收的CRC校验(98 04主机计算的)相等,如果不相等那么说明数据传输有错误这些数据不能要。
2、数据传输
INT8U OX[20];/*输出线圈*/
INT8U IX[20];/*输入线圈*/
INT16U HoldDataReg[30];/*保存寄存器*/
INT16U InDataReg[30];/*输入寄存器*/
2.1、主机对从机写数据操作
如果从机接收到一个报文那么就对报文进行解析执行相应的处理
01 | 06 | 00 01 | 00 17 | 98 04 |
---|---|---|---|---|
从机地址 | 功能码 | 数据待写入起始地址 | 数据 | CRC校验 |
假如本机地址是 1 ,那么单片机接收到这串数据根据数据计算CRC校验判断数据是否正确,如果判断数据无误,则结果是:HoldDataReg[1] = 0x0017;
MODBUS主机就完成了一次对从机数据的写操作,实现了通讯。
2.2、主机对从机读数据操作
主机进行读HoldDataReg[1] 操作,则报文是:
主机发送给从机
01 | 03 | 00 01 | 00 01 | D5 CA |
---|---|---|---|---|
从机地址 | 功能码 | 数据地址 | 读取数据个数 | CRC校验 |
单片机接收到这串数据根据数据计算CRC校验判断数据是否正确,如果判断数据无误,则返数据给主机,返回的信息也是有格式的:
从机发送给主机
01 | 03 | 02 | 0017 | F8 4A |
---|---|---|---|---|
从机地址 | 功能码 | 数据字节个数 | 两个字节数据 | CRC校验 |
MODBUS主机就完成了一次对从机数据的读操作,实现了通讯。
3、实验
- 主机写从机:master.execute(slave 地址,功能码,数据待写入起始地址,output_value=[待写入的数据,列表形式]):CRC不需要我们添加。
- 主机读从机:master.execute(slave 地址,功能码,数据待读取起始地址,读取数据个数):CRC不需要我们添加。
写线圈寄存器(只有0和1):
red = master.execute(2, cst.WRITE_MULTIPLE_COILS, 0, output_value=[1,1,0,1,0])
2:Slave ID(Slave地址)
cst.WRITE_MULTIPLE_COILS:功能码
0:数据起始地址
output_value:数据
读线圈寄存器(只有0和1):
red = master.execute(2, cst.READ_COILS, 0, 2)
返回:(1, 1)
其他的寄存器操作类似。
4、源码
# -*- coding: utf_8 -*-import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtudef mod(PORT="com1"):red = []alarm = ""try:# 设定串口为从站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)red = master.execute(2, cst.READ_COILS, 0, 2) # 这里可以修改需要读取的功能码print(red)alarm = "正常"return list(red), alarmexcept Exception as exc:print(str(exc))alarm = (str(exc))return red, alarm ##如果异常就返回[],故障信息if __name__ == "__main__":mod()
modbus-tk学习笔记相关推荐
- modbus协议学习笔记
前言 在学习modbus协议之前,读者最好能够具备有串行通信的基础知识.串行通信是指数据以串行的方式传输的一种通信,即仅使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度. ...
- TCL/TK 学习笔记 之 用C定义自己的TCL命令
第一步:编写一个.c文件,例如simple.c /**simple.c**/ #include "simple.h" ...
- tcl/tk学习笔记《二》 tcl/tk概览二
(6) 控制结构(粗略看一下) http://www.tcl.tk/man/tcl8.6/TclLib/NRE.htm#M5 tcl的控制语言结构,如下看一下while循环 ...
- Modbus Slave学习笔记
第一章 初识Modbus 1.1什么是Modbus 简而言之,Modbus通信协议是工业领域通信协议的业界标准,并且是当前工业电子设备之间相当常用的连接方式之一. Modbus 协议是应用于电子控 ...
- Modbus 协议学习笔记及常用功能码详解
下面的MODBUS 协议的相关知识 是自己在网上搬运的 以便以后自己查看 01. 寄存器分类 Modbus寄存器分为四种,如下表所示: 线圈寄存器:实际上可以表示一个开关量,线圈操作位(bit)一个b ...
- 485之modbus通讯协议学习笔记
485之modbus通讯协议学习笔记 这里主要探讨两个寄存器 03 读保持寄存器 04读输入寄存器 输入寄存器其中的温度值和湿度值分别各占两个字节,一个字节八位使用十六进制00 01表示两个字节的寄存 ...
- 【学习笔记】线性代数全家桶(在编程竞赛中的应用)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 0x00. 矩阵 0x01. 矩阵 0x02. 矩阵的加法与数量乘法 0x03. 矩阵乘法 0x ...
- Python学习笔记:常用第三方模块3
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
- 统计学习方法 学习笔记(十):决策树
这一个学习笔记将要了解决策树,在研一上机器学习这门课的时候,老师在讲到这一节的时候,举了一个例子我现在还能记得:你们坐在这里上课,就像这个决策树一样,在你人生中的每一个重要结点,你都做出了选择,经过多 ...
最新文章
- qemu模拟A9/A15运行Linux4.2.3
- 【转】Struts2中转换Date类型的问题
- gnuradio 使用eclipse 编辑器记录
- Sequence 带来的更多乐趣
- mysql field flags_PHPmysql_field_flags()实例教程_PHP教程
- 基于Python和MySQL的学生信息管理系统
- 第二章 Jsp基本语法
- windows 安装h2o_H2O-安装
- 机器学习十大经典算法入门
- 面试技巧: 轻松过关10种方法
- 机器人学:操作臂运动学(Manipulator Forward Kinematics)
- 【论文阅读笔记】MFRDet:A single-shot multi-level feature reused neural network for object detection
- 抛出异常和捕获异常_多捕获和最终重新抛出的异常处理
- 福州的宝贝原来都藏在这里
- 中标麒麟兆芯版7.0
- SDHC(高容量SD存储卡)
- 柯尼卡美能达Konica Minolta 7155 打印机驱动
- 好用的窗口透明软件:Vitrite
- 网络笔记(8) 世界这么大,我想出网关:欧洲十国游与玄奘西行
- android midi 编辑6,Android6.0MIDI设备相关应用程序开发
热门文章
- 子域名接管_在S3上利用子域接管
- mongdb 下载慢,解决
- 管廊隧道怎么定位人员?分享管廊隧道人员定位系统解决方案
- Windows9x系统下汉字输入法的基本原理
- Charles--使用Charles抓Https包
- 微电网经济调度(风、光、柴油机、蓄电池、电网交互)(Matlab代码实现)
- 分支与循环语句(下)
- 《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》——2.6 类和继承...
- 关于yolov3.weights文件下载地址的分享
- python: xlsx表格转为csv文件