6. Expressions

Light Guide uses a powerful expression evaluation tool that can compute complicated functions. These expressions can be used in the Variables Tab in the logic column, or in a Variable Command when setting a variable to an expression.

Expression Types

  • Boolean Expressions - operate with True and False values
  • Arithmetic Expressions - full library of math functions
  • Inequality Expressions - compare values.
  • Text Expressions - find substrings, concatenate, split strings.
  • ToString Function - create text strings from other types.
  • Conditional Expressions - if statements.
  • Binary Expressions - bit reversing.
  • Parsing Expressions - pulling data from formatted text.

 

Expression Examples

Using division and modulus (%) operators, you can format Work Instructions Time (normally in seconds only) to show hours, minutes, and seconds.

HH:mm:ss - (WI_Time / 3600).tostring("00") + ":" + ((WI_Time / 60) % 60).tostring("00") + ":" + (WI_Time % 60).tostring("00")

mm:ss - (WI_Time / 60).tostring("00") + ":" + (WI_Time % 60).tostring("00")

Breakdown of the evaluation of a string expression.

Breakdown of the evaluation of an integer and if() expression.

Boolean Expressions


Constants

True and False can be used as constants, but this is never necessary. See the sections below about NOT and = to see why.

Boolean Operators

The following operators can be used with Boolean variables.

AND

VarA  | VarB    VarA AND VarBFalse | False  ->  FalseFalse | True   ->  FalseTrue  | False  ->  FalseTrue  | true   ->  True

OR

VarA  | VarB     VarA OR VarBFalse | False  ->   FalseFalse | True   ->   TrueTrue  | False  ->   TrueTrue  | true   ->   True

XOR

VarA  | VarB     VarA XOR VarBFalse | False  ->   FalseFalse | True   ->   TrueTrue  | False  ->   TrueTrue  | true   ->   False

NOT

This produces the opposite value of the variable.

VarA      NOT VarAFalse   ->  TrueTrue    ->  False

You can produce the same result using other, longer, more confusing methods.

VarA = False  (i.e. this is true if the value equals false)VarA <> True  (i.e. this is true if the value does not equal true)VarA XOR True (i.e. this is true if VarA is false and false when VarA is true -- this is not the best way to accomplish this logic, it is not recommended to do this)

= (Equals Operator)

This checks to see if two variables are equal to each other.

VarA  | VarB     VarA = VarBFalse | False  ->   TrueFalse | True   ->   FalseTrue  | False  ->   FalseTrue  | true   ->   True

This incidentally works for other variable types as well.

VarA  | VarB     VarA = VarB 1    |  0     ->   False  (integer variables) 1    |  1     ->   True3.14  | 1.618  ->   False  (float variables)3.14  | 3.14   ->   True"LOL" | "BRB"  ->   False  (text variables)"LOL" | "LOL"  ->   True

Again, you could get the same result via more confusing means, but please don't do this.

NOT (VarA XOR VarB)

Finally, watch out for this common mistake.

VarA = True   

The = True is unnecessary. Instead, just write VarA by itself.

Latching Variables

Variables can reference themselves in function (circular logic).

Latch Function

Name   LogicVarA : Latch(VarA, VarB, VarC)

The first parameter of this function should be the name of the variable that the set by the function. The second parameter is triggering the output to go true when it goes true, the output will stay true after the second parameter goes back false. The third parameter will reset the output to false when it goes true.

You could write this out manually using an AND and an OR statement.

(VarA or VarB) and not VarC

Latch True

For a variable named VarA, the logic expression should start with "VarA OR". Once VarA goes true, then it does not matter what comes after the "OR" because the result will be true.

Latch False

For a variable named VarA, the logic expression should start with "VarA AND". Once VarA goes false, then it doesn't matter what comes after the "AND" because the result will be false.

Resetting a Latched Variable

Once a variable is suitably latched true or false, there are 3 ways to reset the variable value.

  1. Restart Light Guide
  2. Use the Variable Commandcommand to force the value.
  3. Put an AND operator at the end so that when the value after it goes false, then whole expression becomes false (see Latch function above).

 

 

Boolean Example

It may be easier to understand complicated boolean logic by telling a story. I only want to execute this task if they have picked up the torque tool (VarA) and if they have grabbed bolt 3 (VarB) but not if they currently have the velcro in hand (VarC) or the screw (VarD).

VarA AND VarB AND NOT (VarC OR VarD)

To verify that you will get the desired effect you can make and review a truth table.

VarA  | VarB  | VarC  | VarD     ResultFalse | False | False | False -> FalseFalse | False | False | True  -> FalseFalse | False | True  | False -> FalseFalse | False | True  | True  -> FalseFalse | True  | False | False -> FalseFalse | True  | False | True  -> FalseFalse | True  | True  | False -> FalseFalse | True  | True  | True  -> FalseTrue  | False | False | False -> FalseTrue  | False | False | True  -> FalseTrue  | False | True  | False -> FalseTrue  | False | True  | True  -> FalseTrue  | True  | False | False -> TrueTrue  | True  | False | True  -> FalseTrue  | True  | True  | False -> FalseTrue  | True  | True  | True  -> False

There are many online truth table generators where you can input the logic and review the results. See this one made by students at Stanford.

