FORUM CTRLX AUTOMATION
ctrlX World Partner Apps for ctrlX AUTOMATION
Dear Community User! We are updating our platform to a new
system.
Read more: Important
information on the platform change.
09-09-2022 02:18 PM - edited 09-09-2022 02:19 PM
I already checked the examples described in the forum.
But all examples described here, have methods, which returns a "pointer to real" or "pointer to string", ... so an easy datatype.
My task is, to read the pending diagnostic and in this case, the method returns an object "pointer to DiagnosticInformation from the table"
And I don´t know, how to get access to this returned table. I have no chance to the information to the returned diagnostic string.
Here´s my example:
Declaration:
PROGRAM PLC_PRG2
VAR
strMyInstancename : STRING := 'MyInstance';
bRead: BOOL;
bExecute: BOOL;
strNodePath: STRING(255) := 'diagnosis/get/actual/log';
fbDL_ReadNodeValue: DL_ReadNodeValue;
DataRead: CXA_Datalayer.DL_NodeValue;
fbDiagInfo : CXA_AutomationCore_fbs.common_log_diagnosis_fbs_DiagnosisIdentificationWithTimestamp;
pendingDiag: CXA_AutomationCore_fbs.common_log_diagnosis_fbs_DiagnosisIdentification;
strTimeStamp: STRING;
pendingDiag2: POINTER TO CXA_AutomationCore_fbs.common_log_diagnosis_fbs_DiagnosisIdentification;
END_VAR
Implementation:
IF bRead THEN
bRead := FALSE;
bExecute := TRUE;
END_IF
IF fbDL_ReadNodeValue.Done THEN
fbDiagInfo.getRootAsDiagnosisIdentificationWithTimestamp(data:= DataRead.GetData(), size:= DataRead.GetSize());
pendingDiag2 := fbDiagInfo.getDiagnosisIdentification();
pendingDiag := pendingDiag2^;
strTimeStamp := fbDiagInfo.getTimestamp();
bExecute := FALSE;
END_IF
fbDL_ReadNodeValue(
Execute:= bExecute, ClientId:= , NodeName:= strNodePath, NodeValue:= DataRead);
I get access to the Pointer, but I don´t know, how to get access to special content of this table:
What can i do to see the actual diagnostic?
Solved! Go to Solution.
09-12-2022 08:58 AM
I´ve got in on my own.
You have to extend the code with:
myDiagnosisNumber := pendingDiag.getMainDiagnosisNumber();
myDetailDiagnosis := pendingDiag.getDetailedDiagnosisNumber();
myDiagTimestamp := fbDiagInfo.getTimestamp();
You have to use the pointer you return from method fbDiagInfo.getDiagnosisIndentification() to call additional methods.
For example "pendingDiag.getMainDiagnosisNumber()" to get the diagnosis number.
09-13-2022 10:34 AM - edited 09-26-2022 02:58 PM
See also here an example, how to read out the list of all pending diagnostics using CXA_Autiomationcore_fbs at least version 1.14.0.1 and CXA_Datalayer:
Declaration:
PROGRAM common_log_diagnosis_fbs_DiagnosisIdentificationWithTimestamp
VAR
//fbs_DiagnosisIdentification: common_log_diagnosis_fbs_DiagnosisIdentification;
fbs_ErrorList: common_log_diagnosis_fbs_ListDiagnosisIdentificationWithTimestamp;
fbs_ErrorWithTimestamp: CXA_AutomationCore_fbs.common_log_diagnosis_fbs_DiagnosisIdentificationWithTimestamp;
fbs_DL_ReadNodeValue: DL_ReadNodeValue;
pDiagnosisTable: POINTER TO CXA_AutomationCore_fbs.common_log_diagnosis_fbs_DiagnosisIdentification;
bExecute: BOOL;
bDone: BOOL;
bActive: BOOL;
bError: BOOL;
ErrorID: CXA_Datalayer.ERROR_CODE;
ErrorIdent: CXA_Datalayer.ERROR_STRUCT;
NodePath: STRING(255) := 'diagnosis/get/actual/list';
DataRead: CXA_Datalayer.DL_NodeValue;
fb_R_TRIG: R_TRIG;
udiErrorListLength: UDINT;
i: INT;
arstrTimestamps: ARRAY[0..100] OF STRING;
arstrMainDiagnosisNumber: ARRAY[0..100] OF STRING;
arstrDetailedDiagnosisNumber: ARRAY[0..100] OF STRING;
arstrEntity: ARRAY[0..100] OF STRING;
END_VAR
Implementation:
fbs_DL_ReadNodeValue(
Execute:= bExecute,
Done=> bDone,
Active=> bActive,
Error=> bError,
ErrorID=> ErrorID,
ErrorIdent=> ErrorIdent,
ClientId:= ,
NodeName:= NodePath,
NodeValue:= DataRead);
fb_R_TRIG(CLK:= bDone, Q=> );
IF fb_R_TRIG.Q THEN
bExecute := FALSE;
fbs_ErrorList.getRootAsListDiagnosisIdentificationWithTimestamp(data:= DataRead.GetData(), size:= DataRead.GetSize());
udiErrorListLength := fbs_ErrorList.getListDiagnosisIdentificationWithTimestampLength();
FOR i := 0 TO TO_INT(udiErrorListLength)-1 BY 1 DO
fbs_ErrorList.getListDiagnosisIdentificationWithTimestamp(i,ADR(fbs_ErrorWithTimestamp));
arstrTimestamps[i] := fbs_ErrorWithTimestamp.getTimestamp();
pDiagnosisTable := fbs_ErrorWithTimestamp.getDiagnosisIdentification();
arstrMainDiagnosisNumber[i] := pDiagnosisTable^.getMainDiagnosisNumber();
arstrDetailedDiagnosisNumber[i] := pDiagnosisTable^.getDetailedDiagnosisNumber();
arstrEntity[i] := pDiagnosisTable^.getEntity();
END_FOR
END_IF
09-26-2022 02:32 PM
In CodeShepherds code
fbs_ErrorList.getListDiagnosisIdentificationWithTimestamp(i,ADR(fbs_ErrorWithTimestamp));
should be
fbs_ErrorWithTimestamp := fbs_ErrorList.getListDiagnosisIdentificationWithTimestamp(i)^;
?
09-26-2022 02:58 PM - edited 09-26-2022 02:58 PM
No, the line in my code is correct. Please see the library version I mentioned above. The "old" interface you are referring to, will not work.
10-23-2023 07:56 AM
See topic "Recommended method to identify new diagnostic error/warning?" for new information using library CXAC_Diagnostics.