Implementing Modbus TCP Slave Functionality for ABB Robots

For more content, please click on the above ABB Robot Practical Skills to follow us.

You can also click on the public account below Classic Articles to browse more content.

Please leave a message in the background before reprinting, let’s support original content together and promote the use and development of robots.

This public account provides technical support for various ABB robot applications, simulations, and graduation projects. For details, please leave a message in the background.

This public account sincerely hopes to cooperate with various robot training institutions and robot application units to provide technical support, for details, please leave a message in the background.

ABB robots do not natively support the Modbus TCP slave function (external devices reading and writing robot registers or coils).

The following code can be used to implement this:

  • It is recommended that the robot use multi-tasking functions and run the following code in the background.

  • Users can associate the robot’s system outputs and system input signals with the corresponding registers or coils based on their needs, enabling external operations on the robot based on Modbus.

  • A pers type variable can be created in the foreground task to synchronize the register data from the background to the foreground, allowing external devices to read and write the robot’s registers (while the robot can also use these registers).

The implemented function codes include:

  • 0x01 Read Multiple Coils,

  • 0x03 Read Holding Registers,

  • 0x05 Write Single Coil,

  • 0x06 Write Single Register

  • 0x0F Write Multiple Coils

  • 0x10 Write Multiple Registers

External devices can use Modbus Poll software for testing. Note: All ABB registers and coil starting addresses are 1.

MODULE modbusTCP_slave    !author: Liao Chen, [email protected]    ! Aug.21, 2023    !!!!!!! register 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 receives wrong data, robot will not send feedback    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];    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];    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;    ENDPROCENDMODULE

********************************

How to Get More Classic Articles?

Follow the public account ABB Robot Practical Skills, click on the bottom of the page Classic Articles and Configuration to see more classic content.

Click Read the Original to learn about RobotStudio simulation and get complete teaching videos.

More Content

How to Search Historical Articles

Transfer files to HOME based on pcsdk.

Send real numbers and negative integers through the bus.

★ Use timed interrupts to send robot positions to PLC.

★ Accurate early triggering of signals.

★ Calibration of positioning machines.

★ Secrets of zero position calibration for ABB robots.

★ Create UDP communication.

★ Left and right multiplication of rotation posture.

Control robot start and stop via socket.

Real-time display of robot speed on the upper computer dashboard.

Robot drawing Doraemon.

Real-time control of robot movement via upper computer EGM.

Control ABB robot movement with Python.

Batch modification of EIO files via Excel.

Forward kinematics calculation of robots with linkages.

Make a four-bar linkage mechanism.

Robot PROFINET acts as both CONTROLLER and DEVICE.

Voice control of ABB robots.

★ Access web control of robots via mobile phone.

★ Custom servo welding gun.

★ Create a conveyor chain for grabbing and transporting pallets.

★ Random material generation and grabbing.

Define TCP for four-axis robots.

★ Custom external axis – positioning machine.

Teach four points to complete palletizing.

★ Multimove with dual robots and positioning machine.

Enable and disable collision prediction in Robotware 6.08.

SMB board pin explanation.

Coupling limits for six and four joints.

Calculate the distance between two points.

New I/O DSQC1030 configuration.

ABB robot configuration for servo welding gun.

Settings to not prompt for angular path faults.

Select robot programs via external PLC.

One-click return to HOME program.

Modify the upper and lower limits for each robot axis.

Explanation of Wobjdata data.

Connection between conveyor tracking and vision.

Wiring for emergency stop and automatic stop.

For more expert explanation videos, you can search for ABB Robot Practical Skills on WeChat, or scan the following QR code to follow us.

Implementing Modbus TCP Slave Functionality for ABB Robots

Leave a Comment