Wincc flexible - efficient tag assignment

Michael_B

Member
Join Date
Dec 2012
Location
Tel Aviv
Posts
4
Hi everyone,

I'm writing an application for a machine that is supposed to run different auto programs, each consisting of up to 50 steps. Each auto step is represented by a struct (in the plc) and the whole list of the stored programs in the plc is an array (of that struct). The programs are written and modified by the operator.

The screen is large enough for showing a single auto program at once, so now I have about 150 different IO_fields/switches on the screen all have to be assigned a process variable.
Is there some method for this other than repeating the same "tag selection process" for 150 times?

P.S.
If it was only possible to do the assignment during runtime, I could have used a vbscript since all the (groups of) objects on the screen are named seqentially ("object_1","object_2","object_3", and so on...) so a simple "for" loop could do the job.
 
I have done something similar in WinCCFlex by using a script to generate pointers (byte number and bit numbers) to direct the tags to the actual data to be displayed based on the selected auto program.

Set up the tags with indirect addressing whereby you can specify the DB, Byte address and Bit address to be other tags. In this way your script can calculate the values for these tags based on the selected auto program.

Make a memory tag that is the program to be viewed and use the on change event to trigger the script and also when the page loads.

I also wrote code on the PLC that calculated the sise of the UDT on power up so that the script could calculate the offset corrctly between one program and the next if anything was added to the UDT then the HMI didn't need too much work.

Here is an abridged script that calculates pointers for the HMI.

Code:
Dim LineNo
Dim Sizeof_Recipe   'Size of the Recipe UDT
Dim Sizeof_HydData   'Size of Hydraulic Data UDT
Dim Sizeof_RecipeMan  'Size of Recipe Manager UDT
Dim Offset_To_X_State  'Offset from the start of the UDT to the X State
Dim Offset_To_Y_State  'Offset from the start of the UDT to the Y State
Dim Offset_To_1stDES  'Offset from the start of the DB to the 1st Descaler State
Dim Offset_To_1stTT   'Offset from the start of the DB to the 1st TTable State
Dim Offset_To_1stVTUCAP  'Offset from the start of the DB to the 1st VTU Capstan State
Dim Offset_To_1stDES_DB  'Offset to the first Descaler Drive DB
Dim Offset_To_1stTT_DB  'Offset to the first Turntable Drive DB
Dim Offset_To_1stVTUCAP_DB 'Offset to the first VTU Capstan Drive DB
Dim Offset_To_RecipeNumber 'Offset to Recipe Number within UDT
Dim Offset_To_RecipeControl 'Offset to Recipe Control byte within UDT
Dim Offset_To_Speed   'Offset to linespeed in within Recipe
Dim Offset_To_RodSize  'Offset to rod size in within Recipe
Dim Offset_To_TargetDiam 'Offset to Target Diameter in within Recipe
Dim Offset_To_Tension  'Offset to Tension in within Recipe
Dim Offset_To_X_Position 'Offset to X Position in within Recipe
Dim Offset_To_Y_Position 'Offset to Y Position in within Recipe
Dim Offset_To_X_Park 'Offset to X Park Position in within Recipe
Dim Offset_To_Y_Park 'Offset to Y Park Position in within Recipe
Dim Offset_To_StorePosByte 'Offset in bytes to store Position bit
Dim Offset_To_StorePosBit 'Offset in bits to store Position bit
Dim Offset_To_RecipeName 'Offset to Name within Recipe
Dim Offset_To_Hyd_Manual 'Offset to the manual byte with the UDT
Dim Offset_To_Hyd_Pressure_X 'Offset to the X axis Pressure 
Dim Offset_To_Hyd_Pressure_Y 'Offset to the Y axis Pressure 
Dim Offset_To_Hyd_Position_X 'Offset to the X axis Position
Dim Offset_To_Hyd_Position_Y 'Offset to the Y axis Position
Dim TakeUp_Byte    'Byte Number for Take Up Slack 
Dim TakeUp_Bit    'Bit Number for Take Up Slack
Dim VTU_Master_Byte   'Byte Number for VTU Master
Dim VTU_Master_Bit   'Bit Number for VTU Master
Dim VTU_Master_Start_Byte  'Start Byte for VTU Master
Dim VTU_Master_Start_Bit  'Start Bit for VTU Master
Dim Offset_To_MPMSpeed   'Offset to the first MPMspeed
Dim SpeedPointer    'Pointrer to MPM Speed
...
 
