上接【顿悟分享-云表应用】云表与物联网(MODBUS-TCP协议)-(一) 3、打开MODBUS采集程序公式内容明细 在解释公式明细内容前,我们得先了解一下MODBUS协议的知识,这里只讨论MODBUS-TCP协议的功能码03(读保持寄存器)的请求的数据内容及含义 请求示例: 19 B2 00 00 00 06 06 03 00 27 00 02 19 B2 00 00 00 06 19 B2 两个字节是Client发出的检验信息,Sever端只是需要将这两个字节的内容copy以后再放到response的报文的相应位子就可以了(由于response报文中没有回复请求的起始地址,所以我在此放入的请求的起始地址供解析时使用的小技巧) 00 00 两个字节是表示tcp/ip 的协议的modbus的协议; 00 06 两个字节表示的是header handle后面还有多长的字节,即表示的是该字节以后的字节长度(lengch),可以看到在00 06后面还有 “06 03 00 27 00 02”六个字节,所以这两个字节表示的就是6; PDU: “06 03 00 27 00 02” 06 一个字节表示slave address(0-247随意,MODBUS-TCP不要求); 03 为Fuction code (功能码:读取保持寄存器); 00 27 表示Client request的起始寄存器地址; 00 02 表示request 寄存器的长度(寄存器个数); 有了上述的理论,我们再来看打开外部程序的公式: 由于MODBUS-TCP一次最多只能请求127个寄存器,因此本实例用了一个序号列表的数据源,用于循环多次执行外部程序,每次最多只请求100个寄存器。 外部程序参数表达式 表达式生成一个字符串:IP>> xxx.xxx.xxx.xxx|端口>> 502|数据名称>>返回值|协议>> MODBUS-TCP|数据>>xxxxxxxxxxxxxxxxxxxxxxxx(注:|和>>用于外部程序的字符串分割) 表达式中使用了一个自定义函数:MODBUS读保持寄存器报文(),这是为了方便生成报文数据,具体内容如下: function MODBUS读保持寄存器报文(标识符,从机号,寄存器起始地址,寄存器长度) { var modbusstr=""; var 功能码="03"; modbusstr+= INT转HEX(标识符,"int16")+"0000"+"0006"+INT转HEX(从机号,"int8"); modbusstr+= 功能码+ INT转HEX(寄存器起始地址,"int16")+ INT转HEX(寄存器长度,"int16"); return modbusstr; } INT转HEX()函数如下: //10进制转16进制 function INT转HEX(num,datatype) { var result16=""; do{ result16=_to16(num%16)+result16; num=parseInt(num/16); } while(num>0); if (datatype=="int16") { while ( (4 - result16.length)>0){ result16="0"+result16; } } else if (datatype=="int32") { while ( (8 - result16.length)>0){ result16="0"+result16; } } else if (datatype=="int8") { while ( (2 - result16.length)>0){ result16="0"+result16; } } else if (datatype=="") { result16=result16; } return result16; } function _to16(v){ //十六进制单位转换 var res="0"; if (v==10) { res= "A"; } else if (v==11) { res="B"; } else if (v==12) { res="C"; } else if (v==13) { res="D"; } else if (v==14) { res="E"; } else if (v==15) { res="F"; } else if (v==0) { res="0"; } else if (v==1) { res="1"; } else if (v==2) { res="2"; } else if (v==3) { res="3"; } else if (v==4) { res="4"; } else if (v==5) { res="5"; } else if (v==6) { res="6"; } else if (v==7) { res="7"; } else if (v==8) { res="8"; } else if (v==9) { res="9"; } else { res="0"; } return res; } |
+10
0 条回帖