上位机C#通过TCP/IP和机器人通讯

电子说

1.3w人已加入

描述

要想和库卡机器人通讯,首先要给机器人安装“ETHERNETKRL”这个软件,对,是给机器人安装。具体软件的安装以及初步通讯测试就不多做介绍了。

因为本文不是介绍该软件的安装,所以就不多做解释,下面的内容默认已经能用自带的测试软件获取库卡机器人发送过来的数据。在此基础上,我来说一下c#利用tcp/ip是如何跟库卡机器人进行通讯的.

首先当然是TCP/IP的基础部分,服务器和客户端。这里将库卡机器人作为客户端,上位机作为服务器进行通讯。

private void button1_Click(object sender, EventArgs e)
        {
            OpenTCP();
        }
        ///


        /// TCP放在后台线程
        ///

        private void OpenTCP()
        {
            //新建一个委托线程
            ThreadStart myThreadDelegate = new ThreadStart(Listen);
            //实例化新线程
            myThread = new Thread(myThreadDelegate);
            myThread.Start();
  
        }
        ///
        /// 创建TCP服务端并监听
        ///

        public void Listen()//创建tcp服务端
        {   //设置端口
            setPort = 59152;
            //初始化SOCKET实例
            newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //允许SOCKET被绑定在已使用的地址上。
            newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            //初始化终结点实例
            localEP = new IPEndPoint(IPAddress.Parse("172.31.1.250"), setPort);
            try
            {
                _sessionTable = new Hashtable(53);
                //绑定
                newsock.Bind(localEP);
                //监听
                newsock.Listen(10);
                //开始接受连接,异步。=
                newsock.BeginAccept(new AsyncCallback(OnConnectRequest), newsock);
            }
            catch (Exception ex)
            {
             }
         }
        ///
        /// 客户端连接
        ///

        ///
        public void OnConnectRequest(IAsyncResult ar)
        {
            //初始化一个SOCKET,用于其它客户端的连接
 
            server1 = (Socket)ar.AsyncState;
            Client[theIndex] = server1.EndAccept(ar);
            DateTimeOffset now = DateTimeOffset.Now;
            Byte[] byteDateLine = new Byte[65534];
            remote = Client[theIndex].RemoteEndPoint;
            //把连接成功的客户端的SOCKET实例放入哈希表
            _sessionTable.Add(Client[theIndex].RemoteEndPoint, null);
 
            //等待新的客户端连接
            theListClient[theIndex, 0] = Client[theIndex].RemoteEndPoint.ToString();
            theListClient[theIndex, 1] = "1";
            server1.BeginAccept(new AsyncCallback(OnConnectRequest), server1);
            theIndex++;
            int myIndex = theIndex - 1;
            while (true)
            {
                try
                {
                    if (theListClient[myIndex, 1] == "0") return;
                    Thread.Sleep(150);
                    int recv = Client[myIndex].Receive(byteDateLine);
 
                    string stringdata = Encoding.UTF8.GetString(byteDateLine, 0, recv);
 
                    string ip = Client[myIndex].RemoteEndPoint.ToString();
 
                    //接受到客户端消息
                    if (stringdata != "")
                    {
                        MessageBox.Show(stringdata);
                    }
                    //显示客户端发送过来的信息
                 }
                catch (Exception ex)
                {
                    //从列表中移除通讯失败的客户端
                    string ip = Client[myIndex].RemoteEndPoint.ToString();
                    _sessionTable.Remove(Client[myIndex].RemoteEndPoint);
                    for (int i = 0; i < 256; i++)
                    {
                        if (Client[myIndex].RemoteEndPoint.ToString() == theListClient[i, 0]) theListClient[i, 1] = "0";
                    }
                    break;
                }
            }
 
        }

通过按钮事件,创建后台线程用于TCP服务端,创建服务端并开启监听后,就可以等待机器人客户端发来的消息了。

库卡机器人TCP通讯存在三种数据发送格式:固定长度字节,任意长度字节,和xml格式。个人感觉xml格式比较好用,这里介绍xml的通讯。

xml的通讯,其实可以分解为几个步骤:

机器人发送到上位机:机器人程序将变量或者数值写入xml的元素中→机器人将xml发送通过服务端发送到上位机的服务端→服务端接受到数据,按照xml的格式解析其中元素。

RET=EKI_Init("XmlCallBack")//初始化xml文件
RET=EKI_Open("XmlCallBack")//打开(相当于客户端请求连接)
//将变量或值写入到xml文件的元素中
;FOLD Write data to connection
  ; Write frame to
  RET=EKI_SetFrame("XmlCallBack","Robot/Data/LastPos", TOOL_DATA[1])
  ; Write real to
  RET=EKI_SetReal("XmlCallBack","Robot/Data/ActPos/@X", 1000.12)
  ; Write int to
  RET=EKI_SetInt("XmlCallBack","Robot/Status", 12345678)
  ; Write string to
  RET=EKI_SetString("XmlCallBack","Robot/Mode","ConnectSensor")
  ; Write bool to
  RET=EKI_SetBool("XmlCallBack","Robot/RobotLamp/GrenLamp/LightOn",true)
;ENDFOLD (Write data to connection)
//发送xml到服务端
RET = EKI_Send("XmlCallBack","Robot")

上位机服务端获取到的数据是:

12345678ConnectSensor1

然后对数据进行逐个元素的解析就可以了。要增加变量,只要对应在mxl文件,机器人程序和上位机解析过程中添加就可以了。

上位机发送到机器人:上位机将变量写成xml格式,利用客户端发送到机器人中的xml文件→机器人读取xml文件中的元素值到程序中的变量

写成xml格式:

sendstr = sendstr + "FALSE";
sendstr = sendstr + "";

然后是tcp发送
///


        /// 将字符串发送给机器人
        ///

        ///
        private void sendToRobot(string str)
        {
            string sendstr;
            str = str.Replace(" ", "");
            string[] fields = str.Split(',');
            string header = "", tail = "";//变量xml文件中的父元素
 
            sendstr = header;
            //设置xml文件中变量的值,格式:<变量名>变量值
            foreach (string item in fields)
            {
                string[] arr = item.Split('=');
                sendstr += "<" + arr[0] + ">" + arr[1] + "";
            }
            sendstr += tail;
            //这些变量的某些中间父元素与前面的不同,所以另外写
            sendstr = sendstr + "FALSE";
            sendstr = sendstr + "";
            string strDataLine = sendstr;
            try
            {
                Byte[] sendData = Encoding.UTF8.GetBytes(strDataLine);
 
                foreach (DictionaryEntry de in _sessionTable)
                {
                    EndPoint temp = (EndPoint)de.Key;
                    {
                        for (int i = 0; i < theIndex; i++)
                        {
                            if (theListClient[i, 1] == "1")
                            {
                                if (temp.ToString() == theListClient[i, 0])
                                {
                                    try
                                    {
                                        Client[i].SendTo(sendData, temp);
                                    }
                                    catch (Exception ex)
                                    {
                                        
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch
            { }
        }

等发送完成之后,机器人再读取

机器人从xml元素中读取值或者属性并赋予创建的变量

 RET=EKI_GetString("XmlCallBack","Sensor/Message",valueChar[])
 RET=EKI_GetInt("XmlCallBack","Sensor/Nmb",valueInt)
 RET=EKI_GetBool("XmlCallBack","Sensor/Status/IsActive" ,valueBOOL)
 RET=EKI_GetFrame("XmlCallBack","Sensor/Read/xyzabc",valueFrame)

然后就可以在机器人程序中使用,或者通过查看变量值检测是否正确。
 

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分