ABB机器人原生不支持modbusTCP 从站功能(外部设备读写机器人寄存器或者线圈)
可以使用以下代码实现:
建议机器人使用多任务功能,将以下代码作为后台运行。
用户可以根据自己需要,将机器人的系统输出,系统输入信号关联到对应寄存器或者线圈上,实现外部基于modbus对应机器人的操作。
可以在前台任务创建pers类型变量,将后台的寄存器数据同步前台,实现外部设备对机器人的寄存器读写(同时机器人也能使用这些寄存器)
实现的功能码包括:
0x01 读多线圈,
0x03 读保持寄存器,
0x05 写单个线圈,
0x06 写单个寄存器
0x0F 写多个线圈
0x10 写多个寄存器
外部设备可以使用modbus poll软件测试,注意:ABB所有寄存器,线圈开始地址为1
MODULEmodbusTCP_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 feadbackVARsocketdev temp_socket;VARsocketdev client_socket;VARstring received_string;VARbool keep_listening:=TRUE;VARrawbytes recv_raw;VARrawbytes send_raw;
!!!!!! data need to be modifiedPERSstring rb_ip:="127.0.0.1";
PERSnum 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];
PERSnum 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];
PROCmain()SocketClosetemp_socket;SocketCloseclient_socket; SocketCreate temp_socket;SocketBindtemp_socket,rb_ip,502;SocketListentemp_socket;SocketAccepttemp_socket,client_socket;
WHILEkeep_listening DOSocketReceiveclient_socket\RawData:=recv_raw\Time:=WAIT_MAX;modbusHandle;ENDWHILESocketClosetemp_socket;ERRORIFERRNO=ERR_SOCK_TIMEOUT THENTRYNEXT;
ELSEIFERRNO=ERR_SOCK_CLOSED THENSocketClosetemp_socket;SocketCloseclient_socket;SocketCreatetemp_socket;SocketBindtemp_socket,rb_ip,502;SocketListentemp_socket;SocketAccepttemp_socket,client_socket;RETRY;ELSE TPWrite "ERRNO = "\Num:=ERRNO;Stop;ENDIF ENDPROC
PROCmodbusHandle()VARnum pro_len;VARnum data_len;VARnum raw_len;VARnum funNo;VARnum regAdd;
ClearRawBytessend_raw;raw_len:=RawBytesLen(recv_raw);IFraw_len<=0 THENgotoEND;ENDIF
UnPackRawBytesrecv_raw\Network,5,pro_len\IntX:=UINT;IFpro_len<>(raw_len-6) THENgotoEND;ENDIF
UnPackRawBytesrecv_raw\Network,9,regAdd\IntX:=UINT;IFregAdd<=0 THENgotoEND;ENDIF
UnPackRawBytesrecv_raw\Network,8,funNo\IntX:=USINT; ! get FunNo
TESTfunNoCASE3:readMultiRegregAdd;CASE6:writeSingRegregAdd;CASE16:writeMultiRegregAdd;CASE1:readMultiCoilregAdd;CASE5:writeSingCoilregAdd;CASE15:writeMultiCoilregAdd;DEFAULT:gotoEND;ENDTESTSocketSendclient_socket\RawData:=send_raw;END: ENDPROC
PROCwriteMultiCoil(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;VARnum tmpValue;VARbyte inValue;VARnum byteCount:=1;
CopyRawBytesrecv_raw,1,send_raw,1\NoOfBytes:=12;UnPackRawBytesrecv_raw\Network,11,coilCount\IntX:=UINT;
FORi FROM 1 TO coilCount DOIF(i mod 8)=1 THENUnPackRawBytesrecv_raw\Network,13+byteCount,tmpValue\IntX:=USINT;inValue:=tmpValue;byteCount:=byteCount+1;ENDIFcoils{regAdd+i-1}:=bitand(inValue,1);inValue:=BitRSh(inValue,1);ENDFORPackRawBytes6,send_raw\Network,5\IntX:=uint; ENDPROC
PROCwriteSingCoil(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 dataVARnum value;CopyRawBytesrecv_raw,1,send_raw,1\NoOfBytes:=12;UnPackRawBytesrecv_raw\Network,11,value\IntX:=UsINT;IFvalue=255 THENcoils{regAdd}:=1;ELSEcoils{regAdd}:=0;ENDIF ENDPROC
PROCreadMultiCoil(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
VARnum coilCount;VARnum outValue{50};VARnum byteCount:=1;VARnum tmpValue;
ClearRawBytessend_raw;CopyRawBytesrecv_raw,1,send_raw,1\NoOfBytes:=8;UnPackRawBytesrecv_raw\Network,11,coilCount\IntX:=UINT;
FORi FROM 1 TO coilCount DO outValue{byteCount}:=outValue{byteCount}+coils{regAdd+i-1}*pow(2,(i-1) mod 8);IF(i mod 8)=0 THENbyteCount:=byteCount+1;ENDIFENDFOR
FORi FROM 1 TO byteCount DOtmpValue:=outValue{i};PackRawBytestmpValue,send_raw\Network,9+i\IntX:=1;ENDFOR
PackRawBytesbyteCount,send_raw\Network,9\IntX:=usint;PackRawBytesbyteCount+3,send_raw\Network,5\IntX:=uint;ENDPROC
PROCreadMultiReg(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
VARnum regCount;CopyRawBytesrecv_raw,1,send_raw,1\NoOfBytes:=8;UnPackRawBytesrecv_raw\Network,11,regCount\IntX:=UINT;FORi FROM 1 TO regCount DOPackRawBytesholdingReg{regAdd+i-1},send_raw\Network,9+(2*i-1)\IntX:=uint;ENDFOR
PackRawBytesregCount*2,send_raw\Network,9\IntX:=usint;PackRawBytesregCount*2+3,send_raw\Network,5\IntX:=uint;ENDPROC
PROCwriteMultiReg(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
VARnum regCount;VARnum value;CopyRawBytesrecv_raw,1,send_raw,1\NoOfBytes:=12;UnPackRawBytesrecv_raw\Network,11,regCount\IntX:=UINT;
FORi FROM 1 TO regCount DOunPackRawBytesrecv_raw\Network,13+(2*i-1),value\IntX:=uint;holdingReg{regAdd+i-1}:=value;ENDFORPackRawBytes6,send_raw\Network,5\IntX:=uint;ENDPROC
PROCwriteSingReg(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 dataVARnum value;CopyRawBytesrecv_raw,1,send_raw,1\NoOfBytes:=12;UnPackRawBytesrecv_raw\Network,11,value\IntX:=UINT;holdingReg{regAdd}:=value; ENDPROCENDMODULE
********************************
如何获取更多经典文章?
关注公众号 ABB机器人实战技巧,点击页面底部的往期经典和配置,查看更多经典内容
点击阅读原文,学习robotstudio仿真,获取完整教学视频
更多内容
★ 如何搜索历史文章
★基于pcsdk传输文件到HOME及加载
通过总线发送实数及负整数
★使用定时中断向PLC发送机器人位置
★信号的准确提早触发
★变位机校准
★ABB机器人零位校准的那些秘密
★创建UDP通讯
★旋转姿态的左乘与右乘
★通过socket控制机器人启停
上位机仪表盘实时显示机器人速度
★机器人画哆啦A梦
上位机实时控制机器人运动之EGM
Python控制ABB机器人运动
通过Excel批量修改EIO文件
带连杆的机器人正运动学计算
制作四连杆机构
机器人PROFINET同时做CONTROLLER和DEVICE
★语音控制ABB机器人
★手机访问web控制机器人
★自定义伺服焊枪
★制作输送链抓取搬运码垛工作站
★随机物料产生与抓取
★四轴机器人定义TCP
★自定义外部轴-变位机
★示教四点完成码垛
★multimove之双机器人与变位机
Robotware6.08碰撞预测启用与关闭
SMB板针脚解释
四六关节耦合限制
求两点间距离
新I/O DSQC1030配置
ABB机器人配置伺服焊枪
转角路径故障不提示设置
外部PLC选择机器人程序
一键回HOME程序
机器人各轴上下限位修改
Wobjdata数据解释
输送链跟踪与视觉的联系
急停与自动停止接线
|