KUKAVARPROXY 在 KRC4 中接收和发送消息的格式 (2)

目录 Content
[hide]

一、目的

在上一篇文章《KUKAVARPROXY 在 KRC4 中接收和发送消息的格式 (1) 》中,LT 囫囵吞枣分析了 KUKAVARPROXY 数据收发消息格式,虽然贴出了分析内容和源代码,不过还是不够直观,所以 LT 决定用形象的方式再分析一次 KUKAVARPROXY 的报文格式。

KUKAVARPROXY

二、分析

这次仍以读写变量 $OV_PRO 为例。

KUKAVARPROXY_MSG

A. 客户端请求读取变量

消息ID设为 12345,请求读取变量 $OV_PRO。主要分四步完成:
KUKAVARPROXY_MSG_READ_REQUEST
a. 存储变量的字面值。本例 “$OV_PRO” 的 ANSI 值为 24 4F 56 5F 50 52 4F
b. 获取变量字面值字节个数,占用2个byte,本例为 00 07,叠加在a前面,即 00 07 24 4F 56 5F 50 52 4F
c. 读标识 0,占用1个byte,叠加在b前面,即 00 00 07 24 4F 56 5F 50 52 4F
d. 获取 c 字节的个数,占用2个byte,本例为 00 0A,叠加在c前面,即 00 0A 00 00 07 24 4F 56 5F 50 52 4F,在最前面叠加消息编号,占用2个byte,本例为 30 39,最终报文内容为 30 39 00 0A 00 00 07 24 4F 56 5F 50 52 4F

Qt 实现代码为:

QByteArray formatMsg(QByteArray varName, quint32 idMsg){

    const char READVARIABLE=0;

    QByteArray header, block;
    quint32 blockLen,varNameLen;
    unsigned char hByte, lByte;
    unsigned char hByteMsgID,lByteMsgID;

    varNameLen=varName.size();
    hByte=(varNameLen & 0xff00) >> 8;
    lByte=(varNameLen & 0x00ff);

    block.append(READVARIABLE).append(hByte).append(lByte).append(varName);

    blockLen=block.size();
    hByte=(blockLen & 0xff00) >> 8;
    lByte=(blockLen & 0x00ff);

    hByteMsgID=(idMsg & 0xff00) >> 8;
    lByteMsgID=(idMsg & 0x00ff);

    header.append(hByteMsgID).append(lByteMsgID).append(hByte).append(lByte);
    block.prepend(header);

    return block;
}

B. 客户端请求写值变量

消息ID设为 54321,请求将值 55 写入变量 $OV_PRO。主要分五步完成:
KUKAVARPROXY_MSG_WRITE_REQUEST
a. 存储变量的字面值。本例 “$OV_PRO” 的 ANSI 值为 24 4F 56 5F 50 52 4F
b. 获取变量字面值字节个数,占用2个byte,本例为 00 07,叠加在a前面,即 00 07 24 4F 56 5F 50 52 4F
c. 写标识 1,占用1个byte,叠加在b前面,即 01 00 07 24 4F 56 5F 50 52 4F
d. 获取变量值的字面值字节个数,占用2个byte,本例为 00 02 ,叠加在c 后面,再在后面叠加变量值的字面值,本例为 35 35,即 01 00 07 24 4F 56 5F 50 52 4F 00 02 35 35
e. 获取d字节的个数,占用2个byte,本例为 00 0E,叠加在d前面,即 00 0E 01 00 07 24 4F 56 5F 50 52 4F 00 02 35 35,在最前面叠加消息编号,占用2个byte,本例为 D4 31,最终报文内容为 D4 31 00 0E 01 00 07 24 4F 56 5F 50 52 4F 00 02 35 35

Qt 实现代码为:

QByteArray formatMsg(QByteArray varName, QByteArray varValue, quint32 idMsg){

    const char WRITEVARIABLE=1;

    QByteArray header, block;
    quint32 blockLen,varNameLen,varValueLen;
    unsigned char hByte, lByte;
    unsigned char hByteMsgID,lByteMsgID;

    varNameLen=varName.size();
    hByte=(varNameLen & 0xff00) >> 8;
    lByte=(varNameLen & 0x00ff);

    block.append(WRITEVARIABLE).append(hByte).append(lByte).append(varName);

    varValueLen=varValue.size();
    hByte=(varValueLen & 0xff00) >> 8;
    lByte=(varValueLen & 0x00ff);

    block.append(hByte).append(lByte).append(varValue);

    blockLen=block.size();
    hByte=(blockLen & 0xff00) >> 8;
    lByte=(blockLen & 0x00ff);

    hByteMsgID=(idMsg & 0xff00) >> 8;
    lByteMsgID=(idMsg & 0x00ff);

    header.append(hByteMsgID).append(lByteMsgID).append(hByte).append(lByte);
    block.prepend(header);

    return block;
}

C. 服务器端返回变量值

消息ID为54321,返回变量 $OV_PRO 的值 55。

KUKAVARPROXY_MSG_WRITE_RETURN

返回的报文内容为 D4 31 00 08 01 00 02 35 35 00 01 01
1. 前2个byte,为消息编号,本例为 D4 31,即 54321
2. 紧跟着2个byte,为报文主体长度,本例为 00 08
3. 第5个byte为读写标识,本例为 01
4. 紧跟着2个byte,为变量值字面值的长度,本例为 00 02,即 2
5. 第8个byte开始,即为变量值的字面值,占用“变量值字面值的长度”个字节,本例为 35 35
6. 紧跟着3个byte。最后1个 byte 表示读写是否OK,倒数第2个 byte 与倒数第1个 byte 相同,本例为 01 01 表示OK 。倒数第3个byte总是 00

——————————————————————————————————————–

20160414 LT 询问了作者 Massimiliano 最后三个字节的含义,解释如下:

the last three bytes have the following meaning:

 
D4 31 00 08 01 00 02 35 35 00 01 01
                                                |    |    |
                                                |    |    —> 01 read/write OK; 00 read/write KO
                                                |    —–> 01 read/write OK; 00 read/write KO (the same)
                                                ——> always 00

——————————————————————————————————————–

Qt 实现代码为:

quint32 clearMsg(QByteArray msg, QByteArray &varValue){

    short lenBlock,func,lenValue;
    quint32 idMsg;

    if(msg.size() > 0){

        idMsg=((unsigned char)msg[0])<<8 | ((unsigned char)msg[1]);
        lenBlock=((unsigned char)msg[2])<<8 | ((unsigned char)msg[3]);
        func=((int)msg[4]);
        lenValue=((unsigned char)msg[5])<<8 | ((unsigned char)msg[6]);
        varValue = msg.mid(7,lenValue);

        return idMsg;
    }
    else{

        varValue = QByteArray("");

        return 0;
    }
}

 

2 thoughts on “KUKAVARPROXY 在 KRC4 中接收和发送消息的格式 (2)

  1. 你好!很感谢你写的文章,看了以后很有收获!我目前在学习采用JOpenShowVar和KUKAVARPROXY读取KUKA KRC4 的数据,但是不太清楚怎么在控制器端的$CONFIG.DAT文件中配置一个自定义的待读取变量的结构,请问你能否提供这方面的指导?非常感谢!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.