Please enable JavaScript to view this site.

DAQFactory User's Guide

Navigation: 5 Sequences & Scripting

5.10 Variables

Scroll Prev Top Next More

In addition to channels and V Channels for storing data, DAQFactory also supports several different types of variables: public, registry, private and static.  Private and static variables are used in sequences and discussed in the next section.  Public variables exist throughout DAQFactory and can be used in expressions or sequences.  They can be set using the same mechanisms that channels can be set, even with knobs, switches and other components.  

Public, global Variables

In order to use a variable, you must first declare it.  To declare a public variable visible from everywhere within DAQFactory, use the global sequence command:

 

global MyVariable

You can also do an assignment at the same time:

 

global MyVariable = 3

String variables are created by adding "string" to the declaration:

 

global string MyStringVariable

MyStringVariable = "some string"

To determine if a variable exists yet, use the IsEmpty() function:

IsEmpty(MyVariable) returns 1 if MyVariable is not defined yet.

Note, however, that IsEmpty() will return 1 if MyVariable is declared, but contains NULL.  Variables are empty until assigned a value.  NULL can also be assigned: x = NULL, or is returned by several system functions.  

ClearGlobals():  

If you need to clear out your globals (and defines decribed below), use the ClearGlobals() function.  This clears all globals and defines and basically resets the global variable namespace.  Note that the "false" and "true" defines cannot be cleared out, but instead will reset to 0 and 1.  You can, however, redefine them if you really wanted to.

Note: Channels in the default connection also have global scope, so you should be careful to choose different names for your variables and channels to avoid any conflict.  If there is a conflict, the variable will take precedence over the channel.

Variables vs. Channels

Variables can be used just like channels.  Unlike channels, they do not have a history, but they can be created as arrays.  Here are some differences:

MyChannel = 5  will set the output channel MyChannel to a value of 5 and move all previous values in MyChannel's history back one spot, setting the most recent value to 5.  So if MyChannel had a history of {3,2,6} before the above statement, it would have a history of {5,3,2,6} afterwards.

MyVariable = 5  will set the variable MyVariable to a value of 5.  Any data already in MyVariable is cleared out.

OK, we lied, if you are using DAQFactory Lite or higher there are several variable functions that will allow you to create a history using a variable, much like a channel.  The big advantage of this is that variables tend to be faster than channels because they don't go through broadcasting, logging or alarming or any drivers.  The functions are similar to their analogies for channels.  All will start with the variable name, for example MyVariable.AddValue(x) :

AddValue(Value):  

Calling this function adds a value to the history of the variable, moving the current value(s) in the variable back in the array.  Value can be a scalar value or an array of values.  If Value has time associated with it, the time of each row is inserted as well.  If Value does not have time associated with it, the current time is inserted before the data is added to the channel.  For array data with multiple rows, you must have time in the array beforehand.  Use the InsertTime() function for this.  Data will build up until the history length for the variable is reached.  The default history length for a variable is 3600.  To change, set the HistoryLength parameter of the variable to the new value, fox example: MyVariable.HistoryLength = 100.  History only applies in a variable if you use the AddValue() function.

AliasFor(ChannelName):

Causes the variable to become an alias for a particular channel.  The channel name should be passed as a string (i.e. myVariable.aliasFor("myChannel")).  This function is especially useful when you have objects and want member variables of the objects to be connected to channels.  Once a variable is set as an alias, reading the variable will instead give you the value in the channel, and likewise, setting the variable will send the value to the channel instead.  To clear the alias setting of a variable, pass a blank string: myVariable.aliasFor("")

Append(Value):

Adds the given value to the end of the array, increasing the size of the array.  This is the same as myvar[numrows(myvar)] = Value.

AssignDoesAddValue(newSetting):

By default, when you do myVar = 3 it will replace whatever is currently in myVar with 3.  If you call AssignDoesAddValue(1) on your variable, then whenever you do myVar = 3 the system will in fact call AddValue(3) instead, moving the existing value back in the history.  Calling this function with 0 will set it back to normal.  When active, only one row of data can be added at a time.  I.e. doing myVar = {3,4} will cause only the value 3 to be added to the variable.  This is to allow you to do myVar++ or myVar+=4 without copying the history over.

