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_CONBEGINFORCE_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 THENWRITE('Connect successful ',CR)b_connet = TRUEELSEWRITE('Connect failed ! ',STATUS,CR)b_connet = FALSEPOST_ERR(38092,socket_id+' SOCKET 连接失败 !!! ',0,2)ENDIFCHK_ERR(STATUS)END SOCKET_CON
2. Socket断开Routine,参考程序
ROUTINE SOCKET_DISCBEGINWRITE('Disconnect ...',CR)MSG_DISCO(socket_id,STATUS)IF STATUS = 0 THENWRITE('Socket disconnect Successful',CR)b_connet = FALSEELSEWRITE('Socket disconnect Failed',STATUS,CR)b_connet = TRUEPOST_ERR(38092,socket_id+' SOCKET 断开失败 !!! ',0,2)ENDIFCHK_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_DATABEGINSET_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)ELSEWRITE(socket_id,' file open Failed.',CR)ABORTENDIFCHK_ERR(STATUS)int_nofbtyes = 0WRITE(socket_id,' receiving data ...',CR)WHILE (int_nofbtyes = 0) DOBYTES_AHEAD(file_var,int_nofbtyes,STATUS)IF (STATUS = 0) AND (int_nofbtyes > 0) THEN--WRITE(socket_id,' read buffer successful.',int_nofbtyes,CR)ENDIFDELAY 10ENDWHILEstr_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)ELSEWRITE(socket_id,' read file failed; byte : ',int_i,CR)ABORTENDIFCHK_ERR(STATUS)int_i = int_i + 1int_nofbtyes = int_nofbtyes-1str_recv = str_recv + str_tempUNTIL int_nofbtyes = 0SET_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_varEND RECV_DATA
5. 数据发送Routine,参考程序
ROUTINE SEND_DATA(str_send: STRING)BEGINSET_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)ELSEWRITE(socket_id,' file open failed.')ENDIFCHK_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_varEND SEND_DATA
第二部分:编写一个简单的Socket程序
PROGRAM DATA_TRANS%COMMENT = 'Socket_TEST'%NOPAUSE = ERROR+COMMAND+TPENABLE%NOLOCKGROUP%NOPAUSESHFT--%NOABORT = ERROR+COMMAND+TPENABLE%NOABORT = ERROR+TPENABLEVARconnect_stat :INTEGERsocket_id :STRING[10]STATUS :INTEGERfile_var :FILEb_connet :BOOLEANint_value :INTEGERreal_value :REALstr_value :STRING[10]str_send :STRING[20]----------------------------------------------------------------------------ROUTINE SOCKET_CON-------FUNCTION Socket Connect---------------------------------------------------------------------ROUTINE SOCKET_CON(socket_id :STRING)BEGINFORCE_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 THENWRITE('Connect successful ',CR)b_connet = TRUEELSEWRITE('Connect failed ! ',STATUS,CR)b_connet = FALSEPOST_ERR(38092,socket_id+' SOCKET 连接失败 !!! ',0,2)ENDIFEND SOCKET_CON----------------------------------------------------------------------------ROUTINE SOCKET_DISC-------FUNCTION Socket disconnect---------------------------------------------------------------------ROUTINE SOCKET_DISC(socket_id :STRING)BEGINWRITE('Disconnect ...',CR)MSG_DISCO(socket_id,STATUS)IF STATUS = 0 THENWRITE('Socket disconnect Successful',CR)b_connet = FALSEELSEWRITE('Socket disconnect Failed',STATUS,CR)b_connet = TRUEPOST_ERR(38092,socket_id+' SOCKET 断开失败 !!! ',0,2)ENDIFEND SOCKET_DISC----------------------------------------------------------------------------Routine SEND_DATA-------FUNCITON DATA SEND---------------------------------------------------------------------ROUTINE SEND_DATA(str_send: STRING)BEGINSET_FILE_ATR(file_var,ATR_IA) --交互式SET_FILE_ATR(file_var,ATR_READAHD,2) --缓存区256OPEN FILE file_var('rw',socket_id)STATUS = IO_STATUS(file_var)IF STATUS = 0 THEN--WRITE(socket_id,' file open successful.',CR)ELSEWRITE(socket_id,' file open failed.')ENDIFWRITE file_var( str_send)WRITE file_var(CR)WRITE(socket_id,' data send successful.',CR)WRITE('Send Data : ', str_send,CR)CLOSE FILE file_varEND SEND_DATA----------------------------------------------------------------------------Main Program---------------------------------------------------------------------BEGINFORCE_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 THENPOST_ERR(38092,socket_id+'参数1 连接未定义 ',0,2)ABORTENDIFconnect_stat = int_valueGET_TPE_PRM(2,3,int_value,real_value,str_value,status)--标号IF status <> 0 THENPOST_ERR(38092,socket_id+'参数2 标签号未定义 ',0,2)ABORTENDIFsocket_id = str_value + ':'GET_TPE_PRM(3,3,int_value,real_value,str_value,status)--数据IF status <> 0 THENPOST_ERR(38092,socket_id+'参数3 数据未定义 ',0,2)ABORTENDIFIF connect_stat = 1 THEN----------------Socket ConnectSOCKET_CON(socket_id)ENDIFIF connect_stat = 2 THEN----------------Socket disConnectSOCKET_DISC(socket_id)DELAY 200ABORTENDIFstr_send = str_value----------------DATA SENDSEND_DATA(str_send)END DATA_TRANS
编译
创建TP程序调用此PC程序,机器人作为客户端,TCP助手为服务器
参数1 :为1时连接,其他断开参数2:服务器或者客户端标号参数3:发送的数据(字符串)
下图为 机器人作为服务器时的数据发送
若要对系统的变量、寄存器进行赋值,原理是将上位机发送过来的数据利用karel来进行设定,SET_REG_PRM、SET_STR_REG....等等
谢谢 !