'Set Offsets
Offset_To_X_State = 16
Offset_To_Y_State = 18
Offset_To_1stDES = 0
Offset_To_1stTT = 80
Offset_To_1stVTUCAP = 40
Offset_To_1stDES_DB = 540
Offset_To_1stTT_DB = 520
Offset_To_1stVTUCAP_DB = 500
Offset_To_RecipeNumber = 2
Offset_To_RecipeControl = 0
Offset_To_Speed = 2
Offset_To_RodSize = 6
Offset_To_TargetDiam = 18 
Offset_To_Tension = 22
Offset_To_X_Position = 26
Offset_To_Y_Position = 30
Offset_To_X_Park = 34
Offset_To_Y_Park = 38
Offset_To_StorePosByte = 28
Offset_To_StorePosBit = 3
Offset_To_RecipeName = 34
Offset_To_Hyd_Manual = 28
'Find UDT Sizes
LineNo = SmartTags("iLineNumber") 'Set Line Number
HmiRuntime.Trace "Line Number = " & LineNo
Sizeof_Recipe = SmartTags("dbCalibration.iSizeof_Recipe") 'Size of Recipe
HmiRuntime.Trace "SizeOf recipe = " & Sizeof_Recipe
Sizeof_HydData = SmartTags("dbCalibration.iSizeof_HydData") 'Size of Hydraulic Data
HmiRuntime.Trace "SizeOf Hydraulics = " & Sizeof_HydData
Sizeof_RecipeMan = SmartTags("dbCalibration.iSizeof_RecipeMan") 'Size of Recipe Manager 
HmiRuntime.Trace "SizeOf recipe Manager = " & Sizeof_RecipeMan
'Calculate Pointers to States
X_State_Pointer = ((LineNo -1) * Sizeof_HydData) + Offset_To_X_State
Y_State_Pointer = ((LineNo -1) * Sizeof_HydData) + Offset_To_Y_State
DES_State_Pointer = ((LineNo -1) * 2) + Offset_To_1stDES
TT_State_Pointer = ((LineNo -1) * 2) + Offset_To_1stTT
VTUCAP_State_Pointer = ((LineNo -1) * 2) + Offset_To_1stVTUCAP
'Calculate Drive DB Numbers
DES_DriveDB = Offset_To_1stDES_DB + (LineNo -1)
TT_DriveDB = Offset_To_1stTT_DB + (LineNo -1)
VTUCAP_DriveDB = Offset_To_1stVTUCAP_DB + (LineNo -1)
'Calculate recipe pointers
RecipeNumberPointer = ((LineNo -1)*Sizeof_RecipeMan) + Offset_To_RecipeNumber
RecipeControlPointer = ((LineNo -1)*Sizeof_RecipeMan) + Offset_To_RecipeControl
RecipeSpeedPointer = ((LineNo -1)*Sizeof_Recipe) + Offset_To_Speed
RecipeRodSizePointer = ((LineNo -1)*Sizeof_Recipe) + Offset_To_RodSize
RecipeDiameterPointer = ((LineNo -1)*Sizeof_Recipe) + Offset_To_TargetDiam
RecipeTensionPointer = ((LineNo -1)*Sizeof_Recipe) + Offset_To_Tension
RecipeX_PosPointer = ((LineNo -1)*Sizeof_Recipe) + Offset_To_X_Position
RecipeY_PosPointer = ((LineNo -1)*Sizeof_Recipe) + Offset_To_Y_Position
RecipeNamePointer = ((LineNo -1)*Sizeof_Recipe) + (Sizeof_Recipe -12) 'Offset_To_RecipeName
Hyd_Park_X_Pointer = ((LineNo -1) * Sizeof_Recipe) + Offset_To_X_Park
Hyd_Park_Y_Pointer = ((LineNo -1) * Sizeof_Recipe) + Offset_To_Y_Park
'Calculate Pointers to Hydraulics
Hyd_Manual_Pointer = ((LineNo -1) * Sizeof_HydData) + Offset_To_Hyd_Manual
Hyd_Position_X_Pointer = ((LineNo -1) * Sizeof_HydData) + Offset_To_Hyd_Position_X
Hyd_Position_Y_Pointer = ((LineNo -1) * Sizeof_HydData) + Offset_To_Hyd_Position_Y
Hyd_Pressure_X_Pointer = ((LineNo -1) * Sizeof_HydData) + Offset_To_Hyd_Pressure_X
Hyd_Pressure_Y_Pointer = ((LineNo -1) * Sizeof_HydData) + Offset_To_Hyd_Pressure_Y
Hyd_Store_Pos_Pointer = ((LineNo -1) * Sizeof_HydData) + Offset_To_StorePosByte
'Calculate pointers for alarm handling
FaultReset_Byte = Int((Offset_to_FaultReset + (LineNo - 1)) / 8)
FaultReset_Bit = (Offset_to_FaultReset + (LineNo - 1)) Mod 8
FaultAck_Byte = Int((Offset_to_FaultAck + (LineNo -1)) / 8)
FaultAck_Bit = (Offset_to_FaultAck + (LineNo - 1)) Mod 8
...
 
