【TRIO-Basic从入门到精通教程十八】Trio运动控制器UDP快速交换数据通讯
应客户的需求,今天给大家带来一篇两个或多个控制器之间相互通讯的实例。
在实际的项目应用中,经常需要和另外一方控制器进行交换数据,当前的方案正好可以满足你的需求。
通过udp通讯,快速交换多台控制器数据,这个方案比较合适,实际ethernet/ip中,也应用了当前类似方法。
我们接下来看看当前的通讯方案配置:

配置:
控制器1:MC405
IP地址:192.168.0.8
控制器2:MC405
IP地址:192.168.0.9
交换机1台
进入代码内容,通讯核心代码分装到库中
文件名:SINOLIB.BAL
'初始化控制UDP通讯
'ipadr ip地址数据 192.168.0.9
'sockport ip地址端口 8899
FUNCTION initudp(ipadr AS STRING,sockport AS INTEGER)
DIM ipadrframe AS STRING(64)
DIM channel AS INTEGER
channel=20
ipadrframe ="dgram:"
ipadrframe =ipadrframe+ipadr
ipadrframe =ipadrframe+"("
ipadrframe =ipadrframe+STR(sockport,0)
ipadrframe =ipadrframe+")"
IF CONTROL >400 THEN
OPEN #channel AS ipadrframe FOR READ_WRITE
PRINT #0,"Init udp network:",ipadrframe
ENDIF
ENDFUNC
'等待接受数据
'startadr 数据存放地址
'num 数据存放长度
FUNCTION recvdata(startadr AS INTEGER,num AS INTEGER)
DIM getdata AS STRING(255)
DIM getinter AS INTEGER(4)
DIM channel AS INTEGER
DIM idex_read AS INTEGER
DIM get_float AS FLOAT
IF num >60 THEN
num=60
ENDIF
channel=20
IF KEY#channel THEN
'wait recv delay time
WA(1)
CHANNEL_READ(channel,getdata)
'"@" start
IF ASC(getdata)=64 THEN
FOR idex_read=0 TO num-1
getinter(0)=ASC(MID(getdata,1+idex_read*4))
getinter(1)=ASC(MID(getdata,2+idex_read*4))
getinter(2)=ASC(MID(getdata,3+idex_read*4))
getinter(3)=ASC(MID(getdata,4+idex_read*4))
get_float=IEEE_IN(getinter(0),getinter(1),getinter(2),getinter(3))
VR(startadr+idex_read)=get_float
NEXT idex_read
ENDIF
ENDIF
ENDFUNC
'发送数据
'startadr 数据存放地址
'num 数据存放长度
FUNCTION senddata(startadr AS INTEGER,num AS INTEGER)
DIM getdata AS STRING(255)
DIM getinter AS INTEGER(4)
DIM channel AS INTEGER
DIM idex_read AS INTEGER
DIM get_float AS FLOAT
IF num >60 THEN num=60
channel=20
'send header data
getdata="@"
FOR idex_read=0 TO num-1
get_float=VR(startadr+idex_read)
getinter(0)=IEEE_OUT(get_float,0)
getinter(1)=IEEE_OUT(get_float,1)
getinter(2)=IEEE_OUT(get_float,2)
getinter(3)=IEEE_OUT(get_float,3)
getdata =getdata + CHR(getinter(0))
getdata =getdata + CHR(getinter(1))
getdata =getdata + CHR(getinter(2))
getdata =getdata + CHR(getinter(3))
NEXT idex_read
getdata =getdata +CHR(13)+CHR(10)
PRINT #channel,getdata;
ENDFUNC库中代码封装三个函数
1、初始化UDP通讯,设置目标IP地址和端口号
'初始化控制UDP通讯
'ipadr ip地址数据 192.168.0.9
'sockport ip地址端口 8899
FUNCTION initudp(ipadr AS STRING,sockport AS INTEGER)
2、读取数据包并保存指定的寄存器中
'等待接受数据
'startadr 数据存放地址
'num 数据存放长度
FUNCTION recvdata(startadr AS INTEGER,num AS INTEGER)
3、发送数据包自动从指定寄存器抓取数据
'发送数据
'startadr 数据存放地址
'num 数据存放长度
FUNCTION senddata(startadr AS INTEGER,num AS INTEGER)
实际工程代码调用库函数
'设置保存时钟 DIM save_ticks,setpt_ticks AS INTEGER DIM local_ipadr,send_ipadr AS STRING(32) DIM main_program AS INTEGER main_program=0 IF main_program=0 THEN local_ipadr="192.168.0.8" send_ipadr="192.168.0.9" ELSEIF main_program=1 THEN local_ipadr="192.168.0.9" send_ipadr="192.168.0.8" ENDIF IP_ADDRESS=local_ipadr WA(100) PRINT #0,"set local network:",local_ipadr PRINT #0,"set send network:",send_ipadr TICKS=0 '设置交换数据周期:单位ms setpt_ticks=100 save_ticks=TICKS '初始化控制UDP通讯 'ipadr ip地址数据 192.168.0.9 'sockport ip地址端口 8899 'FUNCTION initudp(ipadr AS STRING,sockport AS INTEGER) initudp(send_ipadr,8899) WHILE TRUE IF ABS(save_ticks-TICKS)>=setpt_ticks THEN save_ticks=TICKS senddata(2000,20) ENDIF 'read data per loop time recvdata(3000,20) WA(10) WEND
效果演示
192.168.0.8=》向192.168.0.9发送数据

192.168.0.9=》向192.168.0.8发送数据

实验测试成功,达到预期效果
功能如下:
无需提前建立通讯,单方上线即时通讯
数据实时发送,无断线问题