CountTrue - Counting Booleans That Are True

The CountTrue function can take any number of Boolean variables and will return an integer value for how many of them are true.

CountTrue(true, false, true, true) = 3

If you have restrictions on IO communication to a device and you need to return a 0 or 1 kind of boolean value instead of the typical true or false boolean returns you can wrap it in a CountTrue to achieve that effect.

 

TestBool = trueCountTrue(TestBool) = 1

CountTrue is also useful for knowing how many 3D vision tools are true at once since it is uncommon you would ever want more than one to be true at the same time if multiple were being triggered you could initiate a redo.

TryAgain = (CountTrue(Tool1, Tool2, Tool3, Tool4) > 1)

CountTrue will only hold the number of the true Booleans in the instance you check, so if a Boolean value changes so will the result of CountTrue.

If you are looking for something more concrete, perhaps you want to make sure the operator reached into every spot that you have a 3D vision tool set up for, then you could combine this with latching Booleans so once they are true, they will stay true until you clear them with a reset Boolean variable. 

Bool1 = Latch(Bool1, ConditionA, Reset)Bool2 = Latch(Bool2, ConditionB, Reset)Bool3 = Latch(Bool3, ConditionC, Reset)IsComplete = (CountTrue(Bool1, Bool2, Bool3) = 3)

Bool2Int - Turning many Booleans into an Integer.

If you have one or more Booleans that represent different bits of an integer, then the Boot2Int function can convert them for you.

Bool2Int(true) = 1Bool2Int(false) = 0Bool2Int(false, true) = 1Bool2Int(true, false) = 2Bool2Int(true, false, true) = 5Bool2Int(true, false, false, false) = 8

Bool2Int implements the following general logic for any number of Boolean variable inputs.

Bool2Int(Var1, Var2, Var3, Var4, Var5, Var6, Var7, Var8) =if(Var1, 128, 0) + if(Var2, 64, 0) + if(Var3, 32, 0) + if(Var4, 16, 0) + if(Var5, 8, 0) + if(Var6, 4, 0) + if(Var7, 2, 0) + if(Var8, 1, 0)

 

As another example, please consider the following:

01001001 is the binary equivalent of 73. Spreading this out, you can see that it matches the arguments in the Bool2Int function.           0     1      0      0     1      0      0     1Bool2Int(False, True, False, False, True, False, False, True) = 73

Functions That Provide Boolean Results

  • =, (Equality Operator)
  • <>(Not Equals)
  • <<=>>=(Inequality Operators)
  • .equals()(Text-specific Equality operator, it is interchangeable with the regular =operator)
  • .contains()(Text function)

Random Boolean Values

You can use this function to randomly get a true or false value based on a probability argument where 0 = always false and 100 = always true.

RandomBool(50) = 50% odds of true or false.

Please remember that you are not guaranteed to get 5 true values out of every 10 tries. Every calculation is random and does not depend on what previous values were. The actual number of true results out of N tries can be calculated as a cumulative binomial distribution. (See [[1]] for more information.)

If you call this function 10 times, the odds of getting exactly 5 true results are only 24.6%

Exactly 5 true results = 24.6%4-6 true results = 65.6%3-7 true results = 89.1%2-8 true results = 97.9%1-9 true results = 99.8%no true results = 0.1%all true results = 0.1%

Note that this works much better with larger numbers. If you run it 100 times:

Exactly 50 true results = 8.0%40-60 true results = 96.5%30-70 true results = 99.997%

Heartbeat

This is a toggling boolean value that is great for a "keep alive" for PLC communications. The parameters are the true time and the false time, both in milliseconds.

Heartbeat(2000,1000) is true for 2 seconds, then false for 1 second, before going true again for 2 seconds, etc.

Arithmetic Expressions

You can perform most common math functions.

Standard Operators

  • +- Add
  • -- Subtract
  • *- Multiply
  • /- Divide
  • %- Modulus, the remainder after dividing.

Trig Function

  • pi- Gives the value for pi.
  • Deg2Rad(Float)- Converts from degrees to radians.
  • Rad2Deg(Float)- Converts from radians to degrees.
  • Sin(Float)- Sine of an angle, in radians, (opposite side versus hypotenuse).
  • Asin(Float)- Inverse Sine, returns the angle in radians.
  • Cos(Float)- Cosine of an angle, in radians, (adjacent side versus hypotenuse).
  • Acos(Float)- Inverse Cosine, returns the angle in radians.
  • Tan(Float)- Tangent of an angle, in radians, (opposite side versus adjacent).
  • Atan(Float)- Inverse Tangent, returns the angle in radians from the ratio of the two sides.
  • Atan2(Float, Float)- Inverse Tangent, supply the two sides as arguments without dividing them first.

Hyperbolic Trig Function

  • Sinh(Float)- Hyperbolic Sine
  • Cosh(Float)- Hyperbolic Cosine
  • Tanh(Float)- Hyperbolic Tangent

Exponential and Log Functions

  • Pow(Float, Float)- First argument to the power of the second argument
  • Exp(Float)- The constant "e" to the power of the argument
  • Log(Float)- Natural logarithm
  • Log10(Float)- Log based 10

Square Root

  • Sqrt- Square Root