This function is called automatically with a setting of 1 if you call the SetupPersist() function below.  

ClearHistory(len):  

Calling this function will clear the variable's history of all values except for the number of points specified in the function.  Leaving this parameter blank clears all the points in the history, which is the same as ClearHistory(0).  After clearing, the history will rebuild itself as you call AddValue().

There are several other useful variable functions for inserting and removing array elements.  The history length of the variable has no affect on these functions, so you'll have to limit the length of the arrays yourself if needed.  These functions only work in the row dimension:

InsertAt(index, Value):

Inserts the given value at the given index of the array.  So, if the variable contains {1,2,3} and you do MyVar.InsertAt(1,4), MyVar will become {1,4,2,3}.

Push(Value):

Pushes the given value into the top of the array.  This is almost identical to AddValue() except the history length is not looked at.  It is largely used in conjunction with Pop() to create a stack.  

Pop():

Removes the top element of the array (the last Push() usually) and returns that element. y=x.pop() is basically the same as doing y=x[0] followed by x.removeAt(0).

RemoveAt(index, [count]):

Removes count elements starting at index. So, if the variable contains {1,4,2,3} and you do MyVar.RemoveAt(1,2), MyVar will become {1,3}.  Count is optional and defaults to 1.

SetupPersist(filePath, history length, persist length, [init value]):

(this function is only supported in DAQFactory Pro or higher)

This function allows you to create a persist file similar to channels, but associated with the variable, thus allowing the variable to persist to disk much like a channel.  This is especially useful when used with objects.  FilePath is the full file path to the desired file.  You can name it whatever you want and put it wherever you want as long as DAQFactory can write to the folder.  History and persist length are just like their channel equivalents.  The persist file is created full size when the function is first called.  Of course if the persist file already exists and is the correct size it will be used even after restarts.  Init value is optional and allows you to specify a value to initialize the variable to if it is currently empty.

Calling this function also calls the AssignDoesAddValue() function with a value of 1 as this is the primary way this function should be used.  Note that when in this mode only one row of data can be added at a time.  I.e. doing x = {3,4} will cause only the value 3 to be added to the variable.  This is to allow you to do x++ or x+=4 without copying the history over.

Arrayed Data

Arrayed data can be stored in variables though using either array notation:

MyVariable = {5,3,2,5}  or by using subset notation to set individual elements-for example MyVariable[3] = 5

When using the subset notation in an assignment like this, existing values are not cleared out.  So the following:

 

MyVariable = {5,3,2,5}

MyVariable[3] = 2

results in {5,3,2,2}

If you are initializing an array using the subset notation, it is recommended that you start with the last value in the array and work towards 0.  When you set an array element past the end of an existing array, or in a new array, all intermediary values are set to 0.  So, assuming MyVariable was empty, MyVariable[3] = 5 will set MyVariable to {0,0,0,5}.  By starting at the end of the array, you allocate the memory for the variable once, rather than reallocating multiple times which is much slower.

You can also make 3 and 4 dimensional arrays using similar notation:

MyVariable[0][3][1] = 2 will, assuming MyVariable is empty, set MyVariable to {{{0,0},{0,0},{0,0},{0,2}}}.  If MyVariable wasn't empty, it would simply set the array element in the 1st row, 4th column, 2nd depth to 2.

Like channels, variables can also have time associated with them.  When you set a variable to a scalar value (MyVariable = 5), the time when the variable was set is also stored.  This does not occur when setting array values.  You can access this time using the GetTime() function, or you can use the following notation:

 

MyVariable.Time

or for an array:

MyVariable.Time[5] returns the time of the 6th row of the MyVariable array if time is available.

This notation also allows you to manually assign a time to a variable:

 

MyVariable.Time = 1h3m

