using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using S7.Net; using System.Net.NetworkInformation; using System.Net; using NLog; using System.Diagnostics; namespace Test_S7 { public partial class TestMainForm : Form { #region Private Fields /// /// indica se serva refresh parametri e quindi PLC... /// private bool needRefresh = true; #endregion Private Fields #region Protected Fields /// /// contenuto x log/debug /// protected string contenuto = ""; /// /// Oggetto PLC da ri-utilizzare... /// protected Plc currPLC; /// /// Lungh massima stringhe /// protected int maxStrChar = 20; /// /// parametri di connessione /// protected connParam parametri; /// /// Oggetto cronometro x test vari... /// protected Stopwatch sw = new Stopwatch(); /// /// titolo x log/debug /// protected string titolo = ""; #endregion Protected Fields #region Public Fields /// /// oggetto logging /// public static Logger lg; /// /// Configurazione valori da LEGGERE dal PLC /// public otherData[] memMapR; /// /// Configurazione valori da SCRIVERE nel PLC /// public otherData[] memMapW; /// /// Byte dimensione buffer dati memoria (da file map) /// public int numByte = 0; #endregion Public Fields #region Public Constructors public TestMainForm() { InitializeComponent(); myInit(); } #endregion Public Constructors #region Private Methods private void btnCharWrite_Click(object sender, EventArgs e) { setParamPlc(); eseguiScritturaCharArray(); } private void btnNumWriteB_Click(object sender, EventArgs e) { setParamPlc(); eseguiScritturaByte(); } private void btnNumWriteDW_Click(object sender, EventArgs e) { setParamPlc(); eseguiScritturaDWord(); } private void btnNumWriteReal_Click(object sender, EventArgs e) { setParamPlc(); eseguiScritturaReal(); } private void btnNumWriteW_Click(object sender, EventArgs e) { setParamPlc(); eseguiScritturaWord(); } private void btnReadByte_Click(object sender, EventArgs e) { setParamPlc(); eseguiLetturaByte(); } private void btnReadChar_Click(object sender, EventArgs e) { setParamPlc(); eseguiLetturaCharArray(); } private void btnReadDWord_Click(object sender, EventArgs e) { setParamPlc(); eseguiLetturaDWord(); } /// /// Lettura real /// /// /// private void btnReadReal_Click(object sender, EventArgs e) { setParamPlc(); eseguiLetturaReal(); } private void btnReadString_Click(object sender, EventArgs e) { setParamPlc(); eseguiLetturaString(); } private void btnReadWord_Click(object sender, EventArgs e) { setParamPlc(); eseguiLetturaWord(); } /// /// Scrivo memoria tipo STRING /// /// /// private void btnStrWrite_Click(object sender, EventArgs e) { setParamPlc(); eseguiScritturaString(); } private void cbCpuType_SelectedIndexChanged(object sender, EventArgs e) { needRefresh = true; } /// /// Esecuzione lettura! /// private void eseguiLetturaByte() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtMemArea.Text); int numByte = 1; int.TryParse(txtMemSize.Text, out numByte); Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte); titolo = string.Format("READ BLOCK MEM BYTE: {0} --> {1} byte", txtMemArea.Text, numByte); contenuto = ""; string byteVal = ""; for (int i = 0; i < memByteRead.Length; i++) { byteVal = Convert.ToString(memByteRead[i], 2).PadLeft(8, '0'); contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, memByteRead[i], Environment.NewLine); } showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione lettura tipo Char Array! /// private void eseguiLetturaCharArray() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtMemArea.Text); int numByte = 1; int.TryParse(txtMemSize.Text, out numByte); Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte); titolo = string.Format("READ BLOCK MEM CHAR[]: {0} --> {1} byte", txtMemArea.Text, numByte); contenuto = ""; // poi prendo la stringa... string outVal = ""; for (int i = 0; i < numByte; i++) { outVal += Char.ConvertFromUtf32(memByteRead[i]); } contenuto += string.Format("{0}{1}", outVal, Environment.NewLine); showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione lettura DWORD! /// private void eseguiLetturaDWord() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtMemArea.Text); int numByte = 1; int.TryParse(txtMemSize.Text, out numByte); Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte); titolo = string.Format("READ BLOCK MEM WORD: {0} --> {1} byte", txtMemArea.Text, numByte); contenuto = ""; uint intVal = 0; string byteValA = ""; string byteValB = ""; string byteValC = ""; string byteValD = ""; for (int i = 0; i < memByteRead.Length / 4; i++) { byteValA = Convert.ToString(memByteRead[i * 4], 2).PadLeft(8, '0'); byteValB = Convert.ToString(memByteRead[i * 4 + 1], 2).PadLeft(8, '0'); byteValC = Convert.ToString(memByteRead[i * 4 + 2], 2).PadLeft(8, '0'); byteValD = Convert.ToString(memByteRead[i * 4 + 3], 2).PadLeft(8, '0'); intVal = S7.Net.Types.DWord.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray()); contenuto += string.Format("W{0:000}: {1} | {2}-{3}-{4}-{5}{6}", i, intVal, byteValA, byteValB, byteValC, byteValD, Environment.NewLine); } showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione lettura Real! /// private void eseguiLetturaReal() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtMemArea.Text); int numByte = 1; int.TryParse(txtMemSize.Text, out numByte); Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte); titolo = string.Format("READ BLOCK MEM WORD: {0} --> {1} byte", txtMemArea.Text, numByte); contenuto = ""; double realVal = 0; string byteValA = ""; string byteValB = ""; string byteValC = ""; string byteValD = ""; for (int i = 0; i < memByteRead.Length / 4; i++) { byteValA = Convert.ToString(memByteRead[i * 4], 2).PadLeft(8, '0'); byteValB = Convert.ToString(memByteRead[i * 4 + 1], 2).PadLeft(8, '0'); byteValC = Convert.ToString(memByteRead[i * 4 + 2], 2).PadLeft(8, '0'); byteValD = Convert.ToString(memByteRead[i * 4 + 3], 2).PadLeft(8, '0'); realVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray()); contenuto += string.Format("W{0:000}: {1} | {2}-{3}-{4}-{5}{6}", i, realVal, byteValA, byteValB, byteValC, byteValD, Environment.NewLine); } showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione lettura tipo STRING! /// private void eseguiLetturaString() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtMemArea.Text); int numByte = 1; int.TryParse(txtMemSize.Text, out numByte); Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte); titolo = string.Format("READ BLOCK MEM STRING: {0} --> {1} byte", txtMemArea.Text, numByte); contenuto = ""; string byteVal = ""; // i primi 2 byte sono LUNGHEZZA MAX e lungh effettiva quindi setto il NUM BYTE.... for (int i = 0; i < 2; i++) { byteVal = Convert.ToString(memByteRead[i], 2).PadLeft(8, '0'); contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, memByteRead[i], Environment.NewLine); } // prendo 2° valore (num max valori) numByte = memByteRead[1]; // poi prendo la stringa... string outVal = ""; for (int i = 2; i < numByte + 2; i++) { outVal += Char.ConvertFromUtf32(memByteRead[i]); } contenuto += string.Format("{0}{1}", outVal, Environment.NewLine); showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione lettura WORD! /// private void eseguiLetturaWord() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtMemArea.Text); int numByte = 1; int.TryParse(txtMemSize.Text, out numByte); Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte); titolo = string.Format("READ BLOCK MEM WORD: {0} --> {1} byte", txtMemArea.Text, numByte); contenuto = ""; ushort shortVal = 0; string byteValA = ""; string byteValB = ""; for (int i = 0; i < memByteRead.Length / 2; i++) { byteValA = Convert.ToString(memByteRead[i * 2], 2).PadLeft(8, '0'); byteValB = Convert.ToString(memByteRead[i * 2 + 1], 2).PadLeft(8, '0'); shortVal = S7.Net.Types.Word.FromByteArray(memByteRead.Skip(2 * i).Take(2).ToArray()); contenuto += string.Format("W{0:000}: {1} | {2}-{3}{4}", i, shortVal, byteValA, byteValB, Environment.NewLine); } showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione SCRITTURA Byte! /// private void eseguiScritturaByte() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtWriteAddr1.Text); byte num2write = 0; string val2write = txtWriteVal2.Text; byte.TryParse(txtWriteVal1.Text, out num2write); byte[] DB_Byte = new byte[1]; DB_Byte[0] = num2write; currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, DB_Byte); titolo = string.Format("WRITE BLOCK MEM: {0}", txtWriteAddr1.Text); contenuto = ""; contenuto += string.Format("DT: {0} | DbNum: {1} | indiceMem: {2} | num2write: {3}{4}{4}", DataType.DataBlock, memoria.DbNum, memoria.indiceMem, num2write, Environment.NewLine); string byteVal = ""; for (int i = 0; i < DB_Byte.Length; i++) { byteVal = Convert.ToString(DB_Byte[i], 2).PadLeft(8, '0'); contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, DB_Byte[i], Environment.NewLine); } showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione SCRITTURA Char Array! /// private void eseguiScritturaCharArray() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtWriteAddr2.Text); int num2write = 0; // verifico di no sforare con lunghezza string val2write = txtWriteVal2.Text; // se è maggiore di maxStrChar TRIMMA::: if (val2write.Length > maxStrChar) { val2write = val2write.Substring(0, 20); } // scambio spazi con underscore... e MAIUSCOLO!!! val2write = val2write.Replace(' ', '_').ToUpper(); num2write = val2write.Length; byte[] DB_Byte = new byte[maxStrChar]; // converto 1-1 i char in byte... for (int i = 0; i < num2write; i++) { DB_Byte[i] = (byte)(val2write[i]); } currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, DB_Byte); titolo = string.Format("WRITE BLOCK MEM: {0}", txtWriteAddr1.Text); contenuto = ""; contenuto += string.Format("DT: {0} | DbNum: {1} | indiceMem: {2} | stringa: {3}{4}{4}", DataType.DataBlock, memoria.DbNum, memoria.indiceMem, num2write, Environment.NewLine); showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione SCRITTURA DWORD! /// private void eseguiScritturaDWord() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtWriteAddr1.Text); uint num2write = 0; string val2write = txtWriteVal2.Text; uint.TryParse(txtWriteVal1.Text, out num2write); byte[] DB_Byte = new byte[4]; S7.Net.Types.DWord.ToByteArray(num2write).CopyTo(DB_Byte, 0); currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, DB_Byte); titolo = string.Format("WRITE BLOCK MEM: {0}", txtWriteAddr1.Text); contenuto = ""; contenuto += string.Format("DT: {0} | DbNum: {1} | indiceMem: {2} | num2write: {3}{4}{4}", DataType.DataBlock, memoria.DbNum, memoria.indiceMem, num2write, Environment.NewLine); string byteVal = ""; for (int i = 0; i < DB_Byte.Length; i++) { byteVal = Convert.ToString(DB_Byte[i], 2).PadLeft(8, '0'); contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, DB_Byte[i], Environment.NewLine); } showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } private void eseguiScritturaReal() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtWriteAddr1.Text); double num2write = 0; double.TryParse(txtWriteVal1.Text.Replace(".", ","), out num2write); byte[] DB_Byte = new byte[4]; S7.Net.Types.Double.ToByteArray(num2write).CopyTo(DB_Byte, 0); currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, DB_Byte); titolo = string.Format("WRITE BLOCK MEM: {0}", txtWriteAddr1.Text); contenuto = ""; contenuto += string.Format("DT: {0} | DbNum: {1} | indiceMem: {2} | num2write: {3}{4}{4}", DataType.DataBlock, memoria.DbNum, memoria.indiceMem, num2write, Environment.NewLine); string byteVal = ""; for (int i = 0; i < DB_Byte.Length; i++) { byteVal = Convert.ToString(DB_Byte[i], 2).PadLeft(8, '0'); contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, DB_Byte[i], Environment.NewLine); } showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione SCRITTURA String! /// private void eseguiScritturaString() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtWriteAddr2.Text); int num2write = 0; // verifico di non sforare con lunghezza string val2write = txtWriteVal2.Text; // se è maggiore di maxStrChar TRIMMA::: if (val2write.Length > maxStrChar) { val2write = val2write.Substring(0, 20); } // scambio spazi con underscore... e MAIUSCOLO!!! val2write = val2write.Replace(' ', '_').ToUpper(); num2write = val2write.Length; byte[] DB_Byte = new byte[maxStrChar + 2]; // primi 2 byte sono 20 (fix) e lung effettiva... DB_Byte[0] = 20; DB_Byte[1] = (byte)num2write; // converto 1-1 i char in byte... for (int i = 0; i < num2write; i++) { DB_Byte[2 + i] = (byte)(val2write[i]); } currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, DB_Byte); titolo = string.Format("WRITE BLOCK MEM: {0}", txtWriteAddr1.Text); contenuto = ""; contenuto += string.Format("DT: {0} | DbNum: {1} | indiceMem: {2} | stringa: {3}{4}{4}", DataType.DataBlock, memoria.DbNum, memoria.indiceMem, num2write, Environment.NewLine); showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Esecuzione SCRITTURA WORD! /// private void eseguiScritturaWord() { sw.Restart(); if (testCncConn()) { // decodifico memoria... memAddress memoria = new memAddress(txtWriteAddr1.Text); UInt16 num2write = 0; string val2write = txtWriteVal2.Text; UInt16.TryParse(txtWriteVal1.Text, out num2write); byte[] DB_Byte = new byte[2]; S7.Net.Types.Word.ToByteArray(num2write).CopyTo(DB_Byte, 0); currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, DB_Byte); titolo = string.Format("WRITE BLOCK MEM: {0}", txtWriteAddr1.Text); contenuto = ""; contenuto += string.Format("DT: {0} | DbNum: {1} | indiceMem: {2} | num2write: {3}{4}{4}", DataType.DataBlock, memoria.DbNum, memoria.indiceMem, num2write, Environment.NewLine); string byteVal = ""; for (int i = 0; i < DB_Byte.Length; i++) { byteVal = Convert.ToString(DB_Byte[i], 2).PadLeft(8, '0'); contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, DB_Byte[i], Environment.NewLine); } showOut(titolo, contenuto); } sw.Stop(); tslRTime.Text = string.Format("{0}", sw.Elapsed); } /// /// Caricamento conf memoria DB del SIEMENS /// private void loadMemConf() { // carico conf memoria utils.loadConfFile(ref memMapR, filePath("MMapR"), 1, ref numByte); utils.loadConfFile(ref memMapW, filePath("MMapW"), 1, ref numByte); } /// /// inizializzo /// private void myInit() { lg = LogManager.GetCurrentClassLogger(); // inizializzo parametri... parametri = new connParam() { ipAdrr = "127.0.0.1", tipoCpu = CpuType.S7200, slot = 0, rack = 0 }; setParamPlc(); } /// /// Imposto parametri PLC /// private void setParamPlc() { txtOut.Text = ""; // SE è necessario refresh... if (needRefresh) { lg.Info("Refreshing connection..."); try { short.TryParse(txtSlot.Text, out parametri.slot); short.TryParse(txtRack.Text, out parametri.rack); parametri.tipoCpu = (CpuType)Enum.Parse(typeof(CpuType), cbCpuType.SelectedItem.ToString()); parametri.ipAdrr = txtIP.Text.Trim(); titolo = "PARAM PLC (pre connect)"; lg.Info(titolo); contenuto = string.Format("IP: {0}{1}", parametri.ipAdrr, Environment.NewLine); contenuto += string.Format("CPU: {0}{1}", parametri.tipoCpu, Environment.NewLine); contenuto += string.Format("RACK: {0}{1}", parametri.rack, Environment.NewLine); contenuto += string.Format("SLOT: {0}", parametri.slot, Environment.NewLine); } catch (Exception exc) { lg.Error(exc, "Errore in parse parametri"); } // ora tento avvio PLC... SE PING OK... if (testPing() == IPStatus.Success) { try { currPLC = new Plc(parametri.tipoCpu, parametri.ipAdrr, parametri.rack, parametri.slot); currPLC.Open(); if (currPLC.IsConnected) { titolo = "CONNESSIONE AVVENUTA"; } else { titolo = "Impossibile connettersi al PLC"; } lg.Info(titolo); } catch (Exception exc) { lg.Error(exc, "Errore in INIT PLC"); } needRefresh = false; } // carico conf vettore memoria... loadMemConf(); lg.Info("Eseguito loadMemConf"); // mostra output showOut(titolo, contenuto); } } /// /// Test connessione CNC /// /// private bool testCncConn() { bool answ = false; IPStatus pingStatus = testPing(); // se passa il ping faccio il resto... if (pingStatus != IPStatus.Success) { titolo = "Errore ping"; contenuto = string.Format("Reply Status per {0}: {1}", parametri.ipAdrr, pingStatus); showOut(titolo, contenuto); } else { if (!currPLC.IsConnected) currPLC.Open(); if (!currPLC.IsAvailable) { titolo = "Errore Disponibilità"; contenuto = string.Format("{0} | {1}", currPLC.LastErrorCode, currPLC.LastErrorString); currPLC.ClearLastError(); showOut(titolo, contenuto); } else { if (!currPLC.IsConnected) { titolo = "Errore connessione"; contenuto = string.Format("{0} | {1}", currPLC.LastErrorCode, currPLC.LastErrorString); currPLC.ClearLastError(); showOut(titolo, contenuto); tslConn.Text = "NO Connection"; } else { tslConn.Text = "Connection OK"; answ = true; } } } return answ; } /// /// test ping all'indirizzo impostato nei parametri /// /// private IPStatus testPing() { IPStatus answ = IPStatus.Unknown; ; IPAddress address; PingReply reply; Ping pingSender = new Ping(); address = IPAddress.Loopback; IPAddress.TryParse(parametri.ipAdrr, out address); reply = pingSender.Send(address, 100); answ = reply.Status; return answ; } private void txtIP_TextChanged(object sender, EventArgs e) { needRefresh = true; } private void txtMemArea_TextChanged(object sender, EventArgs e) { needRefresh = true; } private void txtMemSize_TextChanged(object sender, EventArgs e) { needRefresh = true; } private void txtRack_TextChanged(object sender, EventArgs e) { needRefresh = true; } private void txtSlot_TextChanged(object sender, EventArgs e) { needRefresh = true; } #endregion Private Methods #region Protected Methods /// /// Restituisce path completo file da chaive configurazione /// /// chaive conf x file richiesto /// protected string filePath(string keyFile) { return string.Format(@"{0}\{1}", utils.confDir, utils.CRS(keyFile)); } protected void showOut(string title, string content) { string outText = ""; // a video outText += string.Format("{0}--------------------------------------------------------------------------------------{0}", Environment.NewLine); outText += string.Format("- {0}{1}", title, Environment.NewLine); outText += string.Format("--------------------------------------------------------------------------------------{0}", Environment.NewLine); outText += string.Format("{0}{1}", content, Environment.NewLine); outText += string.Format("--------------------------------------------------------------------------------------{0}{0}", Environment.NewLine); // aggiorno visualizzazione txtOut.Text += outText; // loggo! lg.Info(outText); } #endregion Protected Methods #region Public Methods /// /// formatta un numero in forma binaria 0/1 a 32 bit (4 byte) /// /// /// public static string binaryForm(int valore) { string answ = ""; try { answ = string.Format(new BinaryFormatter(), "{0:B}", valore); } catch { } return answ; } #endregion Public Methods } }