Limits

  • Floor(Float)- Integer that is just less than or equal to the argument
  • Ceiling(Float)- Integer that is just greater than or equal to the argument
  • Round(Float, Integer)- Round the first argument to the number of decimal digits from the second argument
  • Truncate(Float)- Chop off the fractional part of the argument (this is like floor except for negative numbers)

Comparison

  • Min(float, float)- Returns the minimum of the two numbers
  • Max(float, float)- Returns the maximum of the two numbers

Signs

  • Abs(float)- Absolute value
  • Sign(float)- +1 for positive numbers, -1 for negative numbers

Distance

  • Distance(float, float, float, float)- Distance between two points, parameters are (x1, y1, x2, y2). This is the same as writing sqrt(pow(x1-x2,2) +pow(y1-y2,2)).

Random

  • RandomNumber(integer, integer)- Generates a random number. The first parameter is the minimum and the second parameter is the maximum.

Unit Conversions

  • In2mm(Float)- Converts from inches to millimeters. In case it is ambiguous, that is a capital "i" for "inch" not an "L".
  • mm2In(Float)- Converts from millimeters to inches.
  • ft2m(Float)- Converts from feet to meters.
  • m2ft(Float)- Converts from meters to feet.

Inequality Expressions

These expressions result in a True or False.

= Equals

<> Not Equals (can also use the word NOT, i.e., NOT (VarA = VarB))

> Greater Than

>= Greater Than or Equal

< Less Than

<= Less Than or Equal

Examples

Note that the format 0 < VarA < 12 is not allowed. You must break it up into two sections with an AND in the middle.

(VarA > 0) AND (VarA <= 12)

Note that you have two options with a not equals.

VarA <> 0

--or--

NOT (VarA = 0)

This can be used with an if statement to make a limit. If you want to make sure that you never have a negative number, for example, you can do this.

if(VarA < 0, 0, VarA)    NOTE you can also use max(0,VarA)

This can be used to make an absolute value function.

if(VarA < 0, -VarA, VarA)    NOTE you can also use abs(VarA)

There are Integer and Float types of Numeric variables.

Integer is used for whole numbers (i.e. 1, 2, 3) Float is used for numbers with decimal points (i.e 3.14)

Text Expressions


Text expressions are used to manipulate text strings.

These expressions use Barcode = “Some_String”

 

Logical Text Expressions

These return a True or False value.

text.Equals(text) = boolean

This checks to see if two strings are equals to each other.

  1. (Text) base text string

Example: Barcode = "Some_String"

Barcode.equals(“Some_String”) = TrueBarcode = "Some_String" = True

Contains(text, text) = boolean

This checks to see if a string exists anywhere within another string. Note that this will be True if the second argument is empty text.

  1. (Text) base text string
  2. (Text) substring to find anywhere in the base string.

Example: Barcode = "Some_String"

Barcode.contains(“Some”) = TrueContains(Barcode, "Some") = TrueContains(Barcode, "") = True

Present(text, text) = boolean

This is the same as Contains but will be False if searching for empty text.

  1. (Text) base text string
  2. (Text) substring to find anywhere in the base string.

Example: Barcode = "Some_String"

Present(Barcode, "Some") = TruePresent(Barcode, "") = False

Startswith(text, text) = boolean

This is more stringent than Contains since the string has to be at the beginning of the other string.

  1. (Text) base text string
  2. (Text) substring to find on the left end of the base string.

Example: Barcode = "Some_String"

StartsWith(Barcode, "Some") = True

Endswith(text, text) = boolean

This is true if the string ends with the second string. In this example, "ring" is at the end of "Some_String"

  1. (Text) base text string
  2. (Text) substring to find on the right end of the base string.

Example: Barcode = "Some_String"

EndsWith(Barcode, "ring") = True

IsNumber(text) = boolean

This is great to be able to tell a quantity barcode scan apart from a previous scan that contains letters, for example.

  1. (Text) base text string

Example: Barcode = "Some_String"

IsNumber(Barcode) = FalseIsNumber("5") = True

TextLike(text, text) = boolean

You can check the format of a text string using Regex-style comparisons (Regular Expressions). This example requires the word "Spare" to be exactly right, including capitalization, followed by 3 numbers in a row. No additional characters would be allowed to return True.

  1. (Text) base text string
  2. (Text) pattern to match the base string against

Example:

TextLike("Spare001", "[S][p][a][r][e]###") = True

The comparison is made using the following format specifiers:

? Any single character* Zero or more characters# Any single digit (0-9)[ charlist ] Any single character in charlist[ !charlist ] Any single character not in charlistUse hyphens to denote ranges, like A-F for A, B, C, D, E, and F.

Numeric Text Expressions

This returns an Integer value.

Count(text, text) = integer

This will look in the first text argument and return how many occurrences of the second text argument are found.

  1. (Text) base text string
  2. (Text) substring to count in the base string.

Example:

Count("Hello World", "Hello" = 1Count("Hello World", "l") = 3

Length(text) = integer

The older form “. Length" is interchangeable with the "Length()" form.

  1. (Text) base text string to measure

Example: Barcode = "Some_String"

Barcode.Length = 11Length(Barcode) = 11

IndexOf(text, text, [text], [integer]) = integer

Gives the start index of a substring. There is an optional start position argument that can help you skip past matches towards the left of the string.

  1. (Text) base text string
  2. (Text) search string
  3. optional (Text) delimiter that separates elements in the string instead of using character position.
  4. optional (integer) character position to start searching from, zero is at the beginning.

Examples: Barcode = "Some_String"

IndexOf(Barcode, "S") = 0IndexOf(Barcode, "S", 1) = 5String -  Some_StringIndexes - 0123456789...

There is also an option to specify a delimiter and return the position in terms of that delimiter string. Again, there is an optional start position argument to skip past earlier occurrences of a match. This example has a colon-delimited string, looking for a "C" from the beginning of the string (first example) or starting at the 4th position (second example).

IndexOf("A:B:C:D:E:C:G", "C", ":") = 2IndexOf("A:B:C:D:E:C:G", "C", ":", 3) = 5String -  A:B:C:D:E:C:GIndexes - 0 1 2 3 4 5 6

String Expressions

These return Text values.

Concatenation

There is no Concatenate function per se. You just use the "+" operator instead.

Example: Barcode = "Some_String".

Barcode + “!” = “Some_String!”Barcode + “,” + Barcode = “Some_String,Some_String”

Substring(text, integer, [integer]) = text

This cuts up a string based on a start position (0 is the first digit) and an optional length. Note that there is an older Substring function where you would write "Barcode.Substring(3, 2)". This function generates an error if the Barcode variable is too short. The new Substring function as described below will not generate an error but will instead return a blank value.

  1. (Text) base text string
  2. (integer) staring position of substring, first digit is at zero.
  3. optional (integer) number of characters to use.

This function is fault tolerant so that it will return an empty string if, for example, you attempt to take a substring that is outside of the range of the base string. It will also return all available characters from the end of the base string if you ask for more characters than the base string has.

Example: Barcode = "Some_String".

Substring(Barcode, 3) = “e_String”Substring(Barcode, 3, 2) = “e_”Substring(Barcode, 100) = “”Substring(Barcode, 3, 100) = “e_String”

ToUpper(text) = text

This converts all lowercase letters to uppercase. It has no effect on numbers, spaces, and symbols.

  1. (Text) base text string

Example: Barcode = "Some_String".

ToUpper(Barcode) = "SOME_STRING"

ToLower(text) = text

This converts all uppercase letters to lowercase. It has no effect on numbers, spaces, and symbols.

  1. (Text) base text string

Example: Barcode = "Some_String"

ToLower(Barcode) = "some_string"

Reverse(text) = text

Reverses the order of the characters in a text string.

  1. (Text) base text string

Example: Barcode = "Some_String".

Reverse(Barcode) = "gnirtS_emoS"

RandomLetter([integer], [integer]) = text

This will create an uppercase letter at random. Without any arguments, it will choose any letter from the English alphabet (character codes 65 through 90 on the ASCII table). You can also use a start and range value to randomly from a consecutive section of the Unicode table.

  1. optional (integer) starting character code.
  2. optional (integer) number of characters to choose from

Example:

RandomLetter(0, 2) = Either ""A" or "B".RandomLetter(2, 3) = Either ""C", "D", or "E".RandomLetter() = RandomLetter(0, 26) = "A", "B", ... , or "Z".

You can go beyond the ASCII codes 65 through 90 when you have arguments, but you must subtract 65 from the actual Unicode value.

RandomLetter(880, 25) = random lowercase letter from the Greek alphabet.RandomLetter(975, 32) = random uppercase letter from the Cyrillic alphabet.

PadLeft(text, integer, text) = text

Adds characters to the left of the base text string to bring to overall length of it to a specified value.

  1. (Text) base text string.
  2. (integer) desired overall length.
  3. (Text) character to add to the base string.

Example: Barcode = "Some_String"

PadLeft(Barcode, 15, "x") = "xxxxSome_String"

PadRight(text, integer, text) = text

Adds characters to the right of the base text string to bring to overall length of it to a specified value.

  1. (Text) base text string.
  2. (integer) desired overall length.
  3. (Text) character to add to the base string.

Example: Barcode = "Some_String"

PadRight(Barcode, 15, "x") = "Some_Stringxxxx"

 

Trim(text, [text]) = text

Removes white space characters like spaces, tabs, line feeds from the left and right side of a text string. You can also specify characters to remove.

  1. (Text) Base text string.
  2. optional (Text) Text to be removed.

Example: Removing whitespace and removing "x" characters.

Trim("  Some_String   ") = "Some_String"Trim("xxxSome_Stringxxx","x") = "Some_String"

This removes the following characters. Note that carriage return (13) and line feed (10) often appear together in barcode scans and when you press enter in a text file.

Code Name  9   Tab 10   Line Feed 11   Vertical Tab (rare) 12   Form Feed (rare) 13   Carriage Return 32   Space

This will NOT remove null characters (code 0) or any other non-printable characters.

TrimStart(text, [text]) = text

Removes white space characters like spaces, tabs, line feeds from the left side of a text string. You can also specify characters to remove.

  1. (Text) Base text string.
  2. optional (Text) Text to be removed.

Example: Removing whitespace and removing "x" characters.

TrimStart("   Some_String   ") = "Some_String   "TrimStart("xxxSome_Stringxxx","x") = "Some_Stringxxx"

TrimEnd (text, [text]) = text

Removes white space characters like spaces, tabs, line feeds from the right side of a text string. You can also specify characters to remove.

  1. (Text) Base text string.
  2. optional (Text) Text to be removed.

Example: Removing whitespace and removing "x" characters.

TrimEnd("  Some_String   ") = "   Some_String"TrimEnd("xxxSome_Stringxxx","x") = "xxxSome_String"

Replace(text, text, text) = text

Replace a substring with another substring (or blank string). The most common use of this in practice is to replace a specific substring with empty quotes in order to remove that substring.

  1. (Text) Base text string.
  2. (Text) Text to be replaced.
  3. (Text) Text replacing the above text.

Example: In this example, we replace all occurrences of "Some" with "The" in Barcode = "Some_String". We also show removing "_" characters.

Replace(Barcode, "Some", "The") = "The_String"Replace(Barcode, "_", "") = "SomeString"

Remove(text, integer, integer) = text

Cut out a section of a text string, beginning at a start index and a given number of characters to remove.

  1. (text) Base text string.
  2. (integer) Start position, starting at zero.
  3. (integer) Number of characters to remove.

Example: 2 characters are removed starting at index 3 (the 4th character) from Barcode = "Some_String"

Remove(Barcode, 3, 2) = "SomString"

ToChar(integer) = text

Creates a character from its Unicode value (which matches ASCII codes for small values) - see http://www.asciitable.com/.

  1. (integer) Unicode character code

Example:

ToChar(9) = [Tab]ToChar(10) = [Line Feed]ToChar(13) = [Carriage Return]ToChar(34) = """ (quote)ToChar(65) = "A"ToChar(49) = "1"ToChar(937) = "Ω" (capital omega)

FormatSeconds(integer, text) = text

Convert an integer variable containing seconds into hours, minutes, days, etc. as needed.

  1. (integer) time span in seconds
  2. (Text) format string

Here is how the format string works:

dd - days with leading zero, e.g. 03 days d - days without leading zero, e.g. 3 dayshhh - hours with up to 2 leading zeroes, e.g. 003 hours hh - hours with up to 1 leading zero, e.g. 03 hours  h - hours without leading zeroes, e.g. 3 hoursmmmm - minutes with up to 3 leading zeros, e.g. 0003 minutes mmm - minutes with up to 2 leading zeros, e.g. 003 minutes  mm - minutes with up to 1 leading zero, e.g. 03 minutes   m - minutes without leading zeros, e.g. 3 minutessssss - seconds with up to 4 leading zeros, e.g. 00003 seconds  ssss - seconds with up to 3 leading zeros, e.g. 0003 seconds   sss - seconds with up to 2 leading zeros, e.g. 003 seconds    ss - seconds with up to 1 leading zero, e.g. 03 seconds     s - seconds without leading zeros, e.g. 3 seconds .fff - seconds accurate to the thousandths place e.g. 0.333 seconds (but LGS does not update this fast).ff - seconds accurate to the hundredths place e.g. 0.33 seconds (but LGS does not update this fast).f - seconds accurate to the tenths place e.g. 0.3 seconds

If you specify hours, then the minutes will show 0-59 minutes. If you do not specify any hours, then the minutes will be able to go above 59 minutes as needed. This is true for the other units.

FormatSeconds(123, "m:ss") = "2:03"FormatSeconds(123, "ssss") = "0123"

If you do not specify any formatting, then it will default to "hh:mm:ss" formatting.

WrapText(text, integer) = text

Force a text value to wrap (by adding carriage returns and line feeds) so that each line of text is a up to a specified length long.

  1. (Text) Text to wrap
  2. (Integer) maximum characters per line

Example: Barcode = "Let's wrap this sentence up."

WrapText(Barcode, 8)=Let's wrap this sentenceup.

WrapWords(text, integer) = text

This wraps text like WrapText, but it will attempt to keep words together.

  1. (Text) Text to wrap
  2. (Integer) maximum characters per line


 

Example: Barcode = "Let's wrap this sentence up."

WrapText(Barcode, 8)=Let'swrap this sentenceup.

Convert Other Formats into Text

Use the ToString Function.

Convert Text into Other Formats

Text2Int(text) = integer

Take a text value and attempt to convert it into an integer. Anything that is not clearly an integer will result in a 0 returned. Note that decimal points will cause this to not compute as an integer - for example "1.0" is not an integer and will return 0.

  1. (Text) string with integer numeric value

Example:

Text2Int("1") = 1Text2Int("1.0") = 0

Text2Float(text) = float

Take a text value and attempt to convert it into a floating-point number. This is just like Text2Int but will accept decimal points. Decimal points are not required. Note that decimal points are region-specific and will be commas (,) where appropriate.

  1. (Text) string with decimal numeric value

Example:

Text2Int("1") = 1.0Text2Int("1.0") = 1.0

 

Text2Hex(text) = text

Take a text value and convert the characters into their ASCII codes in hexadecimal format. (v3.5.2.5)

  1. (Text) string with integer numeric value

Example:

Text2Hex("1") = "31"Text2Hex("A") = "41"Text2Hex("ABC") = "414243"Text2Hex("Hello World!") = "48656C6C6F20576F726C6421"

Creating a New Line (CrLf)

You can use CrLf in your expressions as a constant for a carriage return and line feed (ASCII codes, 13 and 10). This will make a new line between two other text values. This is a variable that you do not need to define, so you can use it just like you use any other text variable.

For example, if you want to create a two-line text expression, it might look like this:

"Here is the line one stuff..." + CrLf + "...and here is the line two stuff."

Convert Numbers to String

The following examples use VarA = 1.25

  VarA.tostring(“0”) = 1  VarA.tostring(“0.0”) = 1.3  VarA.tostring(“0.00”) = 1.25  VarA.tostring(“0.000”) = 1.250   VarA.tostring(“0.0000”) = 1.2500  VarA.tostring(“0.0##”) = 1.25  VarA.tostring(“00.0##”) = 01.25  VarA.tostring(“#0.0##”) = 1.25  VarA.tostring(“0000”) = 0001

You can also convert into hexadecimal format. Use a capital "X" followed by how many digits you want to get.

  15.tostring("X1") = "F"  16.tostring("X4") = "0010"  256.tostring("X4") = "0100"

Conditional Expressions

If Statements

It can be very useful to have if-then-else statements. Here is the syntax for doing "if" statements for variables:

if(boolean expression, result if true, result if false)

Note that it may be tempting to use "if" statements to find the min or max value between two numbers, but there are Min and Max functions that are more efficient at this. See Arithmetic Expressions for more information on Min and Max.

Examples

You have a boolean variable called VarA, you need a Text variable that is “T” when the variable is True and “F” when it is False:

if(VarA,“T”,“F”)

You have 3 bolts that each have a vision tool confirming them. You need a Text variable that shows which are true:

if(Cam1_01T,“1”,“0”) + if(Cam1_02T,“2”,“0”) + if(Cam1_03T,“3”,“0”)

Cam1_01T | Cam1_02T | Cam1_03T    Result

------------------------------    ------

 False   |  False   |  False       000

 False   |  False   |  True    ->  003

 True    |  False   |  True        103

 True    |  True    |  True        123

WOW! You can nest if statements!!! If you need to close clamp 1 then clamp 2 then clamp 3, you can set an Integer variable with the lowest numbered clamp that is still open:

if(Open1,1,if(Open2,2,if(Open3,3,0)))

Open1 | Open2 | Open3     Result

---------------------     ------

False | False | False      0

False | False | True   ->  3

True  | False | True       1

True  | True  | True       1

ToString Function

 

Convert Times to String

Time of Day

  Now.tostring(“yyyy.MM.dd HH:mm:ss”) = 2015.03.03 18:52:59

  • yyyy = full year (2015)
  • yy = short year (15)
  • MMM = month abbreviation (Mar)
  • MM = month number (3)
  • dd = day of the month (3)
  • HH = hours in 24-hour time (18)
  • hh = hours in 12-hour time (6)
  • mm = minutes (52)
  • ss = seconds (59)
  • f = fractional seconds

You can use other characters as needed like “.”, “/”, “:”, etc.

 

Step or WI Time

  (floor(StepTime / 3600)).tostring("00") + ":" + (floor((StepTime / 60) % 60)).tostring("00") + ":" + (StepTime % 60).tostring("00") = 18:52:59

This is a system text variable. Use this logic to turn StepTime (which is just seconds) into an HH:mm:ss format.

This logic can be used with any time counting up, like WI_Time.

 

When using VDF Text

Use Advanced VDF Text when showing a value of a variable in a VDF Text and you will not have to create a special text variable in order to format it.

 

Binary Expressions

Reversing Bits and Bytes

Several functions are used to change the bit order in integer values. This is useful especially in PLC communications because some PLC will communicate integers with bits in different orders. For example, using an Anybus Gateway with an Allen Bradley ControlLogix PLC will have the bits reversed within each byte and can be corrected with the ReverseBitsInBytes function.

  • ReverseBits(int, int)- All bits are reversed
  • ReverseBytes(int, int)- Bits are in order within bytes, but bytes are reversed within the integer
  • ReverseBitsInBytes(int, int)- Bits are reversed within each byte, but the bytes remain in order

  Mode       - -- -- -- -- -- --  Bit Ordering -- -- -- -- -- -- -> Decimal = Binary ExampleNormal       - 15 14 13 12 11 10  9  8 .  7  6  5  4  3  2  1  0 ->    363  = 00000001.00000111Bits         -  0  1  2  3  4  5  6  7 .  8  9 10 11 12 13 14 15 ->  57472  = 11100000.10000000Bytes        -  7  6  5  4  3  2  1  0 . 15 14 13 12 11 10  9  8 ->   1793  = 00000111.00000001BitsInBytes  -  8  9 10 11 12 13 14 15 .  0  1  2  3  4  5  6  7 ->  32992  = 10000000.11100000

Masking Bits

You can do bitwise AND, OR, and XOR functions using the same operators as logical AND, OR, and XOR. These examples use a variable called PLC_In00 that is an 8-bit integer with a value of 6, which in binary is 0000000000000110

PLC_In00 AND 1 = 0 -> In binary notation, this is 00000110 AND 00000001 = 00000000PLC_In00 AND 2 = 2 -> In binary notation, this is 00000110 AND 00000010 = 00000010PLC_In00 AND 4 = 4 -> In binary notation, this is 00000110 AND 00000100 = 00000100PLC_In00 AND 8 = 0 -> In binary notation, this is 00000110 AND 00001000 = 00001000

You can check to see if the result of the mask is greater than zero in order to get a True or False from this.

(PLC_In00 AND 1) > 0

In order to make this simpler, we have a BitMask function that does this logic automatically.

BitMask(int, int) - the first parameter is an integer that you want to mask a bit from, the second parameter is the bit position. This returns True if that bit is a 1 and False if it is a zero.

BitMask(PLC_In00, 0) is the same as (PLC_In00 AND 1) > 0 = FalseBitMask(PLC_In00, 1) is the same as (PLC_In00 AND 2) > 0 = TrueBitMask(PLC_In00, 2) is the same as (PLC_In00 AND 4) > 0 = TrueBitMask(PLC_In00, 3) is the same as (PLC_In00 AND 8) > 0 = FalseBitMask(PLC_In00, 4) is the same as (PLC_In00 AND 16) > 0 = False

Parsing Expressions

Parsing Types

There are 5 main text format types that we can parse.

  • Array
  • Key-Value Pair
  • JSON (JavaScript Object Notation)
  • XML (Extensible Markup Language)
  • GET/POST URL parameters

These all return a text value unless you use a "Bool", "Int", or "Float" suffix to return specific types. This is sometimes important when using these functions inside "if" statements or other functions.

Array

ArrayParse(text, text, integer) = text

Breaks up a text string using a delimiter and grab a particular indexed value with this function.

  1. (Text) Delimited string
  2. (Text) Delimiter (what separates values from each other)
  3. (Integer) Index of which value to return

The following example grabs the 3rd item from a barcode with comma-delimited values.

Example: Barcode = "9,8,7,6,5,4,3,2,1"

ArrayParse(Barcode, ",", 2) = "7"

ArrayParseBool(text, text, integer) = boolean

Breaks up a text string using a delimiter and grab a particular indexed value with this function.

  1. (Text) Delimited string
  2. (Text) Delimiter (what separates values from each other)
  3. (Integer) Index of which value to return.

The following example grabs the 3rd item from a barcode with comma-delimited values.

Example: Barcode = "1,0,1,0,0,0,1,0,1"

ArrayParseBool(Barcode, ",", 2) = True

ArrayParseInt(text, text, integer) = integer

Breaks up a text string using a delimiter and grab a particular indexed value with this function.

  1. (Text) Delimited string
  2. (Text) Delimiter (what separates values from each other)
  3. (Integer) Index of which value to return.

The following example grabs the 3rd item from a barcode with comma-delimited values.

Example: Barcode = "9,8,7,6,5,4,3,2,1"

ArrayParseInt(Barcode, ",", 2) = 7

ArrayParseFloat(text, text, integer) = float

Breaks up a text string using a delimiter and grab a particular indexed value with this function.

  1. (Text) Delimited string
  2. (Text) Delimiter (what separates values from each other)
  3. (Integer) Index of which value to return

The following example grabs the 3rd item from a barcode with comma-delimited values.

Example: Barcode = "9.2,8.1,7.7,6.8,5.3,4.2,3.1,2.0,1.9"

ArrayParseFloat(Barcode, ",", 2) = 7.7

 

Key-Value Pair

KVPParse(text, text, text, text, [text]) = text

Grabs value data from key-value pair text using a key name. This will always return text data, even when the value is numeric.

  1. (Text) key-value pair string to grab data from
  2. (Text) key name
  3. (Text) separator between key and value
  4. (Text) delimiter between sets of key-value pairs
  5. (Text) default value to return if the key is not found or the data is invalid

Example: Barcode = "Apples=4;Oranges=3"

JSONParse(Barcode, "Apples", "=", ";") = "4"JSONParse(Barcode, "NotATag", "=", ";", "ERROR") = "ERROR"

KVPParseBool(text, text, text, text, [boolean]) = boolean

Grabs value data from key-value pair text using a key name. This will always return text data, even when the value is numeric.

  1. (Text) key-value pair string to grab data from.
  2. (Text) key name.
  3. (Text) separator between key and value.
  4. (Text) delimiter between sets of key-value pairs.
  5. (Boolean) default value to return if the key is not found or the data is invalid.

Example: Barcode = "Apples=T;Oranges=F"

JSONParseBool(Barcode, "Apples", "=", ";") = TrueJSONParseBool(Barcode, "NotATag", "=", ";", False) = False

KVPParseInt(text, text, text, text, [integer]) = integer

Grabs value data from key-value pair text using a key name. This will always return text data, even when the value is numeric.

  1. (Text) key-value pair string to grab data from.
  2. (Text) key name.
  3. (Text) separator between key and value.
  4. (Text) delimiter between sets of key-value pairs.
  5. (Integer) default value to return if the key is not found or the data is invalid.

Example: Barcode = "Apples=4;Oranges=3"

JSONParseInt(Barcode, "Apples", "=", ";") = 4JSONParseInt(Barcode, "NotATag", "=", ";", -1) = -1

KVPParseFloat(text, text, text, text, [float]) = float

Grabs value data from key-value pair text using a key name. This will always return text data, even when the value is numeric.

  1. (Text) key-value pair string to grab data from.
  2. (Text) key name.
  3. (Text) separator between key and value.
  4. (Text) delimiter between sets of key-value pairs.
  5. (Float) default value to return if the key is not found or the data is invalid.

Example: Barcode = "Apples=4.5;Oranges=3.2"

JSONParseFloat(Barcode, "Apples", "=", ";") = 4.5JSONParseFloat(Barcode, "NotATag", "=", ";", -1.0) = -1.0

URL

GetURLParameter(text, text) = text

Pull the value of a URL parameter when using a GET or POST command like the following:

  1. (Text) Raw URL reponse.
  2. (Text) parameter key.

Example: MyURLResult = "GET /?param1=hello&param2=world HTTP/1.1"

GetURLParameter(MyURLResult, "param1") = "hello"

JSON

JSONParse(text, text, text) = text

Grabs value data from JSON using a key name. This will always return text data, even when the value is numeric.

  1. (Text) JSON string to grab data from.
  2. (Text) key name.
  3. (Text) default value to return if the key is not found or the data is invalid.

JSON looks like this: {"key1":"value1","key2":"value2"}

Example: Barcode = {"Apples":4,"Oranges":3}

JSONParse(Barcode, "Apples", "ERROR") = "4"JSONParse(Barcode, "NotATag", "ERROR") = "ERROR"

JSONParseBool(text, text, boolean) = boolean

This is the same as JSONParse but will return an integer value. It will return a default value (third parameter) if the tag does not exist or is not a boolean.

  1. (Text) JSON string to grab data from.
  2. (Text) key name.
  3. (Boolean) default value to return if the key is not found or the data is invalid.

Example: Barcode = {"PartPresent":"T","SkipPart":"false"}

JSONParseBool(Barcode, "PartPresent", False) = TrueJSONParseBool(Barcode, "NotATag", False) = False

JSONParseInt(text, text, integer) = integer

This is the same as JSONParse but will return an integer value. It will return a default value (third parameter) if the tag doesn't exist or is not an integer.

  1. (Text) JSON string to grab data from.
  2. (Text) key name.
  3. (integer) default value to return if the key is not found or the data is invalid.

Example: Barcode = {"Apples":4,"Oranges":3}

JSONParseInt(Barcode, "Apples", -1) = 4JSONParseInt(Barcode, "NotATag", -1) = -1

JSONParseFloat(text, text, float) = float

This is the same as JSONParse but will return a float value. It will return a default value (third parameter) if the tag doesn't exist or is not a float.

  1. (Text) JSON string to grab data from.
  2. (Text) key name.
  3. (Float) default value to return if the key is not found or the data is invalid.

Example: Barcode = {"Apples":4,"Oranges":3}

JSONParseFloat(Barcode, "Apples", 99.0) = 4.0JSONParseFloat(Barcode, "NotATag", 99.0) = 99.0

XML

XMLParse(text, text, [integer]) = text

Grab text data from XML using a tag name and [optional index] (in case the same tag appears more than once).

  1. (Text) XML string to grab data from.
  2. (Text) tag name.
  3. optional (integer) index, starting at 0, for tags that appear more than once.

Example: Barcode = <tag1>water</tag1><tag2>flour</tag2><tag3>yeast</tag3><tag1>salt</tag1>

XMLParse(Barcode, "tag1") = "water"XMLParse(Barcode, "tag1", 1) = "salt"

XMLParseBool(text, text, [integer]) = boolean

Grab text data from XML using a tag name and [optional index] (in case the same tag appears more than once).

  1. (Text) XML string to grab data from.
  2. (Text) tag name.
  3. optional (integer) index, starting at 0, for tags that appear more than once.

Example: Barcode = <tag1>false</tag1><tag2>true</tag2><tag3>true</tag3><tag1>true</tag1>

XMLParseBool(Barcode, "tag1") = FalseXMLParseBool(Barcode, "tag1", 1) = True

XMLParseInt(text, text, [integer]) = integer

Grab text data from XML using a tag name and [optional index] (in case the same tag appears more than once).

  1. (Text) XML string to grab data from.
  2. (Text) tag name.
  3. optional (integer) index, starting at 0, for tags that appear more than once.

Example: Barcode = <tag1>8</tag1><tag2>12</tag2><tag3>3</tag3><tag1>21</tag1>

XMLParseInt(Barcode, "tag1") = 8XMLParseInt(Barcode, "tag1", 1) = 21

XMLParseFloat(text, text, [integer]) = float

Grab text data from XML using a tag name and [optional index] (in case the same tag appears more than once).

  1. (Text) XML string to grab data from.
  2. (Text) tag name.
  3. optional (integer) index, starting at 0, for tags that appear more than once.



 

Example: Barcode = <tag1>2.0</tag1><tag2>2.1</tag2><tag3>2.2</tag3><tag1>99.99</tag1>

XMLParseFloat(Barcode, "tag1") = 2.0XMLParseFloat(Barcode, "tag1", 1) = 99.99