To set the time of array values, just use subset notation:

 

MyVariable.Time[3] = 1h3m

Remember that only the Rows dimension has time, so the following:

 

MyVariable.Time[3][2] = 1h3m

and

 

MyVariable.Time[3][3] = 1h3m

will do the same thing because the row subset is the same.

As an alternative, you can use the InsertTime() function to quickly insert evenly spaced time values into an array.

Note: Graphs, and some other functions require time to be sorted in the array from most recent time back.  Element 0 should have the most recent (largest) time.  Use the SortTime() function to sort an array based on time into this order.  If you are using InsertTime(), use a negative interval to go back in time.

Channels also support the .Time notation, but only for reading the time:

MyChannel.Time[3] returns the time of the 4th most recent data point of MyChannel.

MyChannel.Time[3] = SysTime() is invalid.

Defined constants:

Defined constants are used when you have a "magic number", a constant that has some meaning.  For example, in DAQFactory, False is equivalent to the constant 0, while True is equivalent to the constant 1.  These are predefined constants.  Defined constants work a little differently then variables.  For one thing they are read only, and once you initialize them, you cannot change them.  Also, because they are implemented at a compiler level for speed, the define statement is evaluated when the sequence compiles, not when it runs.  Defines have global scope and will override pretty much any other names you may have created in DAQFactory, including global variables and channels.  The declaration of a defined constant is similar to a variables.  Since the define is constant and read only, you have to initialize it in the declaration.  For example:

 

Define False = 0

False = 3 // this does nothing

Like regular variables, add "string" to create a string define:

 

Define string CompanyName = "AzeoTech"

You can use defined constants just like regular global variables, except of course you cannot assign them a new value once declared except by redeclaring them.  So if you do:

 

Define x = 3

Define x = 4

x = 5

then x will end up being 4.

You can clear defines and global variables by using the ClearGlobals() function.  This function erases all defines and globals from memory.

Pulling constants out of C style .h files with Include():

If you are using an external DLL (using extern()) or a device that uses constants (i.e. LabJack), there are often a number of important constants defined in a header file, typically with device prototypes as well.  While DAQFactory can't use the device prototypes directly, it can import a C style .h file and pull out most of the constants and create defines for them.  It will pull out all non-array, non-string constants declared with either const or #define.  To do so, use the include() function:

 

include("c:\program files\labjack\drivers\labjackud.h")

this will create a define for each valid constant DAQFactory can find in the header file.  The variable type is largely ignored, as long as its a number, as DAQFactory only uses the double numeric type.

Registry variables:

Registry variables are also a global variable, but they are stored in the Window's registry and therefore persist between different sessions of DAQFactory.  There is no declaration of registry variables.  Registry variables are accessed by prefixing the variable name with Registry:

 

Registry.MyNumber = 5

Registry.strMyString = "data"

Registry variables have some limitations:

· In newer versions of windows (i.e. 7 and 8), access to the registry is limited for regular users.  You will likely need to run DAQFactory as an Admin, or be logged in as an Admin or a similar user with the proper rights to write to the registry for registry variables to work.

· String registry variables must start with "str".

· Registry variables are a bit slower to access then regular variables.  

· Registry variables do not support arrays.

· Registry variables only support positive integers and strings.  Integers are double words and therefore must be between 0 and 2^32.

· Registry variables do not have time associated with them.

Uninitialized string registry variables will return an empty string "", which is not the same as an empty variable, i.e. a variable containing NULL.  Uninitialized numeric registry variables return 0.  

Once initialized, the only way to uninitilize the registry variable is to use the Windows Registry editor and manually remove the variable.  On 32 bit versions of Windows, registry variables are stored in HKEY_LOCAL_MACHINE/Software/DAQFactory/Control/Variables.  On 64 bit versions, they are stored in HKEY_LOCAL_MACHINE/Software/Wow6432Node/DAQFactory/Control/Variables.  Setting a string registry variable to an empty string ("") will not uninitilize the variable, but instead will simply store an empty string.