From 614e21af78a6eca808ad32ea6d41e5c65599e9cc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 11 Jun 2020 19:45:20 +0200 Subject: [PATCH] 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);