HmiRuntime.Trace "Recipe Control Pointer = " & RecipeControlPointer
SmartTags("iRecipeNumber_Pointer") = RecipeNumberPointer
HmiRuntime.Trace "Recipe Number Pointer = " & RecipeNumberPointer
SmartTags("iRunSpeedPointer") = RecipeSpeedPointer
HmiRuntime.Trace "Run Speed Pointer = " & RecipeSpeedPointer
SmartTags("iRunRodSizePointer") = RecipeRodSizePointer
HmiRuntime.Trace "Run RodSize Pointer = " & RecipeRodSizePointer
SmartTags("iRunDiamPointer") = RecipeDiameterPointer
HmiRuntime.Trace "Run Diameter Pointer = " & RecipeDiameterPointer
SmartTags("iRunTensionPointer") = RecipeTensionPointer
HmiRuntime.Trace "Run Tension Pointer = " & RecipeTensionPointer
SmartTags("iRunPosXPointer") = RecipeX_PosPointer
HmiRuntime.Trace "Run X Pos Pointer = " & RecipeX_PosPointer
SmartTags("iRunPosYPointer") = RecipeY_PosPointer
HmiRuntime.Trace "Run Y Pos Pointer = " & RecipeY_PosPointer
SmartTags("iXparkPointer") = Hyd_Park_X_Pointer
HmiRuntime.Trace "Park X Pos Pointer = " & Hyd_Park_X_Pointer
SmartTags("iYparkPointer") = Hyd_Park_Y_Pointer
HmiRuntime.Trace "Park Y Pos Pointer = " & Hyd_Park_Y_Pointer
SmartTags("iCurrentXPos_Pointer") = Hyd_Position_X_Pointer
HmiRuntime.Trace "Current X Pos Pointer = " & Hyd_Position_X_Pointer
SmartTags("iCurrentYPos_Pointer") = Hyd_Position_Y_Pointer
HmiRuntime.Trace "Current Y Pos Pointer = " & Hyd_Position_Y_Pointer
SmartTags("iPressureX_Pointer") = Hyd_Pressure_X_Pointer
HmiRuntime.Trace " X Pressure Pointer = " & Hyd_Pressure_X_Pointer
SmartTags("iPressureY_Pointer") = Hyd_Pressure_Y_Pointer
HmiRuntime.Trace " Y Pressure Pointer = " & Hyd_Pressure_Y_Pointer
SmartTags("iHyd_Manual_Pointer") = Hyd_Manual_Pointer
HmiRuntime.Trace " Hydraulics Manual Pointer = " & Hyd_Manual_Pointer
SmartTags("iStorePointerByte") = Hyd_Store_Pos_Pointer
HmiRuntime.Trace " Hydraulics Store Pos Pointer = " & Hyd_Store_Pos_Pointer
SmartTags("iAckByte") = FaultAck_Byte
HmiRuntime.Trace " Fault Ack Byte = " & FaultAck_Byte
SmartTags("iAckBit") = FaultAck_Bit
HmiRuntime.Trace " Fault Ack Bit = " & FaultAck_Bit
SmartTags("iFaultByte") = FaultActive_Byte
HmiRuntime.Trace " Fault Active Byte = " & FaultActive_Byte
SmartTags("iFaultBit") = FaultActive_Bit
HmiRuntime.Trace " Fault Active Bit = " & FaultActive_Bit
SmartTags("iResetByte") = FaultReset_Byte
HmiRuntime.Trace " Fault Reset Byte = " & FaultReset_Byte
SmartTags("iResetBit") = FaultReset_Bit
HmiRuntime.Trace " Fault Reset Bit = " & FaultReset_Bit
SmartTags("iFault_Un_Ack_Byte") = FaultUnAck_Byte
HmiRuntime.Trace "Un_Ack Fault Byte = " & FaultUnAck_Byte
SmartTags("iFault_Un_Ack_Bit") = FaultUnAck_Bit
HmiRuntime.Trace "Un_Ack Fault Bit = " & FaultUnAck_Bit
'Set iTempRecipeNumber
RecipeNumber = SmartTags("dbRecipeMan.iRecipeNumber")
SmartTags("iTempRecipeNumber") = RecipeNumber
HmiRuntime.Trace "iTempRecipeNumber = " & RecipeNumber
strAlarmFilter = "Line " & CStr(LineNo)& " "
...

