This is an old revision of the document!
Please keep in mind that registers of Dxx type and some other internal registers, except for DSxx, Sxx return to the initial state (usually 0) after initialization of the project (what happens with any editing of project elements - scripts, registers, connections, etc.). If such registers are used as variables to generate event triggers or conditions for executing other scripts, this can lead to a violation of the execution logic. You should consider this feature when choosing registers as input and output script variables.
Variables in scripts declared before the 'main' function store their values between script calls, but also reset when initializing. They can be used to store constants, coefficients, and other similar values.
Some script can be assigned to run on the first scan when the project is initialized and make some initialization of variables from one place. Sometimes you might need to define inside the script itself whether this was the first call after initialization. You can create a global variable first_scan:
first_scan = true -- global var remember value between scans function main (userId) local var = 0 -- local var will be initialized in each script call if first_scan then first_scan = false -[[ Actions for the first scan --]] end --if first_scan -- other actions end -- main
Remember that registers such as Dxx, CDxx and other internal registers, except for DSxx, return to the initial state (usually 0) after initializing the project (which happens when editing project elements - scripts, registers, connections, etc.). If such registers are used as variables to generate event triggers or conditions for executing other scripts, this can lead to a violation of the execution logic. You should consider this feature when choosing registers as input and output script variables.
There are some differences in the operation of the SetReg and WriteReg functions with respect to internal registers (Dxx, DSxx). These functions directly change the values of the internal registers inside the scan, and do not delay WriteReg writing to the next scan start. Thus, at the end of the scan, the internal register can have a value different from the one at the scan input. Then, for example, a situation is possible where:
If the order of execution of the scripts is 1 - 2, then everything will work, because at the current scan start script #2 saw one value, and before its execution another one(which script #1 has changed before), and will correctly work 'by changing the state of the register.' If the script execution order is interchanged, then script 2 will not work, because at the the current scan start it will see the changed value, and the new change will occur after script #2 execution in script #1.
If you take the new WebHMI with clean internal DS - memory, where some complex project has to be run, usually you need some presets (initial values) for correct operation. You can use a recipe feature and make a list of all registers with initial values, and then just apply this recipe.
If the project was linked to Level2 account, when restoring its backup on the new WebHMI, check that Level2 integration is switched off, otherwise this WebHMI may interefer another one which use same Level2 account.
It is desirable after the key moments of logic or calculations in scripts to immediately put the functions INFO, ERROR, DEBUG, TRACE, with respectve values at this point, script's name, line number at the beginning, etc. Then these fragments are conveniently searched and analyzed in the communication log.
When there is a lot of records in the communication log, you can filter out unneccerary output from scripts with this method.
In the script editor, there is a debugging console, which always prints out the functions INFO, DEBUG, ERROR, TRACE regardless of the system log level settings. If the output changes too quickly to analize, you can slow down the script by changging in execution type to “Execute on register's value change” and link to system time register or another one, slower.
There are also messaging functions like AddInfoMessage, which can be used to write in a separate Messages log. Just take care of using them in logic transition points, otherwise you will get huge number of records generated in every scan from these functions.