Communication Process
The VTScada software module, "VTSDriver" (the source code for which is stored in a file named, "VTSDrvr.web"), provides the link between the communication driver and the VTScada application. A unique instance of VTSDriver is automatically created for every instance of every driver within an application.
Briefly, the role of VTSDriver is to:
- Distribute data to I/O tags
- Trigger polling
- Distribute data to client workstations via RPC.
- Synchronize data on startup.
Reading Data
VTSDriver contains a module called, "AddRead" that is called by an input tag to create a request to read a specific range of memory. AddRead expects the following parameters:
- The address from the input tag.
- The number of elements (size of the block) to read.
- A pointer to a place to put the retrieved values.
- The rate at which to perform the read.
AddRead calls VTSGetAddr and VTSMaxBlock in the communication driver to get the information it needs to coalesce the addresses into appropriate blocks. A ReadBlock module is then launched, which determines the best organization of blocks and launches a separate VTSRead module for each actual block of data to be read.
VTSRead, VTSGetAddr and VTSMaxBlock all reside in the communication driver, not in the VTSDriver module. This is an important detail to note if you are planning to write your own communication driver.
Writing Data
Whenever a value is changed in an output tag, a Write module in VTSDrvr.web is called. This module expects the following parameters:
- The address from the I/O tag.
- The number of elements to write.
- A pointer to the source of the written data.
- The data type.
- The name of the I/O tag that called this module to request a write.
The Write module launches WriteData, which in turn calls VTSGetAddr to obtain the information it needs to call VTSWrite. VTSWrite, a module in the communication driver, is then launched.
To emphasize, note that VTSWrite is a module that you create in the communication driver, not in VTSDrvr.web.
Rewriting Data
VTSDriver provides the ability to store and rewrite the last set of output values if requested or required. This feature is controlled by the following code that you may add to your custom driver:
Data Storage
Your custom driver must contain a variable named, StoreOutputs. When set to TRUE (1), VTSDrvr stores the last output value sent to each address. If later changed to FALSE (0), the stored values are erased so that they cannot be written accidentally.
Each VTScada Driver instance stores its own information on what value was written to what address in a retained dictionary. The dictionary is keyed on address and stores both the value and the tag name.
The information is populated only after a successful write has been carried out. It is stored via the module RememberOutputs().
Data Rewrite
A rewrite may be triggered either automatically, or manually.
A module in VTSDrvr named ForceRewrites carries out the rewrite. This module is launched by MonitorRewrites, which determines when the rewrite should execute.
ForceRewrites may be triggered by a user pressing the widget button, Rewrite Outputs. It may also be triggered automatically as follows:
Your custom driver must contain a module named CheckCommLossErr(). An example is provided later in this chapter. This module is called whenever SaveCommStats in VTSDrvr detects an error. CheckCommLossErr() returns a true or false to indicate whether that error qualifies as a loss of communications.
Your custom driver must also contain a Boolean variable named AutoRewrite. If set to TRUE, and if CheckCommLossErr() returns a TRUE value, the trigger is armed.
Upon restoration of communications, as indicated by CheckCommLossErr() returning a FALSE, MonitorRewrites will then execute as follows:
MonitorRewrites monitors the state of the trigger variable, verifies that the server machine's IO instance is in a position to do the writes and verifies that it is the server. Because of the server clause, there will only ever be one instance of this MonitorRewrites through all machines.
The trigger will not be disarmed until ForceRewrite has completed at least one good write.
Read Block Value Coalescing
VTScada combines individual PLC/RTU addresses into a single group or block that is intended to be executed as a single communication message. This is known as "coalescing" and is an attempt to increase throughput by allowing the reading and writing of large blocks of data, where possible.
There are a number of VTScada modules and variables that control how coalescing will be performed:
- VTSGetAddr: Gets the addresses for the blocks of data and parses them. The Info1, Info2, and Info3 parameters provided to this module must be either invalid or the same type in order for coalescing to occur.
- VTSMaxBlock: The value of the VTSMaxBlock variable sets the maximum number of values that can be coalesced into a single read. As an alternative, there may be a VTSMaxBlock subroutine defined, which returns the size of the maximum block for a given address.
The result of coalescing depends on the data type of the MemAddr parameter in VTSGetAddr:
- If MemAddr is numeric, VTScada will coalesce the message blocks into a continuous address range, even if that range includes addresses that are not identified or needed. For example, if the system is configured to read addresses 15 and 50, and the VTSMaxBlock variable is set to 100, then VTSRead is called such that addresses 15 to 50 will be read as a single read message, even though address 16 to 49 inclusive are not needed.
- If the data type of MemAddr is a string, then the result of the coalescing algorithm includes the configured addresses. Using the same example as above, VTSRead is passed an array of strings (in the MemAddr parameter) with two elements 15 and 50.