交互(通信)标识:2个字节 为此次通信事务处理标识符,一般每次通信之后将被要求加1以区别不同的通信数据报文。
协议标识:2个字节 表示该条指令遵循ModbusTCP协议,一般都为00 00
报文长度:2个字节 表示后面数据的长度,有几个字节,高字节在前
(前六位Modbus/TCP协议不同功能码通用)
设备标识 :1个字节 设备地址,这个可以用于局域网里面的具体的地址,如果目标机器有固定ip,这个就不起作用,直接上写成 00
功能码:1个字节 功能码在modbus协议用于表示信息帧的功能
数据:N个字节 后面数据根据不同功能码不同。
| 十进制 | 功能 | 数据类型 |
|---|---|---|
| 01 | 读取 多个线圈 | 位 |
| 02 | 读取 多个离散量输入量 | 位 |
| 03 | 读取 多个保持寄存器 | 16进制整型 |
| 04 | 读取 多个输入寄存器 | 16进制整型 |
| 05 | 写入 单个线圈 | 位 |
| 06 | 写入 单个寄存器 | 16进制整型 |
| 15 | 写入 多个线圈 | 位 |
| 16 | 写入 多个寄存器 | 16进制整型 |
示例报文:
请求:00 01 00 00 00 06 FF 01 00 01 00 10
第1,2位 00 01 交互标识
第3,4位 00 00 协议标识
第5,6位 00 06 后面报文长度 有6位
第7位 FF 设备地址,发送什么,响应什么
第8位 01 功能码
第9,10位00 01 起始地址
第11,12位 00 10查询线圈长度,查询16位线圈
响应:00 01 00 00 00 05 FF 01 02 0A 02
前四位和7,8位同请求发送的报文
第5,6位是后面报文长度
第9位是后面数据位的长度,
第10位开始是数据位。
01查询线圈,每一个16进制数据表示8位线圈
第10位0A --> 0000 1010 第二位是1,第四位是1
同01
寄存器读取与线圈的区别,响应数据,寄存器数据每两个字节表示1位,一次请求不能超过127个地址
示例报文:
请求:00 01 00 00 00 06 01 03 00 05 00 02
第1,2位 00 01 交互标识
第3,4位 00 00 协议标识
第5,6位 00 06 后面报文长度 有6位
第7位 01 设备地址,发送什么,响应什么
第8位 03 功能码
第9,10位00 05起始地址
第11,12位 00 02查询寄存器长度,查询2个寄存器
响应:00 01 00 00 00 07 01 03 04 00 22 00 00
前四位(00 01 00 00)和7,8位(01 03)同请求发送的报文
第5,6位 00 07 是后面报文长度
第9位 04 是后面数据位的长度
第10-13位 数据位(00 22 00 00)
同03
请求:00 01 00 00 00 06 FF 05 00 01 FF 00
第9,10位 00 01 写入线圈的地址
第11,12位 写入的数据值 FF 00 表示置ON/1状态 00 00 表示置OFF/0状态
响应:00 01 00 00 00 06 FF 05 00 01 FF 00
请求:00 01 00 00 00 06 FF 0F 00 05 00 0A 02 CD 01
第9,10位 00 05写入的起始地址
第11,12位 00 0A写入线圈数量
第13位 02数据字节数量
第14位之后是数据 低字节在前
CD 01 —> 1100 1101 0000 0001
| 位 | 0C | 0B | 0A | 09 | 08 | 07 | 06 | 05 |
| 值 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
| 位 | 14 | 13 | 12 | 11 | 10 | 0F | 0E | 0D |
| 值 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
请求:00 05 00 00 00 06 FF 06 00 05 00 23
向地址为5的寄存器写入35。
第9,10位 00 05写入的起始地址
第11,12位 00 0A写入寄存器的值
响应:00 05 00 00 00 06 FF 06 00 05 00 23
请求:00 06 00 00 00 0B FF 10 00 02 00 02 04 00 21 00 2A
从地址2开始写入两个寄存器,2寄存器写入33,3寄存器写入42
第9,10位 00 02写入的起始地址
第11,12位 00 02写入寄存器的数量
第13位 04 后面数据的字节
第14-17位 数据
响应:00 06 00 00 00 06 FF 10 00 02 00 02
从地址2开始写入两个寄存器,2寄存器写入33,3寄存器写入42
第9,10位 00 02写入的起始地址
第11,12位 00 02写入寄存器的数量
第13位 04 后面数据的字节
第14-17位 数据
响应:00 06 00 00 0 0 06 FF 10 00 02 00 02
当发生通讯异常时,响应前7位仍然为modbus正常协议格式,第八位响应功能码(请求功能码+0x80),第九位异常码。
异常数据即包含异常码的数据:
目前使用的异常码是:01,02,03和04。
| 异常码 | 名称 | 含义 |
|---|---|---|
| 01 | 非法功能 | 对于服务器(或从站)来说,询问中接收到的功能码是不可允许的操作,可能是因为功能码仅适用于新设备而被选单元中不可实现同时,还指出服务器(或从站)在错误状态中处理这种请求,例如:它是未配置的,且要求返回寄存器值。 |
| 02 | 地址非法 | 对于服务器(或从站)来说,询问中接收的数据地址是不可允许的地址,特别是参考号和传输长度的组合是无效的。对于带有100个寄存器的控制器来说,偏移量96和长度4的请求会成功,而偏移量96和长度5的请求将产生异常码02。 |
| 03 | 数据非法 | 对于服务器(或从站)来说,询问中包括的值是不可允许的值。该值指示了组合请求剩余结构中的故障。例如:隐含长度是不正确的。modbus协议不知道任何特殊寄存器的任何特殊值的重要意义,寄存器中被提交存储的数据项有一个应用程序期望之外的值。 |
| 04 | 从站设备故障 | 当服务器(或从站)正在设法执行请求的操作时,产生不可重新获得的差错。 |
float 按IEEE-754标准协议存储
C#中浮点数的二进制格式遵循IEEE754标准
IEEE-754格式标准:一个浮点数有2部分组成:底数m和指数e
IEEE-754
Modbus协议定义的寄存器地址是5位十进制地址,即:
线圈(DO)地址:00001~09999
触点(DI)地址:10001~19999
输入寄存器(AI)地址:30001~39999
输出寄存器(AO)地址:40001~49999
0x代表线圈(DO)类地址,1x代表触点(DI)类地址、 3x代表输入寄存器(AI)类地址、4x代表输出寄存器(AO)类地址。
在实际编程中,前缀的区分作用(有功能码进行区分),所以只需说明后4位数,而且需转换为4位十六进制地址。
Modbus 数据地址格式是从0开始,寄存器地址对应报文中地址关系,x0001对应00 00,示例40003对应 00 02地址
以上根据开发时查的资料和网上资料整理一些的有用信息,方便开发查询
我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("
我想用Nokogiri解析HTML页面。页面的一部分有一个表,它没有使用任何特定的ID。是否可以提取如下内容:Today,3,455,34Today,1,1300,3664Today,10,100000,3444,Yesterday,3454,5656,3Yesterday,3545,1000,10Yesterday,3411,36223,15来自这个HTML:TodayYesterdayQntySizeLengthLengthSizeQnty345534345456563113003664354510001010100000344434113622315
我使用的第一个解析器生成器是Parse::RecDescent,它的指南/教程很棒,但它最有用的功能是它的调试工具,特别是tracing功能(通过将$RD_TRACE设置为1来激活)。我正在寻找可以帮助您调试其规则的解析器生成器。问题是,它必须用python或ruby编写,并且具有详细模式/跟踪模式或非常有用的调试技术。有人知道这样的解析器生成器吗?编辑:当我说调试时,我并不是指调试python或ruby。我指的是调试解析器生成器,查看它在每一步都在做什么,查看它正在读取的每个字符,它试图匹配的规则。希望你明白这一点。赏金编辑:要赢得赏金,请展示一个解析器生成器框架,并说明它的
我有这样的HTML代码:Label1Value1Label2Value2...我的代码不起作用。doc.css("first").eachdo|item|label=item.css("dt")value=item.css("dd")end显示所有首先标记,然后标记标签,我需要“标签:值” 最佳答案 首先,您的HTML应该有和中的元素:Label1Value1Label2Value2...但这不会改变您解析它的方式。你想找到s并遍历它们,然后在每个你可以使用next_element得到;像这样:doc=Nokogiri::HTML(
我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::