上位機C#通過TCPIP和庫卡機器人通訊
注:本文章文字、圖片部分來自網絡
版權歸原作者,侵刪。
您是否對將工業自動化集成到您的設施中感興趣?如果是這樣,那么您應該致電工業自動化和集成領域的領導者工博士。工博士是包括
FANUC,Yaskawa,KUKA,Kawasaki和
ABB在內的多家不同機器人公司的認證集成商。我們的員工致力于幫助您為您的行業和預算構建和定制完美的自動化系統。
因為本文不是介紹該軟件的安裝,所以就不多做解釋,下面的內容默認已經能用自帶的測試軟件獲取庫卡機器人發送過來的數據。在此基礎上,我來說一下c#利用tcp/ip是如何跟庫卡機器人進行通訊的.
首先當然是TCP/IP的基礎部分,服務器和客戶端。這里將庫卡機器人作為客戶端,上位機作為服務器進行通訊。
private void button1_Click(object sender, EventArgs e)
{
OpenTCP();
}
/// <summary>
/// TCP放在后臺線程
/// </summary>
private void OpenTCP()
{
//新建一個委托線程
ThreadStart myThreadDelegate = new ThreadStart(Listen);
//實例化新線程
myThread = new Thread(myThreadDelegate);
myThread.Start();
}
/// <summary>
/// 創建TCP服務端并監聽
/// </summary>
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)
{
}
}
/// <summary>
/// 客戶端連接
/// </summary>
/// <param name="ar"></param>
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 <LastPos X="" Y="" Z="" A="" B="" C="" />
RET=EKI_SetFrame("XmlCallBack","Robot/Data/LastPos", TOOL_DATA[1])
; Write real to <ActPos X="" />
RET=EKI_SetReal("XmlCallBack","Robot/Data/ActPos/@X", 1000.12)
; Write int to <Status></Status>
RET=EKI_SetInt("XmlCallBack","Robot/Status", 12345678)
; Write string to <Mode></Mode>
RET=EKI_SetString("XmlCallBack","Robot/Mode","ConnectSensor")
; Write bool to <LightOn></LightOn>
RET=EKI_SetBool("XmlCallBack","Robot/RobotLamp/GrenLamp/LightOn",true)
;ENDFOLD (Write data to connection)
//發送xml到服務端
RET = EKI_Send("XmlCallBack","Robot")
上位機服務端獲取到的數據是:
<Robot><Data><LastPos X="483.980011" Y="7.210000" Z="239.869995" A="0.000000" B="0.000000" C="0.000000"></LastPos><ActPos X="1000.119995"></ActPos></Data><Status>12345678</Status><Mode>ConnectSensor</Mode><RobotLamp><GrenLamp><LightOn>1</LightOn></GrenLamp></RobotLamp></Robot>
然后對數據進行逐個元素的解析就可以了。要增加變量,只要對應在mxl文件,機器人程序和上位機解析過程中添加就可以了。
上位機發送到機器人:上位機將變量寫成xml格式,利用客戶端發送到機器人中的xml文件→機器人讀取xml文件中的元素值到程序中的變量
寫成xml格式:
sendstr = sendstr + "<Sensor><Status><IsActive>FALSE</IsActive></Status></Sensor>";
sendstr = sendstr + "<Sensor><Read><xyzabc X='10.0' Y='20.0' Z='30.0' A='40.0' B='50.0' C='60.0'></xyzabc></Read</Sensor>";
然后是tcp發送
/// <summary>
/// 將字符串發送給機器人
/// </summary>
/// <param name="str"></param>
private void sendToRobot(string str)
{
string sendstr;
str = str.Replace(" ", "");
string[] fields = str.Split(',');
string header = "<Sensor>", tail = "</Sensor>";//變量xml文件中的父元素
sendstr = header;
//設置xml文件中變量的值,格式:<變量名>變量值</變量名>
foreach (string item in fields)
{
string[] arr = item.Split('=');
sendstr += "<" + arr[0] + ">" + arr[1] + "</" + arr[0] + ">";
}
sendstr += tail;
//這些變量的某些中間父元素與前面的不同,所以另外寫
sendstr = sendstr + "<Sensor><Status><IsActive>FALSE</IsActive></Status></Sensor>";
sendstr = sendstr + "<Sensor><Read><xyzabc X='10.0' Y='20.0' Z='30.0' A='40.0' B='50.0' C='60.0'></xyzabc></Read></Sensor>";
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)
然后就可以在機器人程序中使用,或者通過查看變量值檢測是否正確
本例中的xml文件和機器人程序文件src由ETHERNETKRL軟件中自帶的測試例子修改而來。不用原例子的原因是,原例子只有程序文件src而沒有數據文件dat,程序里的變量都是臨時變量,無法在示教器上查詢變量的值。所以新建了一個程序,將原例子的變量定義放在dat數據文件中,處理過程放在src程序文件中。另外,對上位機發送到機器人的元素有做一些刪改。
————————————————
版權聲明:本文為CSDN博主「千年de小妖」的原創文章,
原文鏈接:
https://blog.csdn.net/qq_29221215/article/details/95759479
在此處聯系我們或致電186-1656-9600與我們聯系,以獲取有關庫卡機器人解決方案和快速簡便的報價。
了解更多:
庫卡機器人