大家好,我们今天基于以太网TCP协议实现MC协议通讯。三菱Q自带以太网端口,默认协议MC。
讲解本实现本通讯方法,起到抛砖引玉的作用,可以实现更多控制器或者传感器的通讯协议。
测试方案:
主站:Trio
IP地址:192.168.0.251
从站:三菱Q
IP地址:192.168.0.220
通讯端口:2000
我们直接上传代码:
DIM com_port AS INTEGER
com_port=20
TICKS=0
DIM savelast_tick AS INTEGER
savelast_tick=0
DIM print_port AS INTEGER
print_port=6
DIM read_array AS INTEGER(256)
DIM read_sendstr AS STRING(32)
DIM write_sendstr AS STRING(64)
DIM read_index,write_index AS INTEGER
DIM get_str,clearbuf_len AS INTEGER
DIM read_timeout,loop_time,save_looptick,writedata1,writedata2 AS INTEGER
read_timeout=250
loop_time=100
save_looptick=TICKS
'=============================================================
GOSUB open_port
GOSUB ready_readstr
WHILE TRUE
GOSUB start_read
GOSUB start_write
REPEAT
WA(5)
UNTIL ABS(save_looptick-TICKS)>=loop_time
save_looptick=TICKS
WEND
'=============================================================
WA(50)
STOP
'=============================================================
'open port
open_port:
CLOSE #com_port
WA(20)
OPEN #com_port AS "TCP:192.168.0.220(2000)" FOR READ_WRITE
WA(20)
GOSUB clear_buf
RETURN
'=============================================================
'ready send read str
'read data d100~d119
'low->hight
'50 00 send cmd
'00 ff
'ff 03
'00 modid
'0c 00 000c->12
'10 00 0010->16*250ms
'01 04 0401
'00 00
'64 00 00 adr=>00 00 64 ->100
'a8 DADR
'14 00 Len=0014 ->20
'=============================================================
ready_readstr:
read_sendstr=CHR($50)+CHR($00)
read_sendstr=read_sendstr+CHR($00)+CHR($ff)
read_sendstr=read_sendstr+CHR($ff)+CHR($03)
read_sendstr=read_sendstr+CHR($00)
read_sendstr=read_sendstr+CHR($0c)+CHR($00)
read_sendstr=read_sendstr+CHR($01)+CHR($00)
read_sendstr=read_sendstr+CHR($01)+CHR($04)
read_sendstr=read_sendstr+CHR($00)+CHR($00)
read_sendstr=read_sendstr+CHR($64)+CHR($00)+CHR($00)
read_sendstr=read_sendstr+CHR($a8)
read_sendstr=read_sendstr+CHR($14)+CHR($00)
RETURN
'=============================================================
'ready write read str
'write data d100~d119
'low->hight
'50 00 send cmd
'00 ff
'ff 03
'00 modid
'0c 00 000c->12
'10 00 0010->16*250ms
'01 04 0401
'00 00
'64 00 00 adr=>00 00 64 ->100
'a8 DADR
'14 00 Len=0014 ->20
'=============================================================
ready_writestr:
write_sendstr=CHR($50)+CHR($00)
write_sendstr=write_sendstr+CHR($00)+CHR($ff)
write_sendstr=write_sendstr+CHR($ff)+CHR($03)
write_sendstr=write_sendstr+CHR($00)
'write len
write_sendstr=write_sendstr+CHR($10)+CHR($00)
'time out
write_sendstr=write_sendstr+CHR($01)+CHR($00)
'write cmd
write_sendstr=write_sendstr+CHR($01)+CHR($14)
write_sendstr=write_sendstr+CHR($00)+CHR($00)
'write adr
write_sendstr=write_sendstr+CHR($64)+CHR($00)+CHR($00)
write_sendstr=write_sendstr+CHR($a8)
'len
write_sendstr=write_sendstr+CHR($02)+CHR($00)
'write data
writedata1=writedata1+5
writedata2=writedata2+10
write_sendstr=write_sendstr+CHR(writedata1 AND $ff)+CHR((writedata1>>8) AND $ff)
write_sendstr=write_sendstr+CHR(writedata2 AND $ff)+CHR((writedata2>>8) AND $ff)
RETURN
'=============================================================
clear_buf:
clearbuf_len=0
WHILE KEY #com_port
GET #com_port,get_str
clearbuf_len=clearbuf_len+1
WEND
IF clearbuf_len>0 THEN PRINT #print_port,TIME$,"Clear BufLen:",clearbuf_len
RETURN
'=============================================================
start_read:
GOSUB clear_buf
PRINT #com_port,read_sendstr
savelast_tick=TICKS
WA(20)
read_index=0
REPEAT
WHILE KEY #com_port
GET #com_port,get_str
' PRINT #print_port,HEX(get_str)
read_array(read_index)=get_str
read_index=read_index+1
WEND
UNTIL ABS(savelast_tick-TICKS)>=read_timeout OR read_index>=51
PRINT #print_port,TIME$,"Read Data Len:",read_index,ABS(savelast_tick-TICKS)
'start read data
IF read_array(0)=$d0 AND read_array(1)=$00 THEN
' VR(0)=read_array(8)+ read_array(9)<<8
' VR(1)=read_array(10)+ read_array(11)<<8
ENDIF
IF ABS(savelast_tick-TICKS)>=read_timeout THEN
PRINT #print_port,TIME$,"Time Read Timeout=:",ABS(savelast_tick-TICKS)
GOSUB open_port
ENDIF
RETURN
'=============================================================
start_write:
GOSUB clear_buf
GOSUB ready_writestr
PRINT #com_port,write_sendstr
savelast_tick=TICKS
WA(20)
read_index=0
REPEAT
WHILE KEY #com_port
GET #com_port,get_str
' PRINT #print_port,HEX(get_str)
read_index=read_index+1
WEND
UNTIL ABS(savelast_tick-TICKS)>=read_timeout OR read_index>=11
PRINT #print_port,TIME$,"Write ret Data Len:",read_index,ABS(savelast_tick-TICKS)
'start read data
IF ABS(savelast_tick-TICKS)>=read_timeout THEN
PRINT #print_port,TIME$,"Time Read Timeout=:",ABS(savelast_tick-TICKS)
GOSUB open_port
ENDIF
RETURN
上述程序支持如下功能:
1、通讯快速超时功能
2、断线重连功能
3、超时无响应重连功能
4、可设置准确的超时时间
谢谢大家支持!