Nick
 
Hi Nick, thanks for the reply.

I think you didn't understand me... You've shown an example where you connected tags whose values are shown on the screen to the corresponding data on the plc, based on some input from the operator.
I was talking about the assignment of the tag name to the graphical objects on the screen, and I've got a lot of those. All the tags have almost a similar name, the only thing that is different is the index of the array, so i thought there might be a better way rather than manually going to the properties window of each object, opening the process tag field, and selecting the proper tag from the list.
 
Hi have you looked into indirect tags in wincc flex. Each recipe can be a db (1 per recipe is easiest, say DB200...DB500 for 300 recipes)

Then create a tag recipe_number (int)

Then create tags to DB200 items, and the replace DB200.xxxxxxxxx with DB[recipe_number].xxxxxxxxxxxxxxxxx in the tag declaration area

This way you only populate your HMI page once
 

Similar Topics

Hi, We have upgraded our laptop which includes Windows 11. It appears that WinCC flexible 2008 advanced does not support Windows 11. What...
Replies
11
Views
254
Hello everyone I Have an Issue with the usage of recipes in Wincc Flexible 2008, I create the recipe to change the values in a fast way The...
Replies
0
Views
103
Hi colleagues.We do data logging system.We want to record three temperatures under a certain condition. We prepared the project as follows. We do...
Replies
1
Views
747
Hello to everyone. I change the value of a "PQW" with a button in Wincc flexible. The code of the button is defined as M102.0. Value reset...
Replies
10
Views
4,567
Hello Friends I have installed WinCC Flexible 2008 SP5 Update 2. I have open the software, but the Transfer option does not appear. Is It...
Replies
2
Views
1,468
Back
Top Bottom