【顿悟分享-云表应用】云表与物联网(MODBUS-TCP协议)-(二)
2024-1-22 09:46:05
1346
0
上接【顿悟分享-云表应用】云表与物联网(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;
}
|
+1
0
0条回帖