对于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学习笔记相关推荐

  1. modbus协议学习笔记

    前言   在学习modbus协议之前,读者最好能够具备有串行通信的基础知识.串行通信是指数据以串行的方式传输的一种通信,即仅使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度. ...

  2. TCL/TK 学习笔记 之 用C定义自己的TCL命令

    第一步:编写一个.c文件,例如simple.c               /**simple.c**/               #include "simple.h"     ...

  3. tcl/tk学习笔记《二》 tcl/tk概览二

    (6) 控制结构(粗略看一下)   http://www.tcl.tk/man/tcl8.6/TclLib/NRE.htm#M5           tcl的控制语言结构,如下看一下while循环   ...

  4. Modbus Slave学习笔记

    第一章 初识Modbus 1.1什么是Modbus 简而言之,Modbus通信协议是工业领域通信协议的业界标准,并且是当前工业电子设备之间相当常用的连接方式之一. ​ Modbus 协议是应用于电子控 ...

  5. Modbus 协议学习笔记及常用功能码详解

    下面的MODBUS 协议的相关知识 是自己在网上搬运的 以便以后自己查看 01. 寄存器分类 Modbus寄存器分为四种,如下表所示: 线圈寄存器:实际上可以表示一个开关量,线圈操作位(bit)一个b ...

  6. 485之modbus通讯协议学习笔记

    485之modbus通讯协议学习笔记 这里主要探讨两个寄存器 03 读保持寄存器 04读输入寄存器 输入寄存器其中的温度值和湿度值分别各占两个字节,一个字节八位使用十六进制00 01表示两个字节的寄存 ...

  7. 【学习笔记】线性代数全家桶(在编程竞赛中的应用)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 0x00. 矩阵 0x01. 矩阵 0x02. 矩阵的加法与数量乘法 0x03. 矩阵乘法 0x ...

  8. Python学习笔记:常用第三方模块3

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  9. 统计学习方法 学习笔记(十):决策树

    这一个学习笔记将要了解决策树,在研一上机器学习这门课的时候,老师在讲到这一节的时候,举了一个例子我现在还能记得:你们坐在这里上课,就像这个决策树一样,在你人生中的每一个重要结点,你都做出了选择,经过多 ...

最新文章

  1. qemu模拟A9/A15运行Linux4.2.3
  2. 【转】Struts2中转换Date类型的问题
  3. gnuradio 使用eclipse 编辑器记录
  4. Sequence 带来的更多乐趣
  5. mysql field flags_PHPmysql_field_flags()实例教程_PHP教程
  6. 基于Python和MySQL的学生信息管理系统
  7. 第二章 Jsp基本语法
  8. windows 安装h2o_H2O-安装
  9. 机器学习十大经典算法入门
  10. 面试技巧: 轻松过关10种方法
  11. 机器人学:操作臂运动学(Manipulator Forward Kinematics)
  12. 【论文阅读笔记】MFRDet:A single-shot multi-level feature reused neural network for object detection
  13. 抛出异常和捕获异常_多捕获和最终重新抛出的异常处理
  14. 福州的宝贝原来都藏在这里
  15. 中标麒麟兆芯版7.0
  16. SDHC(高容量SD存储卡)
  17. 柯尼卡美能达Konica Minolta 7155 打印机驱动
  18. 好用的窗口透明软件:Vitrite
  19. 网络笔记(8) 世界这么大,我想出网关:欧洲十国游与玄奘西行
  20. android midi 编辑6,Android6.0MIDI设备相关应用程序开发

热门文章

  1. 子域名接管_在S3上利用子域接管
  2. mongdb 下载慢,解决
  3. 管廊隧道怎么定位人员?分享管廊隧道人员定位系统解决方案
  4. Windows9x系统下汉字输入法的基本原理
  5. Charles--使用Charles抓Https包
  6. 微电网经济调度(风、光、柴油机、蓄电池、电网交互)(Matlab代码实现)
  7. 分支与循环语句(下)
  8. 《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》——2.6 类和继承...
  9. 关于yolov3.weights文件下载地址的分享
  10. python: xlsx表格转为csv文件