Skip to main content
Skip table of contents

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 read
  • error (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] = 0xC0A8
  • tbl_Values[2] = 0x0164
  • If 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:

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 eReadAddresseWriteAddress, 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:

- lua

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.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.