diff --git a/CMS_CORE_Library/NcThermo.cs b/CMS_CORE_Library/NcThermo.cs index 4d523d3..fa58356 100644 --- a/CMS_CORE_Library/NcThermo.cs +++ b/CMS_CORE_Library/NcThermo.cs @@ -620,6 +620,27 @@ namespace CMS_CORE_Library #region THERMO high level data + /// + /// Process Status/command words + /// + /// + public abstract CmsError PLC_RStatusCommand(ref List statusCmd); + /// + /// Process conf request for RISK data + /// + /// + public abstract CmsError PLC_WAckConfRiskRequest(); + /// + /// Process conf request for RECIPE data + /// + /// + public abstract CmsError PLC_WAckConfRecipeRequest(); + /// + /// Process production info update + /// + /// + 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 756ecdd..9ea14c9 100644 --- a/CMS_CORE_Library/S7Net/Nc_S7Net.cs +++ b/CMS_CORE_Library/S7Net/Nc_S7Net.cs @@ -515,10 +515,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 +1171,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,7 +1216,75 @@ 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 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 strobe is down and ack is up + if (readValue) + { + // 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); @@ -1262,6 +1337,56 @@ 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; + + // aspetto 100ms + Thread.Sleep(100); + + CmsError cmsError; + do + { + // Check Strobe + cmsError = MEM_RWBoolean(R, 0, memType, TABLE, strobeByte, bitId, ref readValue); + if (cmsError.IsError()) + return cmsError; + + // If false reset ACK + if (readValue == false) + { + // 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 (forced) + writeValue = false; + 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 +1930,70 @@ namespace CMS_CORE_Library.S7Net #region THERMO high level data + + /// + /// Read Status/command words + /// + /// + public override CmsError PLC_RStatusCommand(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_WAckConfRiskRequest() + { + CmsError cmsError = NO_ERROR; + + // Call ack for config request RISK + cmsError = PLC_WAck(REQ_CONF_ACK, REQ_CONF_STROBE, 8); + if (cmsError.IsError()) + return cmsError; + + 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_STROBE, 9); + if (cmsError.IsError()) + return cmsError; + + return cmsError; + } + /// + /// Process production info update + /// + /// + 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; +#endif + + return cmsError; + } + /// /// read current recipe parameter list /// @@ -2033,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 { @@ -2045,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 - { - } + { } } } } @@ -3175,7 +3368,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 +4928,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 +4962,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);