Variables
Variables are container for values that are defined only at command execution. They can only be defined for actors, in modules. Variables are typed: the main type is the external type which is the type for the datafeed going to and from the actor (in relation with other actors). Yet upon execution, their type can be changed to be integrated into a command for example.
For the SMC100 controller that pilot a XY stage, there are commands to get and set the position for axis X.
axisX = "1"
[connections.connect_smc100.cmds]
moveX = ["$(axisX)PA$(X)\r\n", ""]
getXpos = ["$(axisX)TP\r\n", "$(axisX)TP$(X)"]
First axisX is not a variable but an alias to another value define in the module instance. Each command gives one actor (an actor is an instance of command). As a consequence, the command moveX requires the variable X, and the command getXpos produces a variable X. They can be named identically only because they share the same description node:
[vars.X]
type = ["String", "f64", "dv:m"]
exponent = [0, -3, 0]
termination = "\r\n"
min = "-50mm"
max = "50mm"
The line
type = ["String", "f64", "dv:m"]
specifies the type conversion chain from the raw data to the external data: the bytes read are first interpreted as a String. Then this string is converted to a float ("f64") then to a dimensional value, in meters ("dv:m").
The thing is the value is outputed in millimeters from the SMC controller, at the start of the chain. So an exponent is applied on the "f64" intermediate value (the value is multiplied by 10^3). The given value is applied when transforming in the direction from the firt type to the last type. In the other direction, the opposite value is applied instead.
In the other direction for the "moveX" command, the data has to be provided as a dimensional value and will be converted into bytes according to the conversion chain (in reverse).
The exponent can be specified by a value (integer between -24 and 24).
The external value can be constrained:
min = "-50mm"
max = "50mm"
An error will be raised if the value fed is outside this range (both min and max are optional).
Finally, to be read, a variable must defines how it ends. Here
termination = "\r\n"
means that the X String is finished upon the "\r\n" substring.
It is also possible to specify the end as a number of bytes.
[vars.key]
type = "raw"
byte_len = 16
Here the key consists in 16 bytes.
The byte_len can also be defined by a String containing a dollar token of the Data Description Syntax. The following example, reading traces from an oscilloscope, is therefore valid.
[connections.connect_dsos404a.cmds]
get_data = [":WAV:DATA?\n", "#$(PACKET_SCOUNT_SIZE)$(PACKET_SCOUNT)$(SAMPLES)\n"]
[vars.PACKET_SCOUNT_SIZE]
type = ["String", "i64"]
byte len = 1
[vars.PACKET_SCOUNT]
type = ["String", "i64"]
byte_len = "$(PACKET_SCOUNT_SIZE)"
[vars.SAMPLES]
type = "raw"
byte_len = "$(PACKET_SCOUNT)"
This example read data of the form '#210xxxxxxxxxx\n':
- 2 is a string that describes the number of digits in the PACKET_SCOUNT variable.
- 10, the value of the PACKET_SCOUNT variable, is a string representing the number of bytes to read for obtaining the trace data.
It is also possible to specify a duration: when attempting to receive the var, the link will wait for the given duration. All bytes received during this interval will be considered as the value of the variable.
[vars.message]
type = "string"
duration = "150ms"
Only the type key is mandatory when sending a var. When receiving one, the end of sequence must be specified by either byte_len or termination.