Epson之Tcp/IP通讯
网络助手设置
注意1:设置ip为0.0.0.0
注意2:发送信息需要加上换行符
因为下面设置的时候,设置了CRLF SetNet #201,IP$,8080,CRLF,NONE,0Function main 'qt Test ' 启动后台任务,不等它,继续往下走 Call TcpConnect 'rint"主程序继续干活"'ait2Fend Function TcpConnect String IP$ IP$="192.168.0.12"' PC(网络调试助手)的局域网 IP CloseNet All ' 先关掉所有旧连接,防止残留 Wait1' 配置通道 #201:目标=192.168.0.12,端口=8080,CRLF 换行,无校验 SetNet #201,IP$,8080,CRLF,NONE,0OpenNet #201As Client ' 以客户端身份拨号 WaitNet #201,10' 最多等10秒连接结果IfTW=True Then ' TW=True 表示连接失败 Print"连接上位机失败,请确认网络调试助手已启动监听"CloseNet All Quit All EndIf Print"连接成功"FendEpson 机械手 TCP/IP 通信教程(SPEL+ 版)
一、TCP/IP 是什么?先打个比方
IP 地址 = 门牌号。你的机械手控制器和上位机(视觉软件)都在同一个局域网里,每台设备有一个唯一门牌号(如192.168.1.50)。发数据前先要知道对方门牌号。
端口 = 房门号。一个门牌号下面有很多房间(端口)。机械手和视觉软件约定好:取料数据走 9600 号房,下相机数据走 9700 号房。两边同时开多个"房间"各聊各的,互不干扰。
客户端 / 服务器 = 打电话的主动方和被动方。服务器(视觉软件)一直"守机待呼";客户端(机械手)主动拨号过去。本项目里机械手是客户端,视觉软件是服务器:
机械手控制器(客户端) 视觉电脑(服务器) │ │ │ OpenNet #201 As Client │ (监听端口 9600) │───────────────────────────────────────▶│ │ Print #201, "get" ←── 发命令 ──▶ │ 收到"get" │ Input #201, ... ◀── 等回复 ── │ 回 "gok1,123.5,45.6,90" ▼ ▼一问一答 = 对讲机。连上之后,两边就靠Print(发)和Input(收)轮流说话,一问一答,保证不抢话。
数据格式 = 信封写法。双方约定一行数据用逗号分隔字段,行尾用换行符(CRLF)表示"这句话说完了"。
二、Epson 网络指令全家桶
| 指令 | 作用 | 项目里怎么用 |
|---|---|---|
SetNet #n, IP$, 端口, CRLF, NONE, 超时 | 配置一个网络通道(相当于"拨号设置") | SetNet #201, "192.168.1.50", 9600, CRLF, NONE, 0 |
OpenNet #n As Client | 以客户端身份发起连接 | OpenNet #201 As Client |
WaitNet #n, 秒 | 等待连接结果,最多等 N 秒 | WaitNet #201, 10 |
TW | 连接/发送失败标志(True = 失败) | If TW = True Then ... 报错退出 |
CloseNet #n/CloseNet All | 关闭通道 / 全部通道 | 重连前先CloseNet All |
Print #n, 内容 | 通过通道发送数据 | Print #201, "get" |
Input #n, 变量1, 变量2, ... | 从通道接收一行,按逗号拆分 | Input #201, CMD$, X$, Y$, A$ |
SetNet 参数逐个说:
| 参数 | 含义 | 取值说明 |
|---|---|---|
#n | 通道号 | 一个控制器可开多个通道,本项目用了 #201 / #210 / #216 |
| IP 地址 | 对方门牌号 | 字符串,如"192.168.1.50" |
| 端口 | 对方房门号 | 数字,本项目 9600 / 9700 |
| CRLF | 行终止符 | 每句话结尾的换行格式,双方要一致 |
| NONE | 校验位 | 常用 NONE(无校验) |
| 超时 | 连接超时 | 项目初始化用 0,标定程序用了 5000(具体以控制器手册为准) |
一句话记忆:SetNet 配置 → OpenNet 连接 → WaitNet 等结果 → Print/Input 收发 → CloseNet 关闭。
三、源码①:初始化连接(机械手主动连上位机)
3.1 打开网络调试助手,启动服务端
3.2 写客户端代码
下面这段来自项目Main.prg的ini()函数,做了简化。功能:连接视觉上位机,连不上就提示并退出。
FunctionTcpConnectStringIP$IP$="192.168.1.50"' 上位机视觉软件的门牌号 CloseNet All ' 先关掉所有旧连接,防止残留Wait1' 配置通道 #201:IP=192.168.1.50,端口=9600,CRLF 换行,无校验 SetNet #201,IP$,9600,CRLF,NONE,0OpenNet #201AsClient ' 以客户端身份拨号 WaitNet #201,10' 最多等10秒连接结果IfTW=TrueThen' TW=True 表示连接失败Print"连接上位机失败,请确认视觉软件已启动" CloseNet All Quit All ' 退出整个程序 EndIfPrint"连接上位机成功" ' 再开一个通道给下相机(不同端口各聊各的) SetNet #210,IP$,9700,CRLF,NONE,0OpenNet #210AsClient WaitNet #210,10IfTW=TrueThenPrint"连接下相机失败" CloseNet All Quit All EndIfPrint"连接下相机成功" Fend逐行理解:
CloseNet All:重连前先清场,避免"上一个连接没断,新连接失败"。SetNet只是"写好拨号设置",真正打电话的是OpenNet。WaitNet是等结果的关键;不看WaitNet结果就直接发数据,等于不等对方接电话就说话。TW是"是否出问题"的标志:连接失败、发送失败都会变 True,一定要判断。
四、源码②:一问一答——向上位机要坐标(取料核心)
这是本项目最典型的通信模式:机械手发命令 → 视觉回坐标 → 机械手拿坐标去取料。
FunctionGetNutAndTakeStringCMD$,X$,Y$,A$ ' 接收的命令字+三个坐标值 ' 循环"要料",直到拿到有效坐标DoPrint#201,"get"' ① 发命令:我要料Input#201,CMD$,X$,Y$,A$ ' ② 等回复,例如"gok1,123.45,67.89,90.0"PrintCMD$,X$,Y$,A$ ' ③ 打印看看收到啥(调试必备)IfCMD$="gok1"Then' ④ 收到"可以取第1颗" → 跳出循环ExitDoEndIfIfCMD$="gok2"OrCMD$="gok3"OrCMD$="gok4"ThenExitDoEndIf ' ⑤ 没收到有效坐标:回安全位,让上位机重新准备,1秒后再问 Jump homeposWait1Loop' ⑥ 拿到坐标,去取料(Val把字符串转成数值) Tool1Jump XY(Val(X$),Val(Y$),-10,Val(A$))/R '/R 相对当前位置移动 Fend这个模式叫"协议握手",要点:
- 先发后收,一问一答:
Print和Input必须配对,谁先说话、回什么,双方提前约定好。 - 回复是"命令字 + 逗号 + 数据":
gok1,123.45,67.89,90.0拆成 4 个变量,Input自动按逗号拆分。 - 无效回复就重试:收到不认识的内容别硬干,回安全位等 1 秒再问,这就是"异常容错"。
Val()转数值:通信收进来全是字符串,取料前记得Val()转成数字。
五、源码③:完整的 TCP 测试程序(可复制到 RC+ 直接跑)
想在真实控制器上体验通信?写一个"机械手-上位机对讲":机械手连上后每 1 秒发一个ping,上位机回pong就打印。上位机一侧可以用任意 TCP 调试工具(如网络调试助手)监听 9600 端口当服务器。
'============================================================' TCP 测试程序:机械手作为客户端,与上位机一问一答 ' 上位机(服务器)监听192.168.1.50:9600,收到 ping 回 pong '============================================================FunctionTcpTestStringCMD$IntegerCount CloseNet AllWait0.5' ① 连接 SetNet #201,"192.168.1.50",9600,CRLF,NONE,0OpenNet #201AsClient WaitNet #201,10IfTW=TrueThenPrint"连接失败!请检查:"Print"1.上位机是否监听9600端口"Print"2.IP是否192.168.1.50"Print"3.网线/防火墙是否放行" Quit All EndIfPrint"连接成功,开始对讲测试" ' ② 一问一答循环 Count=0DoCount=Count+1Print#201,"ping"' 发命令Print"发送 ping(第", Count, "次)"Input#201,CMD$ ' 等回复(会阻塞,上位机必须回)IfCMD$="pong"ThenPrint"收到 pong,通信正常"ElsePrint"收到未知内容:",CMD$ EndIfWait1LoopFend跑这个程序前请注意:
Input是阻塞等待的——上位机不回话,程序会一直停在那。所以先启动服务器端(TCP 调试工具),再运行程序。- 如果卡住不动,多半是"发了没人回"或"换行符不一致",先 Ctrl+C / 急停退出程序,再检查。
六、项目里的通信协议长什么样
本项目一共有三个通道,各管一摊:
| 通道 | 端口 | 用途 | 上行(机械手→视觉) | 下行(视觉→机械手) |
|---|---|---|---|---|
| #201 | 9600 | 取料视觉 | get、checknutcount、RobotIniOK | Start、gok1~gok4(X,Y,A) |
| #210 | 9700 | 下相机 | acqDown,1、checkCoord | downcamacqok(X,Y,U)、checkCoord 坐标 |
| #216 | 9600 | 标定 | moveacq、toolset、go9point等 | moveok、toolsetok、anglerotationok |
协议设计建议:
- 命令字 + 逗号 + 参数:
acqDown,1比acqDown1好扩展,视觉端用Split一下就行。 - 一问一答要成对:发了命令必须等回复,回复里带命令字(如
downcamacqok)方便判状态。 - 回复要能区分"成功/失败":视觉侧回了
gok系列代表"有料",回别的代表"没料/异常",机械手据此决定取还是等。 - 每条命令都有兜底:项目里取料用
Do...Loop循环重试,防止上位机一时没准备好吃料。 - 换行符必须一致:机械手设
CRLF,视觉软件解析时也要按 CRLF 切行,否则两条数据粘在一起。
七、常见问题排查表
| 现象 | 原因 | 处理方法 |
|---|---|---|
TW = True,连接失败 | IP 不对 / 端口没监听 / 上位机没启动 / 防火墙拦截 | 先 Ping 通 IP;确认视觉软件已启动;关防火墙或加白名单 |
连上了但收不到数据,程序卡在Input | 上位机没回、或回的行尾不是 CRLF | 用网络调试助手模拟回复;确认视觉端用 CRLF 换行 |
| 收到乱码/数据粘在一起 | 换行符不一致、半包/粘包 | 统一 CRLF;数据太长时分多次收发 |
| 有时能连有时连不上 | 上次连接没关闭 | 重连前先CloseNet All+Wait 1 |
| 通信正常但机械手乱动 | 坐标没Val()转换、或没加/R导致绝对定位 | 取料点用Val(X$)并加/R相对移动 |
| 标定程序连不上 5000 | 通道超时参数设太小 | 参考项目:标定通道SetNet #216, ..., 5000 |
排查三板斧:
- 先
Print打印收到的字符串,看内容对不对——通信调试第一原则:先看数据再谈运动。 - 用网络调试助手当假服务器,不发真视觉软件也能测通协议。
- 卡住先急停/退出程序,再查原因,别让机械手一直等。
八、Epson 源码速查(复制即用)
1. 连接初始化(含双通道)
FunctionTcpInit CloseNet AllWait1SetNet #201,"192.168.1.50",9600,CRLF,NONE,0OpenNet #201AsClient WaitNet #201,10IfTW=TrueThenPrint"连接失败" Quit All EndIf SetNet #210,"192.168.1.50",9700,CRLF,NONE,0OpenNet #210AsClient WaitNet #210,10IfTW=TrueThenPrint"连接失败" Quit All EndIf Fend2. 发送命令
Print#201,"get"' 发不带参数的命令Print#210,"acqDown,",Index ' 发带参数的命令(逗号拼接)3. 接收并拆分
Input#201,CMD$,X$,Y$,A$ ' 一行按逗号拆成4个字符串PrintCMD$,X$,Y$,A$ ' 先打印再使用(调试习惯)4. 带超时的等待(防死等)
' 发完命令后,最多等3秒回复;超时重发Print#201,"get"Wait0.1TmReset1DoIfTmr(1)>3ThenPrint"等待超时,重新发送"Print#201,"get"TmReset1EndIfWaitSw(CheckXiQi1)=On,0.1' 占位:循环体里做点别的,避免空转LoopWhile1=0' (占位结构,实际按需求改写)说明:
Input本身没有超时参数,需要"限时等待"时用Tmr计时器 + 重发逻辑做保护,这是现场防死机的标准做法。
九、一句话总结
SetNet 配好门牌 → OpenNet 拨号 → WaitNet 等接通 → Print 说话 → Input 听话 → CloseNet 挂断,这就是 Epson TCP/IP 通信的全部骨架。剩下的,就是和上位机约定好"说什么、回什么、用逗号还是空格、换行用啥",然后把每一问一答都加上重试和超时保护。