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