MODULE modbusTCP_Master
! author: Liao Chen, mousechen17@163.com
!!!!!!! support holding register
!!!!!!! support holding coil
!!!!!!! support 0x03 0x06 0x10 0x01 0x05 0x0F function
VAR socketdev sock_mod;
VAR rawbytes recv_raw;
VAR rawbytes send_raw;
!!!!!! data need to be modified
PERS bool bBigEndian:=TRUE;
PERS string slave_ip:="127.0.0.1";
PERS num slave_ID:=1;
PERS num write_data{2}:=[10,20]; var num read_data{2}:=[0,0]; PERS num write_coils{20}:=[1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0]; var num read_coils{20}; PERS num regAdd:=1;
VAR num outValue{50};
PROC main()
writeMultiReg regAdd,2,write_data;
! 向地址1开始的2个寄存器写入数据,数据为write_data中的前2个数据
readMultiReg 1,2,read_data;
! 从地址1开始的2个寄存读取数据,存入read_data中的前2个数据
stop;
writeSingReg regAdd,99;
! 向地址regAdd的寄存器写入数据99
readMultiReg 1,1,read_data;
! 从地址1开始的1个寄存器,读取数据并存储到readdata中第一个元素
stop;
writeMultiCoil regAdd,10,write_coils;
! 向地址regAdd开始的连续10个线圈写入值
readMultiCoil regAdd,10,read_coils;
! 从regAdd开始的10个线圈读取值并存储到read_coils数组中
stop;
writeSingCoil regAdd,0;
! 向地址regAdd线圈写入值0
readMultiCoil regAdd,1,read_coils;
! 从regAdd开始的1个线圈读取值并存储到read_coils数组中的第一个元素
stop;
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 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 num outValue{50}; VAR num byteCount:=1;
VAR num b{100}; checkSocket;
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
outValue{byteCount}:=outValue{byteCount}+coils{i}*pow(2,(i-1) mod 8); IF (i mod 8)=0 THEN
byteCount:=byteCount+1;
ENDIF
ENDFOR
FOR i FROM 1 TO byteCount DO
PackRawBytes outValue{i},send_raw\Network,13+i\IntX:=1; ENDFOR
PackRawBytes byteCount,send_raw\Network,13\IntX:=1;
PackRawBytes 7+byteCount,send_raw\Network,5\IntX:=2;
sendAndReceive;
ENDPROC
PROC sendAndReceive()
SocketSend sock_mod\RawData:=send_raw;
SocketReceive sock_mod\RawData:=recv_raw;
ENDPROC
PROC writeSingCoil(num regAdd,num data\switch bSiemens)
! 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 b{100}; checkSocket;
b{1}:=0x00; b{2}:=0x00; b{3}:=0x00; b{4}:=0x00; b{5}:=0x00; b{6}:=0x06; b{7}:=slave_ID; b{8}:=0x05;
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;
IF data>0 THEN
data:=0xFF00;
ENDIF
IF Present(bSiemens) THEN
PackRawBytes data,send_raw,11\IntX:=2;
ELSE
PackRawBytes data,send_raw\Network,11\IntX:=2;
ENDIF
sendAndReceive;
ENDPROC
PROC readMultiCoil(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
VAR byte inValue;
VAR num byteCount:=1;
VAR num tmpValue;
VAR num b{100}; checkSocket;
b{1}:=0x00; b{2}:=0x00; b{3}:=0x00; b{4}:=0x00; b{5}:=0x00; b{6}:=0x06; b{7}:=slave_ID; b{8}:=0x01;
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 readMultiReg(num regAdd,num regCount,inout num data{*}\switch bSiemens) ! 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 b{100}; VAR num dataByteLen;
checkSocket;
b{1}:=0x00; b{2}:=0x00; b{3}:=0x00; b{4}:=0x00; b{5}:=0x00; b{6}:=0x06; b{7}:=slave_ID; b{8}:=0x03;
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 regCount,send_raw\Network,11\IntX:=2;
sendAndReceive;
UnPackRawBytes recv_raw\Network,9,dataByteLen\IntX:=UsINT;
FOR i FROM 1 TO dataByteLen/2 DO
IF present(bSiemens) THEN
UnPackRawBytes recv_raw,9+(2*i-1),data{i}\IntX:=UINT; ELSE
UnPackRawBytes recv_raw\Network,9+(2*i-1),data{i}\IntX:=UINT; ENDIF
ENDFOR
ENDPROC
PROC writeMultiReg(num regAdd,num regCount,num data{*}\Switch bSiemens) ! 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 b{100}; VAR num value;
VAR num dataByteLen;
checkSocket;
b{1}:=0x00; b{2}:=0x00; b{3}:=0x00; b{4}:=0x00; ! b{5}:=0x00; ! b{6}:=0x06; b{7}:=slave_ID; b{8}:=0x10;
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 regCount,send_raw\Network,11\IntX:=2;
PackRawBytes regCount*2,send_raw\Network,13\IntX:=1;
FOR i FROM 1 TO regCount DO
IF Present(bSiemens) THEN
PackRawBytes data{i},send_raw,13+(2*i-1)\IntX:=2; ELSE
PackRawBytes data{i},send_raw\Network,13+(2*i-1)\IntX:=2; ENDIF
ENDFOR
PackRawBytes 7+regCount*2,send_raw\Network,5\IntX:=2;
sendAndReceive;
ENDPROC
PROC writeSingReg(num regAdd,num data\switch bSiemens)
! 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 b{100}; VAR num value;
VAR num dataByteLen;
checkSocket;
b{1}:=0x00; b{2}:=0x00; b{3}:=0x00; b{4}:=0x00; b{5}:=0x00; b{6}:=0x06; b{7}:=slave_ID; b{8}:=0x06;
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;
IF Present(bSiemens) THEN
PackRawBytes data,send_raw,11\IntX:=2;
ELSE
PackRawBytes data,send_raw\Network,11\IntX:=2;
endif
sendAndReceive;
ENDPROC
ENDMODULE