要想和庫(kù)卡機(jī)器人通訊,首先要給機(jī)器人安裝“ETHERNETKRL”這個(gè)軟件,對(duì),是給機(jī)器人安裝。具體軟件的安裝以及初步通訊測(cè)試就不多做介紹了。
因?yàn)楸疚牟皇墙榻B該軟件的安裝,所以就不多做解釋?zhuān)旅娴膬?nèi)容默認(rèn)已經(jīng)能用自帶的測(cè)試軟件獲取庫(kù)卡機(jī)器人發(fā)送過(guò)來(lái)的數(shù)據(jù)。在此基礎(chǔ)上,我來(lái)說(shuō)一下c#利用tcp/ip是如何跟庫(kù)卡機(jī)器人進(jìn)行通訊的.
首先當(dāng)然是TCP/IP的基礎(chǔ)部分,服務(wù)器和客戶(hù)端。這里將庫(kù)卡機(jī)器人作為客戶(hù)端,上位機(jī)作為服務(wù)器進(jìn)行通訊。
private void button1_Click(object sender, EventArgs e)
{
OpenTCP();
}
///
/// TCP放在后臺(tái)線程
///
private void OpenTCP()
{
//新建一個(gè)委托線程
ThreadStart myThreadDelegate = new ThreadStart(Listen);
//實(shí)例化新線程
myThread = new Thread(myThreadDelegate);
myThread.Start();
}
///
/// 創(chuàng)建TCP服務(wù)端并監(jiān)聽(tīng)
///
public void Listen()//創(chuàng)建tcp服務(wù)端
{ //設(shè)置端口
setPort = 59152;
//初始化SOCKET實(shí)例
newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//允許SOCKET被綁定在已使用的地址上。
newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//初始化終結(jié)點(diǎn)實(shí)例
localEP = new IPEndPoint(IPAddress.Parse("172.31.1.250"), setPort);
try
{
_sessionTable = new Hashtable(53);
//綁定
newsock.Bind(localEP);
//監(jiān)聽(tīng)
newsock.Listen(10);
//開(kāi)始接受連接,異步。=
newsock.BeginAccept(new AsyncCallback(OnConnectRequest), newsock);
}
catch (Exception ex)
{
}
}
///
/// 客戶(hù)端連接
///
///
public void OnConnectRequest(IAsyncResult ar)
{
//初始化一個(gè)SOCKET,用于其它客戶(hù)端的連接
server1 = (Socket)ar.AsyncState;
Client[theIndex] = server1.EndAccept(ar);
DateTimeOffset now = DateTimeOffset.Now;
Byte[] byteDateLine = new Byte[65534];
remote = Client[theIndex].RemoteEndPoint;
//把連接成功的客戶(hù)端的SOCKET實(shí)例放入哈希表
_sessionTable.Add(Client[theIndex].RemoteEndPoint, null);
//等待新的客戶(hù)端連接
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();
//接受到客戶(hù)端消息
if (stringdata != "")
{
MessageBox.Show(stringdata);
}
//顯示客戶(hù)端發(fā)送過(guò)來(lái)的信息
}
catch (Exception ex)
{
//從列表中移除通訊失敗的客戶(hù)端
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;
}
}
}
通過(guò)按鈕事件,創(chuàng)建后臺(tái)線程用于TCP服務(wù)端,創(chuàng)建服務(wù)端并開(kāi)啟監(jiān)聽(tīng)后,就可以等待機(jī)器人客戶(hù)端發(fā)來(lái)的消息了。
庫(kù)卡機(jī)器人TCP通訊存在三種數(shù)據(jù)發(fā)送格式:固定長(zhǎng)度字節(jié),任意長(zhǎng)度字節(jié),和xml格式。個(gè)人感覺(jué)xml格式比較好用,這里介紹xml的通訊。
xml的通訊,其實(shí)可以分解為幾個(gè)步驟:
機(jī)器人發(fā)送到上位機(jī):機(jī)器人程序?qū)⒆兞炕蛘邤?shù)值寫(xiě)入xml的元素中→機(jī)器人將xml發(fā)送通過(guò)服務(wù)端發(fā)送到上位機(jī)的服務(wù)端→服務(wù)端接受到數(shù)據(jù),按照xml的格式解析其中元素。
RET=EKI_Init("XmlCallBack")//初始化xml文件
RET=EKI_Open("XmlCallBack")//打開(kāi)(相當(dāng)于客戶(hù)端請(qǐng)求連接)
//將變量或值寫(xiě)入到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)
//發(fā)送xml到服務(wù)端
RET = EKI_Send("XmlCallBack","Robot")
上位機(jī)服務(wù)端獲取到的數(shù)據(jù)是:
然后對(duì)數(shù)據(jù)進(jìn)行逐個(gè)元素的解析就可以了。要增加變量,只要對(duì)應(yīng)在mxl文件,機(jī)器人程序和上位機(jī)解析過(guò)程中添加就可以了。
上位機(jī)發(fā)送到機(jī)器人:上位機(jī)將變量寫(xiě)成xml格式,利用客戶(hù)端發(fā)送到機(jī)器人中的xml文件→機(jī)器人讀取xml文件中的元素值到程序中的變量
寫(xiě)成xml格式:
sendstr = sendstr + "
sendstr = sendstr + "
然后是tcp發(fā)送
///
/// 將字符串發(fā)送給機(jī)器人
///
///
private void sendToRobot(string str)
{
string sendstr;
str = str.Replace(" ", "");
string[] fields = str.Split(',');
string header = "
sendstr = header;
//設(shè)置xml文件中變量的值,格式:<變量名>變量值變量名>
foreach (string item in fields)
{
string[] arr = item.Split('=');
sendstr += "<" + arr[0] + ">" + arr[1] + "" + arr[0] + ">";
}
sendstr += tail;
//這些變量的某些中間父元素與前面的不同,所以另外寫(xiě)
sendstr = sendstr + "
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
{ }
}
等發(fā)送完成之后,機(jī)器人再讀取
機(jī)器人從xml元素中讀取值或者屬性并賦予創(chuàng)建的變量
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)
然后就可以在機(jī)器人程序中使用,或者通過(guò)查看變量值檢測(cè)是否正確。
審核編輯:湯梓紅
-
機(jī)器人
+關(guān)注
關(guān)注
212文章
29233瀏覽量
210760 -
通訊
+關(guān)注
關(guān)注
9文章
925瀏覽量
35419 -
TCP
+關(guān)注
關(guān)注
8文章
1395瀏覽量
80077 -
上位機(jī)
+關(guān)注
關(guān)注
27文章
952瀏覽量
55432
原文標(biāo)題:上位機(jī)C#通過(guò)TCP/IP和機(jī)器人通訊
文章出處:【微信號(hào):愛(ài)上PLC,微信公眾號(hào):愛(ài)上PLC】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
履帶式移動(dòng)機(jī)器人的設(shè)計(jì)
上位機(jī)全套程序,上位機(jī)與機(jī)器人和PLC通訊都是通過(guò)以太網(wǎng)總線方式
上位機(jī)與機(jī)器人和PLC都是如何進(jìn)行通訊的
[求助]W5500 上位機(jī)通訊程序 TCP/IP協(xié)議
如何通過(guò)IP命令控制機(jī)器人?
EPSON機(jī)器人如何與視覺(jué)上位機(jī)實(shí)現(xiàn)TCP通信
C#上位機(jī)和松下PLC通訊

ABB機(jī)器人與上位機(jī)進(jìn)行Socket通信的RAPID代碼實(shí)現(xiàn)(服務(wù)端)

圖文詳解ABB機(jī)器人如何與相機(jī)通訊

運(yùn)動(dòng)控制卡網(wǎng)絡(luò)通訊的心跳檢測(cè)之C#上位機(jī)編程

評(píng)論