TestController, Configuration of non SCPI devices

The program supports many different devices, not all uses SCPI, to handle them there are a some build in drivers that will translate between a simplified SCPI and the actual instrument protocol. Some of these drives are nearly fully hard coded, i.e. the device file basically list the name of the device, other can be configured with a device file.
For most of these drivers the only practical configuration that can be done without programing is declaring similar devices.
I will not be explaining most tags, see the SCPI configuration for more explanation.
Content
Single value
Binary DMM protocol
matchSpecification
Example
Modbus serial & network
Modbus register types
Commands to access the registers
Unsupported commands
Defining commands
Other commands
Modbus error codes
Definitions that uses this driver
Difference between the 3 SCPI/ascii drivers (SCPI, SCPIx, Ascii)
SCPI
SCPIx
Ascii
Non-SCPI ascii devices (Ascii)
Commands to write and read values
Defining commands
Other commands
Skeleton example
Definitions that uses this driver
Non-SCPI ascii devices with binary envelope (AsciiBin)
Binary with fixed communication blocks (Block)
Commands to write and read values
format specification
Defining commands
Other commands
Main page
Functions for use in calculator and definitions
Single value
This driver is for device that returns a single line with a single value on it. It can be something like this: "DC 45.3 mV" or "456.45".
The value can be returned at regular intervals or after a poll.
The first part is similar to SCPI definitions:
Code:
#idString first two parts of *idn? answer
#name The device name
#handle A short handle
#port The port used
#baudrate Baudrate for serial devices
#eol Used to change the standard LF end of line to CR or CRLF or disable with \_.
The id string must be constructed to look similar to real id strings, typical: "brand, brand model,"
To load this driver use:
Code:
#driver SingleValue
Next comes data type definition, either a single line without a selector or multiple lines with a selector matching the mode. Mode will be constructed from letters in the original line, start TestCOntroller in debug mode to see what it is for different modes.
A device with a single mode
Code:
#value Frequency Hz SI
Device with multiple modes
Code:
#value VoltageDC V d4 DCV
#value CurrentDC A si DCA
#value VoltageAC V d4 ACV
#value CurrentAC A si ACA
#value Resistance ohm si RESISTANCEOHM
Meters will usually use a text for error condition and may also use it for some other stuff.
Code:
#valueText value text
#valueText value "text"
;Examples:
#valueText OL OL
#valueText -OL "- OL"
#valueText 1 OPEN
It is possible to use OL or -OL as values. To include spaces in the text it must be in quotes.
The text is checked before checking for modes and if a match is found it is removed from the input before assembling the mode string.
The last entry is optional, it is only used if the device must be polled for the string:
It is possible to use escapes in the poll, i.e. \r for a return character or 0x17 for character 17 hex.
This poll will be combined with the #EOL value that has a default value of \n (i.e. a linefeed character). Defining "#eol \_" will disable the end of line character.
Example 1
Code:
#idString HKJ,HKJ Test
#name HKJ Test
#handle Test
#port comfixedbaud
#baudrate 1200
#eol \_
#driver SingleValue
#value VoltageAC V d5 ACV
#value VoltageDC V d5 DCV
#value Resistance V d5 RESISTANCEohm
#askValues \r
Example 2
Code:
#idString HKJ,HKJ Test
#name HKJ Test
#handle Test
#port comfixedbaud
#baudrate 1200
#driver SingleValue
#value Frequency Hz SI
For a complete example see the Protek506 definition file.
Binary DMM protocol
This protocol can handle fixed length binary data formats from a DMM, both with digits as Ascii values or as 7 segment values. It is part of the DMM2 and USBHIDDMM driver and is activated with:
Code:
#driver DMM2
#subDriver Definition
or
#driver USBHIDDMM
#subDriver Definition
The first definition is the data message format with the length and start detection bytes:
Code:
#dataFormat length firstByte firstByteMask
#dataFormat 15 0x02
#dataFormat 13 0x30 0xf0
#dataFormat 13 0 0
length specify the length in bytes.
firstByte is the first byte in the message.
firstByteMask is a mask to define what bytes to compare, (use 0xff for all bits and 0 to accept any byte). When missing 0xff is assumed.
For 7-segments displays the segments must be defined:
Code:
#segments stringWithA-F
#segments byteOfs stringWithA-F byteOfs stringWithA-F byteOfs stringWithA-F byteOfs stringWithA-F
#segments "....afe.....bgcd"
The stringWithA-F must be 8, 16, 24 or 32 characters long, depending on number of bytes used for each digit. Any character not in the A-F range is a unused position.
If the segments for the digits are non-sequential the second format must be used, any number of "byteOfs stringWithA-F" pairs can be specified and is numbered in sequence with the first one as digit 1.
If the display has a "1" digit that is outside the normal segment definition, use:
Code:
#addDigit digits matchSpecification
This will add the digits before the display reading. This is first done after decimal point processing.
The actual value is read with:
Code:
#digits byteOfs digits
#digits digit digits
#digits 1 5
byteOfs is how many bytes from the start of the data the digits starts.
digit is only used when the segment decoder contains the byteOfs (See #segments definition)
digits is the number of digits to read (Not the number of bytes). If lsb is first use a negative digit specification.
The sign is nearly always needed to show negative values, in some cases a overload flag must be used to reliable detect overload:
Code:
#sign matchSpecification
#overload matchSpecification
#sign b(7,"xxxxx1xx")
#overload b(7,"xxxxxxx1")
The above number do not contain any decimal point or adjustment for range, this is done with:
Code:
#point digit matchSpecification
#point 3 b(9, "xxxxxxx1")
#point 2 b(7,"xxxxxxx1")
#point 1 b(5,"xxxxxxx1")
When used there will usually be multiple of these specifications, but often one or two less than there are digits.
This specification is usually only used for 7-segment coding, not for ascii coding.
In addition to the decimal point a multiplier must be used to adjust the number:
Code:
#point factor matchSpecification
#mult M b(11, "xxxxxx1x")
#mult k b(11, "xxxxxxx1")
#mult m b(13, "xxxxxxx1")
#mult 1e0 v(0,0x30)
#mult 1e1 v(0,0x31)
#mult 1e2 v(0,0x32)
The factor is either a SI prefix, matching the segment on the display or just a numeric factor.
Next the range or mode must be defined:
Code:
#range mode
#range - matchSpecification
#range mode matchSpecification
#range mode /factor matchSpecification
#range mode *factor matchSpecification
#range Ohm b(12, "xxxxx10x")
#range F b(13, "xxxxx1xx")
#range F /1e12 v(6,0x36)
#range - !b(12, "00001101")
#range - b(14, "xxxxx11x") | !b(14, "1110xxxx")
mode is a string matching the internal mode table, it can be one of V A F Ohm Hz % TempC TempF %mA dB dBm W VA VAR Wh
factor is either multiplied or divided with the display value and is typically used for ascii formats.
A range without a matchSpecification sets a default range or mode for the driver, this is useful when starting on a specification, but is best removed when finished.
The mode = - is a stop specification (No value is decoded) and is used to block invalid messages or states.
All the modes are tested in the specified sequence and the testing will stop at the first match.
In addition to the above there is AC/DC specifications, they are added to the above modes when present:
Code:
#rangeAC matchSpecification
#rangeDC matchSpecification
#rangeDC b(10,"xxxx1xxx")
#rangeAC b(10,"xxxxx1xx")
They only work for modes where a AC/DC/ACDC mode is relevant (V A W Wh).
With the above most multimeters will work, but some chips have a few special issues that cannot be handled with that easily.
Some issues are handled automatic:
dBm: When #range is "dB" and #mult is 1e-3 or m the dB range will change to dBm
%: The minus flag is ignored
Hz: The minus flag is ignored
TempF: A conversion to Celsius is performed.
For anything else a script can be added to a range/mode:
Code:
#modify1 matchSpecification
#modify2 matchSpecification
#modify range expression
#modify VAC (mult==1)?value/1e5:value
#modify Hz (mult>5)?value/10:value
To handle this it is possible to use expressions to process the value. The modify1/2 is optional flags.
There are some variables:
value: The value with decimal point (from #point) placed.
mult: The multiplier made from #range & #mult specifications.
modify1: Result from #modify1
modify2: Result from #modify2
matchSpecification
This specification will return true or false, depending on if it matches the specified bytes or not. There are a couple of different formats, the "b" is the basic format, the other formats are for convenience.
Code:
b(byteOfs,bitmask)
s(byteOfs,segmentList)
c(byteOfs,character)
v(byteOfs,value)
b(14, "xxxxx01x")
s(9,"adef")
c(9,"C")
v(6,0x3d)
byteOfs is the offset into data
bitmask is 0/1 bits, any other character will assume a do not care position. It must have exactly 8 characters
segmentList is a list of segments to be on in a digit, i.e. letters from A to F
character will match a ascii character, with 7-segment only "0-9, L E F C r" is recognized
value is a integer value either in decimal or hex and must match the full byte.
The result from a matchSpecification can be inverted with a ! in front of it, this will not affect matchSpecification after this one:
It is possible to chain multiple matchSpecification on a line:
Code:
b(14, "xxxxx01x") & s(9,"adef")
b(14, "xxxxx01x") | s(9,"adef")
& means both must be true
| means at least one of them must be true.
Example
Download some examples in a zip file
These are complete definitions matching the internal hard coded definition.
Modbus serial & network
Modbus is a packet based interface, with a couple of fixed formats based in a hardware model with different types of input/output.
This protocol is build on top of SCPI and requires all the stuff that a normal SCPI definition does, in addition to a couple of #scpiCmd definitions.
Modbus register types
Register can be read/write or read only types, this is (hopefully) listen in the device manual.
The 4 different types of registers do not necessarily share address space, i.e. the same address can be different things in the different register types.
- Coil: These registers are bit registers, it is possible read one or many bits at a time, but only one can be written at a time.
- Discrete input: Bit registers, these can be read one or many bits at a time, but not written.
- Input register: Register that uses 16 bit (word) data, these can be read one or many words at a time, but not written.
- Holding register: Register that uses 16 bit (word) data, these can be read or written one or many words at a time.
It is common to combine holding registers to 32 bit data as long or float values.
Commands to access the registers
These commands can be used directly from the command line, but this is mostly for test.
- Coil address value
- Coil? address {bits}
- dInput? address {bits}
- holding address value {moreValues...} {*factor or /factor }
- holding? address {{words} *factor or /factor or &mask}
- holdingS? address {{words} *factor or /factor}
- input? address {{words} *factor or /factor or &mask}
- holdingL address value {moreValues...} {*factor or /factor}
- holdingL? address {{doubleWords} *factor or /factor}
- holdingSL? address {{doubleWords} *factor or /factor}
- holdingF address value {moreValues...} {*factor or /factor}
- holdingF? address {{floats} *factor or /factor}
- holdingBytes? address {words}
- unitId id
The Coil? & dInput? will return all bits in a single number, the other command will return a list of values.
The address can be in decimal or in hex by prefixing with 0x
Reading commands has a optionally count, when not specified one value is read, when specified it defines how many values to read.
The L, SL and F prefix works with 32 bit values for either unsigned integers, singed integer or floats.
The *factor or /factor is used to scale the values, i.e. use /10 to divide by 10 or *10 to multiply by 10
The &mask can be used to remove undefined bits and can be something like "&0xff" to only return 8 bits from the 16 bit answer
The unitId command only works for modbus TCP and will set the unit identifier.
The holdingBytes? uses return the a string with all data bytes from the answer that can be typecast to bytes and must be processed with a :readmath:
Unsupported commands
Do not expect a device to support all the different register access commands, not all registers may be implemented and writing may be restricted to 1 or many registers.
Because TestController automatic select between single and multi register write, there will be a problem with devices not supporting single write (A single write can be simulated with a multi write where the count is 1). To force TestController into always using multi write use this define in the definition file:
Code:
#disableWriteSingle 1
Defining commands
The above commands are only supposed to be used for defining other commands with. By defining commands it makes the definition easier to read and it also makes it easier to directly give commands on the command line.
The format is fairly simple:
Code:
#scpiCmd name register access command with parameters
;Examples:
#scpiCmd Current holdingF 0xa01 (value)
#scpiCmd Current? holdingF? 0xa01
Use (value) to insert parameters from the "name" command. It is possible to use value multiple times and it is also possible to use an expression inside the brackets.
If a value needs to be carried between scpiCmd it can be saved with a ":setvar:" tag
Code:
;Save input value
#scpiCmd mode holding 0xa00 (value)
:setvar: currentMode=value
;Save answer
#scpiCmd mode? holding? 0xb04 1 &0xff
:setvar: currentMode=value
;Using the saved value
#scpiCmd on holding 0xa00 (currentMode);holding 0xa00 (getElement("43 42",value))
It is important that this variable is created before it is used. To do this use a command in "#initCmd" that has a :setVar: for the variable.
Other commands
A few more commands are supported.
To verify it is the correct device that is connected use this command. Often it is possible to read a model number from the device and compare that to the value.
Code:
#verifyDevice value commandToGetvalue
;Example, note mode? is defined with "#scpiCmd model? holding? 0xb06" (I could have used the holding? directly).
#verifyDevice 2 model?
The software always ask for serial number and software versions when connecting to a device, by defining these two command they will be read:
Code:
#scpiCmd getDeviceSW? ...
#scpiCmd getDeviceSN? ...
Not all devices can handle a steady communication, some needs a small delay between each message to work correctly. This is done with this optional setting:
Code:
#cmdDelayTime time in ms
;Example
#cmdDelayTime 50
The standard modbus driver is RTU, but it can be switched to the TCP driver with:
Code:
#subDriver TCP
#subDriver RTU// Is also valid, but not needed
#subDriver Kunkin// Kunkin modbus format including swapped crc bytes
#subDriver Kunkinx// Kunkin modbus format, used in newer versions of the Kunkin software
#subDriver Ascii
When using modbus TCP the #port will usually need to be defined as "#port 502"
Modbus error codes
TestController will return error codes as negative value, i.e. -1 is error 1.
- 1: Illegal Function
- 2: Illegal Data Address
- 3: Illegal Data Value
- 4: Slave Device Failure
- 5: Acknowledge
- 6: Slave Device Busy
- 7: Negative Acknowledge
- 8: Memory Parity Error
- 10: Gateway Path Unavailable
- 11: Gateway Target Device Failed to Respond
Definitions that uses this driver
The power supply definitions RidenRD6006 uses this driver. I has a fairly advanced configuration menu.
Maynuo M97xx definition is a electronic load.
Difference between the 3 SCPI/ascii drivers (SCPI, SCPIx, Ascii)
Test controller supports 3 different drivers for two way ascii communication with a device, in some ways they are similar, but there is also significant differences.
SCPI
This is the default driver and is used when no driver is specified.
- It will always use the *idn? command to identify a device and will not accept a device without a answer that matches the selected device.
- Anything typed on the command line will be passed directly to the device, except when starting with # or =
- Unsolicited data from a device will be shown in the log window.
SCPIx
This is a slightly modified SCPI driver
- It will always use the *idn? command to identify a device and will not accept a device without a answer that matches the selected device.
- The answer from *idn? can be modified with #modifyIDN before comparing to selected device.
- There is a option (#forceUpperCase) to force any command into uppercase before it is transmitted to the device.
- It is possible to define commands with #scpiCmd (The commands used to redefine can also be used from the command line).
- Anything typed on the command line will be passed directly to the device, except when starting with #, =, matching a #scpiCmd definition or internal command.
- There is a option to remove a prompt from the device (#removePromptChars)
Ascii
This driver is for devices that do not follow SCPI command syntax.
- Driver can connect without identifying the device.
- A simulated *idn? command can be implemented with #verifyDevice, getdevicesn? and getdevicesw?, this add identification/verification.
- Only commands defined with #scpiCmd is passed to the device (The commands used to redefine can also be used from the command line).
- It can directly control a GPIB interface with [CLR], [LLO], [LOC], [TRG]
- It supports slowing down communication with #cmdDelayTime
- This driver will generate a command list in the help window, based on the defined commands.
Non-SCPI ascii devices (Ascii)
This interface will work with devices that requires strings of ascii commands, but are not SCPI compliant. It works in a similar way to the Modbus definition.
This protocol is build on top of SCPI and requires all the stuff that a normal SCPI definition does, in addition to a couple of #scpiCmd definitions.
Commands to write and read values
These commands can be used directly from the command line, but this is mostly for test.
- tx cmd - Send the cmd to the device, do not expect any answer.
- txrx cmd - Send the cmd to the device, waits for an answer, but do not return the answer.
- txrx? cmd - Send the cmd to the device, waits for an answer and returns the answer.
- txrx2? cmd - Send the cmd to the device, waits for a two line answer and returns the answer.
- txrn? lines cmd - Send the cmd to the device, waits for a multi line answer and returns the answer.
- rxuntil? expression - Receive until expression is true, last received data is in "value"
- rxalluntil? expression - Receive until expression is true, all received data is in "value"
- txBin cmd This command will send a string without the default line termination character(s) and will not expect an answer.
- txrx1Bin? cmd This command will send a command and then read one answering byte, result is returned as a number.
- txrxnBin? cnt cmd This command will send a command and then read cnt answering byte, result is returned as a number for up to 8 characters and a bytes string for more characters.
- txrx1Bin cmd This command will send a command and then read one answering byte, no result is returned
- txrxnBin cnt cmd This command will send a command and then read cnt answering byte, no result is returned
- none Dummy write command, used together with ":servar: variableName=inputValue" to save something.
- none? Dummy read command, used to read a variable from :setvar: with a ":readmath: variableName"
In a #scpiCmd definition the ; is transmitted directly.
The Bin commands do not use specified EOL format, it must be included in the cmd (See escape codes below).
It is very important to use command that waits for an answer, if the cmd will return an answer.
Escape codes for bin commands: \b \t \n \r \\ \" \' \u0000 \x00, \u is followed by a four digit unicode hex value, \x is followed by a two digit hex code.
Defining commands
The above commands are only supposed to be used for defining other commands with. By defining commands it makes the definition easier to read and it also makes it easier to directly give commands on the command line.
The scpiCmd has shares a common context, this means it is possible to use :setvar: and then reference to the variable in another #scpiCmd.
The format is fairly simple:
Code:
#scpiCmd name tx cmd
#scpiCmd name txrx cmd
#scpiCmd name? txrx? cmd
#scpiCmd name? txrx? cmd
#scpiCmd name? txrx2? cmd
#scpiCmd name? txrxn? lines cmd
#scpiCmd name? txrxnBin? bytes cmd
#scpiCmd name? txrx1Bin? cmd
#scpiCmd name txrxnBin bytes cmd
#scpiCmd name txrx1Bin cmd
#scpiCmd name tx cmd (value)
#scpiCmd name txrx cmd (value)
#scpiCmd name? txrx? cmd (value)
Use (value) to insert parameters from the "name" command. It is possible to use value multiple times and it is also possible to use an expression inside the brackets.
On the :readmath: and :setVar: tags a valueInput can be used to access the this value, the "value" parameter will show the return value.
A number or n in the command lines means multiple lines, except with bin where it means bytes (Up to 8, answer is return as a number).
If a value needs to be carried between scpiCmd it can be saved with a ":setvar:" tag
Code:
;Save input value
#scpiCmd name tx (value)
:setvar: currentMode=value
;Save answer
#scpiCmd name? txrx? cmd
:setvar: currentMode=value
;Using the saved value
#scpiCmd name tx (currentMode)
It is important that this variable is created before it is used. To do this use a command in "#initCmd" that has a :setVar: for the variable.
Other commands
A few more commands are supported.
To verify it is the correct device that is connected use this command. Often it is possible to read a model number from the device and compare that to the value.
Code:
#verifyDevice value commandToGetvalue
;Example, note model? must defined with "#scpiCmd model?
#verifyDevice 2 model?
The software always ask for serial number and software versions when connecting to a device, by defining these two command they will be read:
Code:
#scpiCmd getDeviceSW? ...
#scpiCmd getDeviceSN? ...
Not all devices can handle a steady communication, some needs a small delay between each message to work correctly. This is done with this optional setting:
Code:
#cmdDelayTime time in ms
;Example
#cmdDelayTime 50
Skeleton example
Use the below skeleton when starting a new definition.
Code:
#idString brand,brand model
#name brand model
#handle mostlyModel
#driver Ascii
; port can be com, comfixedbaud, comnobaud or a port number for network devices.
#port 5025
; Baudrate definition is needed for comfixedbaud types.
;#baudrate 9600
; The author statement is used for the listing in the About window.
;#author you name or handle
; There must be a line for each of the original device commands that will be used, converting it to a similar SCPI command
;#scpiCmd init tx command to init
;#scpiCmd values? txrx? command to read current value or values. It is possible to define value1?, value2?, etc. and then use them all with a ; between in the #askValues statement.
; A list of possible column name with unit and formatter (SI, Time, Int, D0..D6)
#value Voltage V SI
; Use these commands to get a full id line and prevent connection to other devices
;#verifyDevice value commandToGetvalue
;#scpiCmd getDeviceSW? ...
;#scpiCmd getDeviceSN? ...
; This is a single line command
#askValues values?
;Accept this delay when reading values (seconds)
#readingDelay 5
; Prepare the meter to response to #askValues
;#prepareSample
; Initial commands to meter when establishing connection
;#initCmd
; Final command to meter before breaking connection
;#finalCmd
; Used when output off button is pressed
;#outputOff
Definitions that uses this driver
FeelElecFY6x00-xxM defines many ARB models using this driver.
HP3478A is a device from before SCPI.
Non-SCPI ascii devices with binary envelope (AsciiBin)
This driver is very similar to the ascii driver, but will handle a binary envelope around the messages. It supports the same definitions as the ascii driver, with the addition that a packet format must be specified.
Code:
#driver AsciiBin
#packetFormat name
The supported packet format (envelope) names are:
- Length7: Prefix message with a length byte where bit 7 is 1. The length byte is not included in the length count.
- Length15: Prefix message with two length byte (msb first) where bit 15 is 1. The length bytes is not included in the length count.
- Length31: Prefix message with four length byte (msb first) where bit 31 is 1. The length bytes is not included in the length count.
Note: txrxn? and txrx2? is not supported.
Binary with fixed communication blocks (Block)
This driver can handle binary protocols with fixed length messages, it is possible to extract one or more values from each message.
Commands to write and read values
These commands can be used directly from the command line, but this is mostly for test.
- tx byteSequence - Send the byte sequence, no answer is expected
- txrx1 byteSequence - Send the byte sequence, 1 byte answer is expected, but is not returned from the driver.
- txrx2 byteSequence - Send the byte sequence, 2 byte answer is expected, but is not returned from the driver.
- txrxn count byteSequence - Send the byte sequence, count byte answer is expected, but is not returned from the driver.
- txrx1? byteSequence {/ format}- Send the byte sequence, 1 byte answer is expected and returned
- txrx2? byteSequence {/ format}- Send the byte sequence, 2 byte answer is expected and returned
- txrxn? count byteSequence {/ format}- Send the byte sequence, count byte answer is expected and returned
byteSequence is a list of numbers, both decimal and hex is accepted.
/ when present will disable the default unsigned integer conversion and expect format specifiers instead.
format makes it possible to interpret the answer as any data type and can handle more than 8 bytes.
It is very important to use command that waits for an answer, if the cmd will return an answer.
format specification
One or more formats can be specified and each will return a number/string. The general format is:
byteIndex dataType bytes {multiplier} {offset}
All elements must be combined without any space between.
- byteIndex: Index into the answer, first byte is index 0
- dataType: Type of data and modifiers:
- i: Signed integer, can be from 1 to 8 bytes long. lsb is first (See r).
- u: Unsigned integer, can be from 1 to 8 bytes long. lsb is first (See r).
- f: Floating point, can be either 4 or 8 bytes long. lsb is first (See r).
- d: Binary coded decimal, can 1 to 9 bytes long. msb is first (See r, n & !).
- s: String, no length restriction, assumed to be ISO8859-1 (Similar to US ASCII for 7 but characters).
- b: Bit, test if a single bit is 0 or 1, the bytes specifications is a bit no specification and ! will invert the bits.
- #: Put bytes back into byte list, used with r modifier to handle special byte sequences. Only use when no other solution.
- z: Must be used after one of the above (Only iud) and will zero the msb bit, up to 8 z's can be used.
- r: Must be used after one of the above and will swap the byte sequence. Used to handle endianness.
- !: Must be used after one of the above and will invert the bits, useful for BCD and b formats.
- x: Must be used after one of the above and will reverse bits in each byte.
- n: Must be used after one of the above and will swap nipples, may be needed together with r for BCD with lsb first.
- bytes: Number of bytes, each data type has some restrictions.
- multiplier: Either multiply or divide with a factor, use *number or /number
- offset: Either add or subtract a offset, use +number of -number
There is no restriction on rxnz! modifiers, but there is only a few combinations that are useful.
Some examples:
- 3i2: Signed integer at byte 3 and 4, 3 is lsb
- 3ir2: Signed integer at byte 3 and 4, 4 is lsb
- 0u1: Unsigned integer at byte 0
- 2s5: String in byte 2, 3, 4, 5 and 6, byte 2 is first character in string.
- 4f4: Floating point number in byte 4, 5, 6 and 7. Byte 4 is lsb
- 4fr4: Floating point number in byte 4, 5, 6 and 7. Byte 7 is lsb
- 1i3/10: Signed integer in byte 1, 2 and 3, value is divide by 10.
- 1i3*2+3: Signed integer in byte 1, 2 and 3, value is multiplies by 2 and 3 is added to the result.
- 1b3: Return 1 if bit 3 in byte 1 is 1, it may often be better to return a full byte or more and do the bit checking in a :readmath: statement.
- 1b!3: Return 1 if bit 3 in byte 1 is 0
Defining commands
The above commands are only supposed to be used for defining other commands with. By defining commands it makes the definition easier to read and it also makes it easier to directly give commands on the command line.
The format is fairly simple:
Code:
#scpiCmd name tx byteSequence
#scpiCmd name txrx1 byteSequence
#scpiCmd name txrx2 byteSequence
#scpiCmd name txrxn count byteSequence
#scpiCmd name? txrx1? byteSequence {/ format}
#scpiCmd name? txrx2? byteSequence {/ format}
#scpiCmd name? txrxn? count byteSequence {/ format}
Use (value) to insert parameters from the "name" command, each () must return a byte sized value. It is possible to use value multiple times and it is also possible to use an expression inside the brackets.
If a value needs to be carried between scpiCmd it can be saved with a ":setvar:" tag
Other commands
A few more commands are supported.
To verify it is the correct device that is connected use this command. Often it is possible to read a model number from the device and compare that to the value.
Code:
#verifyDevice value commandToGetvalue
;Example, note model? must defined with "#scpiCmd model?
#verifyDevice 2 model?
The software always ask for serial number and software versions when connecting to a device, by defining these two command they will be read:
Code:
#scpiCmd getDeviceSW? ...
#scpiCmd getDeviceSN? ...
Not all devices can handle a steady communication, some needs a small delay between each message to work correctly. This is done with this optional setting:
Code:
#cmdDelayTime time in ms
;Example
#cmdDelayTime 50