vlambda博客
学习文章列表

karel中的Socket与上位机收发数据

 USer Socket是一个用户与PC传递数据的功能选项,Socket 通讯传递与使用TCP / IP网络协议的所有网络硬件配置兼容,能够利用Karel来处理Socket传来的数据,并赋值给控制装置内的寄存器、逻辑信号、系统变量、用户自定义变量等等。


一、工具、选项要求

  1. 机器人控制装置选项(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调试助手

karel中的Socket与上位机收发数据


工具下载链接  [ https://share.weiyun.com/7ktFavCm ]


二、机器人的通讯配置设定

 1. karel_ENB 系统变量设定

karel中的Socket与上位机收发数据


MENU | 设置 | 主机通讯

karel中的Socket与上位机收发数据


选择TCP/IP 点击详细

karel中的Socket与上位机收发数据


端口1/端口2取决于电脑与控制装置端口的连接

karel中的Socket与上位机收发数据


实机连接 电脑PC IPV4的设定 (Robouide不需设定)

karel中的Socket与上位机收发数据


karel中的Socket与上位机收发数据


karel中的Socket与上位机收发数据





3. Client Server 设定

Server特征:被动角色,等待来自客户端的连接请求,处理请求并回传结果。
Client的特征:主动角色,发送连接请求,等待服务器的响应。

  

  1. 机器人作为Client 上位机作为Server

按照上述过程对机器人IP配置重启后对Client的设定

MENU | 设置 | 主机通讯 | 显示 | 客户端

karel中的Socket与上位机收发数据


系统提供了8个用于Client的标签

选择标签号,并记住所使用的标签号,这里以标签3为例

karel中的Socket与上位机收发数据


协议选择SM(Socket Message)

karel中的Socket与上位机收发数据


启动状态选择定义

karel中的Socket与上位机收发数据


注意:

机器人IP 192.168.0.2

电脑PC IP 192.168.0.1

TCP/IP  IP 192.168.0.3

karel中的Socket与上位机收发数据


动作 |  定义

karel中的Socket与上位机收发数据


端口号的设定

MENU | 系统 | 系统变量

karel中的Socket与上位机收发数据


注意:

HOSTC_CFG 为机器人作为客户端

HOSTS_CFG 为机器人作为服务端


按照上述过程,机器人 作为Client 上位机作为Server

此处应当选择 HOSTC_CFG

karel中的Socket与上位机收发数据



选择同上面步骤客户端设定中选择的标签号3

karel中的Socket与上位机收发数据


找到$SERVER_PORT输入除特殊用的端口号的数字,这里设定5200

karel中的Socket与上位机收发数据



karel中的Socket与上位机收发数据


设定完成,重启机器人,必须重启,否则配置不会生效


2.机器人作为服务器,上位机作为服务端

其过程与上述Client一致

配置选择,服务器

karel中的Socket与上位机收发数据

karel中的Socket与上位机收发数据


karel中的Socket与上位机收发数据


端口仍然以系统变量进行设定,应当选择HOSTS_CFG

karel中的Socket与上位机收发数据


karel中的Socket与上位机收发数据


设定完成,重启机器人,必须重启,否则配置不会生效


三、Karel程序的编写及使用

第一部分:Routine参考程序

  1. Socket连接Routine,参考程序


ROUTINE SOCKET_CONBEGIN 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 = TRUEELSE 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_DISCBEGIN WRITE('Disconnect ...',CR) MSG_DISCO(socket_id,STATUS)IF STATUS = 0 THEN WRITE('Socket disconnect Successful',CR) b_connet = FALSEELSE 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 = 1REPEATREAD 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_tempUNTIL 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+TPENABLEVAR 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)  ENDIFEND 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


编译

karel中的Socket与上位机收发数据


创建TP程序调用此PC程序,机器人作为客户端,TCP助手为服务器

参数1 :为1时连接,其他断开参数2:服务器或者客户端标号参数3:发送的数据(字符串)

karel中的Socket与上位机收发数据

karel中的Socket与上位机收发数据

karel中的Socket与上位机收发数据

karel中的Socket与上位机收发数据


下图为 机器人作为服务器时的数据发送



若要对系统的变量、寄存器进行赋值,原理是将上位机发送过来的数据利用karel来进行设定,SET_REG_PRM、SET_STR_REG....等等




谢谢 !