抖音粉丝群1
『7x24小时有问必答』

更多内容请点击上方 ABB机器人实战技巧 关注
也可点击公众号下方 往期经典 浏览更多内容
转载请先后台留言,大家一起支持原创,推动机器人使用和发展
本公众号对各类ABB机器人应用,仿真,毕业设计提供技术支持,详细后台留言
本公众号诚挚希望与各机器人培训机构,机器人使用单元合作,提供技术支持,详细后台留言
ABB机器人原生不支持modbusTCP 从站功能(外部设备读写机器人寄存器或者线圈
可以使用以下代码实现:

建议机器人使用多任务功能,将以下代码作为后台运行。
用户可以根据自己需要,将机器人的系统输出,系统输入信号关联到对应寄存器或者线圈上,实现外部基于modbus对应机器人的操作。

可以在前台任务创建pers类型变量,将后台的寄存器数据同步前台,实现外部设备对机器人的寄存器读写(同时机器人也能使用这些寄存器)

实现的功能码包括:
0x01 读多线圈,
0x03 读保持寄存器,
0x05 写单个线圈, 
0x06 写单个寄存器
0x0F 写多个线圈
0x10 写多个寄存器 
外部设备可以使用modbus poll软件测试,注意:ABB所有寄存器,线圈开始地址为1
MODULE modbusTCP_slave
    !author: Liao Chen, mousechen17@163.com
    ! Aug.21, 2023
    !!!!!!! regiser start_address is 1!!!!
    !!!!!!! coil start_add is 1!!!!!
    !!!!!!! support holding register
    !!!!!!! support holding coil
    !!!!!!! support 0x03 0x06 0x10 0x01 0x05 0x0F function
    !!!!!!! if robot receive wrong data, robot will not send feadback
    VAR socketdev temp_socket;
    VAR socketdev client_socket;
    VAR string received_string;
    VAR bool keep_listening:=TRUE;
    VAR rawbytes recv_raw;
    VAR rawbytes send_raw;

    !!!!!! data need to be modified
    PERS string rb_ip:="127.0.0.1";

    PERS num holdingReg{100}:=[563,2567,868,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0];

    PERS num coils{100}:=[1,1,1,1,0,1,1,1,1,0,
        1,1,1,1,0,1,1,1,1,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0];

    PROC main()
        SocketClose temp_socket;
        SocketClose client_socket;
        SocketCreate temp_socket;
        SocketBind temp_socket,rb_ip,502;
        SocketListen temp_socket;
        SocketAccept temp_socket,client_socket;

        WHILE keep_listening DO
            SocketReceive client_socket\RawData:=recv_raw\Time:=WAIT_MAX;
            modbusHandle;
        ENDWHILE
        SocketClose temp_socket;
    ERROR
        IF ERRNO=ERR_SOCK_TIMEOUT THEN
            TRYNEXT;

        ELSEIF ERRNO=ERR_SOCK_CLOSED THEN
            SocketClose temp_socket;
            SocketClose client_socket;
            SocketCreate temp_socket;
            SocketBind temp_socket,rb_ip,502;
            SocketListen temp_socket;
            SocketAccept temp_socket,client_socket;
            RETRY;
        ELSE
            TPWrite "ERRNO = "\Num:=ERRNO;
            Stop;
        ENDIF
    ENDPROC

    PROC modbusHandle()
        VAR num pro_len;
        VAR num data_len;
        VAR num raw_len;
        VAR num funNo;
        VAR num regAdd;

        ClearRawBytes send_raw;
        raw_len:=RawBytesLen(recv_raw);
        IF raw_len<=0 THEN
            goto END;
        ENDIF

        UnPackRawBytes recv_raw\Network,5,pro_len\IntX:=UINT;
        IF pro_len<>(raw_len-6) THEN
            goto END;
        ENDIF

        UnPackRawBytes recv_raw\Network,9,regAdd\IntX:=UINT;
        IF regAdd<=0 THEN
            goto END;
        ENDIF

        UnPackRawBytes recv_raw\Network,8,funNo\IntX:=USINT;
        ! get FunNo

        TEST funNo
        CASE 3:
            readMultiReg regAdd;
        CASE 6:
            writeSingReg regAdd;
        CASE 16:
            writeMultiReg regAdd;
        CASE 1:
            readMultiCoil regAdd;
        CASE 5:
            writeSingCoil regAdd;
        CASE 15:
            writeMultiCoil regAdd;
        DEFAULT:
            goto END;
        ENDTEST
        SocketSend client_socket\RawData:=send_raw;
        END:
    ENDPROC

    PROC writeMultiCoil(num regAdd)
        ! funNo: 0x0F: write multi Coil
        !        device send:    00 01 00 00 00 09         01         0F      0005   000A        02        CD   01
        !                                   ttl data len   slaveID    funNo    add   coil_num    byte_len byte1 byte2
        !        robot feedback: 0000 0000 0006            01         0F      0005   000A
        !                                  ttl data len   slaveID     funNo    add    coil_num
        VAR num coilCount;
        VAR num tmpValue;
        VAR byte inValue;
        VAR num byteCount:=1;

        CopyRawBytes recv_raw,1,send_raw,1\NoOfBytes:=12;
        UnPackRawBytes recv_raw\Network,11,coilCount\IntX:=UINT;

        FOR i FROM 1 TO coilCount DO
            IF (i mod 8)=1 THEN
                UnPackRawBytes recv_raw\Network,13+byteCount,tmpValue\IntX:=USINT;
                inValue:=tmpValue;
                byteCount:=byteCount+1;
            ENDIF
            coils{regAdd+i-1}:=bitand(inValue,1);
            inValue:=BitRSh(inValue,1);
        ENDFOR
        PackRawBytes 6,send_raw\Network,5\IntX:=uint;
    ENDPROC

    PROC writeSingCoil(num regAdd)
        ! funNo: 0x05: write single coil
        !        device send:    0000 0000 0006           01         05       0002     FF00  
        !                                  ttl data len   slaveID    funNo    add      data(FF00:ON, 0000:OFF)
        !        robot feedback: 0000 0000 0006           01         05       0002     FF00  
        !                                  ttl data len   slaveID    funNo    add      data
        VAR num value;
        CopyRawBytes recv_raw,1,send_raw,1\NoOfBytes:=12;
        UnPackRawBytes recv_raw\Network,11,value\IntX:=UsINT;
        IF value=255 THEN
            coils{regAdd}:=1;
        ELSE
            coils{regAdd}:=0;
        ENDIF
    ENDPROC

    PROC readMultiCoil(num regAdd)
        ! funNo: 0x01: read multi Coil
        !        device send:    00 00 00 00 00 06         01         01      0002      0002     
        !                                   ttl data len   slaveID    funNo    add       coil_num
        !        robot feedback: 0000 0000 0004            01         01       01               01
        !                                  ttl data len   slaveID     funNo    rest_data_len    data

        VAR num coilCount;
        VAR num outValue{50};
        VAR num byteCount:=1;
        VAR num tmpValue;

        ClearRawBytes send_raw;
        CopyRawBytes recv_raw,1,send_raw,1\NoOfBytes:=8;
        UnPackRawBytes recv_raw\Network,11,coilCount\IntX:=UINT;

        FOR i FROM 1 TO coilCount DO
            outValue{byteCount}:=outValue{byteCount}+coils{regAdd+i-1}*pow(2,(i-1) mod 8);
            IF (i mod 8)=0 THEN
                byteCount:=byteCount+1;
            ENDIF
        ENDFOR

        FOR i FROM 1 TO byteCount DO
            tmpValue:=outValue{i};
            PackRawBytes tmpValue,send_raw\Network,9+i\IntX:=1;
        ENDFOR

        PackRawBytes byteCount,send_raw\Network,9\IntX:=usint;
        PackRawBytes byteCount+3,send_raw\Network,5\IntX:=uint;
    ENDPROC

    PROC readMultiReg(num regAdd)
        ! funNo: 0x03: read multi holding register
        !        device send:    0000 0000 0006           01         03       0001      0001
        !                                  ttl data len   slaveID    funNo    add       data_num
        !        robot feedback: 0000 0000 0005           01         03       02               0001
        !                                  ttl data len   slaveID    funNo    rest_data_len    data

        VAR num regCount;
        CopyRawBytes recv_raw,1,send_raw,1\NoOfBytes:=8;
        UnPackRawBytes recv_raw\Network,11,regCount\IntX:=UINT;
        FOR i FROM 1 TO regCount DO
            PackRawBytes holdingReg{regAdd+i-1},send_raw\Network,9+(2*i-1)\IntX:=uint;
        ENDFOR

        PackRawBytes regCount*2,send_raw\Network,9\IntX:=usint;
        PackRawBytes regCount*2+3,send_raw\Network,5\IntX:=uint;
    ENDPROC

    PROC writeMultiReg(num regAdd)
        ! funNo: 0x10: write multi holding register
        !        device send:    0000 0000 000B           FF   10       0002  0002      04              0021   002A
        !                                  ttl_data_len   id  funNo     add   data_num  rest_data_len   data1  data2
        !        robot feedback: 0000 0000 0006           FF   10       0002  00 02
        !                                  ttl_data_len   id   funNo    add   data_num

        VAR num regCount;
        VAR num value;
        CopyRawBytes recv_raw,1,send_raw,1\NoOfBytes:=12;
        UnPackRawBytes recv_raw\Network,11,regCount\IntX:=UINT;

        FOR i FROM 1 TO regCount DO
            unPackRawBytes recv_raw\Network,13+(2*i-1),value\IntX:=uint;
            holdingReg{regAdd+i-1}:=value;
        ENDFOR
        PackRawBytes 6,send_raw\Network,5\IntX:=uint;
    ENDPROC

    PROC writeSingReg(num regAdd)
        ! funNo: 0x06: write single holding register
        !        device send:    0000 0000 0006           01         06       0001     0001
        !                                  ttl data len   slaveID    funNo    add      data
        !        robot feedback: 0000 0000 0006           01          06      0001     0001
        !                                  ttl data len   slaveID    funNo    add      data
        VAR num value;
        CopyRawBytes recv_raw,1,send_raw,1\NoOfBytes:=12;
        UnPackRawBytes recv_raw\Network,11,value\IntX:=UINT;
        holdingReg{regAdd}:=value;
    ENDPROC
ENDMODULE
********************************
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码