karel中的Socket与上位机收发数据
USer Socket是一个用户与PC传递数据的功能选项,Socket 通讯传递与使用TCP / IP网络协议的所有网络硬件配置兼容,能够利用Karel来处理Socket传来的数据,并赋值给控制装置内的寄存器、逻辑信号、系统变量、用户自定义变量等等。
一、工具、选项要求
机器人控制装置选项(Option & Order number)
1A05B-2600-R648 ! User Socket Msg
1A05B-2600-R632 ! KAREL
1A05B-2600-R566 ! KAREL Diagnostic
1A05B-2600-J971 ! KAREL Use Sprt FCTN
2. 连接测试用TCP/IP调试助手
工具下载链接 [ https://share.weiyun.com/7ktFavCm ]
二、机器人的通讯配置设定
1. karel_ENB 系统变量设定
MENU | 设置 | 主机通讯
选择TCP/IP 点击详细
端口1/端口2取决于电脑与控制装置端口的连接
实机连接 电脑PC IPV4的设定 (Robouide不需设定)
3. Client 或 Server 设定
Server特征:被动角色,等待来自客户端的连接请求,处理请求并回传结果。
Client的特征:主动角色,发送连接请求,等待服务器的响应。
1. 机器人作为Client 上位机作为Server
按照上述过程对机器人IP配置重启后对Client的设定
MENU | 设置 | 主机通讯 | 显示 | 客户端
系统提供了8个用于Client的标签
选择标签号,并记住所使用的标签号,这里以标签3为例
协议选择SM(Socket Message)
启动状态选择定义
注意:
机器人IP 192.168.0.2
电脑PC IP 192.168.0.1
TCP/IP IP 192.168.0.3
动作 | 定义
端口号的设定
MENU | 系统 | 系统变量
注意:
HOSTC_CFG 为机器人作为客户端
HOSTS_CFG 为机器人作为服务端
按照上述过程,机器人 作为Client 上位机作为Server
此处应当选择 HOSTC_CFG
选择同上面步骤客户端设定中选择的标签号3
找到$SERVER_PORT输入除特殊用的端口号的数字,这里设定5200
设定完成,重启机器人,必须重启,否则配置不会生效
2.机器人作为服务器,上位机作为服务端
其过程与上述Client一致
配置选择,服务器
端口仍然以系统变量进行设定,应当选择HOSTS_CFG
设定完成,重启机器人,必须重启,否则配置不会生效
三、Karel程序的编写及使用
第一部分:Routine参考程序
1. Socket连接Routine,参考程序
ROUTINE SOCKET_CON
BEGIN
FORCE_SPMENU(TP_PANEL,SPI_TPUSER,1)
SET_FILE_ATR(file_var,ATR_IA)
--SET_VAR(ertry, '*SYSTEM*','$HOSTC_CFG[1].$SERVER_PORT',5200,STATUS)
WRITE('Wait Connecting...',CR)
MSG_CONNECT(socket_id,STATUS)
IF STATUS = 0 THEN
WRITE('Connect successful ',CR)
b_connet = TRUE
ELSE
WRITE('Connect failed ! ',STATUS,CR)
b_connet = FALSE
POST_ERR(38092,socket_id+' SOCKET 连接失败 !!! ',0,2)
ENDIF
CHK_ERR(STATUS)
END SOCKET_CON
2. Socket断开Routine,参考程序
ROUTINE SOCKET_DISC
BEGIN
WRITE('Disconnect ...',CR)
MSG_DISCO(socket_id,STATUS)
IF STATUS = 0 THEN
WRITE('Socket disconnect Successful',CR)
b_connet = FALSE
ELSE
WRITE('Socket disconnect Failed',STATUS,CR)
b_connet = TRUE
POST_ERR(38092,socket_id+' SOCKET 断开失败 !!! ',0,2)
ENDIF
CHK_ERR(STATUS)
END SOCKET_DISC
3. 传入标签号的传参函数
注意:传入参数时,标签号要带 ":" 冒号
param_no = 3 为字符串类型
GET_TPE_PRM(param_no, data_type, int_value, real_value, str_value, status)
str_value = str_value + ‘:’
若调用此PC程序,传入S2,则实际存储到str_value的值为 S2:
4. 数据接收 Routine,参考程序
ROUTINE RECV_DATA
BEGIN
SET_FILE_ATR(file_var,ATR_IA)
SET_FILE_ATR(file_var,ATR_READAHD,2)
OPEN FILE file_var('rw',socket_id)
STATUS = IO_STATUS(file_var)
IF (STATUS = 0) THEN
-- WRITE(socket_id,' file open successful.',CR)
ELSE
WRITE(socket_id,' file open Failed.',CR)
ABORT
ENDIF
CHK_ERR(STATUS)
int_nofbtyes = 0
WRITE(socket_id,' receiving data ...',CR)
WHILE (int_nofbtyes = 0) DO
BYTES_AHEAD(file_var,int_nofbtyes,STATUS)
IF (STATUS = 0) AND (int_nofbtyes > 0) THEN
--WRITE(socket_id,' read buffer successful.',int_nofbtyes,CR)
ENDIF
DELAY 10
ENDWHILE
str_recv = ''
int_i = 1
REPEAT
READ file_var(str_temp::1)
STATUS = IO_STATUS(file_var)
IF STATUS = 0 THEN
--WRITE(socket_id,' read successful; byte : ',int_i,CR)
ELSE
WRITE(socket_id,' read file failed; byte : ',int_i,CR)
ABORT
ENDIF
CHK_ERR(STATUS)
int_i = int_i + 1
int_nofbtyes = int_nofbtyes-1
str_recv = str_recv + str_temp
UNTIL int_nofbtyes = 0
SET_STR_REG(2,str_recv, STATUS)
CHK_ERR(STATUS)
SET_SREG_CMT(2,'RecvData:',STATUS)
CHK_ERR(STATUS)
WRITE('Recv data : ' ,str_recv,CR)
WRITE('Save Data Successful . ',CR)
CLOSE FILE file_var
END RECV_DATA
5. 数据发送Routine,参考程序
ROUTINE SEND_DATA(str_send: STRING)
BEGIN
SET_FILE_ATR(file_var,ATR_IA)
SET_FILE_ATR(file_var,ATR_READAHD,2)
OPEN FILE file_var('rw',socket_id)
STATUS = IO_STATUS(file_var)
IF STATUS = 0 THEN
--WRITE(socket_id,' file open successful.',CR)
ELSE
WRITE(socket_id,' file open failed.')
ENDIF
CHK_ERR(STATUS)
WRITE file_var( str_send)
WRITE file_var(CR)
WRITE(socket_id,' data send successful.',CR)
WRITE('Send Data : ', str_send,CR)
CLOSE FILE file_var
END SEND_DATA
第二部分:编写一个简单的Socket程序
PROGRAM DATA_TRANS
%COMMENT = 'Socket_TEST'
%NOPAUSE = ERROR+COMMAND+TPENABLE
%NOLOCKGROUP
%NOPAUSESHFT
--%NOABORT = ERROR+COMMAND+TPENABLE
%NOABORT = ERROR+TPENABLE
VAR
connect_stat :INTEGER
socket_id :STRING[10]
STATUS :INTEGER
file_var :FILE
b_connet :BOOLEAN
int_value :INTEGER
real_value :REAL
str_value :STRING[10]
str_send :STRING[20]
---------------------------------------------------------------------
-------ROUTINE SOCKET_CON
-------FUNCTION Socket Connect
---------------------------------------------------------------------
ROUTINE SOCKET_CON(socket_id :STRING)
BEGIN
FORCE_SPMENU(TP_PANEL,SPI_TPUSER,1)
SET_FILE_ATR(file_var,ATR_IA)
--SET_VAR(ertry, '*SYSTEM*','$HOSTC_CFG[1].$SERVER_PORT',5200,STATUS)
WRITE('Wait Connecting...',CR)
MSG_CONNECT(socket_id,STATUS)
IF STATUS = 0 THEN
WRITE('Connect successful ',CR)
b_connet = TRUE
ELSE
WRITE('Connect failed ! ',STATUS,CR)
b_connet = FALSE
POST_ERR(38092,socket_id+' SOCKET 连接失败 !!! ',0,2)
ENDIF
END SOCKET_CON
---------------------------------------------------------------------
-------ROUTINE SOCKET_DISC
-------FUNCTION Socket disconnect
---------------------------------------------------------------------
ROUTINE SOCKET_DISC(socket_id :STRING)
BEGIN
WRITE('Disconnect ...',CR)
MSG_DISCO(socket_id,STATUS)
IF STATUS = 0 THEN
WRITE('Socket disconnect Successful',CR)
b_connet = FALSE
ELSE
WRITE('Socket disconnect Failed',STATUS,CR)
b_connet = TRUE
POST_ERR(38092,socket_id+' SOCKET 断开失败 !!! ',0,2)
ENDIF
END SOCKET_DISC
---------------------------------------------------------------------
-------Routine SEND_DATA
-------FUNCITON DATA SEND
---------------------------------------------------------------------
ROUTINE SEND_DATA(str_send: STRING)
BEGIN
SET_FILE_ATR(file_var,ATR_IA) --交互式
SET_FILE_ATR(file_var,ATR_READAHD,2) --缓存区256
OPEN FILE file_var('rw',socket_id)
STATUS = IO_STATUS(file_var)
IF STATUS = 0 THEN
--WRITE(socket_id,' file open successful.',CR)
ELSE
WRITE(socket_id,' file open failed.')
ENDIF
WRITE file_var( str_send)
WRITE file_var(CR)
WRITE(socket_id,' data send successful.',CR)
WRITE('Send Data : ', str_send,CR)
CLOSE FILE file_var
END SEND_DATA
---------------------------------------------------------------------
-------Main Program
---------------------------------------------------------------------
BEGIN
FORCE_SPMENU(TP_PANEL,SPI_TPUSER,1)
WRITE(CHR(128),CHR(137))
GET_TPE_PRM(1,1,int_value,real_value,str_value,status)--1连接,other断开
IF status <> 0 THEN
POST_ERR(38092,socket_id+'参数1 连接未定义 ',0,2)
ABORT
ENDIF
connect_stat = int_value
GET_TPE_PRM(2,3,int_value,real_value,str_value,status)--标号
IF status <> 0 THEN
POST_ERR(38092,socket_id+'参数2 标签号未定义 ',0,2)
ABORT
ENDIF
socket_id = str_value + ':'
GET_TPE_PRM(3,3,int_value,real_value,str_value,status)--数据
IF status <> 0 THEN
POST_ERR(38092,socket_id+'参数3 数据未定义 ',0,2)
ABORT
ENDIF
IF connect_stat = 1 THEN
----------------Socket Connect
SOCKET_CON(socket_id)
ENDIF
IF connect_stat = 2 THEN
----------------Socket disConnect
SOCKET_DISC(socket_id)
DELAY 200
ABORT
ENDIF
str_send = str_value
----------------DATA SEND
SEND_DATA(str_send)
END DATA_TRANS
编译
创建TP程序调用此PC程序,机器人作为客户端,TCP助手为服务器
参数1 :为1时连接,其他断开
参数2:服务器或者客户端标号
参数3:发送的数据(字符串)
下图为 机器人作为服务器时的数据发送
若要对系统的变量、寄存器进行赋值,原理是将上位机发送过来的数据利用karel来进行设定,SET_REG_PRM、SET_STR_REG....等等
谢谢 !