1,虛擬機...系統Win10...里面安裝了VS.
2,本機...系統Win10...里面安裝了博圖15.
3,轉換軟件:NetToPLCSIM.
4,本機和虛擬機連接同一個路由器.注意:
5,設置虛擬機為橋接模式,並且選擇連接了路由器的網卡.
6,網卡設置自動獲取IP地址,並且禁止,啟用,讓網卡獲取IP地址.
正常情況,兩台機器能夠互相ping 成功!,則基本准備,網絡配置完畢.否則,檢查防火牆.我沒遇到,就沒弄.
然后打開博圖,必須要進行get/put打勾!
2,GET/PUT 打勾
3,模擬的時候,先點擊模擬,但是不要下載PLC.
4,打開Nettoplcsim軟件:(其中有 stop server start server 默認即可),注意,一定要先打開這個軟件.
5,打開添加對接畫面:點擊PLCSIM IP.注意,如果先模擬再添加就不會顯示.
6,打開PLC模擬器,並下載PLC 點擊 PLCSIM IP:這個很關鍵,必須它自己跳出來的.選擇PLC.
7,選擇 NET IP ADDR:
8,ok注意 rack和slot選擇
9,在虛擬機的VS里面測試通訊
internal static void TestS7() { Plc plc = new Plc(CpuType.S71200, "192.168.3.62", 0, 1); try { log("begin open plc"); plc.Open();//一個PLC異步函數,注意,異步函數的異常只能通過 log("plc is open!"); } catch(Exception e) { log(e.Message); } }
結果:
10,嘗試讀取寫入byte[]數組:
RecipePLC 數據類型具有:(配方)
一個字符串: string[20] 占用了22個字節.Index0是其大小,應該是22,index1 是實際字符長度.應該是0.現在
一個step數組:step是一個plc數據類型. 其為30個step元素.
每個step含有:
OK,我們先來完成如何讀取寫入這個結構:
10.1首先在vs中架構一個PLCSTRING類,因為 string這個類不好投射.
public class PlcString:IPlcParse { private readonly byte[] bytes; public PlcString() : this(256) { } public PlcString(int len ) { bytes = new byte[len]; bytes[0] = len <= 0xfe ? (byte)len : (byte)0xfe; } public void SetString(string str) { int len = bytes.Length; if (str != string.Empty) { byte[] str_bytes = ASCIIEncoding.ASCII.GetBytes(str); bytes[1] = (byte)str_bytes.Length; str_bytes.CopyTo(bytes, 2); } else { bytes[1] = 0; } } public string GetString() { if (bytes[1] != 0) { byte[] strs = new byte[(int)bytes[1]]; Buffer.BlockCopy(bytes, 2, strs, 0, (int)bytes[1]); return ASCIIEncoding.ASCII.GetString(strs); } else { return string.Empty; } } public static explicit operator String(PlcString obj) { return obj.GetString(); } public object FromBytes(byte[] bytes, ref double numBytes) { numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) numBytes++; Buffer.BlockCopy(bytes, (int)numBytes, this.bytes, 0, this.bytes.Length); numBytes += this.bytes.Length; return this; } public int GetSize() { return bytes.Length; } public void ToBytes(byte[] bytes, ref double numBytes) { numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) numBytes++; Buffer.BlockCopy(this.bytes, 0,bytes, (int)numBytes, this.bytes.Length); numBytes += this.bytes.Length; } public void Display() { foreach (var x in bytes) Console.Write(" {0:X2}", x); Console.WriteLine(); } }
這個類實現了如下的接口:
public interface IPlcParse { void ToBytes(byte[] bytes, ref double numBytes); object FromBytes(byte[] bytes, ref double numBytes); int GetSize(); }
https://gitee.com/mao_qin_bin/s7netplus
算了,太多了,大家到這個地方下載吧. 注意版權.是我的!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
在原有的S7的基礎上更改的實現.(git下來之后,我們再開始下一步)
下面我們來實現VS中的step步:
public class Recipe_Step { public short element1; public short element2; public short element3; public short element4; public short element5; public short element6; public double element7; public double element8; public double element9; public double element10; public double element11; public double element12; public double element13; public bool element14; public bool element15; public short element16; }
1,int--投射成short
2,real-投射成double
3,注意大小是64個字節.我們來計算下我們的類的大小.
public static void demo5() { PlcClassHelper.DisplayObject(new Recipe_Step()); }
結果:
Recipe_Step : ConsoleApp1.PlcClass.Recipe_Step Size:44 Class of Recipe_Step Int16 : 0 Size:2 Int16 : 0 Size:2 Int16 : 0 Size:2 Int16 : 0 Size:2 Int16 : 0 Size:2 Int16 : 0 Size:2 Double : 0 Size:4 Double : 0 Size:4 Double : 0 Size:4 Double : 0 Size:4 Double : 0 Size:4 Double : 0 Size:4 Double : 0 Size:4 Boolean : False Size:2 Boolean : False Size:2 Int16 : 0 Size:2
OK.
然后再測試下Recipe1:
public class Recipe { public static Recipe StaticInstance=new Recipe(); public PlcString Recipe_Name = new PlcString(20, ""); public Recipe_Step[] Recipe_Steps = new Recipe_Step[30]; private Recipe() { for(var i = 0; i < Recipe_Steps.Length; i++) { Recipe_Steps[i] = new Recipe_Step(); } } }
這是PLC數據塊(非優化)編譯好的
這是我測試的:
Recipe : ConsoleApp1.PlcClass.Recipe Size:1342
Class of Recipe
PlcString : String = Bytes = : 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Size:22
Array of ConsoleApp1.PlcClass.Recipe_Step[] :
Recipe_Step : ConsoleApp1.PlcClass.Recipe_Step Size:44
Class of Recipe_Step
Int16 : 0 Size:2
Int16 : 0 Size:2
Int16 : 0 Size:2
Int16 : 0 Size:2
Int16 : 0 Size:2
Int16 : 0 Size:2
Double : 0 Size:4
Double : 0 Size:4
Double : 0 Size:4
Double : 0 Size:4
Double : 0 Size:4
Double : 0 Size:4
Double : 0 Size:4
Boolean : False Size:2
Boolean : False Size:2
Int16 : 0 Size:2
Recipe_Step : ConsoleApp1.PlcClass.Recipe_Step Size:44
完全正確.下面設定下一些數據並且從PLC的讀取:
10.5 設置PLC數據
10.6 從PLC讀取數據:
完全一致:
10.7 將數據寫入PLC:
public static void demo6() { Recipe curRecipe = Recipe.StaticInstance;//引用配方 Recipe.Initial(); short t = 0; foreach(var step in curRecipe.Recipe_Steps) { step.element1 = t++; step.element16 = t++; } Plc plc = new Plc(CpuType.S71200, "192.168.3.62", 0, 1); try { plc.Open(); plc.WriteBytes(DataType.DataBlock, 1, 0, PlcClass.ToBytes(curRecipe)); PlcClassHelper.DisplayObject(curRecipe); } catch (PlcException e) { Console.WriteLine("Exception'Message is {0},Exception's Errcode is {1}", e.Message, e.ErrorCode.ToString()); } finally { plc.Close(); } }
上面的Initial是將staticInstance實列給初始化了.
查看結果: PLC
查看結果:VS

















