S7.Net与西门子PLC通讯——纯新手必看
前言
本文檔適合從未接觸過PLC的.NET開發(fā)程序員入門查看。(其實看完了之后,PLC開發(fā)也就那樣)
PLC通訊入門比較難,需要關(guān)注的細(xì)節(jié)比較多。一邊學(xué)習(xí)一邊舉一反三多思考,一定要自己創(chuàng)建Demo跟著步驟
由于項目還未開發(fā)完成,準(zhǔn)備空抽補(bǔ)充陸續(xù)完成這篇博客,更好的設(shè)計思路也能給自己加深印象。
近期公司有一個跟雷達(dá)、光電、干擾炮等設(shè)備通訊的項目,讓我來負(fù)責(zé),整個項目只有我一個人且沒有PLC開發(fā)經(jīng)驗的同事,這對于從未接觸過PLC開發(fā)的我來說,無疑是一團(tuán)迷霧,不知從何入手。公司之前也沒有PLC開發(fā)經(jīng)驗和項目, 頭大。。。
正所謂“沒有撤退可言,只有活下來的人才有資格清兵線!”
開始在網(wǎng)上找各種資料,在此記錄一下學(xué)習(xí)的過程和踩過的坑
1.快速鎖定有效文章,對于初學(xué)來說,先看理論,有些花里胡哨且亂的資料直接關(guān)閉
2.盡量能找到可以理解的demo,覺得有用但還看不懂的可以先notepad做下筆記
3.如果有人在看 WinTcpS7_1K.dll 的,趕緊關(guān)閉,并送到回收站快速清理,收費的。1500授權(quán)3臺電腦(這個家伙廣告特別多,涉及各個論壇,還要CSDN下載積分,注意看評論),最主要封裝的還很難用
4.最后的最后找到 S7NetPlus ,成功實現(xiàn)了PLC的通訊,博客也會總結(jié)對S7NetPlus的使用
5.要有中心思路,不要一會這個,一會看那個
由于也是初學(xué),如有講錯或不到位的地方還望大佬指教,及時修正!
先發(fā)個視頻,這是我在Youtube上找到的一系列視頻中的一個,作者通過S7.net的dll控件實現(xiàn)了與西門子S7系列的PLC通信的功能
鏈接:https://pan.baidu.com/s/1g3wo4e1HEiuwrzXYD-dSGA
提取碼:lllg
開發(fā)環(huán)境準(zhǔn)備
同時由于設(shè)備還未采購,沒有設(shè)備進(jìn)行測試開發(fā),會安裝一個仿真模擬器進(jìn)行調(diào)試。(真心的,誰想到還能仿真模擬設(shè)備)
需要安裝的軟件包括
?TIA Portal V14
?S7-PLCSIM V14
?NetToPLCsim-S7o-v-1-2-2-0
TIA Portal
西門子官方管理設(shè)備數(shù)據(jù)塊的客戶端,每一個項目等同于一個設(shè)備型號,可以理解為是我們經(jīng)常使用的數(shù)據(jù)塊客戶端
S7-PLCSIM
創(chuàng)建一個仿真的模擬環(huán)境,使用TIA Portal進(jìn)行調(diào)用,控制仿真設(shè)備的運行停止
NetToPLCsim
提供本地服務(wù)去連接到仿真設(shè)備,和PLCsim之間建立網(wǎng)絡(luò)通訊
安裝完TIA之后,有兩處需要進(jìn)行設(shè)置(重要!)
1. 選中組態(tài)的PLC設(shè)備,常規(guī)下找到防護(hù)與安全,選擇允許從遠(yuǎn)程伙伴使用PUT/GET通信訪問
2. 建立的數(shù)據(jù)塊文件,右鍵屬性,需要取消優(yōu)化的塊訪問選項,使用絕對地址
軟件交互使用
第一步: TIAPortal新建項目,選擇需要通訊的設(shè)備型號
第二步:添加數(shù)據(jù)塊
第三步:添加數(shù)據(jù)類型之后,點擊編輯,生成偏移量(Offset),后面獲取單個數(shù)值時需要
第四步:開始仿真,點擊之后會自動打開S7-PLCSIM,根據(jù)提示點擊“裝載”,點“完成”
第五步:在S7-PLCSIM上點擊RUN,運行設(shè)備仿真環(huán)境
第六步:設(shè)置 NetToPLCsim
6.1點擊Add,添加連接到PLCSIM環(huán)境
6.2NetWork IP Address手寫填為本機(jī)(127.0.0.1)
6.3 Plcsim Ip Address點擊后面兩點,選擇192.168.0.1 TCP/IP,必須要在仿真環(huán)境運行之后才能選擇
6.4根據(jù)不同設(shè)備型號設(shè)置Rack / Slot ,我是S7-1200,設(shè)置 0 / 1
第七步:開啟服務(wù),這里也很坑!如果沒有按順序操作,也能Start Server,但是編碼時連接不到。最開始不懂仿真設(shè)備,在這里研究了好久,Demo硬是連不上
ok ! 現(xiàn)在就可以開始進(jìn)行編碼了,這里重點介紹從[連接]到[讀寫]的集中方式和介紹
創(chuàng)建連接
以前的歷史版本 plc.Open();會有一個返回值,可以通過返回值獲取ErrorCode和 ErrorMessage
我使用了當(dāng)前最新版(V0.4.0),沒有返回值使用 try-catch
using (var plc = new Plc(CpuType.S71200, "127.0.0.1", 0, 1))
{
try
{
plc.Open();
}
catch (Exception)
{
Console.WriteLine($"連接到PLC設(shè)備失敗:IsConnect={plc.IsConnected},IsAvailable={plc.IsAvailable}");
return;
}
}
讀取單個數(shù)據(jù)項【Read】
代碼中用到三種數(shù)據(jù)獲取方式: DBX、DBW、DBD,深入理解的可以查一下網(wǎng)上資料
簡單理解就是DBX讀取位,比如bool類型;DBW讀取字;DBD讀取數(shù)值
注釋中是對應(yīng)的 TIAPortal數(shù)據(jù)塊類型
#region 單個數(shù)據(jù)項讀取
var db1Bool1 = plc.Read("DB1.DBX0.0");
Console.WriteLine("DB1.DBX0.0: " + db1Bool1);
bool db1Bool2 = (bool)plc.Read("DB1.DBX0.1");
Console.WriteLine("DB1.DBX0.1: " + db1Bool2);
// Int
int intVariable = (ushort)plc.Read("DB1.DBW2.0");
Console.WriteLine("DB1.DBW2.0: " + intVariable);
// Real
var realVariabl = ((uint)plc.Read("DB1.DBD4.0")).ConvertToFloat();
Console.WriteLine("DB1.DBD4.0: " + realVariabl);
// DInt
var dIntVariable = (uint)plc.Read("DB1.DBD8.0");
Console.WriteLine("DB1.DBD8.0: " + dIntVariable);
// DWord
var dWordVariable = (uint)plc.Read("DB1.DBD12.0");
Console.WriteLine("DB1.DBD12.0: " + dWordVariable);
// Word
var wordVariable = (ushort)plc.Read("DB1.DBW16.0");
Console.WriteLine("DB1.DBW16.0: " + wordVariable);
#endregion
另一種方式,通過ReadBytes讀取單個數(shù)據(jù)
// 讀取int類型
byte [] int0 = (byte[])plc.ReadBytes(DataType.DataBlock, 1, 2, 2);
byte[] revint0 = int0.Reverse().ToArray();
short f5 = BitConverter.ToInt16(revint0, 0);
Console.WriteLine("DB1.DBD2: " + f5);
批量讀取數(shù)據(jù)塊【ReadBytes】
看注釋
#region 批量數(shù)據(jù)項讀取 / 讀取整個DB
// DataType: 數(shù)據(jù)類型,DB或Memory等
// DB : DataBlock=1,Memory=0
// count : 偏移量(offset),設(shè)置多少就獲取到具體位置的數(shù)據(jù)
// eg: 比如最后一個DBW是16,那么數(shù)據(jù)類型長度為2,count就需要傳18才能獲取到
var bytes = plc.ReadBytes(DataType.DataBlock, 1, 0, 18);
Console.WriteLine(bytes);
var bool1 = bytes[0].SelectBit(0);
Console.WriteLine("DB1.DBX0.0: " + bool1);
var bool2 = bytes[0].SelectBit(1);
Console.WriteLine("DB1.DBX0.0: " + bool2);
// Int
int intVariable = S7.Net.Types.Int.FromByteArray(bytes.Skip(2).Take(2).ToArray());
Console.WriteLine("DB1.DBD2.0: " + intVariable);
// Real
Double realVariable = S7.Net.Types.Double.FromByteArray(bytes.Skip(4).Take(4).ToArray());
Console.WriteLine("DB1.DBD4.0: " + realVariable);
// DWord
uint dWordVariable = S7.Net.Types.DWord.FromByteArray(bytes.Skip(12).Take(4).ToArray());
Console.WriteLine("DB1.DBD12.0: " + dWordVariable);
// Word
var wordVariable = S7.Net.Types.Word.FromByteArray(bytes.Skip(16).Take(2).ToArray());
Console.WriteLine("DB1.DBW16.0: " + wordVariable);
#endregion
讀取數(shù)據(jù)塊到類對象【ReadClass】
創(chuàng)建一個Db1類,數(shù)據(jù)類型和變量名跟TAIPortal數(shù)據(jù)塊里一一對應(yīng),這個很簡單!
因為作者已經(jīng)封裝好了,底層實現(xiàn)也是上述原理
#region 讀取數(shù)據(jù)塊(DB)到實體類
var db1 = new Db1();
plc.ReadClass(db1, 1, 0);
#endregion
多個數(shù)據(jù)塊同時讀取 【ReadMultipleVars】
ReadMultipleVars()方法需要構(gòu)造一個List作為參數(shù),這里留作業(yè)
#region 多個數(shù)據(jù)塊(DB)同時讀取
plc.ReadMultipleVars();
#endregion
寫入單個數(shù)據(jù)【W(wǎng)rite】
看完上面的內(nèi)容,就很容易理解這里
// 寫入數(shù)據(jù)
plc.Write("DB1.DBX0.1", true);
plc.Write("DB1.DBD12.0", 123457);
我也是第一次接觸PLC設(shè)備通訊,還有很多沒有講全面,如果有更好的方案或經(jīng)驗歡迎留言一起探討,感謝!
后續(xù)用到本文未提及的地方再回來補(bǔ)充。
補(bǔ)充:
S7.Net作者的GitHub:github.com/killnine(十個殺九個)
總結(jié)
以上是生活随笔為你收集整理的S7.Net与西门子PLC通讯——纯新手必看的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: edge浏览器APP(Edge浏览器下载
- 下一篇: 怎么创建具有真实纹理的CG场景岩石?