If I change the structure of a class, can I download the instances one at a time? I have a fear that downloading one instance of the class will update the class structure in the controller, affecting all the instances. Is that true?
Here is bone-head move that I made. I took the the advice of the books on line and promoted a function block parameter up to the module level. below is the example in the books on line. I did the same thing, but with the PV.
The problem I'm having is that we set the parameter type to "Internal Reference", thinking that it's a parameter showing an internal value.
We'll, we're getting a module level "Output Transfer Error", that I assume is due to the link trying to push a floating point value into an Internal Reference parameter type. The error has been ignored for a while and is not causing any problems at the moment, but I wanted to correct this. I figure I could either delete the link, or change the parameter type. I figure deleting the link would be the easiest.
Thank you,
Frank Jr.
You can do it one by one on control module instances. The only time you have to really worry about it is when you change linked composite structures (i.e. adding a parameter, etc) that'll required download of all the modules.
If you are nervous about it, you can always:
Tedious, but you then have full control what gets flagged for download.
Using the names in the diagram above: As long as your OUTPUT parameter is configured to reference the AI1/OUT then it is already doing the same thing as the wired link and you can just delete the link. In general, it is easier to troubleshoot by following wires because anybody that looks at it in the future will know, at a glance, exactly where the value is coming from.
Frank,
The Class structure is not downloaded to the controller. in fact, if you were to compare the download script of a class based module, or stand alone module with the same design, they would be identical. The Class is used by the database to manage the structure of the module's in the database, but when it comes time to download, each module is compiled into a download script individually. This is why you can change the class and download affected modules one at a time. You should change the Class and perform you downloads as needed. I would not recommend to create a Class and convert the modules to the new class. This is unnecessary.
A Linked Composite is different. The Composite block is downloaded to the controller, and referencing modules use this instance. All modules are affected when this composite is downloaded. In this case, to change the composite and download modules one at a time, you would need to create a new composite, and edit each module to refernece the new composite. If you used the composite in a Class, you'll need to create a new class as Otto suggests.
When a parameter is defined as an internal reference, it acts as a pointer to the referenced parameter. You can read and write through this referenced directly with an expression, or you can wire to it in the module diagram. The INput or OUTput format of the parameter dictates the flow of data when you wire, but an expression can read and/or write. However, you should not write with an exression if the output parameter is wired. The order of execution in the module will determine which value wins.
In your case, if you wired the AI/PV to '/OUTPUT', and defined OUTPUT to reference AI/PV, you have an illegal reference. As Carl explains you can simply remove the wired connect, or chagne the parameter to a Float with Status. I would recommend removing the wire. The wire and Float parameter add CPU and memory load because the AI/PV value is transferred every scan of the module. The Internal reference does not hold the value, and is simply a pointer to the PV. Not a big deal, but cummulatively, this can add up. Also, the act of writing to the Float parameter with a wire sets the exception flag on the parameter, forcing it to update across the network making this a periodic rather than exception reporting. If the source parameter's change flag is not set, but you wire it to the Float parameter, the float parameter will treat the write as a change. With a reference, the AI/PV change flag determines if the value should be communicated.
For ease of trouble shooting, the wired connection is much clearer, so I use them when data flow is important. For promoting parameters to the module level, say as communciation parameters, I prefer the internal references for efficiency, as these are not part of the control loop.
Another difference with internal reference parameters is you cannot upload them. If you create a parameter called GAIN at the module level, and reference it to the PID1/GAIN parameter, you can change the gain of the PID in either location. However if you change the MODULE/GAIN parameter, and attempt to upload it, the Upload utility will not be able to insert the value into the database at this location. More useful might be the SP parameter, which is changed by the Operator, and we never want to upload it. Using an internal reference parameter, we can provide the access to PID1/SP to the operator (DetlaV Security allows Operator to write to this parameter name), but as an internal reference MODULE/SP cannot be uploaded by accident.
If you wired MODULE/SP (configured as FLOAT with STATUS) to PID1/SP, writes to PID1/SP would always be overwritten by the MODULE/SP parmaeter and uploading the MODULE/SP would work.
External references to modules in the same controller work the same as Internal references (Direct pointers to the data source). Modules in remote controllers go through the comm layer, so the reference is direct to the Proxy Client parameter, but writes can take up to 200 ms to be transferred to the destination, where they are written to the parameter location.
Andre Dicaire
Thank you everyone for the responses. A big thanks to Andre for taking the time to fully explain what was happening. It is much apreciated.
-FK Jr.
In reply to AdrianOffield:
Good points SB. My choice of SP for the wired example was not a good choice. Contiously writing to some parameters can prevent a block from transitioning to full automatic control. Something to be cautious of.
Your point about wired output parameters is correct. But it made me wonder if it was clear why this is so. Basically, a wired connection is executed by the destination. The function Blocks have an execution order, and when a block executes, the first thing it does is get the data from the wired sources. The Output parameters are not given an execution order, and are updated after the last FB executes. If you write to a parameter from an expression, the value is written synchronously, and is available with the updated value for use later in the same expression or by other blocks in the module. If you used the CALC/OUT1 parameter and wired this to the same parameter, the value would not transfer to the parameter until after the last block executed and output transfers were done.
If the parameter is an internal reference or external reference in the same controller, writes from expressions go immediately to the parameter location. If you wire to such reference parameters, the transfer to the destination parameter happens at the end of the module.
I use parameters with expressions when I want to store a value as a particular data type. The CALC IN and OUT parameters, as well as internal variables of an expression are Floating point formats. This works accurately for boolenas, and integers no greater than 16 BIT. If you want to preserve a 32 bit integer, you need to store it in a 32 Bit integer type parameter. You cannot wire this from an OUTx parameter of the CACL block. When dowing bitwise operations and masking/shifting bits, I assign intermediate results in parameters of the desired type to avoid conversion errors between integers and their floating point equivalent.
Switchover introduces another twist to module execution and behavior. In general, the Control module executes from start to finish, holding values in memory for the next execution. With redundancy enabled, the module does a little extra work to identify parameters that need to be transfered to the standby controller in order to have the standby module pick up where the last execution left off. To optomize this data link, values that are calculated by a block every time are not transferred. This is true for Alarm XXX_ACT parameters, where the ACT parameter is set by the module before the alarm function executes. However, some users found the ACT parameter useful as an interlock. They found out that on switchover, that due to execution order, a reading module might use the ACT parmaeter before that module had executed, and so read the default value instead of the current value. BOL has a list of critical parameters transferred by the redundancy link. I beleive v11.3 may now update the ACT parameters over the redundancy link.
So if a module used an external reference to read a value from another module, and that parameter is not a critical value, following switchover, the value read by this reference will depend on wheter the other module executed to set the value at the source. Normally, parameters with a default value should have a BAD status associated with them, and the status only goes good when a value is written into the parameter. If so, reading this value after switch over would bring a BAD status if the read happened before the source module executed.
If Status checks are not being done, then it is important to ensure external reads are to critical parameters, such as the AI/OUT and not the AI/PV parameter.
In your case, the FFDO block READBACK value may not be updated before your external Read of the parameter was made, thus reading the default value for this parameter on initial exeuction. I would try wiring the READBACK to a local module parameter, and referencing this parameter for your F_IN connection. The wired connection forces a tranfer of the READBACK value in the active controller, and I believe this will transfer to the standby module.
You could also try a CND block to read the READBACK, and "hold Last value" on a BAD status, The CND/OUT_D transfers on switch over. I'd have to run some tests to confirm my expectations here.
A third option could be to create a Discrete Input parameter for your DC block F_IN signal, and write to this value from the FFDO module, using an external reference Output parameter. The value would be written to the redundant controller and persist until the source module executed and wrote a different value. ( I would not recommend this for modules in separate controllers)
Without a doubt, the most informative thread I've read to date!
Someone needs to make a visualization of this.