基恩士上位机链路通讯_基恩士PLC通讯源码
生活随笔
收集整理的這篇文章主要介紹了
基恩士上位机链路通讯_基恩士PLC通讯源码
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
基恩士PLC KV7000,8000還是比較好用的,那如何和上位機(jī)通訊,我把源碼寫(xiě)出來(lái)了。采用上位鏈路通訊,基恩士官方給我們留了8501端口,這個(gè)端口有意思剛好是我生日。基恩士的資料我覺(jué)得做的特別好,能快速寫(xiě)源代碼得益于官方資料特別詳細(xì),對(duì)了,他的通訊采用是ASCII碼直接通訊。比如你讀到的ASCII碼是666,那他的實(shí)際值也就是666。好了上代碼,如果熱度比較高,大家有不清楚的地方,我出視頻講解。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Net.Sockets;using System.Threading;using System.Net;namespace WDBaseCommuntionHelper{ public class KV7_8000Service { Socket KVTCPClicent; readonly object LockKVTCP = new object(); public enum DataType { /// /// 16位無(wú)符號(hào) /// U, /// /// 16位有符號(hào) /// S, /// /// 32位無(wú)符號(hào) /// D, /// /// 32位有符號(hào) /// L, /// /// 16位16進(jìn)制數(shù) /// H, /// /// 默認(rèn) /// N } #region 命令 /// /// 更改模式 /// const string Command1 = "M"; /// /// 清除錯(cuò)誤 /// const string Command2 = "ER"; /// /// 檢查錯(cuò)誤編號(hào) /// const string Command3 = "?E"; /// /// 查詢機(jī)型 /// const string Command4 = "?K"; /// /// 檢查運(yùn)行模式 /// const string Command5 = "?M"; /// /// 時(shí)間設(shè)定 /// const string Command6 = "WRT"; /// /// 強(qiáng)制置位 /// const string Command7 = "ST"; /// /// 強(qiáng)制復(fù)位 /// const string Command8 = "RS"; /// /// 連續(xù)強(qiáng)制置位 /// const string Command9 = "STS"; /// /// 連續(xù)強(qiáng)制復(fù)位 /// const string Command10 = "RSS"; /// /// 讀取數(shù)據(jù) /// const string Command11 = "RD"; /// /// 讀取連續(xù)數(shù)據(jù) /// const string Command12 = "RDS"; /// /// 讀取連續(xù)數(shù)據(jù) /// const string Command13 = "RDE"; /// /// 寫(xiě)入數(shù)據(jù) /// const string Command14 = "WR"; /// /// 寫(xiě)入連續(xù)數(shù)據(jù) /// const string Command15 = "WRS"; /// /// 寫(xiě)入連續(xù)數(shù)據(jù) /// const string Command16 = "WRE"; /// /// 寫(xiě)入設(shè)定值 /// const string Command17 = "WS"; /// /// 寫(xiě)入連續(xù)設(shè)定值 /// const string Command18 = "WSS"; /// /// 監(jiān)控器登錄 /// const string Command19 = "MBS"; /// /// 監(jiān)控器登錄 /// const string Command20 = "MWS"; /// /// 讀取監(jiān)控器 /// const string Command21 = "MBR"; /// /// 讀取監(jiān)控器 /// const string Command22 = "MWR"; /// /// 注釋讀取 /// const string Command23 = "RDC"; /// /// 存儲(chǔ)體切換 /// const string Command24 = "BE"; /// /// 讀取擴(kuò)展單元緩沖存儲(chǔ)器 /// const string Command25 = "URD"; /// /// 寫(xiě)入擴(kuò)展單元緩沖存儲(chǔ)器 /// const string Command26 = "UWR"; /// /// 回車 /// const string CR = ""; /// /// 空格 /// const string SP = " "; #endregion Encoding encoding = Encoding.ASCII; /// /// PLC連接狀態(tài) /// public bool IsConnected { get; private set; } /// /// 發(fā)送超時(shí)時(shí)間 /// public int SendTimeout { get; set; } = 2000; /// /// 接收超時(shí)時(shí)間 /// public int ReceiveTimeout { get; set; } = 2000; /// /// 等待PLC響應(yīng)周期,這里一個(gè)周期10ms /// public int MaxDelayCycle { get; set; } = 5; string ip; int port; private Dictionary plcValue = new Dictionary(); /// /// PLC值鍵值對(duì) /// public Dictionary PlcValue { get { return plcValue; } } /// /// 重連 /// /// public bool ReConnext() { if (ip == string.Empty || port == 0) { throw new Exception("沒(méi)有IP和端口請(qǐng)調(diào)用Connect函數(shù)連接"); return false; } return Connect(ip,port); } /// /// 連接PLC /// /// /// /// public bool Connect(string ip, int port=8501) { if (this.ip != ip) this.ip = ip; if (this.port != port) this.port = port; KVTCPClicent = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); KVTCPClicent.SendTimeout = SendTimeout; KVTCPClicent.ReceiveTimeout = ReceiveTimeout; IAsyncResult asyncResult= KVTCPClicent.BeginConnect(new IPEndPoint(IPAddress.Parse(ip) ,port),null,null); asyncResult.AsyncWaitHandle.WaitOne(3000,true); if (!asyncResult.IsCompleted) { KVTCPClicent.Close(); return false; } return true; } /// /// 改變PLC運(yùn)行狀態(tài) /// /// true讓PLC運(yùn)行false讓PLC停止 /// public string ChangeCPU(bool run = true) { string str = Command1 + (run ? "1" : "0") + CR; return SendRecive(str); } /// /// 查看PLC運(yùn)行狀態(tài) /// /// public string SeeCPUState() { string str = Command5 + CR; return SendRecive(str); } /// /// 強(qiáng)制置位復(fù)位 /// /// /// /// public string Put(string address, bool value) { string str; if (value) { str = Command7 + SP + address + CR; } else { str = Command8 + SP + address + CR; } return SendRecive(str); } /// /// 連續(xù)強(qiáng)制置位復(fù)位 /// /// /// /// /// public string Put(string address, bool Value, int count) { string str; if (Value) { str = Command9 + SP + address + count + CR; } else { str = Command10 + SP + address + count + CR; } return SendRecive(str); } /// /// 寫(xiě)入字?jǐn)?shù)據(jù) /// /// /// /// /// public string Put(string address, string value, DataType tpye = DataType.N) { string str = Command14 + SP + address + GetDataType(tpye) + SP + value + CR; return SendRecive(str); } /// /// 寫(xiě)入單精度浮點(diǎn)數(shù) /// /// /// /// public string Put(string address, float value) { List result = CalFloatToInt16(value); return Put(address, result); } /// /// 寫(xiě)入連續(xù)字?jǐn)?shù)據(jù) /// /// /// /// /// public string Put(string address, List value, DataType tpye = DataType.N) { StringBuilder sb = new StringBuilder(Command15 + SP + address + GetDataType(tpye) + SP + value.Count); for (int i = 0; i < value.Count; i++) { sb.Append(SP + value[i]); } sb.Append(CR); return SendRecive(sb.ToString()); } /// /// 讀取字?jǐn)?shù)據(jù) /// /// /// /// public string Get(string address, DataType tpye = DataType.N) { string str = Command11 + SP + address + GetDataType(tpye) + CR; return SendRecive(str); } /// /// 讀取連續(xù)字?jǐn)?shù)據(jù) /// /// /// /// /// public string Get(string address, int count, DataType tpye = DataType.N) { string str = Command13 + SP + address + GetDataType(tpye) + SP + count + CR; return SendRecive(str); } public string CalRD(string str, string type, int address, int count) { string[] s1 = str.Split(' '); if (count > s1.Length) { throw new Exception("映射長(zhǎng)度過(guò)長(zhǎng)"); } for (int i = 0; i < count; i++) { plcValue[type + (address + i)] = s1[i].ToString(); } return "OK"; } /// /// 32位浮點(diǎn)轉(zhuǎn)16位字 /// /// /// public List CalFloatToInt16(float value) { byte[] r1 = BitConverter.GetBytes(value); byte[] r2 = new byte[2] { r1[0], r1[1] }; byte[] r3 = new byte[2] { r1[2], r1[3] }; int r4 = BitConverter.ToUInt16(r2, 0); int r5 = BitConverter.ToUInt16(r3, 0); return new List() { r4.ToString(), r5.ToString() }; } /// /// 2個(gè)16位字轉(zhuǎn)32位浮點(diǎn) /// /// /// /// public float CalInt16ToFlaot(string[] value, int startIndex) { byte[] r1 = BitConverter.GetBytes(Convert.ToInt16(value[startIndex])); byte[] r2 = BitConverter.GetBytes(Convert.ToInt16(value[startIndex + 1])); byte[] r3 = new byte[4] { r1[0], r1[1], r2[0], r2[1] }; return BitConverter.ToSingle(r3, 0); } /// /// ASCII編碼解碼 /// /// /// public string SendRecive(string str) { return encoding.GetString(SendRecive(encoding.GetBytes(str))); } /// /// 發(fā)送接收字節(jié)數(shù)組報(bào)文 /// /// /// public byte[] SendRecive(byte[] arry) { try { Monitor.Enter(LockKVTCP); int delay = 0; int reslut = KVTCPClicent.Send(arry); while (KVTCPClicent.Available == 0) { Thread.Sleep(10); delay++; if (delay > MaxDelayCycle) { break; } } byte[] ResByte = new byte[KVTCPClicent.Available]; reslut = KVTCPClicent.Receive(ResByte); return ResByte; } catch (Exception) { IsConnected = false; return null; } finally { Monitor.Exit(LockKVTCP); } } /// /// 根據(jù)數(shù)據(jù)類型生成報(bào)文 /// /// /// public string GetDataType(DataType dataType) { string str = string.Empty; switch (dataType) { case DataType.U: str = ".U"; break; case DataType.S: str = ".S"; break; case DataType.D: str = ".D"; break; case DataType.L: str = ".L"; break; case DataType.H: str = ".H"; break; case DataType.N: str = ""; break; default: str = ""; break; } return str; } }}#上位機(jī)# #PLC# #觸摸屏# #電工交流圈#
如果對(duì)您有幫助,點(diǎn)贊關(guān)注轉(zhuǎn)發(fā),持續(xù)更新,幫大家解答工控問(wèn)題
總結(jié)
以上是生活随笔為你收集整理的基恩士上位机链路通讯_基恩士PLC通讯源码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: three.js两个点给线条加宽度_一台
- 下一篇: python爬取百度迁徙动态图_pyth