DL645协议是一种用于智能电能表的远程抄读通讯标准。制定该标准是为统一和规范多功能电能表与数据终端设备进行数据交换时的物理连接和通信链路及应用技术规范。DL645协议可用于远程监测电力传输和使用状态,是国家在电力行业标准中规定的统一的通信协议。
DL/T 698.45是面对对象的通信协议,适用于主站和采集终端、采集终端和电能表、主站和电能表之间。
DL645/698协议与Modbus协议类似,采用主-从模式的半双工通讯方式,多功能电能表与数据终端设备可进行点对点的或主多从的数据交换。电气层可以是经典的RS485有线通信,也可以是非接触式红外无线通信。
其中非接触式红外读表方式较为常见,它的特点是易于工程实施,电表、计量柜不需要停电接线,将支持DLT645标准的红外读表器放置在电表前方就可以读到电表电量、电压、电流、功率等数据。本篇文章主要是简要介绍DLT645协议,以及介绍利用智能网关ZL400实现高性价比4G远程抄表方案(当然也可以使用配套的ZL011红外超表器)
DL645协议的信息帧由帧起始符、从站地址域、控制码、数据域长度、数据域、帧信息纵向校验码及帧结束符7个域组成。
由采集器向表计发送的查询帧数据格式如下:
| 代码 | 描述 |
|---|---|
| 68h | 帧起始符 |
| A0-A5 | 地址域 |
| 68h | 帧起始符 |
| C | 控制码 |
| L | 数据域长度 |
| DATA | 数据域 |
| CS | 校验码 |
| 16h | 帧结束符 |
例:读表计数据: FE FE FE FE 68 66 55 44 33 22 11 68 11 04 33 33 34 33 17 16
| 说 明 | 帧起始符 | 地址域 | 帧起始符 | 控制码 | 数据域长度 | 数据域 | 校验码 | 帧结束符 |
|---|---|---|---|---|---|---|---|---|
| 实 例 | 68 | 665544332211 | 68 | 11 | 04 | 33 33 34 33 | 17 | 16 |
说明:FE FE FE FE - 引导字符;68 – 帧起始符;11 22 33 44 55 66 – 表地址; 11 – 控制码;04 – 数据域长度;33 33 34 33 – 数据域;17 – 校验码;16 – 帧结束符。
由表计向采集器发送的应答帧数据格式如下:
| 代码 | 描述 |
|---|---|
| 68h | 帧起始符 |
| A0-A5 | 地址域 |
| 68h | 帧起始符 |
| C | 控制码 |
| L | 数据域长度 |
| DATA | 数据域(数据标识+数据) |
| CS | 校验码 |
| 16h | 帧结束符 |
例:表计应答:FE FE FE FE 68 66 55 44 33 22 11 68 91 09 33 33 34 33 97 3C 33 33 0B 16
| 字节 | 0 | 1-5 | 6 | 7 | 8 | 9-13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|
| 说 明 | 帧起始符 | 地址域 | 帧起始符 | 控制码 | 数据域长度 | 数据标识+数据 | 校验码 | 帧结束符 |
| 实 例 | 68 | 665544332211 | 68 | 91 | 08 | 33 33 34 33+97 3C 33 33 | XX | 16 |
说明:FE FE FE FE - 引导字符;68 – 帧起始符; 66 55 44 33 22 11 – 表地址(真实地址为112233445566); 91 – 控制码;08 – 数据域长度;33 33 34 33 – 数据标识(真是为正向有功总00100000);97 3C 33 33 – 数据(真实数据为000009.33) XX – 校验码;16 – 帧结束符。
DLT645协议的数据帧每帧的开始都固定为0x68,作为数据的起始符方便接收方做数据解析
在485总线上可能挂着多个645设备,要找到指定的设备,必须要根据设备的地址查找。每台设备出厂会有自己的地址,也可以修改设备的通信地址。
地址域A0~A5用来表示电表地址,由6个字节构成,低位在前,高位在后;可以为表号、资产号、用户号、设备号等。当使用的地址码长度不足6字节时,用十六进制AAH补足6字节。

如上图该设备的地址为000001684866。
1个字节,例如读取数据的控制码为0x11(00010001),读取通讯地址的控制码为0x13(00010011)

其中功能码又分为两种97规约和07规约

1个字节,表示数据域的字节数,读取数据时L<= 200;写数据时L <= 50,L=0表示无数据域。
数据域包括数据标识和数据、密码等,其结构随控制码的功能而改变。传输时发送方按字节进行加33H处理,接收方按字节进行减33H处理。数据域为变长,字节数由数据长度L决定,传输时候。
数据标识编码具体可以查阅相关文档的《附录A.2——数据标识编码》
常见数据标识编码表如下:


发送方需要加0x33,接收方解析需要减去0x33。
| 发送方数据 | 33 | 33 | 33 | 33 |
|---|---|---|---|---|
| 真实值 | 00 | 00 | 00 | 00 |
从帧起始符(0x68)开始到校验码之前的所有各字节的模256的和, 即各字节二进制算术和,不计超过256的溢出值。
DLT645的指令帧均以0x16作为结束符。
所有数据项均先传送低位字节,后传送高位字节,如表计数据是000009.33,则从站应答数据如下:
D0—0x66—33+33
D1—0x3C—09+33
D2—0x33—00+33
D3—0x33—00+33
DL645协议的缺省速率为2400 bps,字节校验为偶校验。也可以设置为600bps,1200bps,4800bps,9600bps,19200bps。
红外抄表速率一般是1200bps
DEVELOPLINK展联科技的远程抄表网关(ZL400 DTU)内置了Modbus,DLT645/698,CT/J 188协议的解析,只需要简单的可视化配置,就能采集到国网电表的数据,然后将返回数据通过4G,以太网,WIFI等网络方式传到客户服务器,也可以直接解析成json格式上传。
| 硬件准备 | 软件准备 |
|---|---|
| ZL400 DTU(固件版本4.45.63) | 上位机 DevelopLink_SDRTU_V2.2.9 |
| DL645协议电表 | |
| 红外抄表器(选配) |

一般DT645协议的水表,通讯波特率为2400bp,偶检验





ZL400 DTU网络通道支持MQTT,TCP,UDP,HTTP;还内置了阿里云,腾讯云,onenet,developlink平台,华为云,jetlinks的解析内核
用户只需要选择通道类型,简单配置就能上传数据

————————————————————————————————————————
对物联网技术感兴趣请加入我们交流群,欢迎各种技术交流,
QQ群: 830407941
对我们方案感兴趣请查看:
DEVELOPLINK__ DTU
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
最近在学习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总线个人知识总
我有一个Controller,我想为这个Controller创建一个助手,我可以在不包含它的情况下使用它。我尝试像这样创建一个与Controller同名的助手classCars::EnginesController我创建的助手是moduleCars::EnginesHelperdefcheck_fuellogger.debug("chekingfuel")endend我得到的错误是undefinedlocalvariableormethod`check_fuel'for#有没有我遗漏的约定? 最佳答案 如果你真的想在Controll
我有一个模块stat存在于目录结构中:lib/stat_creator/stat/在lib/stat_creator/stat.rb中,我在lib/stat_creator/stat/目录中有我需要的文件,以及:moduleStatCreatormoduleStatendend当我使用该模块时,我将这些类称为StatCreator::Stat::Foo.new现在我想要一个存在于应用程序中的根Stat类。我在app/models中制作了我的Stat类,并在routes.rb中进行了设置。但是,如果我转到Rails控制台并尝试在应用程序/模型中使用Stat类,例如:Stat.by_use