6/26/2012 3:44 PM | |
Joined: 1/17/2007 Last visit: 12/6/2023 Posts: 1527 Rating:
|
Ok I have had a second go at it. It is not possible to work out the UDT size directly from the DB, but you can from a local copy of the UDT. This is OK as you will need to have a local UDT var anyhow as you need to copy the DB data over to it for testing the ID. The block is called with the DB_PTR input set to point at the array of structures in the DB (DBn.ArrayName) and the SRC_ID set to the ID you want to find. This is shown in the image PtrTestFBRuntime.jpg. The DB structure is shown in the image PtrTestDBDeclaration.jpg. The DB test data is shown in the image PtrTestDBRuntime.jpg. Here is the new code. [code] TYPE UDT995 // Your structure STRUCT ID : INT; MOTOR_SP : REAL; FAN_ON : BOOL; END_STRUCT END_TYPE FUNCTION_BLOCK FB995 TITLE = 'ANY Pointer Test' AUTHOR : Smiffy VAR_INPUT SRC_ID : INT; // ID to search for DB_PTR : ANY; // Pointer to array within DB (DBn.ArrayName) END_VAR VAR_OUTPUT DATA : UDT995; // Local UDT definition for calculating the UDT size (could be in TEMP or VAR section if required) END_VAR VAR_TEMP pArr : ANY; // Input variable ANY pointer - used for accessing variable data and type pAnyArr AT pArr : STRUCT // Diassembled ANY pointer structure S7Code : BYTE; // Code for S7 DataType : BYTE; // Code for data type Length : INT; // Repetition factor = Send/receive length DBNumber : INT; // Data block Number MemoryArea : BYTE; // Specified memory area ByteAddressMSB : BYTE; // Byte address most significant bits ByteAddressLSB : WORD; // Byte address least significant bits END_STRUCT; END_VAR VAR RetVal : INT; ArraySize : INT; // Size of UDT in bytes NumElements : INT; // Number of array elements in the DB ID : INT; // Local ID for testing purposes I : INT; // Loop counter END_VAR pArr := DATA; // Pointer to the local UDT type ArraySize := pAnyArr.Length; // Get the size of our UDT type in bytes pArr := DB_PTR; // Pointer to the array structure within the DB NumElements := pAnyArr.Length / ArraySize; // Number of array elements = size of full UDT type array / size of 1 UDT type FOR I := 1 TO NumElements DO // Loop for all array elements in DB Retval := BLKMOV(SRCBLK := pArr, DSTBLK := DATA); // Copy UDT element to local UDT for testing IF RetVal = 0 THEN // If copy sucessful IF SRC_ID = DATA.ID THEN // If DB ID matches search ID we have found our man! ; // Add you code here for whatever you want to do when you have found a match EXIT; // Optional loop exit on ID value found (might want to match several at once, if so remove this) END_IF; ELSE ; // Copy unsucessful - might want to consider some form of error handling here END_IF; // Bump pointer by array size * 8 to convert to bytes to address, so that it points to the next array element in DB pAnyArr.ByteAddressLSB := INT_TO_WORD(WORD_TO_INT(pAnyArr.ByteAddressLSB) + (ArraySize * 8)); END_FOR; // Next array element END_FUNCTION_BLOCK [/code] AttachmentPtrTest.zip (395 Downloads) |
Programming today is the race between software engineers building bigger and better idiot proof programs, and the universe producing bigger and better idiots. |
|
This contribution was helpful to
2 thankful Users |
6/27/2012 9:29 AM | |
Joined: 5/7/2012 Last visit: 12/4/2023 Posts: 35 Rating:
|
Thanks smiffy. This seems to be exactly what I'm looking for. |
This contribution was helpful to
2 thankful Users |
Follow us on