Test controller, functions
TestController supports expressions in a lot of places, for most users it will be the math page and the calculator that is most interesting. All places uses the same evaluator, that support a wide variety of functions. This list will show the most relevant functions, but not all supported functions.
Contents
System
Typecast
Failsafe reading of a variable
Testing for invalid value
Trapping any error or fault
Creating arrays
Bytes
runScript & runScriptAsync
Mathematic
Simple
Complex mathematic
Solve
Poly
Quadratic equation
Electronic functions
Find a standard value
Calculate parallel resistors
Combine two standard values to get an a good match
Voltage divider with standard values
Other voltage divider functions
Decibel dB
Complex values for electronic calculation
Sensor functions
Temperature sensors thermistor/NTC
Temperature sensors PTC
Temperature sensors RTD
Temperature sensors thermocouples
Date & time functions
Getting a date/time variable
Converting between integer and date/time
Timing stuff
Writing a time stamp
Test controller device functions
getDevice
get..., set..., read... name..., unit...
deviceWrite, deviceRead, deviceReadBytes, deviceWriteBytes
Table related functions
tableRows & tableColumns
tableSample
tableTimeIndex
tableColumnName & tableColumnIdentifier
tableColumnUnit
tableColumnFormat
table
tableMin, tableMax & tableRange
tableValue
tableTopPeak & tableBottomPeak
tableRaise & tableFall
tableCalcMax & TableCalcMin
tableCalcAvg
tableCalcSum
tableCalcRMS
tableCalcSlope
tableCalcStdDev
tableCalcTimeSum
tableTime
tableAddCSVText
tableInitHeader && tableAddRow
String functions
unQuote
listIndex
inList
getElement
substring
match
getMatch & getMatchGroup
countMatch
trim
equals & equalsi
replace, replacei, replaceRX
indexOf & lastIndexOf
formatLeft & formatRight
formatDouble
formatSI
formatHMS
parseSI
parseHMS
formatInt
strlen
Other functions
matchBits
matchBitsList
displayVar
binConv
binConvFloat
binConvString
binConvBit
bytesAsHex
makeDouble
hex
addImage
deviceMode
isDeviceMode
modeColumnNames
isLogging
isLoggingToDisk
loggingInterval
printLog
Notes
Main page
Another documentation for the programming language, not related to TestController.
System
Typecast
Generally the evaluator will do automatic typecasting, but sometimes it can be necessary to force a specific type.
Code:
double(value)
complex(value)
int(value)
string(value)
array(value)
vector(value)
matrix(value)
bytes(value)
The above function will return the specified type, but the automatic type casting can change the type to another. This automatic typecast is most obvious between numbers and strings containing numbers.
To check the type of a variable use type(v), the normal types will be long/double/string, but there are also complex/dateTime/array/struct/...
Failsafe reading of a variable
In some cases it is not known if the variable exist before using it, it can be handled in two ways:
This will always return a value, when the name do not exist it will be an empty value, if name exist it will the the value of name.
Returns true or false depending on if a variable with name exist.
Testing for invalid value
A invalid value may fail the expression with a error return or just return a invalid result, but there are ways to trap these conditions:
Code:
isNan(value{,value{,value...}});
Will return true i if any of the listed values is a NaN (Not a Number). It will not detect infinite values.
Code:
isInfinite(value{,value{,value...}});
A infinite value will usually mean the result is infinite, but with this test it can return true instead.
Code:
invalidValue(value);
It is possible to generate a invalid value, depending on value this function will return:
value>0 -> Positive infinite
value<0 -> Negative infinite
value==0 -> NaN (Not a number).
Trapping any error or fault
It is possible to trap any error or fault and return a user defined value. This will trap anything, including syntax and external errors.
Code:
noFault()+any expression
noFault();any statement
noFault(returnValue)+any expression
noFault(returnValue);any statement
The function noFault will always return 0 and enable a trap for any sequent errors. The calls without a returnValue will use a 0 return value on faults/errors.
Creating arrays
Arrays is used to hold many values and some functions will accept an array argument, instead of a list of values.
Arrays are always starting from element 0 and will automatic increase to contain the specified number of elements.
Below I create a array with on element and then increase it to four element:
Code:
var a[0]=1;
a[3]=4;
Another way to create an array and initialize it at the same time is:
Code:
array(listOfValues)
var a=array(1,2,3,4)
A slight variation of the above, here each value of a array parameters will be added separately, i.e. the final array will contain 5 elements (If I had used array() the final array would be two elements with first first element a 4 element array):
Code:
arrayCombine(listOfValues)
var a=arrayCombine(array(1,2,3,4),5)
Note: The array() will try to typecast when called with one parameter.
Bytes
With the bytes data type it is possible to build byte string and read byte strings. Most datatypes can be cast to bytes and will return a binary representation of the contents.
Code:
bytes(value)
bytes(value,value,...)
The bytes function can work either as a typecast when used with one argument or be used to build a byte string used with multiple arguments. When used with multiple arguments a integer will always be used as a single byte, other types will be typecast to bytes before adding them to the string.
The bytes type can be typecast to double (Must be 4 or 8 bytes long), int (Must be up to 8 bytes long), string.
Code:
subbytes(value,from)
subbytes(value,from,to)
Value can be any datatype that can be typecast to bytes and subbytes will return the specified bytes from it (It is similar to substring, except for bytes).
Code:
floatBytes(value{,swap})
doubleBytes(value{,swap})
Cast a float to bytes, float is 4 byte single precision type, double is 8 byte double precision type. Value can be any numeric type. The bytes(value) function will always cast as doubleBytes(value) for a float/double argument.
Conversion to and from string will use codepage ISO-8859-1 that supports all characters from 00 to 0xff.
Code:
bytes(1,2,3,4,5);Make a byte string with: 0x01 0x02 0x03 0x04 0x05
bytes(1000>>8,1000); Encode 1000 in two bytes with msb first
bytes(1000,1000>>8); Encode 1000 in two bytes with lsb first
bytes(subbytes(1000,0,2),subbytes(0,2));Encode two integers with lsb first and two bytes for each
Only a few functions support the bytes datatype, they are:
Typecast functions: double, int, string
binConv, binConvFloat, binConvString, subbytes, floatBytes, doubleBytes, size
runScript & runScriptAsync
Run a command line script with # commands. The async will run in a new thread, i.e. the function call will return immediately .
If the name starts with # it is assumed to be the script.
Code:
runScript(name{,params...});
runScriptAsync(name{,params...});
Mathematic
Simple
All the standard mathematic functions are supported by TestController.
Numeric handling:
Code:
abs(v)// Strip sign
floor(v) // Round toward zero
round(v) // Standard 0.5 rounding
sign(v)// Return sign, i.e. -1, 0 or 1
limit(value,min,max) // Returns value while between min/max else either min or max.
max(v1,v2,...)// Return the highest number from the parameters
min(v1,v2,...)// Return the lowest number from the parameters
Power and exponential functions:
Code:
sqr(v)// Returns square of v, i.e. v*v
sqrt(v)// Returns square root of v
hypot(y,x) // Returns sqrt(sqr(y)+sqr(x))
ln(v)// Return natural logarithmic of v
exp(v)// Returns e to the v power.
log(v)// Return log 10 of v
pow(base,exp) // Returns base to exp power.
Trigonometry functions (Angles are in radians):
Code:
acos(v)// arc cosine, returns result in radians
asin(v)// arc sine, returns result in radians
atan(v)// arc tangent, returns result in radians
atan2(y,x)// Angle in radians from rectangular coordinates
cos(v)// cosine, input is in radians
sin(v)// sine, input is in radians
tan(v)// tangent, input is in radians
toRad(deg)// Convert degree to radians
toDeg(rad)// Convert radians to degree
Hyperbolic trigonometry functions:
Code:
asinh(v)
acosh(v)
atanh(v)
sinh(v)
cosh(v)
tanh(v)
A few constants are included:
There is no i or j constant, but they can easily be defined with "var i=1i;const("i");" making it possible to write 3+i instead of 3+1i
Complex mathematic
Most mathematic functions support complex arguments, but will not use complex arithmetic except one of the arguments are complex.
This means sqrt(-1) is invalid, but sqrt(complex(-1)) or sqrt(-1+0i) is valid. A complex number stays complex, even if the imaginary part is zero.
There are a few functions specific for complex numbers:
Code:
cpxPolar(vector,angle)// Create a complex value from polar coordinates (Angle is in radians)
conj(v)// Calculate the conjugate of a complex value, for sqrt & qeq use this function to show the other complex root.
complex(v)// Cast argument to complex
Solve
This is a function to numerically solve an expression for minimum, maximum or zero result.
It will first calculate the result at the two endpoints, if they have different signs there will be a zero in the range and it will solve for that.
If they have the same sign it will calculate the result midways between start and end. If this value is higher than either start or end it will solve for a maximum, if the result is lower than either start or end it will solve for minimum.
If there are multiple zeros, minimums or maximums inside the range it is unspecific which one is found.
The expression must use the variable x and be in a string type. Being numerically solved the result will not be exact, but the calculated x will have 10 significant digits.
The result will contain x, the value of the expression and what was solved for: min/max/zero
Code:
solve(expression,start,end)
solve("x-2",-10,10)// This will solve for a zero
solve("sqr(x-2)",-10,10)// This will solve for a minimum
solve("sqr(x-2)-5",-10,10)// This will solve for a minimum
solve("sqr(x-2)-5",0,10)// This will solve for a zero
Poly
Calculate a polynomial expression, that is one like this: a0 + a1*x + a2*x*x + a3*x*x*x...
Code:
poly(x,a0,a1,a2,a3,...)
var a=array(a0,a1,a2,a3,...)
poly(x,a)
Quadratic equation
Solver for quadratic equation, it can both handle real and complex arguments.
It will return a fail, one or two values depending on the input. When called with real arguments only real answers will be returned, to get complex answers at least one of the arguments must be complex.
Electronic functions
Find a standard value
There is a couple of function to map a value to the nearest E series value.
series: 0=E3, 1=E6, 2=E12, 3=E24, 4=E48, 5=E96, 6=E192, 12=E12, 24=E24, 48=E48, 96=E96, 125=R125, 192=E192, any other value will return E192
Code:
findE(series,resistor)
findE6(resistor)
findE12(resistor)
findE24(resistor)
findE48(resistor)
findE96(resistor)
findE192(resistor)
Calculate parallel resistors
This function can calculate the parallel value of any number of resistors or inductors or the serial value of capacitors.
Combine two standard values to get an a good match
These functions will do series or parallel coupling of components to get as close to the specified value as possible.
series: 0=E3, 1=E6, 2=E12, 3=E24, 4=E48, 5=E96, 6=E192, 12=E12, 24=E24, 48=E48, 96=E96, 125=R125, 192=E192, any other value will return E192
Code:
findRser(series,resistance)
findRpar(series,resistance)
findCser(series,capacitance)
findCpar(series,capacitance)
findLser(series,inductance)
findLpar(series,inductance)
findR(series,resistance)
findC(series,capacitance)
findL(series,inductance)
findXser & findXpar will only find the best serial or parallel combinations or components in the specified series.
The findX function will locate the optimal combination of parts. This means it will check single part, series parts and parallel parts and return the best match for the requested value.
With E12 the combination will be below 0.8% excluding component tolerance for findX.
With E24 the combination will be below 0.3% excluding component tolerance for findX.
With E48 the combination will be below 0.06% excluding component tolerance for findX.
Voltage divider with standard values
Voltage dividers are easy to calculate, but getting the best combination of resistors from standard values can be a bit tedious work. I have implemented some functions to make it easier:
Code:
vdiv(vin,r1,r2)
vdiv(series,inputVoltage,outputVoltage,dividerCurrent)
vdiv2(series,inputVoltage,outputVoltage,dividerCurrent)
vdiv(12,10,3,1m)
The vdiv with 3 parameters will calculated the output voltage and the divider current.
The vdiv function with 4 parameters will search around the optimal resistor and pick the best combination within a couple of steps. This means there is a fairly large tolerance on the divider current.
The vdiv2 function will pick the best top resistor in the series and then pick a parallel combination for the bottom resistor. This will give more precise divider current and more precise output voltage at the cost of one extra resistor. This function will skip the paralleling if a single resistor is better.
R1 is top resistor, R2 is bottom resistor.
Other voltage divider functions
vdivLowR() can be used to calculate sensor resistance when the sensor is used with a pullup resistor.
Code:
vdivLowR(inputVoltage,highR,outputVoltage)
vdivLowR(5,10k,1.34) will output 3.6612k as the other resistor (sensor) resistance.
Decibel dB
Decibel is a logarithmic function that is used for both absolute levels and for amplification/attenuation. The implemented functions are for absolute values, this can used on measured input and output levels. Subtracting them from each other will give the amplification/attenuation.
Code:
dBV(voltage)// dB above/below 1V
dBm(power)// dB above/below 1mW
dBm(voltage,resistance)// dB above/below 1mW in resistance
dBm(voltage,600)// dB above/below 0.775 volt, this is very common in audio and is called dBu
Complex values for electronic calculation
Converting capacitors and inductors to complex values makes it possible to calculated with them the same way as with resistors. Note that all calculations are done at a specific frequency.
The functions to turn components into complex values are:
cpxR(R)
cpxC(freq,C)
cpxC(freq,C,Rs)
cpxL(freq,L)
cpxL(freq,L,Rs)
cpxCLRs(freq,C,L,Rs)
cpxCLRs(freq,C,L,Rs,Rp)
cpxCLRp(freq,C,L,Rs)
cpxCLRp(freq,C,L,Rs,Rp)
Note: The cpxR is only a typecast to complex and it not needed (The typecast would be done automatic).
Converting back from complex (The complex value is the complex impedance):
Code:
cpxToQ(cpxValue)
cpxToZ(cpxValue)
cpxToPhase(cpxValue)
cpxToCLRs(freq,cpxValue)
Sensor functions
Temperature sensors thermistor/NTC
Thermistors can be described two ways, either with a beta or with A B & C coefficients (Steinhart–Hart), these last method is more precise. There are functions for both methods.
Code:
ntcB(r0,t0,beta,resistance);
ntcSH(a,b,c,resistance);
ntcBT(r0,t0,beta,temperature);
ntcSHT(a,b,c,temperature);
Sometimes it is easier pack the coefficients into a single variable or to calculate the coefficients from a resistance table. Placing the ntcCoef() function in .../Documents/TestController/Settings/autorun.txt means it will be automatic run each time TestController is started.
Code:
globalvar ntc1=ntcCoef(r,beta)
globalvar ntc1=ntcCoef(a,b,c)
globalvar ntc1=ntcCoef(r1,t1,r2,t2)
globalvar ntc1=ntcCoef(r1,t1,r2,t2,r3,t3)
ntc(ntc1,resistance)
ntcT(ntc1,temperature)
See function vdivLowR(Vin,highR,vout) when sensor is used with a pullup resistor.
Temperature sensors PTC
Precision PTC sensors are silicon based temperature sensitive resistors. These sensor may be polarity and current sensitive, i.e. check the datasheet for correct operating conditions.
The math used is a second or higher degree polynomial with coefficients as specified in the datasheets. These polynomials varies between sensors, TC will select the one matching the specified sensor type.
Code:
ptc(type,resistance)
ptc(type,resistance,reference_resistance)
ptcT(type,temperature)
ptcT(type,temperature,reference_resistance)
ptcTypes()
ptcInfo(type)
ptc("kty81/150",1500)
ptc("kty81/150",1500,1022)
ptcT("kty83/110",100)
ptcT("kty83/110",100,1010)
For NXP and Infineon KTY the type can be one of: KT100, KT110, KT130, KT210, KT230, KT83A, KT83C, KT83D, KT83E, KT83H, KT83K, KT84L, KT84M, KT84O, KTY10-5, KTY10-6, KTY10-62, KTY10-7, KTY11-5, KTY11-6, KTY11-7, KTY13-5, KTY13-6, KTY13-7, KTY21-5, KTY21-6, KTY21-7, KTY23-5, KTY23-6, KTY23-7, KTY81/110, KTY81/120, KTY81/121, KTY81/122, KTY81/150, KTY81/210, KTY81/220, KTY81/221, KTY81/222, KTY81/250, KTY82/110, KTY82/120, KTY82/121, KTY82/122, KTY82/150, KTY82/151, KTY82/210, KTY82/220, KTY82/221, KTY82/222, KTY82/250, KTY82/251, KTY82/252, KTY83/110, KTY83/120, KTY83/121, KTY83/122, KTY83/150, KTY83/151, KTY84/130, KTY84/150, KTY84/151, N1, N5, N6, N7, T1, T5, T6, T7
Note: Infineon types are only precise up to 130°C
For Vishay TFPT the type can be one of: TFPT100, TFPT10K, TFPT120, TFPT150, TFPT180, TFPT1K, TFPT1K2, TFPT1K5, TFPT1K8, TFPT220, TFPT270, TFPT2K2, TFPT2K7, TFPT330, TFPT390, TFPT3K3, TFPT3K9, TFPT470, TFPT4K7, TFPT560, TFPT5K, TFPT5K6, TFPT680, TFPT6K8, TFPT820, TFPT8K2
reference_resistance is not needed, but when used will override the internal specification for sensor resistance. The value must be inside specified range for the selected sensor type.
See function vdivLowR(Vin,highR,vout) when sensor is used with a pullup resistor.
Temperature sensors RTD
These is support for a couple of different RTD sensors:
- PT: Standard termocouplers with alpha=0.00385
- ITS-90: Lab grade termocouplers with alpha=0.003926, will normally be encapsulated in glass.
- CU: Copper with alpha=0.00427
- NI: Nickel with, calibrated for Ni1000 with 1618ohm at 100°C
With PT & ITS-90 sensors the Callendar-Van Dusen equations are used, with Ni a polyfit, with CU it is the simple equation.
The sensor type is specified in the function call:
Code:
rtd(type,resistance)// Shortcut, for types PT100 & PT1000
rtdT(type,temperature)// Shortcut, for types PT100 & PT1000
rtd(type,r0,resistance)
rtdT(type,r0,temperature)
rtd("PT100",105.3);
rtdT("PT",100,300);
Temperature sensors thermocouples
There is support for eight types: J B E N R S T K, I uses ITS90 data from NIST for the conversion, this means all conversion between volt and temperature are better than 0.1°C in precision.
To use it requires a meter with 10uV resolution, i.e. mV with two decimals.
The function do not include cold junction compensation, this must be added/subtracted externally.
Code:
thermocouple(type,voltage)
thermocoupleT(type,temperature)
thermocoupleInfo(type)
thermocouple("j",3m)+25
Date & time functions
There is generally not much use for these in TestController, but one application is a time based trigger when logging using the date() function
Getting a date/time variable
Code:
date();
date(format);
date(year,month,date);
date(hour,minute,seconds,millis);// Will assume the current date
date(year,month,date,hour,minute,seconds);
date(year,month,date,hour,minute,seconds,millis);
This function will return current date and time or encode a date time value from discrete date and time elements.
The date is stored as a millisecond value and can be compared and when read as string it will return a yyyymmddhhmmss format.
To get a integer with the current time and date use long(date()), it will return milliseconds since 1-1-1970
Converting between integer and date/time
Code:
msToDate(ms_since_1970)
dateToms(dateType)
msToDateGMT(ms_since_1970)
dateTomsGMT(dateType)
tzOffset()
This function will convert between integer and date/time type, the integer will be in milliseconds since 1-1-1970, this is similar to unit (unix uses seconds).
The first function (msToDate()) will include timezone in the conversions, the two with GMT in the name will assume timzone is GMT, i.e. 0
The tzOffset() will return the actual timezone offset in milliseconds, using msToDate(xxx-tzOffset()) is similar to msToDateGMT(xxx)
Note: dateToms(dateType) is the same as a typecast: long(dateType)
Timing stuff
This function will return seconds, there is no specific starting value, i.e. it can only be used for time differences like this:
Code:
=var startTime=seconds();
...Do something
="Time used "+(seconds()-startTime)
The resolution is better than milliseconds.
Writing a time stamp
Code:
timestamp();
dateTimestamp();
These functions are a easy way to get a formatted date and time value for use in logs. The date function returns: hh:mm:ss (08:50:25) and the dateTimestamp() returns yyyymmdd hh:mm:ss (20201019 08:50:32)
Test controller device functions
These functions are for controlling devices in TestController.
getDevice
This function is used to get a device of a specific kind, it is independent of brand or specifications for the device, but will return the first, second, etc. device loaded.
When specifying the interfaceType it is possible to add a ":index" to it, this will return 2, 3, 4, ... etc. device. It can either be next unit in a multichannel device or next device.
Use + before the device name to get next device of the same type.
Use * before or after the device name to get all devices of that type as an array.
Code:
getDevice(interfaceType);
var ps=getDevice("PS")
; Initialize all loads and start them, this only works if the devices support the same commands
var loads=getDevice("load*")
#async (loads) current 10;on 1
get..., set..., read... name..., unit...
These functions are the used with the generic interface, they will usually be named the same and have the same parameters across brands.
They are used for making scripts generic, i.e. not depend on a specific brand or type of equipment, only the actual function matters.
The name... can be used to select scales (table must contain data) or define math:
Code:
var ps= getDevice("ps")
#chartCurves (nameVoltage(ps)) (nameCurrent(ps))
#math Capacity Ah SumTimeHour 0 (nameCurrent(ps))
The unit... can be used to show unit when scripting:
Code:
var ps= getDevice("ps")
=readvoltage(ps)+unitVoltage(ps)
Note: Both name... & unit.. only works with the loaded devices, they may not work table data from a loaded file.
deviceWrite, deviceRead, deviceReadBytes, deviceWriteBytes
These two first functions are basically the same, except only deviceRead will return a result. They are used to send SCPI commands to device when in calculator mode.
The third function is very different, it supports the SCPI binary answer mode and will receive any length of binary data. This is returned as a bytes data type and it may be necessary to convert it to text with binConvString(). The deviceWriteBytes() will send a SCPI command followed by a frame with binary data using the SCPI binary mode format. At default the deviceWriteBytes() will not add any eol characters, but they can be added with the fourth parameter (Use "\n").
Code:
deviceWrite(device,scpi_commands)
deviceRead(device,scpi_commands)
deviceReadBytes(device,scpi_commands)
deviceWriteBytes(device,scpi_command,data{,eol})
Table related functions
TestController has functions to access and search the data in the table.
The row is specified with the rowIndex
The column is specified with the index or with the name.
tableRows & tableColumns
Returns the size of the table
Code:
tableRows()
tableColumns()
tableSample
Convert a rowIndex to "Sample" specification for use on export/chart/histogram/range pages.
Code:
tableSample(rowIndex);
tableTimeIndex
Convert a time in seconds to a rowIndex.
Code:
tableTimeIndex(seconds)
tableColumnName & tableColumnIdentifier
Returns the column name for a specified column index.
The identifier is the variable name used for the column, it will usually be the same as name, except with CSV files generated with other software.
Code:
tableColumnName(columnIndex)
tableColumnIdentifier(columnIndex)
tableColumnUnit
Returns the unit for the specified column, will return a empty string if the column is invalid.
Code:
tableColumnUnit(columnIndex)
tableColumnUnit(columnName)
tableColumnFormat
Use the same formatter as the table column, with or without a unit specification, will use a standard format if the column is invalid.
Code:
tableColumnFormat(columnIndex,value)
tableColumnFormat(columnName,value)
tableColumnFormat(columnIndex,value,useUnit)
tableColumnFormat(columnName,value,useUnit)
table
Return a value from table, either a single value or a full row as a array
Code:
table(rowIndex)
table(rowIndex,column)
tableMin, tableMax & tableRange
Returns rowIndex of minimum or maximum value from the table, this can be in a restricted range. The Range version returns (max-min) for the specified range.
rowIndexStart is first row checked
rowIndexEnd is last row checked
Code:
tableMin(column);
tableMin(column,rowIndexStart);
tableMin(column,rowIndexStart,rowIndexEnd);
tableMin(column,rowIndexStart,rowIndexEnd,reverse);
tableMax(column);
tableMax(column,rowIndexStart);
tableMax(column,rowIndexStart,rowIndexEnd);
tableMax(column,rowIndexStart,rowIndexEnd,reverse);
tableRange(column);
tableRange(column,rowIndexStart);
tableRange(column,rowIndexStart,rowIndexEnd);
tableRange(column,rowIndexStart,rowIndexEnd,reverse);
tableValue
Returns rowIndex of value from the table, this can be in a restricted range. This functions looks for the point where the actual values goes from below to above or vice verse and returns the closest entry. I.e. two samples 0, 1 will match any tableValue between 0 and 1 and return the first sample when tableValue is below 0.5.
rowIndexStart is first row checked
rowIndexEnd is last row checked
Code:
tableValue(value,column);
tableValue(value,column,rowStartIndex);
tableValue(value,column,rowStartIndex,rowEndIndex);
tableValue(value,column,rowStartIndex,rowEndIndex,reverse);
tableTopPeak & tableBottomPeak
Returns rowIndex of first peak from the table, this can be in a restricted range.
A top peak is not the highest value, but any value where the value starts dropping again.
rowIndexStart is first row checked
rowIndexEnd is last row checked
Code:
tableTopPeak(column);
tableTopPeak(column,rowStartIndex);
tableTopPeak(column,rowStartIndex,rowEndIndex);
tableTopPeak(column,rowStartIndex,rowEndIndex,reverse);
tableBottomPeak(column);
tableBottomPeak(column,rowStartIndex);
tableBottomPeak(column,rowStartIndex,rowEndIndex);
tableBottomPeak(column,rowStartIndex,rowEndIndex,reverse);
tableRaise & tableFall
Look for fastest raise or fall rate in the specified range.
rowIndexStart is first row checked
rowIndexEnd is last row checked
Code:
tableRaise(column);
tableRaise(column,rowStartIndex);
tableRaise(column,rowStartIndex,rowEndIndex);
tableFall(column);
tableFall(column,rowStartIndex);
tableFall(column,rowStartIndex,rowEndIndex);
tableCalcMax & TableCalcMin
Return maximum or minimum value from the the table (TableMax & TableMin returns rowIndex of value)
rowIndexStart is first row checked
rowIndexEnd is last row checked
Code:
tableCalcMax(column);
tableCalcMax(column,rowStartIndex);
tableCalcMax(column,rowStartIndex,rowEndIndex);
tableCalcMin(column);
tableCalcMin(column,rowStartIndex);
tableCalcMin(column,rowStartIndex,rowEndIndex);
tableCalcAvg
Calculate average value of column.
rowIndexStart is first row included
rowIndexEnd is last row included
Code:
tableCalcAvg(column);
tableCalcAvg(column,rowStartIndex);
tableCalcAvg(column,rowStartIndex,rowEndIndex);
tableCalcSum
Calculate sum value of column.
rowIndexStart is first row included
rowIndexEnd is last row included
Code:
tableCalcSum(column);
tableCalcSum(column,rowStartIndex);
tableCalcSum(column,rowStartIndex,rowEndIndex);
tableCalcRMS
Calculate RMS value of column.
rowIndexStart is first row included
rowIndexEnd is last row included
Code:
tableCalcRMS(column);
tableCalcRMS(column,rowStartIndex);
tableCalcRMS(column,rowStartIndex,rowEndIndex);
tableCalcSlope
Calculate slope value of column.
rowIndexStart is first row included
rowIndexEnd is last row included
Code:
tableCalcSlope(column);
tableCalcSlope(column,rowStartIndex);
tableCalcSlope(column,rowStartIndex,rowEndIndex);
tableCalcStdDev
Calculate standard deviation value of column.
rowIndexStart is first row included
rowIndexEnd is last row included
Code:
tableCalcStdDev(column);
tableCalcStdDev(column,rowStartIndex);
tableCalcStdDev(column,rowStartIndex,rowEndIndex);
tableCalcTimeSum
Calculate time sum value of column, divide result by 3600.0 to get a hour based value.
rowIndexStart is first row included
rowIndexEnd is last row included
Code:
tableCalcTimeSum(column);
tableCalcTimeSum(column,rowStartIndex);
tableCalcTimeSum(column,rowStartIndex,rowEndIndex);
tableTime
This is a shortcut to get the "time" value at the end of the table, it can be very useful when doing annotations.
If no "time" column is present the function will return 0
tableAddCSVText
Replace the table with a text block that is csv formatted.
If the first line in the csv text contains column names the second parameter can be empty (""), if the last parameter is non-zero a index column is added before the data. This function handles the same formats as the #LoadTable command do.
Code:
tableAddCSVText(csv,columnNames,addIndex)
tableInitHeader && tableAddRow
Initialize a new table and add data to it. The tableInitHeader() expect a string with the header names listed and tableAddRow() expect one full row for each call, i.e. if tableInitHeader() defines four columns, each tableAddRow() must have four parameters.
If the specified column names matches a device, the formatting from that definition will be applied.
Code:
tableInitHeader(headerLine);
tableAddRow(column1,column2,...);
String functions
These functions are mostly for use in definitions, especially in the :readmath: function or in brackets.
unQuote
Will return the string with one set of quotes removed, they must be either " or ' and be present at both the start and the end of the string. If no valid quotes are found the string is returned unmodified.
listIndex
Will return the index of value in the list. The list is a couple of items with a delimiter between, the default delimiter is "[|,; ]+"
The delimiter is in regular expression format. The easiest way to specify one is to always use brackets around the delimiter character, i.e. "[ ]" for one space or "[ ]+" for one or more spaces.
If no match is found -1 is returned.
Code:
listIndex(value,listString);
listIndex(value,listString,delimiter);
inList
Very similar to listIndex, but only test for presence of the value in the list.
The list is a couple of items with a delimiter between, the default delimiter is "[|,; ]+"
The delimiter is in regular expression format. The easiest way to specify one is to always use brackets around the delimiter character, i.e. "[ ]" for one space or "[ ]+" for one or more spaces.
If no match is found false is returned.
Code:
inList(value,listString);
inList(value,listString,delimiter);
getElement
Returns element at index. This is used to convert a index (From 0 and up to about 10 or 20) to a text.
The list is split with "[ ]+", i.e. a regular expression string, this string can be changed by specifying another delimiter string. The easiest way to specify one is to always use brackets around the delimiter character, i.e. "[ ]" for one space or "[ ]+" for one or more spaces.
Code:
getElement(listString,index);
getElement(listString,index,delimiter);
substring
Returns part of a string, starting at index from, but not including index to, leaving out to or using a large value for to will return the rest of the string.
Code:
substring(string,from);
substring(string,from,to);
match
Returns true if the string matches the regEx
Code:
match(string,regEx)
Note regEx is a string, i.e. it must be in quotes.
getMatch & getMatchGroup
Returns the part if the string that matches the regular expression. With the group only the regEx match group with that number is returned.
In getMatch it is possible what match to return, the first match is number 0 and is the one returned when no number is specified.
Code:
getMatch(string,regEx{,number})
getMatchGroup(string,regEx,number)
Note regEx is a string, i.e. it must be in quotes.
countMatch
Returns number of times regEx is found in string, overlapping parts are not counted. Use getMatch() with a number to get a specific match.
Code:
countMatch(string,regEx)
Note regEx is a string, i.e. it must be in quotes.
trim
Returns the string with spaces removed from both ends.
equals & equalsi
Return true if the two strings are equal, the i version ignores upper/lower case. Equal is very similar to ==, but will always force the values to strings before comparing them, this means integer and float numbers will never match (Float always has at least one decimal, integer never has decimals).
Code:
equals(string,string)
equalsi(string,string)
replace, replacei, replaceRX
Replace a text with another text. This will replace all occurrences of the text.
The version ending with i will ignore upper/lower case.
The version ending with RX will expect the from argument to be a regular expression.
Code:
replace(string,from,to)
replacei(string,from,to)
replaceRX(string,from_in_regEx,to)
indexOf & lastIndexOf
Return position of specified string, either first occurrence or last occurrence.
Will return -1 if string is not present.
Code:
indexOf(string,search)
lastIndexOf(string,search)
formatLeft & formatRight
Fill the string to the specified length, the original is string is placed left or right as the name implies. The filler is a space of the specified string. The result will always be limited to the specified length.
Code:
formatLeft(string,length)
formatRight(string,length)
formatLeft(string,length,filler)
formatRight(string,length,filler)
formatDouble
Format a floating point number.
The minIntDigits will typically be 1 and maxIntDigits is the maximum number of digits before the decimal point.
The minFracDigits will usually be 0 or same value as maxFracDigits that specify maximum number of digits after the decimal point.
Code:
formatDouble(number,minIntDigits,maxIntDigits,minFracDigits,maxFracDigits)
formatSI
Format a floating point number using SI prefix.
Code:
formatSI(number)
formatSI(number,digits)
formatSI(number,digits,minSIPrefix)
digits is number of digits used, it can be 4 or more digits, values below 4 are ignored.
minSIPrefix is a minimum SI prefix used, it can be one of _munpfazy
formatHMS
Format a seconds into a hh:mm:ss format. The default format is without milliseconds, but it is possible to specify number of digits used for milliseconds.
Code:
formatHMS(number)
formatHMS(number,msDigits)
parseSI
Parses a number with SI prefix, this is one of pnumkMG letters after the number, it will ignore other or more letters. This means a value like "10mA" will be returned as "0.01" (The A is ignored).
Code:
parseSI(string)
parseSI("34kohm") -> 34000
parseSI("34.17nF") -> 3.417E-8
parseSI("-14x") -> -14 x is not a SI prefix and is ignored
parseHMS
Parses a time specification, it can either be with "hh:mm:ss" or with a h or m letter after the number. All elements will accept a point, a minus before any number will make the return value negative.
Code:
parseHMS(string)
parseHMS("1::") -> 3600
parseHMS("1:10") -> 70
parseHMS("1:30:5") -> 5405
parseHMS("1h") -> 3600
parseHMS("1m") -> 60
parseHMS("1s") -> 1
parseHMS("1") -> 1
parseHMS("1:1") -> 61
parseHMS("-1:1") -> -61
parseHMS("1:-1") -> -61
parseHMS("-1:-1") -> -61
formatInt
Format a integer number.
Code:
formatInt(number,minIntDigits,maxIntDigits);
strlen
Length of a value as string. This will convert any variable to string and return the length of the string.
Code:
strlen(value);
strlen("hello") -> 5
strlen(15) -> 2
strlen(8.0) -> 3
Other functions
Function that do not fit any of the above categories.
matchBits
Compare a bit specification with wildcards to a integer value and return true/false.
The bitSpecification will match 1 & 0 digits to the value, any other characters are used as "don't care" bits.
The lsb is to the right and any bits not include in the bitSpecification string is ignored.
Code:
matchBits(bitSpecification,value)
matchBits("1xx0",value)
matchBitsList
This function is used to convert a bit based response into a number or string.
The bitSpecification will match 1 & 0 digits to the value, any other characters are used as "don't care" bits.
The lsb is to the right and any bits not include in the bitSpecification string is ignored.
The function will return the first match.
Code:
matchBitsList(value,bitSpecification1,answer1{,bitSpecification1,answer1{,bitSpecification1,answer1...}}{,defaultAnswer}
matchBitsList(value,"01x",1,"10x",2,0)
matchBitsList(value,"01x","answer1","10x","answer2","noMatch")
displayVar
This function will open a popup and show the parameter in it.
The return value from displayVar is the parameter supplied, this makes it possible to use it in for debug in :readmath:
It can also be used to show show steps in a automatic test.
The popup is shared between all displayVar functions and the Calculator, it will always show the last value.
The popup can always be closed, but will popup again next time a displayVar is used.
The format is controlled from the Calculator.
Code:
displayVar(constant or variable);
displayVar(45);
displayVar("Hello world");
displayVar(array("Hello world",a,b));
binConv
Convert a binary value, this includes extract part of the number, swapping byte sequence and converting to signed.
As input can be used a integer/long value, a string or a bytes type. Use int() typecast to force conversion of a string containing a int/long (This is required in :readmath:).
offset is from lsb or from start of string and is applied before any byte swapping.
count is number of bytes to use. For int/long values count+offset must not be above 4/8
signed will check the most significant bit and if it is 1 the value will be converter to a 2 complement negative value.
swap will swap the byte sequence, a 1 will swap all bytes, a string with the actual byte sequence can also be specified. 0=lsb of input value, first digit is msb of output. Number of digits must match count
Code:
binConv(value,offset,count{,signed{,swap}})
;I use hex() function to show actual byte swapping
hex(binConv(0x12345678,0,4)) -> 12345678
hex(binConv(0x12345678,0,2)) -> 5678
hex(binConv(0x12345678,1,2)) -> 3456
hex(binConv(0x8012,0,2,1)) -> FFFF8012 this is a negative number
hex(binConv(0x12345678,0,4,0,1)) -> 78563412
hex(binConv(0x12345678,0,4,0,"3120")) -> 12563478
hex(binConv("\x12\x34\x56\x78",0,4)) -> 78563412
binConvFloat
Convert a binary value to a floating point value, the bits must be in the correct format for float or double.
As input can be used a integer/long value, a string or a bytes type. Use int() typecast to force conversion of a string containing a int/long (This is required in :readmath:).
offset is from lsb or from start of string and is applied before any byte swapping.
count is number of bytes to use. This must be either 4 for float or 8 for double any other value will return a zero result.
swap will swap the byte sequence, a 1 will swap all bytes, a string with the actual byte sequence can also be specified. 0=lsb of input value, first digit is msb of output. Number of digits must match count
Code:
binConvFloat(value,offset,count{,swap})
binConvString
Convert a binary or bytes value to a text string, this routine is mostly useful to convert part or all of a bytes datatype to text.
Code:
binConvString(value)
binConvString(value,offset)
binConvString(value,offset,count)
binConvString(value,offset,count,codepage)
binConvString(value,offset,0,codepage)
binConvString(value,offset,count,codepage,swap)
binConvString(value,offset,count,codepage,swap,termination)
value is a bytes value (Any supplied value will be cast to bytes).
offset is bytes from the start.
count is number of bytes to use, using a value below 1 means the full length.
codepage is character encoding. Default codepage is ISO-8859-1 that will handle the old 7 & 8 bit ascii characters (8 bit in Western Europe style). It is possible to specify UTF-8, UTF-16, UTF-16BE, UTF-16LE and many other formats.
swap when 1 the byte sequence will be swapped before converting to string, when value is integer is is often necessary to specify count
termination specify termination byte, this is 0 for zero terminated strings.
binConvBit
Convert a binary value, this includes extract part of the number and converting to signed.
As input can be used a integer/long value.
offset is bits from lsb
count is number of bits to use.
signed will check the most significant bit and if it is 1 the value will be converter to a 2 complement negative value.
Code:
binConvBit(value,offset,count{,signed})
;I use hex() function to show actual byte swapping
hex(binConvBit(0x1234,0,8)) -> 0034
hex(binConvBit(0x1234,4,8)) -> 0023
hex(binConvBit(0x1274,0,8,1)) -> 0074
hex(binConvBit(0x1284,0,8,1)) -> FF84
bytesAsHex
Returns the argument as a string of 0xnn items.
item is any variable that can be cast to bytes, the bytes are then converted to 0xnn items in a string result.
digits is number of bytes to show in the final string, when not present it will show the actual number of bytes.
reverse the byte sequence in the output string.
Code:
bytesAsHex(item);
bytesAsHex(item,digits);
bytesAsHex(item,digits,reverse);
bytesAsHex(formatInt(a,8,8)); -> 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x31
bytesAsHex(a); -> 0x01
bytesAsHex(a,8); -> 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
bytesAsHex(a,8,1); 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
makeDouble
This function is used to assemble a value from multiple fields in a protocol, usually the version with index and a string parameter is best for this.
Code:
makeDouble(value,minus,pointAdjust)
makeDouble(value,minus,pointAdjust,overload)
makeDouble(valueIndex,minusIndex,pointAdjustIndex,overloadIndex,valueString)
makeDouble(123,0,1);
makeDouble(123,0,1,0);
makeDouble(0,1,2,3,"123 0 1 0");
value: Any numeric value, will usually be a unsigned integer.
minus: When non-zero the sign on the value will be changed.
pointAdjust: A integer specifying how many places to move the decimal point, positive value is to the right (i.e. 2==/100)
overload: Return a overload value, 1=Infinite, -1:NaN
...Index: For the 5 parameter version all parameters are index values of valueString where the actual value for the parameter is read.
In the index version use negative index to ignore a parameter.
hex
Show value as hex, with one parameter it will adjust the number of digits between 4, 8 and 16 depending on the numbers.
Code:
hex(value)
hex(value,digits)
addImage
Add a image to the image viewer in TestController, the image must be in bytes data format and must be in a standard image file format. The name is shown on the title line.
Code:
addImage(imageData,name)
deviceMode
Get the active modes for a device.
Code:
deviceMode(handle);
isDeviceMode
Check if a specific mode is selected.
Code:
isDeviceMode(handle,mode);
modeColumnNames
Use the definitions for a device and translates a mode string into a column name.
Code:
modeColumnNames(handle,mode);
isLogging
Return 1 when logging is active.
isLoggingToDisk
Return 1 when logging to disk is active, when this function is active table data may be reduced, i.e. not every logged dataset is in the table data.
loggingInterval
Returns the logging interval in seconds, the interval set by the #log command or by selecting a log interval in the menus.
A non-zero logging interval do not mean that logging is active and the logging interval may not match the logging interval in the table.
If actual logging is slower than the logging interval, the logging interval may be automatically adjusted during logging.
printLog
Prints any number of arguments to the log screen in TestController.
Code:
printLog("Hello world");
Notes
The evaluator is a common library I uses in multiple projects, this means it contains functions for a lot of other stuff, not related to TestController or electronic.