通过ModbusTCP读写艾莫迅远程I/O

[复制链接]
查看172 | 回复0 | 2024-9-25 13:52:20 | 显示全部楼层 |阅读模式


机器人通过0x02功能码读取远程I/O的离散输入

机器人通过0x0F功能码写入远程I/O的输出

1.现场使用Modbus/TCP的模块越来越多。例如机器人可以读写基于ModbusTCP的远程I/O模块。此处举例艾莫迅ETH-MODBUS-16IOR模块。相关手册参阅:

http://www.amsamotion.com/product_571.html

该模块有16个DI和16个DO。

DI采用0x02功能码读取输入线圈,DO可以采用0x05(写入单个线圈) 0x0F(写入多个线圈)等功能码写入

2. 为方便使用,建议机器人加入多任务功能,即将modbus的读写放入后台。对于RW6系统,还需要PC Interface选项(RW7不需要选项就可以使用socket通讯)

3. 相关代码如下:

MODULE modbusTCP_Master! author: Liao Chen, mousechen17@163.com!!!!!!! support discrete input coil!!!!!!! support holding coil!!!!!!! support 0x01 0x02 0x05 0x0F function
VAR socketdev sock_mod;VAR rawbytes recv_raw;VAR rawbytes send_raw;
PERS num write_coils{16}:=[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0];pers num read_coils{16}:=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];!!!!!! data need to be modified
PERS string slave_ip:="127.0.0.1";PERS num slave_ID:=1;PERS num regAdd:=0;
PROC main() WHILE true DO readMultiCoil\Input,regAdd,16,read_coils;        ! 读取16个输入并存入read_coils数组 setDI1 16;        ! 将modbus信号存入vdo信号,并通过crossconnection关联到对应DI        ! 此处假设DI信号均为di1,di2.。。di16的命名
writeCoils 16;        ! 将do1.。。do16真实信号的值存入write_coils数组 writeMultiCoil regAdd,16,write_coils;        ! 写入modbus远程 waittime 0.05;    ENDWHILEENDPROC
PROC writeCoils(num count)    ! 假设do信号名为do1...do16 VAR signaldo sig; VAR string name; FOR i FROM 1 TO count DO name:="do"+valtostr(i); AliasIO name,sig; write_coils{i}:=doutput(sig); ENDFORENDPROC
PROC setDI1(num count) FOR i FROM 1 TO count DO setDO_int "vdo"+ValToStr(i),read_coils{i}; ENDFORENDPROC
PROC setDO_int(string name,num value) VAR signaldo sig; aliasIO name,sig; setdo sig,value;ENDPROC
PROC writeMultiCoil(num regAdd,num coilCount,num coils{*}) ! 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_count byte_len byte1 byte2 ! robot feedback: 0000 0000 0006 01 0F 0005 000A ! ttl data len slaveID funNo add coil_num VAR byte outByte{50}; VAR num byteCount:=1;    VAR num b{100}; b{1}:=0x00; b{2}:=0x00; b{3}:=0x00; b{4}:=0x00; ! b{5}:=0x00; ! b{6}:=0x06; b{7}:=slave_ID; b{8}:=0x0F;
ClearRawBytes send_raw; FOR i FROM 1 TO 8 DO PackRawBytes b{i},send_raw,i\IntX:=1; ENDFOR PackRawBytes regAdd,send_raw\Network,9\IntX:=2; PackRawBytes coilCount,send_raw\Network,11\IntX:=2;
FOR i FROM 1 TO coilCount DO outByte{byteCount}:=outByte{byteCount}+coils{i}*pow(2,(i-1) mod 8); IF (i mod 8)=0 THEN byteCount:=byteCount+1; ENDIF ENDFOR
Decr byteCount; FOR i FROM 1 TO byteCount DO PackRawBytes outByte{i},send_raw\Network,13+i\Hex1; ENDFOR PackRawBytes byteCount,send_raw\Network,13\IntX:=1; PackRawBytes 7+byteCount,send_raw\Network,5\IntX:=2; sendAndReceive;ENDPROC
PROC readMultiCoil(\switch Input,num regAdd,num coilCount,inout num coils{*}) ! 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

