From 614e21af78a6eca808ad32ea6d41e5c65599e9cc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 11 Jun 2020 19:45:20 +0200 Subject: [PATCH 1/4] added method for ack to PLC + conf write on request --- CMS_CORE_Library/NcThermo.cs | 16 +++ CMS_CORE_Library/S7Net/Nc_S7Net.cs | 179 ++++++++++++++++++++++++++++- 2 files changed, 189 insertions(+), 6 deletions(-) diff --git a/CMS_CORE_Library/NcThermo.cs b/CMS_CORE_Library/NcThermo.cs index 4d523d3..f56ed94 100644 --- a/CMS_CORE_Library/NcThermo.cs +++ b/CMS_CORE_Library/NcThermo.cs @@ -620,6 +620,22 @@ namespace CMS_CORE_Library #region THERMO high level data + /// + /// Process Status/command words + /// + /// + public abstract CmsError PLC_RManageStatusCommand(ref List statusCmd); + /// + /// Process conf request + /// + /// + public abstract CmsError PLC_WManageConfRequest(); + /// + /// Process production info update + /// + /// + public abstract CmsError PLC_WManageProdUpdate(); + /// /// Get current recipe parameter list /// diff --git a/CMS_CORE_Library/S7Net/Nc_S7Net.cs b/CMS_CORE_Library/S7Net/Nc_S7Net.cs index 756ecdd..9a47e63 100644 --- a/CMS_CORE_Library/S7Net/Nc_S7Net.cs +++ b/CMS_CORE_Library/S7Net/Nc_S7Net.cs @@ -64,6 +64,14 @@ namespace CMS_CORE_Library.S7Net private static ThermoModels.ProdInfoModel ThermoProdInfo; private static ThermoModels.ProdCycleModel ThermoProdCycle; + // variabili delle richieste da PLC + private static bool ThermoReqConfWarmerStr; + private static bool ThermoReqConfWarmerAck; + private static bool ThermoReqConfRecipeStr; + private static bool ThermoReqConfRecipeAck; + private static bool ThermoProdUpdatedStr; + private static bool ThermoProdUpdatedAck; + // connessione S7 private CpuType tipoCpu = CpuType.S71500; private short rack = 0; @@ -515,10 +523,11 @@ namespace CMS_CORE_Library.S7Net if (plcWatchdog) return PLC_NOT_RUNNING_ERROR; - + // tira su il bit... plcWatchdog = true; return MEM_RWBoolean(W, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog); } + /// /// Active message list /// @@ -1170,7 +1179,13 @@ namespace CMS_CORE_Library.S7Net { return FUNCTION_NOT_ALLOWED_ERROR; } - + /// + /// Write strobe and manage ack from PLC + /// + /// + /// + /// + /// private CmsError PLC_WStrobe(MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id) { CmsError cmsError; @@ -1209,6 +1224,52 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } + /// + /// Write ack for strobe received from PLC + /// + /// + /// + /// + /// + private CmsError PLC_WAck(MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id) + { + CmsError cmsError; + bool readValue = false; + bool writeValue = true; + + SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId); + + // Check Strobe + cmsError = MEM_RWBoolean(R, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue); + if (cmsError.IsError()) + return cmsError; + + // If PLC it's performing another request then return + if (readValue) + return NO_ERROR; + + // Check ACK + cmsError = MEM_RWBoolean(R, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref readValue); + if (cmsError.IsError()) + return cmsError; + + // If PLC it's performing another request then return + if (readValue) + return NO_ERROR; + + // Write ACK into memory + cmsError = MEM_RWBoolean(W, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref writeValue); + if (cmsError.IsError()) + return cmsError; + + // Reset wait ack = 1 and reset the strobe + cmsError = ResetAck(alarmBitId, strobeByte, ackByte, ackCell.MemType); + if (cmsError.IsError()) + return cmsError; + + + return NO_ERROR; + } private void SetupAckStrobeAddresses(int ackAddress, int strobeAddress, uint id, out int ackByte, out int strobeByte, out int bit) { @@ -1262,6 +1323,51 @@ namespace CMS_CORE_Library.S7Net return cmsError; } + private CmsError ResetAck(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType) + { + int n = 600; + bool readValue = false; + bool writeValue = false; + bool ok = false; + + CmsError cmsError; + do + { + // Check Strobe + cmsError = MEM_RWBoolean(R, 0, memType, TABLE, strobeByte, bitId, ref readValue); + if (cmsError.IsError()) + return cmsError; + + // If true reset ACK + if (readValue == true) + { + // Reset strobe + cmsError = MEM_RWBoolean(W, 0, memType, TABLE, ackByte, bitId, ref writeValue); + if (cmsError.IsError()) + return cmsError; + // Exit from cycle + n = 0; + ok = true; + } + else + { + // Decrement + n--; + // Wait befor next cycle + Thread.Sleep(20); + } + } while (n > 0); + + if (!ok) + { + // Reset ack + cmsError = MEM_RWBoolean(W, 0, memType, TABLE, ackByte, bitId, ref writeValue); + if (cmsError.IsError()) + return cmsError; + } + + return cmsError; + } private CmsError PLC_ManageActiveAck(int strobeByte, int strobeSubByte, int strobeBit, int ackByte, int ackSubByte, int ackBit, MEMORY_TYPE memType) { @@ -1805,6 +1911,58 @@ namespace CMS_CORE_Library.S7Net #region THERMO high level data + + /// + /// Process Status/command words + /// + /// + public override CmsError PLC_RManageStatusCommand(ref List statusCmd) + { + CmsError cmsError = NO_ERROR; + // leggo intera area DWORD e di conseguenza processo... + statusCmd = new List(); + cmsError = MEM_RWWordList(R, 0, STATUS_CMD_DATA.MemType, STATUS_CMD_DATA.Address, STATUS_CMD_DATA.SubAddress, STATUS_CMD_DATA.Size, ref statusCmd); + if (cmsError.IsError()) + return cmsError; + + return cmsError; + } + /// + /// Process conf request + /// + /// + public override CmsError PLC_WManageConfRequest() + { + CmsError cmsError = NO_ERROR; + + // Call ack for config request: warm + cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_ACK, 8); + if (cmsError.IsError()) + return cmsError; + + // Call ack for config request: recipe + cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_ACK, 9); + if (cmsError.IsError()) + return cmsError; + + return cmsError; + } + /// + /// Process production info update + /// + /// + public override CmsError PLC_WManageProdUpdate() + { + CmsError cmsError = NO_ERROR; + + // Call ack for prod update + cmsError = PLC_WAck(PROD_UPD_STROBE, PROD_UPD_ACK, 4); + if (cmsError.IsError()) + return cmsError; + + return cmsError; + } + /// /// read current recipe parameter list /// @@ -3175,7 +3333,7 @@ namespace CMS_CORE_Library.S7Net CmsError cmsError = MEM_RWWordList(bWrite, Process, MemType, MemTable, MemIndex, 2, ref ListValue); if (cmsError.IsError()) return cmsError; - if(ListValue.Count>0) + if (ListValue.Count > 0) Value = ListValue.First(); return NO_ERROR; @@ -4735,6 +4893,12 @@ namespace CMS_CORE_Library.S7Net internal static MEMORY_CELL PARAMETER_EDIT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); internal static MEMORY_CELL PARAMETER_EDIT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); + // strobe received from PLC + internal static MEMORY_CELL REQ_CONF_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); + internal static MEMORY_CELL REQ_CONF_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); + internal static MEMORY_CELL PROD_UPD_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); + internal static MEMORY_CELL PROD_UPD_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); + // aree Moduli internal static MEMORY_CELL MODULE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 602, 18, 2304); internal static MEMORY_CELL MODULE_RT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 603, 12, 1536); @@ -4763,10 +4927,13 @@ namespace CMS_CORE_Library.S7Net // generic machine gauge data internal static MEMORY_CELL MACHINE_GAUGE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 6, 16); - - + // watchdog internal static MEMORY_CELL NC_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 1); - internal static MEMORY_CELL ACTIVE_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 1); + + // status/command data + internal static MEMORY_CELL STATUS_CMD_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 4); + + internal static MEMORY_CELL ACTIVE_CLIENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4, 1); From 03b108dac85a7d3548408c663e6f503276b9dd66 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 12 Jun 2020 11:38:13 +0200 Subject: [PATCH 2/4] Update method for ack/strobe on status/command --- CMS_CORE_Library/NcThermo.cs | 13 ++++++++---- CMS_CORE_Library/S7Net/Nc_S7Net.cs | 34 +++++++++++++++++------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/CMS_CORE_Library/NcThermo.cs b/CMS_CORE_Library/NcThermo.cs index f56ed94..fa58356 100644 --- a/CMS_CORE_Library/NcThermo.cs +++ b/CMS_CORE_Library/NcThermo.cs @@ -624,17 +624,22 @@ namespace CMS_CORE_Library /// Process Status/command words /// /// - public abstract CmsError PLC_RManageStatusCommand(ref List statusCmd); + public abstract CmsError PLC_RStatusCommand(ref List statusCmd); /// - /// Process conf request + /// Process conf request for RISK data /// /// - public abstract CmsError PLC_WManageConfRequest(); + public abstract CmsError PLC_WAckConfRiskRequest(); + /// + /// Process conf request for RECIPE data + /// + /// + public abstract CmsError PLC_WAckConfRecipeRequest(); /// /// Process production info update /// /// - public abstract CmsError PLC_WManageProdUpdate(); + public abstract CmsError PLC_WAckProdUpdate(); /// /// Get current recipe parameter list diff --git a/CMS_CORE_Library/S7Net/Nc_S7Net.cs b/CMS_CORE_Library/S7Net/Nc_S7Net.cs index 9a47e63..a5a7674 100644 --- a/CMS_CORE_Library/S7Net/Nc_S7Net.cs +++ b/CMS_CORE_Library/S7Net/Nc_S7Net.cs @@ -64,14 +64,6 @@ namespace CMS_CORE_Library.S7Net private static ThermoModels.ProdInfoModel ThermoProdInfo; private static ThermoModels.ProdCycleModel ThermoProdCycle; - // variabili delle richieste da PLC - private static bool ThermoReqConfWarmerStr; - private static bool ThermoReqConfWarmerAck; - private static bool ThermoReqConfRecipeStr; - private static bool ThermoReqConfRecipeAck; - private static bool ThermoProdUpdatedStr; - private static bool ThermoProdUpdatedAck; - // connessione S7 private CpuType tipoCpu = CpuType.S71500; private short rack = 0; @@ -1913,10 +1905,10 @@ namespace CMS_CORE_Library.S7Net /// - /// Process Status/command words + /// Read Status/command words /// /// - public override CmsError PLC_RManageStatusCommand(ref List statusCmd) + public override CmsError PLC_RStatusCommand(ref List statusCmd) { CmsError cmsError = NO_ERROR; // leggo intera area DWORD e di conseguenza processo... @@ -1931,16 +1923,26 @@ namespace CMS_CORE_Library.S7Net /// Process conf request /// /// - public override CmsError PLC_WManageConfRequest() + public override CmsError PLC_WAckConfRiskRequest() { CmsError cmsError = NO_ERROR; - // Call ack for config request: warm + // Call ack for config request RISK cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_ACK, 8); if (cmsError.IsError()) return cmsError; - // Call ack for config request: recipe + return cmsError; + } + /// + /// Process conf request + /// + /// + public override CmsError PLC_WAckConfRecipeRequest() + { + CmsError cmsError = NO_ERROR; + + // Call ack for config request RECIPE cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_ACK, 9); if (cmsError.IsError()) return cmsError; @@ -1951,14 +1953,16 @@ namespace CMS_CORE_Library.S7Net /// Process production info update /// /// - public override CmsError PLC_WManageProdUpdate() + public override CmsError PLC_WAckProdUpdate() { CmsError cmsError = NO_ERROR; +#if false // Call ack for prod update cmsError = PLC_WAck(PROD_UPD_STROBE, PROD_UPD_ACK, 4); if (cmsError.IsError()) - return cmsError; + return cmsError; +#endif return cmsError; } From 642b22c76d46799d27001ab42a6e837608d7f903 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 12 Jun 2020 15:06:49 +0200 Subject: [PATCH 3/4] fixed and tested ACK to PLC (window response time) --- CMS_CORE_Library/S7Net/Nc_S7Net.cs | 67 +++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/CMS_CORE_Library/S7Net/Nc_S7Net.cs b/CMS_CORE_Library/S7Net/Nc_S7Net.cs index a5a7674..af6fabf 100644 --- a/CMS_CORE_Library/S7Net/Nc_S7Net.cs +++ b/CMS_CORE_Library/S7Net/Nc_S7Net.cs @@ -1236,33 +1236,55 @@ namespace CMS_CORE_Library.S7Net if (cmsError.IsError()) return cmsError; - // If PLC it's performing another request then return + // if there's a strobe --> give ack!!! if (readValue) + { + // abbasso ack se fosse su... + cmsError = MEM_RWBoolean(W, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref writeValue); + if (cmsError.IsError()) + return cmsError; + + // attendo 50ms... + Thread.Sleep(50); + + // Reset wait ack = 1 and reset the strobe + cmsError = ResetAck(alarmBitId, strobeByte, ackByte, ackCell.MemType); + if (cmsError.IsError()) + return cmsError; + + // exit and next round will continue... return NO_ERROR; + } + +#if false + // no strobe.... // Check ACK cmsError = MEM_RWBoolean(R, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref readValue); if (cmsError.IsError()) return cmsError; - // If PLC it's performing another request then return + // if strobe is down and ack is up if (readValue) - return NO_ERROR; - - // Write ACK into memory - cmsError = MEM_RWBoolean(W, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref writeValue); - if (cmsError.IsError()) - return cmsError; - - // Reset wait ack = 1 and reset the strobe - cmsError = ResetAck(alarmBitId, strobeByte, ackByte, ackCell.MemType); - if (cmsError.IsError()) - return cmsError; - + { + // Reset wait ack = 1 and reset the strobe + cmsError = ResetAck(alarmBitId, strobeByte, ackByte, ackCell.MemType); + if (cmsError.IsError()) + return cmsError; + } +#endif return NO_ERROR; } - + /// + /// Setup memory for ack/strobe processing + /// + /// + /// + /// + /// + /// + /// 1..8 private void SetupAckStrobeAddresses(int ackAddress, int strobeAddress, uint id, out int ackByte, out int strobeByte, out int bit) { ackByte = ackAddress + (((int)id - 1) / 8); @@ -1322,6 +1344,9 @@ namespace CMS_CORE_Library.S7Net bool writeValue = false; bool ok = false; + // aspetto 100ms + Thread.Sleep(100); + CmsError cmsError; do { @@ -1330,8 +1355,8 @@ namespace CMS_CORE_Library.S7Net if (cmsError.IsError()) return cmsError; - // If true reset ACK - if (readValue == true) + // If false reset ACK + if (readValue == false) { // Reset strobe cmsError = MEM_RWBoolean(W, 0, memType, TABLE, ackByte, bitId, ref writeValue); @@ -1350,9 +1375,11 @@ namespace CMS_CORE_Library.S7Net } } while (n > 0); + if (!ok) { - // Reset ack + // Reset ack (forced) + writeValue = false; cmsError = MEM_RWBoolean(W, 0, memType, TABLE, ackByte, bitId, ref writeValue); if (cmsError.IsError()) return cmsError; @@ -1928,7 +1955,7 @@ namespace CMS_CORE_Library.S7Net CmsError cmsError = NO_ERROR; // Call ack for config request RISK - cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_ACK, 8); + cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_STROBE, 8); if (cmsError.IsError()) return cmsError; @@ -1943,7 +1970,7 @@ namespace CMS_CORE_Library.S7Net CmsError cmsError = NO_ERROR; // Call ack for config request RECIPE - cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_ACK, 9); + cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_STROBE, 9); if (cmsError.IsError()) return cmsError; From 6df07aaf2e3975641b0e814979156d0eb63f9de9 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 12 Jun 2020 16:59:47 +0200 Subject: [PATCH 4/4] fix try/catch data... --- CMS_CORE_Library/S7Net/Nc_S7Net.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/CMS_CORE_Library/S7Net/Nc_S7Net.cs b/CMS_CORE_Library/S7Net/Nc_S7Net.cs index af6fabf..9ea14c9 100644 --- a/CMS_CORE_Library/S7Net/Nc_S7Net.cs +++ b/CMS_CORE_Library/S7Net/Nc_S7Net.cs @@ -1939,7 +1939,7 @@ namespace CMS_CORE_Library.S7Net { CmsError cmsError = NO_ERROR; // leggo intera area DWORD e di conseguenza processo... - statusCmd = new List(); + statusCmd = new List(); cmsError = MEM_RWWordList(R, 0, STATUS_CMD_DATA.MemType, STATUS_CMD_DATA.Address, STATUS_CMD_DATA.SubAddress, STATUS_CMD_DATA.Size, ref statusCmd); if (cmsError.IsError()) return cmsError; @@ -2222,10 +2222,15 @@ namespace CMS_CORE_Library.S7Net // update oggetto thermoParamList... if (ThermoParamList.ContainsKey(currParam.Id)) { - ThermoParamList[currParam.Id].Enabled = currParam.Enabled; - ThermoParamList[currParam.Id].HasError = currParam.HasError; - ThermoParamList[currParam.Id].Visible = currParam.Visible; - ThermoParamList[currParam.Id].ValueAct = currParam.ValueAct; + try + { + ThermoParamList[currParam.Id].Enabled = currParam.Enabled; + ThermoParamList[currParam.Id].HasError = currParam.HasError; + ThermoParamList[currParam.Id].Visible = currParam.Visible; + ThermoParamList[currParam.Id].ValueAct = currParam.ValueAct; + } + catch + { } } else { @@ -2234,8 +2239,7 @@ namespace CMS_CORE_Library.S7Net ThermoParamList.Add(currParam.Id, new ThermoModels.RecipeParam() { Id = currParam.Id, Enabled = currParam.Enabled, HasError = currParam.HasError, Visible = currParam.Visible, ValueAct = currParam.ValueAct }); } catch - { - } + { } } } }