机器人通过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
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];
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;
writeCoils 16;
writeMultiCoil regAdd,16,write_coils;
waittime 0.05; ENDWHILE ENDPROC
PROC writeCoils(num count)
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); ENDFOR ENDPROC
PROC setDI1(num count) FOR i FROM 1 TO count DO setDO_int "vdo"+ValToStr(i),read_coils{i}; ENDFOR ENDPROC
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{*})
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{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{*})
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); ENDFOR ENDPROC
PROC checkSocket() if SocketGetStatus(sock_mod)<>SOCKET_CONNECTED THEN SocketClose sock_mod; SocketCreate sock_mod; SocketConnect sock_mod,slave_ip,502\Time:=10; endif ENDPROC
PROC sendAndReceive() checkSocket; SocketSend sock_mod\RawData:=send_raw; SocketReceive sock_mod\RawData:=recv_raw; ENDPROC ENDMODULE
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"
********************************
|