! funNo: 0x02: read input multi Coil ! device send: 00 00 00 00 00 06 01 02 0002 0002 ! ttl data len slaveID funNo add coil_num ! robot feedback: 0000 0000 0004 01 02 01 01 ! ttl data len slaveID funNo rest_data_len data    VAR byte inValue; VAR num byteCount:=1; VAR num tmpValue;    VAR num b{100}; b{1}:=0x00; b{2}:=0x00; b{3}:=0x00; b{4}:=0x00; b{5}:=0x00; b{6}:=0x06; b{7}:=slave_ID; IF Present(input) THEN b{8}:=0x02; ELSE b{8}:=0x01; endif    ClearRawBytes send_raw; FOR i FROM 1 TO 8 DO PackRawBytes b{i},send_raw,i\IntX:=1; ENDFOR PackRawBytes regAdd,send_raw\Network,9\IntX:=2; PackRawBytes coilCount,send_raw\Network,11\IntX:=2; sendAndReceive; FOR i FROM 1 TO coilCount DO IF (i mod 8)=1 THEN UnPackRawBytes recv_raw\Network,9+byteCount,tmpValue\IntX:=USINT; inValue:=tmpValue; byteCount:=byteCount+1; ENDIF coils{i}:=bitand(inValue,1); inValue:=BitRSh(inValue,1); ENDFORENDPROC
PROC checkSocket() if SocketGetStatus(sock_mod)<>SOCKET_CONNECTED THEN SocketClose sock_mod; SocketCreate sock_mod; SocketConnect sock_mod,slave_ip,502\Time:=10; endifENDPROC
PROC sendAndReceive() checkSocket; SocketSend sock_mod\RawData:=send_raw; SocketReceive sock_mod\RawData:=recv_raw;ENDPROCENDMODULE

IO配置如下:

EIO:CFG_1.0:6:1::#EIO_CROSS: -Name "c1" -Res "di1" -Act1 "vdo1" -Name "c2" -Res "di2" -Act1 "vdo2" -Name "c3" -Res "di3" -Act1 "vdo3" -Name "c4" -Res "di4" -Act1 "vdo4" -Name "c5" -Res "di5" -Act1 "vdo5" -Name "c6" -Res "di6" -Act1 "vdo6" -Name "c7" -Res "di7" -Act1 "vdo7" -Name "c8" -Res "di8" -Act1 "vdo8" -Name "c9" -Res "di9" -Act1 "vdo9" -Name "c10" -Res "di10" -Act1 "vdo10" -Name "c11" -Res "di11" -Act1 "vdo11" -Name "c12" -Res "di12" -Act1 "vdo12" -Name "c13" -Res "di13" -Act1 "vdo13" -Name "c14" -Res "di14" -Act1 "vdo14" -Name "c15" -Res "di15" -Act1 "vdo15" -Name "c16" -Res "di16" -Act1 "vdo16"#EIO_SIGNAL: -Name "di1" -SignalType "DI" -Name "di2" -SignalType "DI" -Name "di3" -SignalType "DI" -Name "di4" -SignalType "DI" -Name "di5" -SignalType "DI" -Name "di6" -SignalType "DI" -Name "di7" -SignalType "DI" -Name "di8" -SignalType "DI" -Name "di9" -SignalType "DI" -Name "di10" -SignalType "DI" -Name "di11" -SignalType "DI" -Name "di12" -SignalType "DI" -Name "di13" -SignalType "DI" -Name "di14" -SignalType "DI" -Name "di15" -SignalType "DI" -Name "di16" -SignalType "DI" -Name "do1" -SignalType "DO" -Name "do2" -SignalType "DO" -Name "do3" -SignalType "DO" -Name "do4" -SignalType "DO" -Name "do5" -SignalType "DO" -Name "do6" -SignalType "DO" -Name "do7" -SignalType "DO" -Name "do8" -SignalType "DO" -Name "do9" -SignalType "DO" -Name "do10" -SignalType "DO" -Name "do11" -SignalType "DO" -Name "do12" -SignalType "DO" -Name "do13" -SignalType "DO" -Name "do14" -SignalType "DO" -Name "do15" -SignalType "DO" -Name "do16" -SignalType "DO"  -Name "vdo1" -SignalType "DO" -Name "vdo2" -SignalType "DO" -Name "vdo3" -SignalType "DO" -Name "vdo4" -SignalType "DO" -Name "vdo5" -SignalType "DO" -Name "vdo6" -SignalType "DO" -Name "vdo7" -SignalType "DO" -Name "vdo8" -SignalType "DO" -Name "vdo9" -SignalType "DO" -Name "vdo10" -SignalType "DO" -Name "vdo11" -SignalType "DO" -Name "vdo12" -SignalType "DO" -Name "vdo13" -SignalType "DO" -Name "vdo14" -SignalType "DO" -Name "vdo15" -SignalType "DO" -Name "vdo16" -SignalType "DO"


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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则