25.3 LabJack Library
The MB and LJ libraries allow access to the Modbus map and provide timing control. It is important to note that function calls dealing with 32-bit integers require special attention due to 32-bit floats being the only valid numerical type.
Modbus Name Functions
Required firmware versions:
T7: 1.0281 and later
T4: 1.0023 and later
Modbus Name Functions use register names like LJM's eReadName and eWriteName. This makes them easy to understand because registers are referenced by name, like DIO_STATE, instead of addresses, like 2800.
Name functions are 0.1% to 20% slower than their address equivalents (see Modbus Address Functions below).
Name functions use more memory than address functions.
MB.readName
value, error = MB.readName("register name string")
Reads a single value from a Modbus register. Any errors encountered will be returned in "error." Some examples:
firmware_ver = MB.readName("FIRMWARE_VERSION")
serial_num = MB.readName("SERIAL_NUMBER")
To read multiple 32-bit values, see MB.readNameArray
below.
MB.writeName
error = MB.writeName("register name string", value)
Writes a single value to a Modbus register. Any errors encountered will be returned in error. Some examples:
MB.writeName("DIO_EF4_ENABLE", 0)
MB.writeName("IO_CONFIG_SET_CURRENT_TO_FACTORY", 1)
To write multiple 32-bit values, see MB.writeNameArray
below.
MB.readNameArray
tbl_Values, error = MB.readNameArray("register_name", numValues, dataType_override)
Sequentially reads one or more values from Modbus registers. The first register read will be the address associated with the register "name". Subsequent registers will be incremented according to the register's data type.
Parameters:
register_name
- Name of the Modbus register to start reading from.numValues
- Integer number of values to be read.dataType_override
(optional) - When this parameter is not provided, the default data-type for the register will be used. When this parameter is provided, the passed data type will be used.
Returns:
tbl_Values
- Lua table containing the values readerror
(optional) - Returns error codes
Some examples:
tbl_Values = MB.readNameArray("AIN2", 3)
- This will read three floating point values (32-bits each) from AIN2, AIN3, and AIN4 (addresses 4, 6, and 8):tbl_Values[1] = AIN2 Voltage
tbl_Values[2] = AIN3 Voltage
tbl_Values[3] = AIN4 Voltage
tbl_Values = MB.readNameArray("ETHERNET_IP", 2, 0)
- This will read the Ethernet IP as two 16-bit unsigned integers. By default, ETHERNET_IP is a 32-bit unsigned integer, which will be truncated if put into in a 32-bit float. This is a limitation with 32-bit data types.Given IP = 192.168.1.100 = (0xC0A80164)
tbl_Values[1]
= 0xC0A8tbl_Values[2]
= 0x0164If we were to read the IP without using the dataType_override the result would be: 0xC0A80100.
MB.writeNameArray
error = MB.writeNameArray("name", numValues, tbl_Values, dataType_override)
Sequentially writes one or more values to Modbus registers. The first register written will be the address associated with the register "name". Subsequent registers will be incremented according to the register's data type.
Parameters:
register_name
- Name of the Modbus register to start writing to.numValues
- Integer number of values to be written.tbl_Values
- Lua table containing the values to be written.dataType_override
(optional) - When this parameter is not provided, the default data-type for the register will be used. When this parameter is provided, the passed data type will be used.
Returns:
error
(optional) - Returns error codes
Some examples:
MB.writeNameArray("DAC0", 2, tbl_Values)
- This will write two floating point values (32-bits each) to DAC0 and DAC1 (addresses 1000, and 1002).DAC0 will be set to the value in
tbl_Values[1]
DAC1 will be set to the value in
tbl_Values[2]
MB.writeNameArray("ETHERNET_IP_DEFAULT", 2, tbl_Values, 0)
- This will write the ETHERNET_IP_DEFAULT register as two 16-bit unsigned integers. By default, ETHERNET_IP_DEFAULT is a 32-bit unsigned integer, which will be truncated if put into in a 32-bit float. This is a limitation with 32-bit data types.Given IP = 192.168.1.100
The upper 16-bits of the IP set to
tbl_Values[1]
The lower 16-bits of the IP set to
tbl_Values[2]
MB.nameToAddress
address, dataType, error = MB.nameToAddress("Name")
Searches for a register with "Name" and returns the corresponding address and dataType. This is useful for improving a script's speed while retaining clarity. For example:
fio5Address, fio5DataType = MB.nameToAddress("FIO5")
Modbus Address Functions
The following Modbus address functions are similar to eReadAddress, eWriteAddress, eReadAddressArray, and eWriteAddressArray. The address and data type need to be provided. The address controls what you want to read or write. The data type controls how the data should be interpreted. Address and data types can be found in the LabJack Modbus Map and in the Kipling Register Matrix.
Data Types - Below is a list of data type indices. The data types match those used by the LJM Library.
0 - unsigned 16-bit integer
1 - unsigned 32-bit integer
2 - signed 32-bit integer
3 - single precision floating point (float)
98 - string
99 - byte - The "byte" dataType is used to pass arrays of bytes in what Lua calls tables
MB.R
value, error = MB.R(Address, dataType)
Modbus read. Reads a single value from a Modbus register. The type can be a u16, u32, a float, or a string. Any errors encountered will be returned in error
.
MB.W
error = MB.W(Address, dataType, value)
Modbus write. Writes a single value to a Modbus register. The type can be a u16, u32, a float, or a string. Any errors encountered will be returned in error
.
MB.WA
error = MB.WA(Address, dataType, nValues, table)
Modbus write array. Reads integer nValues
from the supplied table, interprets them according to the dataType
and writes them as an array to the register specified by Address
. The table must be indexed with numbers from 1 to nValues
.
MB.RA
table, error = MB.RA(Address, dataType, nValues)
Modbus read array. Reads integer nValues
of type dataType
from Address
and returns the results in a Lua table. The table is indexed from 1 to nValues
.
Shortcut Functions
The following functions are shortcuts used to gain a small speed advantage over the equivalent Modbus functions.
LJ.ledtog
LJ.ledtog()
--Toggles status LED. Note that reading AINs also toggles the status LED.
LJ.Tick
Ticks = LJ.Tick()
--Reads the core timer (1/2 core frequency).
LJ.DIO_D_W
LJ.DIO_D_W(3, 1)
--Quickly change DIO3 (FIO3) direction _D_ to 1 (output).
LJ.DIO_S_W
LJ.DIO_S_W(3, 0)
--Quickly change the state _S_ of DIO3 (FIO3) to 0 (output low)
LJ.DIO_S_R
state = LJ.DIO_S_R(3)
--Quickly read the state _S_ of DIO3 (FIO3)
LJ.CheckFileFlag
flag = LJ.CheckFileFlag()
and LJ.ClearFileFlag()
LJ.CheckFileFlag
and LJ.ClearFileFlag
work together to provide an easy way to tell a Lua script to switch files. This is useful for applications that require continuous logging in a Lua script and on-demand file access from a host. Since files cannot be opened simultaneously by a Lua script and a host, the Lua script must first close the active file if the host wants to read file contents. The host writes a value of 1 to FILE_IO_LUA_SWITCH_FILE, and the Lua script is setup to poll this parameter using LJ.CheckFileFlag
. If the file flag is set, Lua code should switch files:
fg = LJ.CheckFileFlag() --poll the flag every few seconds
if fg == 1 then
NumFn = NumFn + 1 --increment filename
Filename = Filepre..string.format("%02d", NumFn)..Filesuf
f:close()
LJ.ClearFileFlag() --inform host that previous file is available.
f = io.open(Filename, "w") --create or replace a new file
print ("Command issued by host to create new file")
end
Timing Functions
LJ.IntervalConfig & LJ.CheckInterval
LJ.IntervalConfig
and LJ.CheckInterval
work together to make an easy-to-use timing function. Set the desired interval time with IntervalConfig, then use LJ.CheckInterval
to watch for timeouts. The interval period will have some jitter but no overall error. Jitter is typically ±30 µs but can be greater depending on processor loading. A small amount of error is induced when the processor's core speed is changed.
Up to 8 different intervals can be active at a time.
LJ.IntervalConfig(handle, time_ms)
Sets an interval timer, starting from the current time.
handle
: Integer value 0-7. Initializes (or reinitializes) an interval identified by this handle.
time_ms
: 32-bit float which represents the number of milliseconds per interval. The minimum configurable interval time is 10us. The maximum value is 50000 ms.
timed_out = LJ.CheckInterval(handle)
handle
: Integer value 0-7. Identifies an interval.
Returns: nil if no intervals have elapsed. Otherwise, returns the number of elapsed intervals. If this number is greater than one, then the script is too complex for the specified interval.
LJ Interval Function Example - lua
LJ.IntervalConfig(0, 1000)
while true do
if LJ.CheckInterval(0) then
--Code to run once per second here.
end
end
Note: Firmware versions prior to T7 1.0283 and T4 1.0024 had an issue where large quantities of missed intervals could cause a device watchdog timer to be triggered and rebooted.
Lua Performance Functions
LJ.setLuaThrottle
LJ.setLuaThrottle(newThrottle)
Set the throttle setting. This controls Lua's processor priority. Value is the integer number of Lua instruction to execute before releasing control to the normal polling loop. After the loop completes Lua will be given processor time again.
LJ.getLuaThrottle
ThrottleSetting = LJ.getLuaThrottle()
Reads the current integer throttle setting.
LJ.ResetOpCount
LJ.ResetOpCount()
--Resets the lua operation counter, which determines when to release control from Lua to the normal device polling loop. This function should be used sparingly; LJ.setLuaThrottle
should be considered for most situations.