LabJack LJM Library Docs Export 20160914
LabJack LJM Library Docs Export 20160914
com)
Home > Support > Software & Driver > API Documentation > LJM Library Docs
Welcome to the LJM User's Guide! This document describes the API and usage of the LabJack LJM library.
An efficient way to navigate this online User's Guide is to browse the table of contents to the left. Rather than clicking on all the links to
browse, you can click on the small plus symbols to expand without reloading the whole page.
If you are looking at a PDF, hardcopy, or other downloaded offline version of this User's Guide, realize that it is possibly out-of-date, as
the original is an online document. Also, this User's Guide is designed as online documentation, so the formatting of an offline version
is often less than ideal.
To create an offline version of this entire document, click "Save as PDF" towards the bottom-right of this page (allow 30+ seconds). To
make an offline version of a particular section go to that page and click "Save as PDF" towards the bottom-right of that page. Doing so
converts this page and all sub-pages to a single HTML page. If you need to translate the document, do that now. To produce a PDF,
use the print option in your browser and use whatever print-to-PDF option you might have available (e.g. PrimoPDF).
Rather than downloading, though, we encourage you to use this web-based documentation. Some advantages:
1. Overview
2. Function Reference
3. Constants
4. Error Codes
File Attachment:
LabJack-LJM-Library-Docs-Export-20160129.pdf
1 - Overview
The LJM Library is a set of functions used to easily communicate with several of our devices using a simple Modbus interface. The goal
is to be easy to use and understand, yet flexible.
All important values & data from the device can be read and/or written by using the associated register(s). Thus, the process for reading
the serial number, an analog input, or a timer is all functionally the same, you simply provide a different address. We have also included
functionality so that values can be specified using a name instead of numerical value, such as "AIN6" to represent the register(s) that
will read analog input number 6.
More on Opening
More on Reading/Writing
More on streaming
More functions.
There are also utility functions provided to do things like debugging and making unit conversions
easier, as well as a few functions that let you configure the library itself.
2 - Function Reference
2.1 - Opening and Closing
Summary
Open a LabJack device to communicate with it. Close it to allow other processes to open it.
Opening
Either LJM_Open or LJM_OpenS must be used to open a LabJack. The LJM_Open and LJM_OpenS functions will detect a LabJack
connected to the computer, and create a device handle. The device handle is then passed as an input to other functions.
USB connections are preferred - If ConnectionType is equal to LJM_ctANY (0), LJM_Open will attempt to open a USB connection
before trying to open a TCP connection.
Device connections are claimed - Once a LabJack device is opened on a given connection type, other processes will generally not be
able to open that same device using the same connection type until the device connection is closed by
using LJM_Close or LJM_CloseAll.
Subsequent calls may return the same handle - Once a device is opened, subsequent calls to LJM_Open/LJM_OpenS will return the
handle to that device if the DeviceType, ConnectionType, and Identifier parameters describe that device. In this case, calling LJM_Open
or LJM_OpenS is nearly instant because no device communication occurs. For example, if a T7 is opened via USB with serial
number 470010729, returning handle x, the following calls would return handle x without opening a new device connection:
Devices like the T7 may have multiple device connections at once. The following calls would each return a different device handle:
LJM_Open(LJM_dtT7, LJM_ctUSB, "470010729", ...)
LJM_Open(LJM_dtT7, LJM_ctETHERNET, "470010729", ...)
LJM_Open(LJM_dtT7, LJM_ctWIFI, "470010729", ...)
Reconnection is automatic - LJM will automatically repair device connections. This reconnection process will, by default, reconnect a
handle according to the same connection type and the same serial number that it was initially opened with. This reconnection process
happens when the device is discovered to be disconnected during a read or write. For more details, see the following LJM
configurations:
LJM_AUTO_RECONNECT_STICKY_CONNECTION
LJM_AUTO_RECONNECT_STICKY_SERIAL
Using an IP Address as the Identifier parameter is efficient - In order to open a TCP device with a specific serial number or name,
LJM will communicate with all LabJack devices on the network, asking each for their serial number or name. In contrast, opening a TCP
LabJack device by IP address will only send packets to that IP address, which is faster and more efficient. Setting up static IP addresses
can be troublesome, so use what is appropriate for you application.
Specific IPs will be checked - Specific IP addresses may be defined, which LJM will try to open during every Ethernet- or WiFi-based Open
or ListAll call.
Closing
Closing a handle will remove the associated device connection from the LJM library. Closing will both free the device to be opened
again, and free allocated system resources.
Devices are closed automatically when LJM is unloaded - When the LJM library (.dll, .dylib, or .so) is unloaded, it will automatically
close all devices.
Open
Opens a desired LabJack and associates a device handle number (connection ID). The device handle may then be passed as an input
to other functions.
Syntax
LJM_ERROR_RETURN LJM_Open(
int DeviceType,
int ConnectionType,
const char * Identifier,
int * Handle)
Parameters
DeviceType [in]
An integer containing the type of the device to be connected:
LJM_dtANY (0) - Open any supported LabJack device type
LJM_dtT7 (7) - Open a T7-series device
LJM_dtDIGIT (200) - Open a Digit-series device
ConnectionType [in]
An integer containing the type of connection desired:
LJM_ctANY (0), LJM_ctUSB (1), LJM_ctTCP (2), LJM_ctETHERNET (3), LJM_ctWIFI (4)
Other UDP options:
LJM_ctNETWORK_UDP (5), LJM_ctETHERNET_UDP (6), LJM_ctWIFI_UDP (7)
Other TCP or UDP options:
LJM_ctNETWORK_ANY (8), LJM_ctETHERNET_ANY (9), LJM_ctWIFI_ANY (10)
Identifier [in]
A string that may identify the device to be connected. To open any device, use LJM_idANY (or the string "ANY"). To specify an
identifier, use a serial number, IP address, or device name. See Identifier Parameter for more information.
Handle [out]
The new handle that represents the device connection.
Returns
Related Functions
LJM_Open and LJM_OpenS are essentially the same, except that LJM_OpenS uses string parameters for DeviceType and
ConnectionType rather than integer parameters.
Remarks
When the ConnectionType parameter of this function is network-based, this function will check the IP addresses listed in
LJM_SPECIAL_ADDRESSES_FILE.
Examples
1 int LJMError;
2 int handle;
3 LJMError = LJM_Open(7, 0, "ANY", &handle);
OpenS
Opens a desired LabJack and associates a device handle number (connection ID). The device handle may then be passed as an input
to other functions.
Syntax
LJM_ERROR_RETURN LJM_OpenS(
const char * DeviceType,
const char * ConnectionType,
const char * Identifier,
int * Handle)
Parameters
DeviceType [in]
A string containing the type of the device to be connected:
"ANY" - Open any supported LabJack device type
"T7" - Open a T7-series device
"DIGIT" - Open a Digit-series device
ConnectionType [in]
A string containing the type of connection desired (USB or TCP):
"ANY", "USB", "TCP", "ETHERNET", or "WIFI"
Additional UDP options:
"NETWORK_UDP", "ETHERNET_UDP", "WIFI_UDP"
Additional TCP or UDP options:
"NETWORK_ANY", "ETHERNET_ANY", "WIFI_ANY"
Identifier [in]
A string that may identify the device to be connected. To open any device, use LJM_idANY (or the string "ANY"). To specify an
identifier, use a serial number, IP address, or device name. See Identifier Parameter for more information.
Handle [out]
The new handle that represents the device connection.
Returns
Relevant Functions
LJM_OpenS and LJM_Open are essentially the same, except that LJM_Open uses integer parameters for DeviceType and
ConnectionType rather than string parameters.
Remarks
When the ConnectionType parameter of this function is network-based, this function will check the IP addresses listed in
LJM_SPECIAL_ADDRESSES_FILE.
Examples
1 int LJMError;
2 int handle;
3 LJMError = LabJack.LJM.OpenS("T7", "Ethernet", "ANY", ref handle);
1 int LJMError;
2 int handle;
3 LJMError = LJM_OpenS("T7", "TCP", "ANY", &handle);
Identifier Parameter
This page describes the Identifier parameter that is used in LJM_Open and LJM_OpenS.
Common Usage
Network-Specific
TCP/UDP port can be specified by appending a colon and the port number. For example, if your Identifier is the IP address
192.168.1.42 and you want to connect to port 502, your Identifier would be "192.168.1.42:502".
For example, for the hexadecimal IP address C0A8012A can be passed as Identifier as "0xC0.A8.01.2A". (An Identifier like
"C0.A8.01.2A" would be interpreted as a hex IP address because it contains letters, but it is highly recommended to use the "0x" prefix
anyway.)
USB-Specific
For USB, pipe can be specified by appending a colon and the pipe number. For example, if your Identifier is the serial number
470010117 and you want to connect to pipe 0, your Identifier would be "470010117:0".
Close
Add new comment
Closing a handle will remove the associated device connection from the LJM library, free the device to be opened again, and free
allocated system resources.
Syntax
LJM_ERROR_RETURN LJM_Close(int Handle)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open, or LJM_OpenS.
Returns
Remarks
LJM_Close is useful when multiple LabJack device connections are open and only a single connection needs to be closed. Use
LJM_CloseAll to close every device in a single function call.
Examples
1 int LJMError;
2 //handle from LJM_Open()
3 LJMError = LabJack.LJM.Close(handle);
1 int LJMError;
2 //handle from LJM_Open()
3 LJMError = LJM_Close(handle);
CloseAll
Closing all devices will remove all device handles from the LJM library, free all previously open devices to be opened again, and free
allocated system resources.
Syntax
LJM_ERROR_RETURN LJM_CloseAll()
Parameters
None
Returns
Remarks
LJM_CloseAll is useful on program exit. Use LJM_Close to close an individual device handle.
Examples
1 int LJMError;
2 LJMError = LJM_CloseAll();
To access device data one value at a time, use the following functions. See the Modbus map to see what values can be accessed.
Name Functions
Name functions access data by a name, such as "AIN5" for analog input 5.
Address Functions
Address functions access data by an address and data type. For example, analog input 5 ("AIN5") would have address 10 and a 32-bit
floating point type.
Need to read or write multiple values at once? Use the Multiple Value Functions.
eWriteName
Add new comment
Syntax
LJM_ERROR_RETURN LJM_eWriteName(
int Handle,
const char * Name,
double Value)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The name that specifies the Modbus register(s) to write. Names can be found throughout the device datasheet or in the Modbus
Map.
Value [in]
The value to send to the device.
Returns
Remarks
For an alternate function using an address rather than name, see LJM_eWriteAddress. More code examples coming soon.
Example
1 int LJMError;
2 //handle from LJM_Open()
3 LJMError = LJM_eWriteName(handle, "DAC0", 2.5);
eReadName
Read one value, specified by name.
Syntax
LJM_ERROR_RETURN LJM_eReadName(
int Handle,
const char * Name,
double * Value)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The name that specifies the Modbus register(s) to read. Names can be found throughout the device datasheet or in the Modbus
Map.
Value [out]
The value returned from the device.
Returns
Remarks
For an alternate function using an address rather than name, see LJM_eReadAddress. More code examples coming soon.
Example
eWriteAddress
Write one value, specified by address.
Syntax
LJM_ERROR_RETURN LJM_eWriteAddress(
int Handle,
int Address,
int Type,
double Value)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Address [in]
The address that specifies the Modbus register(s) to write. Addresses can be found throughout the device datasheet or in the
Modbus Map.
Type [in]
The data type of the value:
LJM Constant LJM Constant
Type
Name Value
unsigned 16-bit
LJM_UINT16 0
integer
unsigned 32-bit
LJM_UINT32 1
integer
signed 32-bit integer LJM_INT32 2
floating point 32-bit LJM_FLOAT32 3
Value [in]
The value to send to the device. The input data type is a double, and will be converted according to the Type input.
Returns
Remarks
For an alternate function using a name rather than address, see LJM_eWriteName.
Examples
1 int LJMError;
2 //handle from LJM_Open()
3 LJMError = LJM_eWriteAddress(handle, 1000, 3, 2.5);
eReadAddress
Read one value, specified by address.
Syntax
LJM_ERROR_RETURN LJM_eReadAddress(
int Handle,
int Address,
int Type,
double * Value)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Address [in]
The address that specifies the Modbus register(s) to read. Addresses can be found throughout the device datasheet or in the
Modbus Map.
Type [in]
The data type of the value:
LJM Constant LJM Constant
Type
Name Value
unsigned 16-bit
LJM_UINT16 0
integer
unsigned 32-bit
LJM_UINT32 1
integer
signed 32-bit integer LJM_INT32 2
floating point 32-bit LJM_FLOAT32 3
Value [out]
The value returned from the device. The output data type is a double, and will be converted according to the Type input.
Returns
Remarks
For an alternate function using a name rather than address, see LJM_eReadName. More code examples coming soon.
Examples
1 int LJMError;
2 double newValue;
3 //handle from LJM_Open()
4 LJMError = LJM_eReadAddress(handle, 60028, 1, &newValue);
5 printf("SERIAL_NUMBER: %f\n", newValue);
eWriteNameString
Writes a string, specified by name.
Syntax
LJM_ERROR_RETURN LJM_eWriteNameString(
int Handle,
const char * Name,
const char * String)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The name that specifies the Modbus string-type register to write. Names can be found throughout the device datasheet or in the
Modbus Map.
String [in]
The string to write. Must null-terminate at size LJM_STRING_ALLOCATION_SIZE (50) or less.
Returns
Remarks
See also LJM_eReadNameString. This is a convenience function that uses LJM_eNames. Only for use with Modbus register(s) listed
as type LJM_STRING (98). More code examples coming soon.
Examples
1 int LJMError;
2 // handle from Open();
3 // LJM_STRING_ALLOCATION_SIZE is 50
4 char newName[LJM_STRING_ALLOCATION_SIZE] = "My Favorite DAQ Device";
5
6 LJMError = LJM_eWriteNameString(handle, "DEVICE_NAME_DEFAULT", newName);
eReadNameString
Reads a string, specified by name.
Syntax
LJM_ERROR_RETURN LJM_eReadNameString(
int Handle,
const char * Name,
char * String)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The name that specifies the Modbus string-type register to read. Names can be found throughout the device datasheet or in the
Modbus Map.
String [out]
A string that is updated to contain the result of the read. Must be allocated to size LJM_STRING_ALLOCATION_SIZE (50) or
greater prior to calling this function.
Returns
Remarks
See also LJM_eWriteNameString. This is a convenience function that uses LJM_eNames. Only for use with Modbus register(s) listed as
type LJM_STRING (98).
Examples
eWriteAddressString
Writes a string, specified by address.
Syntax
LJM_ERROR_RETURN LJM_eWriteAddressString(
int Handle,
int Address,
const char * String)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Address [in]
The address that specifies the Modbus string-type register to write. Addresses can be found throughout the device datasheet or in
the Modbus Map.
String [in]
The string to write. Must null-terminate at size LJM_STRING_ALLOCATION_SIZE (50) or less.
Returns
Remarks
See also LJM_eReadAddressString. This is a convenience function that uses LJM_eAddresses. Only for use with Modbus registers
listed as type LJM_STRING (98). More code examples coming soon.
Examples
1 int LJMError;
2 // handle from Open();
3 // LJM_STRING_ALLOCATION_SIZE is 50
4 char newName[LJM_STRING_ALLOCATION_SIZE] = "My Favorite DAQ Device";
5
6 LJMError = LJM_eWriteAddressString(handle, 60500, newName);
eReadAddressString
Reads a string, specified by address.
Syntax
LJM_ERROR_RETURN LJM_eReadAddressString(
int Handle,
int Address,
char * String)
Parameters
Handle [in]A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The address that specifies the Modbus string-type register to read. Addresses can be found throughout the device datasheet or in
the Modbus Map.
String [out]
A string that is updated to contain the result of the read. Must be allocated to size LJM_STRING_ALLOCATION_SIZE (50) or
greater prior to calling this function.
Returns
Remarks
See also LJM_eWriteAddressString. This is a convenience function that uses LJM_eAddresses. Only for use with Modbus registers
listed as type LJM_STRING (98).
Examples
1 int LJMError;
2 // handle from Open()
3 // LJM_STRING_ALLOCATION_SIZE is 50
4 char devName[LJM_STRING_ALLOCATION_SIZE];
5
6 LJMError = LJM_eReadAddressString(handle, 60500, devName);
7 printf ("%s \n", devName);
To access device data multiple values at once, use the following functions. See the Modbus map to see what values can be accessed.
Name Functions
Name functions access data through a name, such as "AIN5" for analog input 5.
Address Functions
Address functions access data through an address, such as 10 for analog input 5.
eWriteNames
Add new comment
Write multiple values, specified by name.
Syntax
LJM_ERROR_RETURN LJM_eWriteNames(
int Handle,
int NumFrames,
const char ** aNames,
const double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
NumFrames [in]
The total number of frames to access. A frame consists of one value, so the number of frames is the size of the aNames array.
aNames [in]
An array of names that specify the Modbus register(s) to write. Names can be found throughout the device datasheet or in the
Modbus Map.
aValues [in]
An array of values to send to the device. The array size should be the same as the aNames array. The input data type of each
value is a double, and will be converted into the correct data type automatically.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
This function is commonly used to write a handful of values at once, and is more convenient than LJM_eWriteAddresses because it is
not necessary to know the data type. More code examples coming soon.
Examples
[C/C++] Change digital I/O 0, 1, and 2 to output high, and digital I/O 6 to output low.
1 int LJMError;
2 int errorAddress;
3 //handle from LJM_Open()
4 const * char[4] = {"FIO0", "FIO1", "FIO2", "FIO6"};
5 double aValues[4] = {1, 1, 1, 0};
6
7 LJMError = LJM_eWriteNames(handle, 4, aNames, aValues, &errorAddress);
eReadNames
Read multiple values, specified by name.
Syntax
LJM_ERROR_RETURN LJM_eReadNames(
int Handle,
int NumFrames,
const char ** aNames,
double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
NumFrames [in]
The total number of frames to access. A frame consists of one value, so the number of frames is the size of the aNames array.
aNames [in]
An array of names that specify the Modbus register(s) to write. Names can be found throughout the device datasheet or in the
Modbus Map.
aValues [out]
An array of values received from the device. The array size should be same as the aNames array. The values will be converted
into doubles automatically.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
This function is commonly used to read a handful of values at once, and is more convenient than LJM_eReadAddresses because it is
not necessary to know the data type. More code examples coming soon.
Examples
1 int LJMError;
2 int errorAddress;
3 const char * aNames[3] = {"AIN5", "AIN6", "AIN10"};
4 double ainValues[3];
5 //handle from LJM_Open()
6 double ain5;
7 double ain6;
8 double ain10;
9
10 LJMError = LJM_eReadNames(handle, 3, aNames, ainValues, &errorAddress);
11 ain5 = ainValues[0];
12 ain6 = ainValues[1];
13 ain10 = ainValues[2];
eWriteAddresses
Write multiple values, specified by address.
Syntax
LJM_ERROR_RETURN LJM_eWriteAddresses(
int Handle,
int NumFrames,
const int * aAddresses,
const int * aTypes,
const double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
NumFrames [in]
The total number of frames to access. A frame consists of one value, so the number of frames is the size of the aAddresses array.
aAddresses [in]
An array of addresses that specify the Modbus register(s) to write. Addresses can be found throughout the device datasheet or in
the Modbus Map.
aTypes [in]
An array containing the data type of each value:
LJM Constant LJM Constant
Type
Name Value
unsigned 16-bit
LJM_UINT16 0
integer
unsigned 32-bit
integer LJM_UINT32 1
aValues [in]
An array of values to send to the device. The array size should be the size of the aAddresses array. The input data type of each
value is a double, and they will be converted into the data type entered in aTypes.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
This function is used to write a handful of values at once, and is useful in programming languages that are not friendly towards the
usage of strings. For programming languages that can use strings easily, see LJM_eWriteNames. More code examples coming soon.
Examples
[C/C++] Change digital I/O 0, 1, and 2 to output high, and digital I/O 6 to output low.
1 int LJMError;
2 int errorAddress;
3 //handle from LJM_Open()
4 int aAddresses[4] = {2000, 2001, 2002, 2006};
5 int aTypes[4] = {0, 0, 0, 0};
6 double aValues[4] = {1, 1, 1, 0};
7
8 LJMError = LJM_eWriteAddresses(handle, 4, aAddresses, aTypes, aValues, &errorAddress);
eReadAddresses
Read multiple values, specified by address.
Syntax
LJM_ERROR_RETURN LJM_eReadAddresses(
int Handle,
int NumFrames,
const int * aAddresses,
const int * aTypes,
double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
NumFrames [in]
The total number of frames to access. A frame consists of one value, so the number of frames is the size of the aAddresses array.
aAddresses [in]
An array of addresses that specify the Modbus register(s) to read. Addresses can be found throughout the device datasheet or in
the Modbus Map.
aTypes [in]
An array containing the data type of each value:
LJM Constant LJM Constant
Type
Name Value
unsigned 16-bit
LJM_UINT16 0
integer
unsigned 32-bit
LJM_UINT32 1
integer
signed 32-bit integer LJM_INT32 2
floating point 32-bit LJM_FLOAT32 3
aValues [out]
An array of values received from the device. The array size should be the size of the aAddresses array. The output data type of
each value is a double, and they will be converted from the data type entered in aTypes.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
This function is used to read a handful of values at once, and is useful in programming languages that are not friendly towards the
usage of strings. For programming languages that can use strings easily, see LJM_eReadNames. More code examples coming soon.
Examples
1 int LJMError;
2 int errorAddress;
3 int aAddresses[3] = {10, 12, 20};
4 int aTypes[3] = {3, 3, 3};
5 double ainValues[3];
6 //handle from LJM_Open()
7 double ain5;
8 double ain6;
9 double ain10;
10
11 LJMError = LJM_eReadAddresses(handle, 3, aAddresses, aTypes, ainValues, &errorAddress);
12 ain5 = ainValues[0];
13 ain6 = ainValues[1];
14 ain10 = ainValues[2];
eNames
Write/Read multiple values, specified by name. This function is designed to condense communication into arrays. Moreover,
consecutive values can be accessed by specifying a starting name, and a number of values.
Syntax
LJM_ERROR_RETURN LJM_eNames(
int Handle,
int NumFrames,
const char ** aNames,
const int * aWrites,
const int * aNumValues,
double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
NumFrames [in]
The total number of frames to access. A frame consists of one or more values, based on NumValues.
aNames [in]
An array of names that specify the Modbus register(s) to write/read. To access a consecutive group of values, populate an element
of the aNames array with the starting name, and then increase the NumValues parameter according to the group size.
aWrites [in]
An array containing the desired type of access, which is either read(0) or write(1). The array size should be the same as the
aNames array.
aNumValues [in]
An array that contains the per-name number of consecutive values. NumValues is 1 for non-consecutive. The array size should
be the same as the aNames array.
aValues [in/out]
An array of values transferred to/from the device. The array size should be the sum of all elements in the aNumValues array. For
values in the array that are being sent, data is automatically converted into the correct data type. For incoming values, data is
converted to a double automatically.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
LJM_eNames is for programs that need to write and read multiple, arbitrary values in a single function call. For example, a PID loop
may read inputs and set outputs in a single function call. In this way, the communication overhead is reduced. There are simpler single
value functions and simpler multiple value functions for programs that do not need such a level of communication optimization.
To use LJM_eNames:
As an example of the above use-case, consider reading AIN0-2, setting DAC0 to 4.6V, and reading the state of DIO4.
Examples
[C/C++] Read analog inputs 0 through 2, set DAC0 to 4.6V, and read FIO4
1 int LJMError;
2 int errorAddress;
3 const char * aNames[3] = {"AIN0", "DAC0", "FIO4"};
4 int aWrites[3] = {LJM_READ, LJM_WRITE, LJM_READ};
5 int aNumValues[3] = {3, 1, 1};
6 double aValues[5];
7 //handle from LJM_Open()
8 aValues[3] = 4.6;
9
10 LJMError = LJM_eNames(handle, 3, aNames, aWrites, aNumValues, aValues, &errorAddress);
11 printf("AIN0: %f\n", aValues[0]);
12 printf("AIN1: %f\n", aValues[1]);
13 printf("AIN2: %f\n", aValues[2]);
14 printf("FIO4: %f\n", aValues[4]);
eAddresses
Write/Read multiple values, specified by address. This function is designed to condense communication into arrays. Moreover,
consecutive values can be accessed by specifying a starting address, and a number of values.
Syntax
LJM_ERROR_RETURN LJM_eAddresses(
int Handle,
int NumFrames,
const int * aAddresses,
const int * aTypes,
const int * aWrites,
const int * aNumValues,
double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
NumFrames [in]
The total number of frames to access. A frame consists of one or more values, based on NumValues.
aAddresses [in]
An array of addresses that specify the Modbus register(s) to write/read. To access a consecutive group of values, populate an
element of aAddresses array with the starting address, and then increase the NumValues parameter according to the group size.
aTypes [in]
An array of size NumFrames, containing the data type of each value sent/received:
LJM Constant LJM Constant
Type
Name Value
unsigned 16-bit
LJM_UINT16 0
integer
unsigned 32-bit
LJM_UINT32 1
integer
signed 32-bit integer LJM_INT32 2
floating point 32-bit LJM_FLOAT32 3
aWrites [in]
An array containing the desired type of access, which is either read(0) or write(1). The array size should be the same as the
aAddresses array.
aNumValues [in]
An array that contains the per-address number of consecutive values. NumValues is 1 for non-consecutive. The array size
should be the same as the aAddresses array.
aValues [in/out]
An array of values to be transferred to/from the device. The array size should be the sum of all elements in the aNumValues array.
Each value will be converted to/from those defined in aTypes.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
LJM_eNames is for programs that need to write and read multiple, arbitrary values in a single function call. For example, a PID loop
may read inputs and set outputs in a single function call. In this way, the communication overhead is reduced. There are simpler single
value functions and simpler multiple value functions for programs that do not need such a level of communication optimization.
To use LJM_eAddresses:
As an example of the above use-case, consider reading AIN0-2 (addresses 0, 2, 4), setting DAC0 (address 1000) to 4.6V, and reading
the state of DIO4 (address 2004).
Examples
[C/C++] Read analog inputs 0 through 7, set DAC0 to 4.6V, read FIO4
1 int LJMError;
2 int errorAddress;
3 int aAddresses[3] = {0, 1000, 2004};
4 int aTypes[3] = {LJM_FLOAT32, LJM_FLOAT32, LJM_UINT16};
5 int aWrites[3] = {LJM_READ, LJM_WRITE, LJM_READ};
6 int aNumValues[3] = {3, 1, 1};
7 double aValues[5];
8 //handle from LJM_Open()
9 aValues[3] = 4.6;
10
11 LJMError = LJM_eAddresses(handle, 3, aAddresses, aTypes, aWrites, aNumValues, aValues, &errorAddress);
12 printf("AIN0: %f\n", aValues[0]);
13 printf("AIN1: %f\n", aValues[1]);
14 printf("AIN2: %f\n", aValues[2]);
15 printf("FIO4: %f\n", aValues[4]);
eReadAddressArray
Add new comment
Read consecutive values, specified by an address and type.
Syntax
LJM_ERROR_RETURN LJM_eReadAddressArray(
int Handle,
int Address,
int Type,
int NumValues,
double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Address [in]
The address that specifies the Modbus register(s) to read. Addresses can be found throughout the device datasheet or in
the Modbus Map.
Type [in]
The data type of the value(s):
LJM Constant LJM Constant
Type
Name Value
unsigned 16-bit
LJM_UINT16 0
integer
unsigned 32-bit
integer LJM_UINT32 1
NumValues [in]
The number of consecutive values to read.
aValues [out]
An array of values to be transferred from the device. The array size should be equal to NumValues. Each value will be converted
according to Type.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
Examples
1 int LJMError;
2 int errorAddress;
3 double newValues[8];
4 //handle from LJM_Open()
5
6 LJMError = LJM_eReadAddressArray(handle, 0, LJM_FLOAT32, 8, newValues, &errorAddress);
eReadAddressByteArray
Read consecutive byte values, specified by an address.
Syntax
LJM_ERROR_RETURN LJM_eReadAddressByteArray(
int Handle,
int Address,
int NumBytes,
char * aBytes,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Address [in]
The address that specifies the Modbus register(s) to read. Addresses can be found throughout the device datasheet or in
the Modbus Map.
NumBytes [in]
The number of consecutive bytes.
aBytes [out]
An array of bytes transferred from the device. The array size should be equal to NumBytes.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
If NumBytes is large enough, these functions will automatically split reads into multiple packets based on:
This function will treat all of aBytes as either buffer data or as non-buffer data based on whether Address is a buffer register. This means
that you cannot begin reading from a non-buffer register and read into a buffer register.
Examples
eReadNameArray
Read consecutive values, specified by a name.
Syntax
LJM_ERROR_RETURN LJM_eReadNameArray(
int Handle,
const char * Name,
int NumValues,
double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The name that specifies the Modbus register(s) to read. Names can be found throughout the device datasheet or in the Modbus
Map.
NumValues [in]
The number of consecutive values to read.
aValues [out]
An array of values to be transferred from the device. The array size should be equal to NumValues. Each value will be converted
according to the type of Name.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
1 int LJMError;
2 int errorAddress;
3 double newValues[8];
4 //handle from LJM_Open()
5
6 LJMError = LJM_eReadNameArray(handle, "AIN0", 8, newValues, &errorAddress);
eReadNameByteArray
Read consecutive byte values, specified by a name.
Syntax
LJM_ERROR_RETURN LJM_eReadNameByteArray(
int Handle,
const char * Name,
int NumBytes,
char * aBytes,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The name that specifies the Modbus register(s) to read. Names can be found throughout the device datasheet or in the Modbus
Map.
NumBytes [in]
The number of consecutive bytes.
aBytes [out]
An array of bytes transferred from the device. The array size should be equal to NumBytes.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
If NumBytes is large enough, these functions will automatically split reads into multiple packets based on:
This function will treat all of aBytes as either buffer data or as non-buffer data based on whether Name is a buffer register. This means
that you cannot begin reading from a non-buffer register and read into a buffer register.
Examples
eWriteAddressArray
Write consecutive values, specified by an address and type.
Syntax
LJM_ERROR_RETURN LJM_eWriteAddressArray(
int Handle,
int Address,
int Type,
int NumValues,
double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Address [in]
The address that specifies the Modbus register(s) to write. Addresses can be found throughout the device datasheet or in
the Modbus Map.
Type [in]
The data type of the value(s):
LJM Constant LJM Constant
Type
Name Value
unsigned 16-bit
LJM_UINT16 0
integer
unsigned 32-bit
LJM_UINT32 1
integer
signed 32-bit integer LJM_INT32 2
floating point 32-bit LJM_FLOAT32 3
NumValues [in]
The number of consecutive values.
aValues [in]
An array of values to be transferred to the device. The array size should be equal to NumValues. Each value will be converted
according to Type.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
Examples
1 int LJMError;
2 int errorAddress;
3 double newValues[2] = {1.2, 3.4};
4 //handle from LJM_Open()
5
6 LJMError = LJM_eWriteAddressArray(handle, 1000, LJM_FLOAT32, 2, newValues, &errorAddress);
eWriteAddressByteArray
Write consecutive byte values, specified by an address.
Syntax
LJM_ERROR_RETURN LJM_eWriteAddressByteArray(
int Handle,
int Address,
int NumBytes,
const char * aBytes,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Address [in]
The address that specifies the Modbus register(s) to write. Address can be found throughout the device datasheet or in
the Modbus Map.
NumBytes [in]
The number of consecutive bytes.
aBytes [in]
An array of bytes to be transferred to the device. The array size should be equal to NumBytes.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
If NumBytes is large enough, these functions will automatically split writes into multiple packets based on:
Remarks
Examples
1 int LJMError;
2 int ErrorAddress;
3 const char * luaScript =
4 "LJ.IntervalConfig(0, 1000)\n"
5 "while true do\n"
6 " if LJ.CheckInterval(0) then\n"
7 " print(LJ.Tick())\n"
8 " end\n"
9 "end\n"
10 "\0";
11 const unsigned scriptLength = strlen(luaScript) + 1;
12 //handle from LJM_Open()
13 LJMError = LJM_eWriteAddressByteArray(
14 handle,
15 LUA_SOURCE_WRITE_ADDRESS,
16 scriptLength,
17 luaScript,
18 &ErrorAddress
19 );
20 if (LJMError != LJME_NOERROR) {
21 // handle error
22 }
eWriteNameArray
Write consecutive values, specified by a name.
Syntax
LJM_ERROR_RETURN LJM_eWriteNameArray(
int Handle,
const char * Name,
int NumValues,
double * aValues,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The name that specifies the Modbus register(s) to write. Names can be found throughout the device datasheet or in the Modbus
Map.
NumValues [in]
The number of consecutive values.
aValues [in]
An array of values to be transferred to the device. The array size should be equal to NumValues. Each value will be converted
according to the type of Name.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
LJM errorcodes or 0 for no error.
Remarks
Examples
1 int LJMError;
2 int errorAddress;
3 double newValues[2] = {1.2, 3.4};
4 //handle from LJM_Open()
5
6 LJMError = LJM_eWriteNameArray(handle, "DAC0", 2, newValues, &errorAddress);
eWriteNameByteArray
Write consecutive byte values, specified by a name.
Syntax
LJM_ERROR_RETURN LJM_eWriteNameByteArray(
int Handle,
const char * Name,
int NumBytes,
const char * aBytes,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Name [in]
The name that specifies the Modbus register(s) to write. Names can be found throughout the device datasheet or in the Modbus
Map.
NumBytes [in]
The number of consecutive bytes.
aBytes [in]
An array of bytes to be transferred to the device. The array size should be equal to NumBytes.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
If NumBytes is large enough, these functions will automatically split writes into multiple packets based on:
This function will treat all of aBytes as either buffer data or as non-buffer data based on whether Name is a buffer register. This means
that you cannot begin writing to a non-buffer register and write into a buffer register.
Examples
1 int LJMError;
2 int ErrorAddress;
3 const char * luaScript =
4 "LJ.IntervalConfig(0, 1000)\n"
5 "while true do\n"
6 " if LJ.CheckInterval(0) then\n"
7 " print(LJ.Tick())\n"
8 " end\n"
9 "end\n"
10 "\0";
11 const unsigned scriptLength = strlen(luaScript) + 1;
12 //handle from LJM_Open()
13 LJMError = LJM_eWriteNameByteArray(
14 handle,
15 "LUA_SOURCE_WRITE",
16 scriptLength,
17 luaScript,
18 &ErrorAddress
19 );
20 if (LJMError != LJME_NOERROR) {
21 // handle error
22 }
Data Movement
1. The device collects samples at the given scan rate in a buffer on the device.
2. LJM collects samples from the device in a buffer within LJM.
3. LJM_eStreamRead or LJM_eStreamBurst reads those samples from the LJM buffer.
eStreamStart
Add new comment
Initializes a stream object and begins streaming. This function creates a buffer in memory that holds data from the device, so that higher
data throughput can be achieved.
Syntax
LJM_ERROR_RETURN LJM_eStreamStart(
int Handle,
int ScansPerRead,
int NumAddresses,
const int * aScanList,
double * ScanRate)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
ScansPerRead [in]
The number of scans returned by each call to the LJM_eStreamRead function. Increase this parameter to get more data per call of
LJM_eStreamRead. A typical value would be equal to ScanRate or 1/2 ScanRate, which results in a read once or twice per
second.
NumAddresses [in]
The number of addresses in aScanList. The size of the aScanList array.
aScanList [in]
An array of addresses to stream. The scan list is the list of data addresses that are to be buffered by LJM and returned with
LJM_eStreamRead. Find addresses in the Modbus Map. For example, to stream AIN3 add the address 6 to the scan list.
ScanRate [in/out]
A pointer that sets the desired number of scans per second. Upon successful return of this function, ScanRate will be updated to
the actual scan rate that the device will use. Keep in mind that data rate limits are specified in Samples/Second which is equal to
NumAddresses * Scans/Second.
Returns
Remarks
To read data from stream, use LJM_eStreamRead. To stop stream, use LJM_eStreamStop.
Configuration - Channel configuration such as range and resolution must be handled elsewhere. Check the device datasheet for
details about analog inputs and which connection types are capable of stream.
This function writes to the following registers, which cannot be set manually when using LJM_eStreamStart:
STREAM_SCANRATE_HZ
STREAM_NUM_ADDRESSES
STREAM_SAMPLES_PER_PACKET
STREAM_AUTO_TARGET
STREAM_SCANLIST_ADDRESS#(0:127)
STREAM_ENABLE
How samples are moved from the device to your application - When stream is running, there are two sample buffers to consider: the
device buffer and the LJM buffer. The device acquires a scan of stream data at every scan interval according to its own clock and puts
that data into the device buffer. At the same time, LJM is running a background thread that moves data from the device buffer to the LJM
buffer. At the same time the user application needs to move data from the LJM buffer to the user application. Some definitions and
details:
1. MaxBytesPerPacket: Maximum number of bytes per Modbus TCP packet sent between the device and host. For the T7 the limits are
64/1040/500 bytes for USB/Ethernet/WiFi, respectively.
2. MaxSamplesPerPacket: A stream data packet has 16 bytes of overhead and each sample needs 2 bytes, so based on
MaxByesPerPacket above the maximum number of samples per packet for the T7 is 24/512/242 for USB/Ethernet/WiFi, respectively.
3. SamplesPerPacket (STREAM_SAMPLES_PER_PACKET): The actual number of samples per USB/TCP packet, as configured by
LJM. This might be less than MaxSamplesPerPacket if ScansPerRead is set to a smaller value. This is limited by (ScansPerRead *
NumAddresses) and MaxSamplesPerPacket.
4. SamplesPerTransfer: The number of samples transferred per USB/TCP read call done automatically in the LJM background thread.
This sets the interval for how often LJM does a read. An LJM read might consist of multiple USB/TCP packets. This is limited by
(ScansPerRead * NumAddresses) and MaxSamplesPerPacket.
5. ScansPerRead: The number of scans that your software pulls from the LJM stream buffer per call to LJM_eStreamRead. This
parameter is used to limit STREAM_SAMPLES_PER_PACKET, so if you want to minimize blocking that might occur due to LJM's
stream read thread waiting for data, then set ScansPerRead low. Normally, ScansPerRead is set to a higher value as it is most efficient
to move bigger chunks of data less often, but if you want minimum latency between input/output you can set ScansPerRead as low as 1.
Externally clocked stream - Externally clocked stream is when a signal is received on CIO3, for which each edge a single scan is
triggered. This allows for variable scan rates and synchronized streaming.
When using externally clocked stream, LJM_eStreamStart's ScanRate should be the fastest scan rate that the externally clocked stream
will occur at.
If externally clocked stream occurs at a variable scan rate or does not occur immediately after calling LJM_eStreamStart, you'll probably
need to use an LJM configuration to prevent LJM from throwing an error when scans are not received by LJM within the expected
timeframe since LJM normally expects a constant scan rate, and it will throw an error if it does not receive data from the device fast
enough. Here are the options for setting LJM's configs for variable speed and/or delayed start streaming, which should be set using
LJM_WriteLibraryConfigS:
- Set LJM_STREAM_RECEIVE_TIMEOUT_MS to a safe timeout for your expected stream speeds. This should be the longest
expected timeout, plus a small amount extra. If you're not sure how long of a timeout you need, 0 is the infinite timeout and will never time out.
Triggered stream - Triggered stream could also be called "delayed start stream". It is when LJM_eStreamStart has been called but
stream does not start until a signal is received on FIO0 or FIO1, after which stream continues to collect data as normal.
To use triggered stream with LJM, you must enable some LJM configurations and also some T7 configurations.
- Set LJM_STREAM_RECEIVE_TIMEOUT_MS to a safe timeout for how long you expect it to take before stream starts. If you're not
sure how long of a timeout you need, 0 is the infinite timeout and will never time out.
Burst Stream
Burst stream is when a limited number of scans are collected by the device, after which the device stops streaming. LJM_StreamBurst
may be used to automatically perform a burst stream or burst stream may be performed manually using the following steps:
Auto-recovery Precaution
If auto-recovery is enabled (the default), and there is any risk of auto-recovery happening (typically happens at the highest data rates
only), the first channel in the stream scan list should always be an analog input (AIN#). If you only want to stream other channels
besides analog inputs and cannot add a dummy analog input because you need maximum speed, then do either of the following:
Ensure that the first channel in the scan list will never return 0xFFFF as a normal valid reading.
Disable auto-recovery, which means that if the device buffer overflows stream will stop and you will get an error.
Auto-recovery mode is entered when the stream buffer on the LabJack device is too full. At that point, the device will discard further
scans but will keep track of how many scans have been discarded. Once stream read has caught up and emptied the device stream
buffer sufficiently, the device will stop discarding scans, and will send a data packet that reports the number of discarded scans and also
has a scan of all 0xFFFF that denotes the border between pre and post auto-recovery data. In the LJM stream buffer that is read by the
user's application, LJM inserts the proper number of dummy scans, filled with all -9999.0s, to maintain proper timing of stream data
through auto-recovery.
LJM actually looks at the first value in each scan to detect the border scan. Once auto-recovery starts, LJM watches the first channel in a
scan and if it sees 0xFFFF it assumes that is the border scan that marks the start of post auto-recovery data. 0xFFFF is a special
reserved value that analog inputs never return under normal circumstances.
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 int LJMError;
3 const int numAddresses = 2;
4 const int aScanList[] = {0, 2}; // AIN0 and AIN1
5 const int initScanRate = 10000;
6 double scanRate = initScanRate;
7 const int scansPerRead = initScanRate / 2;
8 double aData[numAddresses * scansPerRead];
9 int DeviceScanBacklog;
10 int LJMScanBacklog;
11 int iteration = 0;
12 // Start stream
13 // handle from LJM_Open() or LJM_OpenS()
14 LJMError = LJM_eStreamStart(handle, scansPerRead, numAddresses, aScanList, &scanRate);
15 if (LJMError != 0) {
16 LJM_ErrorToString(LJMError, ErrorString);
17 printf("LJM_eStreamStart error: %s\n", ErrorString);
18 }
19 else {
20 printf("Stream started at %f Hz\n", scanRate);
21 }
22 // Read stream
23 for (iteration = 0; iteration < 10; iteration++) {
24 LJMError = LJM_eStreamRead(handle, aData, &DeviceScanBacklog, &LJMScanBacklog);
25 if (LJMError != 0) {
26 LJM_ErrorToString(LJMError, ErrorString);
27 printf("LJM_eStreamRead error: %s\n", ErrorString);
28 }
29 MyDataProcessingFunction(aData, DeviceScanBacklog, LJMScanBacklog);
30 }
31 // Stop stream
32 LJMError = LJM_eStreamStop(handle);
33 if (LJMError != 0) {
34 LJM_ErrorToString(LJMError, ErrorString);
35 printf("LJM_eStreamStop error: %s\n", ErrorString);
36 }
eStreamRead
Add new comment
Returns data from an initialized and running LJM stream buffer. Waits for data to become available, if necessary.
Syntax
LJM_ERROR_RETURN LJM_eStreamRead(
int Handle,
double * aData,
int * DeviceScanBacklog,
int * LJMScanBacklog)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
aData [out]
An array that contains the values being read. Returns all channels interleaved. Must be large enough to hold (ScansPerRead *
NumAddresses) values, where ScansPerRead and NumAddresses are values passed to LJM_eStreamStart. The data returned is
removed from the LJM stream buffer.
DeviceScanBacklog [out]
The number of scans left in the device buffer, as measured from when data was last collected from the device.
DeviceScanBacklog should usually be near zero and not growing.
LJMScanBacklog [out]
The number of scans left in the LJM buffer, which does not include concurrent data sent in the aData array. LJMScanBacklog
should usually be near zero and not growing.
Returns
Remarks
Before calling this function, create a data buffer using LJM_eStreamStart. To stop stream, use LJM_eStreamStop.
Example
eStreamStop
Stops LJM from storing any more data from the device. LJM will maintain any previously collected data in the buffer to be read. Stops
the device from collecting data in stream mode.
Syntax
LJM_ERROR_RETURN LJM_eStreamStop(int Handle)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Returns
Remarks
STREAM_ENABLE
Use LJM_eStreamStop when the data streaming session is completed, or to temporarily pause new data from being stored. To begin
streaming again, use LJM_eStreamStart.
Example
StreamBurst
Initializes a stream burst and collects data. This function combines LJM_eStreamStart, LJM_eStreamRead, and LJM_eStreamStop, as
well as some other device initialization.
Syntax
LJM_ERROR_RETURN LJM_StreamBurst(
int Handle,
int NumAddresses,
const int * aScanList,
double * ScanRate,
unsigned int NumScans,
double * aData)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
NumAddresses [in]
The number of addresses in aScanList. The size of the aScanList array.
aScanList [in]
An array of addresses to stream. The scan list is the list of data addresses that are to be buffered by LJM and returned in aData.
Find addresses in the Modbus Map. For example, to stream AIN3 add the address 6 to the scan list.
ScanRate [in/out]
A pointer that sets the desired number of scans per second. Upon successful return of this function, ScanRate will be updated to
the actual scan rate that the device used. Keep in mind that data rate limits are specified in Samples/Second which is equal to
NumAddresses * Scans/Second.
NumScans [in]
The number of scans to collect. This is how many burst scans are collected and may not be zero.
aData [out]
An array that contains the values being read. Returns all channels interleaved. Must be large enough to hold (NumScans *
NumAddresses) values.
Returns
Remarks
Address configuration such as range, resolution, and differential voltages must be handled by writing to the device.
Example
1 int err;
2 int numChannels = 2;
3 int aScanList[2] = {0, 2500};
4 double scanRate = 2000;
5 int numScans = 10;
6
7 unsigned int numSamples = numChannels * numScans;
8 double * aBurstSamples = malloc(sizeof(double) * numSamples);
9
10 err = LJM_StreamBurst(handle, numChannels, aScanList, &scanRate, numScans,
11 aBurstSamples);
12 if (err != LJME_NOERROR) {
13 // Handle error
14 }
15
16 // Print the scans in aBurstSamples
17
18 free(aBurstSamples);
2.5 - Device Information Functions
Add new comment
LJM_GetHandleInfo
Device Discovery
The ListAll functions search for available LabJack device connections. LJM_ListAll and LJM_ListAllS are the same function, except that
LJM_ListAll uses integer parameters to filter what connections are searched for, while LJM_ListAllS uses string parameters to do the
same. LJM_ListAllExtended allows arbitrary device registers to be queried.
GetHandleInfo
Returns details about a device handle, which is simply a connection ID to an active device.
Syntax
LJM_ERROR_RETURN LJM_GetHandleInfo(
int Handle,
int * DeviceType,
int * ConnectionType,
int * SerialNumber,
int * IPAddress,
int * Port,
int * MaxBytesPerMB)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
DeviceType [out]
The device type corresponding to a constant:
LJM_dtT7 (7) for T7 series device
LJM_dtDIGIT (200) for Digit series device
ConnectionType [out]
The connection type corresponding to a constant:
LJM_ctUSB (1) for USB
LJM_ctETHERNET (3) for Ethernet
LJM_ctWIFI (4) for WiFi
SerialNumber [out]
The serial number of the device.
IPAddress [out]
The integer representation of the device's IP address when ConnectionType is TCP-based. Unless ConnectionType is TCP-
based, this will be LJM_NO_IP_ADDRESS. Note that this can be converted to a human-readable string with the
LJM_NumberToIP function.
Port [out]
The port number when the device connection is TCP-based, or the pipe if the device connection is USB-based.
MaxBytesPerMB [out]
The maximum packet size in number of bytes that can be sent/received from this device. Note that this can change, depending on
connection type and device type. This information is important if you are using the low-level functions, or when passing large
arrays into other functions.
Returns
LJM errorcodes or 0 for no error.
Remarks
This function is useful to quickly see information about a device handle, such as the serial number, or maximum packet size. In the
event that "ANY"-type parameters were used in opening, this function can be used to see which device was actually opened.
Examples
1 int LJMError;
2 int portOrPipe, ipAddress, serialNumber, packetMaxBytes;
3 int deviceType = LJM_dtANY;
4 int connectionType = LJM_ctANY;
5 char string[LJM_STRING_ALLOCATION_SIZE];
6 char ipAddressString[LJM_IPv4_STRING_SIZE];
7
8 LJMError = LJM_GetHandleInfo(handle, &deviceType, &connectionType, &serialNumber, &ipAddress,
9 &portOrPipe, &packetMaxBytes);
10 if (LJMError) {
11 LJM_ErrorToString(LJMError, string);
12 printf("LJM_GetHandleInfo error: %s (%d)\n", string, LJMError);
13 }
14 else {
15 printf("deviceType: %d\n", deviceType);
16 printf("connectionType: %d\n", connectionType);
17 printf("serialNumber: %d\n", serialNumber);
18
19 if (connectionType == LJM_ctETHERNET || connectionType == LJM_ctWIFI) {
20 LJM_NumberToIP(ipAddress, ipAddressString);
21 printf("IP address: %s\n", ipAddressString);
22 }
23
24 if (connectionType == LJM_ctUSB) {
25 printf("pipe: %d\n", portOrPipe);
26 }
27 else {
28 printf("port: %d\n", portOrPipe);
29 }
30
31 printf("The maximum number of bytes you can send to or receive from this device in one packet is %d bytes.\n",
32 packetMaxBytes);
33 }
ListAll
Scans for LabJack devices, returning arrays describing the devices found. The use of "ANY"-type for DeviceType and ConnectionType
allow this function to perform a broad search.
Syntax
LJM_ERROR_RETURN LJM_ListAll(
int DeviceType,
int ConnectionType,
int * NumFound,
int * aDeviceTypes,
int * aConnectionTypes,
int * aSerialNumbers,
int * aIPAddresses)
Parameters
DeviceType [in]
Filter device type to find. 7 for T7 devices, 200 for Digit devices, etc. 0 for ANY is allowed.
ConnectionType [in]
Filter connection type to scan. 1 for USB, 2 for TCP, 3 for Ethernet, 4 for WIFI. 0 for ANY is allowed.
NumFound [out]
A pointer that returns the number of devices found.
aDeviceTypes [out]
An array of device types, one for each of the NumFound devices. Must be preallocated to size LJM_LIST_ALL_SIZE.
aConnectionTypes [out]
An array of connection types, one for each of the NumFound devices. Must be preallocated to size LJM_LIST_ALL_SIZE.
aSerialNumbers [out]
An array of serial numbers, one for each of the NumFound devices. Must be preallocated to size LJM_LIST_ALL_SIZE.
aIPAddresses [out]
An array of IP Addresses, one for each (if applicable) of the NumFound devices. When the device is not TCP capable, IP address
will be LJM_NO_IP_ADDRESS.
Returns
Remarks
This function is useful for big programs that open multiple kinds of devices, especially when the device type and connection type are
unknown. This function only shows what devices could be opened. To actually open a device, use LJM_Open or LJM_OpenS.
When the ConnectionType parameter of this function is network-based, this function will check the IP addresses listed in
LJM_SPECIAL_ADDRESSES_FILE.
Examples
ListAllExtended
Advanced version of LJM_ListAll that performs an additional query of arbitrary registers on the device.
Syntax
LJM_ERROR_RETURN LJM_ListAllExtended(
int DeviceType,
int ConnectionType,
int NumAddresses,
const int * aAddresses,
const int * aNumRegs,
int MaxNumFound,
int * NumFound,
int * aDeviceTypes,
int * aConnectionTypes,
int * aSerialNumbers,
int * aIPAddresses,
unsigned char * aBytes)
Parameters
DeviceType [in]
Filter device type to find. 7 for T7 devices, 200 for Digit devices, etc. 0 for ANY is allowed.
ConnectionType [in]
Filter connection type to scan. 1 for USB, 2 for TCP, 3 for Ethernet, 4 for WIFI. 0 for ANY is allowed.
NumAddresses [in]
The number of addresses to query. Also the size of aAddresses and aNumRegs.
aAddresses [in]
The addresses to query for each device that is found.
aNumRegs [in]
The addresses to query for each device that is found. Each aNumRegs[i] corresponds to aAddresses[i].
MaxNumFound [in]
The maximum number of devices to find. Also the size of aDeviceTypes, aConnectionTypes, aSerialNumbers, and aIPAddresses.
NumFound [out]
A pointer that returns the number of devices found.
aDeviceTypes [out]
An array of device types, one for each of the NumFound devices. Must be preallocated to size MaxNumFound.
aConnectionTypes [out]
An array of connection types, one for each of the NumFound devices. Must be preallocated to size MaxNumFound.
aSerialNumbers [out]
An array of serial numbers, one for each of the NumFound devices. Must be preallocated to size MaxNumFound.
aIPAddresses [out]
An array of IP Addresses, one for each (if applicable) of the NumFound devices. When the device is not TCP capable, IP address
will be LJM_NO_IP_ADDRESS.
aBytes [out]
An array that must be preallocated to size:
MaxNumFound * <the sum of aNumRegs> * LJM_BYTES_PER_REGISTER,
which will contain the query bytes sequentially. A device
represented by index i would have an aBytes index of:
(i * <the sum of aNumRegs> * LJM_BYTES_PER_REGISTER).
Returns
Remarks
When the ConnectionType parameter of this function is network-based, this function will check the IP addresses listed in
LJM_SPECIAL_ADDRESSES_FILE.
Examples
ListAllS
Scans for LabJack devices, returning arrays describing the devices found. The use of "ANY" for DeviceType and ConnectionType allow
this function to perform a broad search.
Syntax
LJM_ERROR_RETURN LJM_ListAllS(
const char * DeviceType,
const char * ConnectionType,
int * NumFound,
int * aDeviceTypes,
int * aConnectionTypes,
int * aSerialNumbers,
int * aIPAddresses)
Parameters
DeviceType [in]
Filter device type to find. "T7" for T7 devices, "Digit" for Digit devices, etc. "ANY" is allowed.
ConnectionType [in]
Filter connection type to scan. "USB" for USB connection, "TCP" for TCP connection, etc. "ANY" is allowed.
NumFound [out]
A pointer that returns the number of devices found.
aDeviceTypes [out]
An array of device types, one for each of the NumFound devices. Must be preallocated to size LJM_LIST_ALL_SIZE.
aConnectionTypes [out]
An array of connection types, one for each of the NumFound devices. Must be preallocated to size LJM_LIST_ALL_SIZE.
aSerialNumbers [out]
An array of serial numbers, one for each of the NumFound devices. Must be preallocated to size LJM_LIST_ALL_SIZE.
aIPAddresses [out]
An array of IP Addresses, one for each (if applicable) of the NumFound devices. When the device is not TCP capable, IP address
will be LJM_NO_IP_ADDRESS.
Returns
Remarks
This function is useful for big programs that open multiple kinds of devices, especially when the device type and connection type are
unknown. This function only shows what devices could be opened. To actually open a device, use LJM_Open or LJM_OpenS.
When the ConnectionType parameter of this function is network-based, this function will check the IP addresses listed in
LJM_SPECIAL_ADDRESSES_FILE.
Examples
Syntax
LJM_VOID_RETURN LJM_ErrorToString(
int ErrorCode,
char * ErrorString)
Parameters
ErrorCode [in]
The error code number.
ErrorString [out]
A pointer to the char array which will be populated with the null-terminated error name/description. Allocate to size
LJM_MAX_NAME_SIZE.
Returns
None.
Remarks
If the constants file that has been loaded does not contain the error code, this returns a null-terminated message saying so. If the
constants file could not be opened, this returns a null-terminated string containing the expected file path.
Examples
TCVoltsToTemp
Converts thermocouple voltage to temperature.
Syntax
LJM_ERROR_RETURN LJM_TCVoltsToTemp(
int TCType,
double TCVolts,
double CJTempK,
double * pTCTempK)
Parameters
TCType [in]
The thermocouple type. Constants are (alphabetically):
B = 6001
C = 6009
E = 6002
J = 6003
K = 6004
N = 6005
R = 6006
S = 6007
T = 6008
TCVolts [in]
The voltage reported by the thermocouple.
CJTempK [in]
The cold-junction temperature in degrees Kelvin.
pTCTempK [out]
The calculated thermocouple temperature in degrees Kelvin.
Returns
Remarks
Use this function to easily calculate thermocouple temperatures from voltage readings. When thermocouples are connected to the AIN0-
AIN3 screw terminals, the cold-junction temperature can be obtained from AIN14, which maps to a nearby temp sensor inside most
LabJack devices.
Examples
1 int LJMError;
2 double TCTempKelvin;
3
4 LJMError = LJM_TCVoltsToTemp(6004, 0.00134, 299.039, &TCTempKelvin);
5 printf("%f\n", TCTempKelvin);
NumberToIP
Takes an integer representing an IPv4 address and outputs the corresponding decimal-dot IPv4 address as a null-terminated string.
Syntax
LJM_ERROR_RETURN LJM_NumberToIP(
unsigned int Number,
char * IPv4String)
Parameters
Number [in]
A number representing an IPv4 address.
IPv4String [out]
A character array which will be updated to contain the null-terminated string representation of an IPv4 address. Must be allocated
to size LJM_IPv4_STRING_SIZE.
Returns
Remarks
Examples
1 int LJMError;
2 char IPv4String[16];
3
4 LJMError = LJM_NumberToIP(3232235983, IPv4String);
5 printf ("%s \n", IPv4String);
6 // Prints "192.168.1.207"
NumberToMAC
Takes an integer representing a MAC address and outputs the corresponding hex-colon MAC address as a null-terminated string.
Syntax
LJM_ERROR_RETURN LJM_NumberToMAC(
unsigned long long Number,
char * MACString)
Parameters
Number [in]
The number representing a MAC address.
MACString [out]
A character array which will be updated to contain the null-terminated string representation of the MAC address. Must be allocated
to size LJM_MAC_STRING_SIZE.
Returns
Remarks
1 int LJMError;
2 char MACString[18];
3
4 LJMError = LJM_NumberToIP(81952921372024, MACString);
5 printf ("%s \n", MACString);
6 // prints "78:45:C4:26:89:4A"
IPToNumber
Takes a decimal-dot IPv4 string representing an IPv4 address and outputs the corresponding integer version of the address.
Syntax
LJM_ERROR_RETURN LJM_IPToNumber(
const char * IPv4String,
unsigned int * Number)
Parameters
IPv4String [in]
A decimal dot string representing an IPv4 address.
Number [out]
The numerical representation of IPv4String.
Returns
LJM errorcodes or 0 for no error. Returns LJME_INVALID_PARAMETER if IPv4String could not be parsed as an IPv4 address.
Remarks
Use this function to convert a human-readable interpretation of an IP address into an integer value.
Examples
1 int LJMError;
2 unsigned int Number;
3
4 LJMError = LJM_IPToNumber("192.168.1.207", &Number);
5 printf ("%u \n", Number);
6 // prints 3232235983
MACToNumber
Takes a hex-colon string representing a MAC address and outputs the corresponding integer version of the address.
Syntax
LJM_ERROR_RETURN LJM_MACToNumber(
const char * MACString,
unsigned long long * Number)
Parameters
MACString [in]
A hex-colon string representing a MAC address.
Number [out]
The numerical representation of MACString.
Returns
LJM errorcodes or 0 for no error. Returns LJME_INVALID_PARAMETER if MACString could not be parsed as a MAC address.
Remarks
Use this function to convert a human-readable interpretation of a MAC address into an integer value.
Examples
1 int LJMError;
2 unsigned long long Number;
3
4 LJMError = LJM_MACToNumber("78:45:C4:26:89:4A", &Number);
5 printf ("%llu \n", Number);
6 // prints 81952921372024
NameToAddress
Add new comment
Takes a Modbus register name as input and produces the corresponding Modbus address and type. These two values can serve as
input to functions that have Address and Type as input parameters.
Syntax
LJM_ERROR_RETURN LJM_NameToAddress(
const char * Name,
int * Address,
int * Type)
Parameters
Name [in]
A null-terminated c-string register identifier. This register identifiers can be a register name or a register alternate name.
Address [out]
Output parameter containing the address specified by Name.
Type [out]
Output parameter containing the type specified by Name.
Returns
Remarks
Examples
1 int LJMError;
2 int Address;
3 int Type;
4 LJMError = LJM_NameToAddress("AIN3", &Address, &Type);
5 printf("%d \n", Address);
6 // prints 6
7 printf("%d \n", Type);
8 // prints 3 for LJM_FLOAT32
NamesToAddresses
Takes a list of Modbus register names as input and produces two lists as output - the corresponding Modbus addresses and types.
These two lists can serve as input to functions that have Address/aAddresses and Type/aTypes as input parameters.
Syntax
LJM_ERROR_RETURN LJM_NamesToAddresses(
int NumFrames,
const char ** aNames,
int * aAddresses,
int * aTypes)
Parameters
NumFrames [in]
The number of names in aNames and the allocated size of aAddresses and aTypes.
aNames [in]
An array of null-terminated c-string register identifiers. These register identifiers can be register names or register alternate names.
aAddresses [out]
An output array containing the addresses specified by aNames in the same order, must be allocated to the size NumFrames
before calling LJM_NamesToAddresses.
aTypes [out]
An output array containing the types specified by aNames in the same order, must be allocated to the size NumFrames before
calling LJM_NamesToAddresses.
Returns
Remarks
For each register identifier in aNames that is invalid, the corresponding aAddresses value will be set to
LJM_INVALID_NAME_ADDRESS.
Examples
1 int LJMError;
2 const char * aNames[2] = {"AIN3", "DAC0"};
3 int aAddresses[2];
4 int aTypes[2];
5 int AIN3Address;
6 int AIN3Type;
7 int DAC0Address;
8 int DAC0Type;
9
10 LJMError = LJM_NamesToAddresses(2, aNames, aAddresses, aTypes);
11 AIN3Address = aAddresses[0];
12 AIN3Type = aTypes[0];
13 DAC0Address = aAddresses[1];
14 DAC0Type = aTypes[1];
AddressToType
Retrieves the data type for a given Modbus register address.
Syntax
LJM_ERROR_RETURN LJM_AddressToType(
int Address,
int * Type)
Parameters
Address [in]
A Modbus address.
Type [out]
Output parameter containing the data type of Address.
Returns
Remarks
Convenience function to programmatically discover the type of a Modbus address. Most people can simply look in the Modbus Map.
Examples
1 int LJMError;
2 int Type;
3 LJMError = LJM_AddressesToTypes(6, &Type);
4 printf("%d \n", Type);
5 // 3 for LJM_FLOAT32
AddressesToTypes
Retrieves multiple data types for given Modbus register addresses.
Syntax
LJM_ERROR_RETURN LJM_AddressesToTypes(
int NumAddresses,
int * aAddresses,
int * aTypes)
Parameters
NumAddresses [in]
The number of addresses to process.
aAddresses [in]
The array of address numbers to process. Set to size NumAddresses.
aTypes [out]
An output array containing the data types of each address specified in aAddresses. Set to size NumAddresses.
Returns
Remarks
Convenience function to programmatically discover the types of many Modbus addresses. Most people can simply look in the Modbus
Map. For each aAddresses[i] that is not found, the corresponding entry aTypes[i] will be set to LJM_INVALID_NAME_ADDRESS and
this function will return LJME_INVALID_ADDRESS.
Examples
[C/C++] Get the type of Modbus address 6, which is AIN3, and Modbus address 2002, which is FIO2.
1 int LJMError;
2 int aAddresses[2] = {6, 2002};
3 int aTypes[2];
4 int TypeAIN3;
5 int TypeFIO2;
6 LJMError = LJM_AddressesToTypes(2, aAddresses, aTypes);
7 TypeAIN3 = aTypes[0]; //LJM_FLOAT32
8 TypeFIO2 = aTypes[1]; //LJM_UINT16
Once enabled, LJM will write messages to the LJM debug log file. These messages can contain error messages, warnings, raw
packets, and other information.
LJM's debug logging can be enabled using one of two methods via ljm_startup_configs.json or via LJM_WriteLibraryConfigS. Both
methods (described below) require changing the following LJM configuration parameters:
The file ljm_startup_configs.json contains the LJM configurations that are used by LJM when LJM is loaded.
Note that ljm_startup_configs.json is installed / replaced every time the LJM installer is run, so this method is temporary. LJM installs
ljm_startup_configs.json to the following locations:
After opening ljm_startup_configs.json with a text editor, change the parameters as described above.
Use the function LJM_WriteLibraryConfigS to change the LJM parameters as described above.
Log
Saves a message of the specified severity level to the LJM debug log file.
Syntax
LJM_ERROR_RETURN LJM_Log(
int Level,
const char * String)
Parameters
Level [in]
The error severity level of this new log entry. See constants file LJM_DEBUG_LOG_LEVEL.
LJM_STREAM_PACKET = 1
LJM_TRACE = 2
LJM_DEBUG = 4
LJM_INFO = 6
LJM_PACKET = 7
LJM_WARNING = 8
LJM_USER = 9
LJM_ERROR = 10
LJM_FATAL = 12
String [in]
The debug message to write to the log file.
Returns
Remarks
By default, LJM_DEBUG_LOG_MODE is to never log, so LJM does not output any log messages, even from this function. Users must
first use LJM_WriteLibraryConfigS to change the log mode. See the library configuration functions.
Examples
[C/C++] Write "Beginning stream..." to the log file with severity level: Debug.
1 int LJMError;
2 LJMError = LJM_Log(4, "Beginning stream...");
ResetLog
Clears all characters from the debug log file.
Syntax
LJM_ERROR_RETURN LJM_ResetLog()
Parameters
None.
Returns
Remarks
Examples
1 int LJMError;
2 LJMError = LJM_ResetLog();
The low-level Feedback functions LJM_AddressesToMBFB, LJM_MBFBComm, and LJM_UpdateValues may be used together or
separately to perform Modbus Feedback (MBFB) operations on the LabJack device.
Examples
[C/C++] Write to DAC0, read from AIN0 using LJM_AddressesToMBFB, LJM_MBFBComm, and LJM_UpdateValues
/**
* Name: stepwise_feedback.c
* Desc: Shows how to read from a few analog inputs
* using a LabJack and the cross platform LabJackM
* Library using the C-style API
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <LabJackM.h>
#include "LJM_Utilities.h"
int main()
{
int handle, err;
int aAddresses[NUM_FRAMES];
int aTypes[NUM_FRAMES];
int aWrites[NUM_FRAMES] = {LJM_WRITE, LJM_READ };
int aNumValues[NUM_FRAMES] = {1, 1 };
enum { NUM_VALUES = 2 };
double aValues[NUM_VALUES] = {VALUE_0, VALUE_1 };
PrintDeviceInfoFromHandle(handle);
printf("\nLJM_MBFBComm will overwrite the Transaction ID and Unit ID of the following command\n");
PrintFeedbackCommand(aMBFB, "Feedback command");
// Print results
printf("%s: %f\n", ADDRESS_STRINGS[1], aValues[1]);
// Close
err = LJM_Close(handle);
ErrorCheck(err, "LJM_Close");
WaitForUserIfWindows();
return LJME_NOERROR;
}
Possible output:
deviceType: LJM_dtT7
connectionType: LJM_ctUSB
serialNumber: 470010117
pipe: 0
The maximum number of bytes you can send to or receive from this device in one packet is 64 bytes.
LJM_MBFBComm will overwrite the Transaction ID and Unit ID of the following command
Feedback command:
Header: 0x00 0x00 0x00 0x00 0x00 0x0e 0x01 0x4c
frame 00: 0x01 0x03 0xe8 0x02 0x3f 0x9d 0x70 0xa4
frame 01: 0x00 0x00 0x00 0x02
Feedback response:
Header: 0x01 0x89 0x00 0x00 0x00 0x06 0x01 0x4c
data: 0x40 0x9a 0xfd 0x5f
AIN0: 4.843429
AddressesToMBFB
Creates a Modbus Feedback (MBFB) packet. This packet can be sent to the device using LJM_MBFBComm.
Syntax
LJM_ERROR_RETURN LJM_AddressesToMBFB(
int MaxBytesPerMBFB,
int * aAddresses,
int * aTypes,
int * aWrites,
int * aNumValues,
double * aValues,
int * NumFrames,
unsigned char * aMBFBCommand)
Parameters
MaxBytesPerMBFB [in]
The maximum number of bytes that the Feedback command is allowed to consist of. It is highly recommended to pass the size of
the aMBFBCommand buffer as MaxBytesPerMBFB to prevent buffer overflow. See
LJM_DEFAULT_FEEDBACK_ALLOCATION_SIZE.
aAddresses [in]
An array of size NumFrames representing the register addresses to read from or write to for each frame.
aTypes [in]
An array of size NumFrames containing the data type of each value sent/received for each frame.
Types - 0:UINT16, 1:UINT32, 2:INT32, 3:FLOAT32
aWrites [in]
An array of size NumFrames containing the desired type of access for each frame, which is either read(0) or write(1).
aNumValues [in]
An array of size NumFrames that contains the number of consecutive values for each frame. Use 1 for a single (non-consecutive)
value.
aValues [in]
An array of values to be transferred to/from the device. This array contains all the values for all the frames, so its size should be the
sum of all elements in the aNumValues array. Each write value will be converted to its corresponding frame type defined in
aTypes. LJM_UpdateValues can be used later to update this array with read values.
NumFrames [in/out]
Input as the number of frames being created. Output as the number of frames that were successfully put into the aMBFBCommand
buffer, which may be less or equal to the input number. If NumFrames is altered by this function, LJM_AddressesToMBFB will
return the warning code LJME_FRAMES_OMITTED_DUE_TO_PACKET_SIZE.
aMBFBCommand [out]
The resultant Modbus Feedback command. Transaction ID and Unit ID will be blanks that LJM_MBFBComm will fill in.
Returns
Remarks
The LJM_NamesToAddresses and LJM_NameToAddress functions may be used to initialize the aAddresses and aTypes parameters
from register names.
Examples
Please see the Low-level Feedback Functions overview page for an example.
MBFBComm
Sends a Feedback command and receives a Feedback response, parsing the response for obvious errors. The Feedback command
may be generated using LJM_AddressesToMBFB and the Feedback response may be parsed with the LJM_UpdateValues function.
Syntax
LJM_ERROR_RETURN LJM_MBFBComm(
int Handle,
unsigned char UnitID,
unsigned char * aMBFB,
int * ErrorAddress)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
UnitID [in]
The ID of the specific unit that the Feedback command should be sent to. Use LJM_DEFAULT_UNIT_ID (1) unless the device
documentation instructs otherwise.
aMBFB [in/out]
As an input parameter, it is a valid Feedback command, which may be generated using LJM_AddressesToMBFB.
As an output parameter, it is a Feedback response, which may be an error response.
ErrorAddress [out]
If error, the address responsible for causing an error.
Returns
Remarks
Examples
Please see the Low-level Feedback Functions overview page for an example.
UpdateValues
Converts read values in a Modbus Feedback response packet.
Syntax
LJM_ERROR_RETURN LJM_UpdateValues(
unsigned char * aMBFBResponse,
const int * aTypes,
const int * aWrites,
const int * aNumValues,
int NumFrames,
double * aValues)
Parameters
Note that some of these parameters may be used directly from LJM_AddressesToMBFB and/or LJM_MBFBComm.
aMBFBResponse [in]
A valid Feedback response. May be used directly from LJM_MBFBComm.
aTypes [in]
An array of size NumFrames containing the data type of each value sent/received for each frame. May be used directly from
LJM_AddressesToMBFB.
Types - 0:UINT16, 1:UINT32, 2:INT32, 3:FLOAT32
aWrites [in]
An array of size NumFrames containing the desired type of access for each frame, which is either read(0) or write(1). May be used
directly from LJM_AddressesToMBFB.
aNumValues [in]
An array of size NumFrames that contains the number of consecutive values for each frame. Use 1 for a single (non-consecutive)
value. May be used directly from LJM_AddressesToMBFB.
NumFrames [in]
The number of frames. May be used from LJM_AddressesToMBFB after dereferencing.
aValues [out]
An array that contains all the values for all the frames, so its size should be the sum of all elements in the aNumValues array.
Each read value is converted to its corresponding frame type defined in aTypes.
Returns
Remarks
The Type Conversion functions may also be used to read bytes to types.
Examples
Please see the Low-level Feedback Functions overview page for an example.
ReadRaw
Attempts to receive unaltered bytes from a device.
Syntax
LJM_ERROR_RETURN LJM_ReadRaw(
int Handle,
unsigned char * Data,
int NumBytes)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Data [Out]
Buffer to be filled with bytes from the read
NumBytes [out]
The number of bytes that were read, or -1 for error.
Returns
Remarks
WriteRaw
Attempts to send unaltered bytes to a device.
Syntax
LJM_ERROR_RETURN LJM_WriteRaw(
int Handle,
const unsigned char * Data,
int NumBytes)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Data [in]
Buffer of bytes to send to the device.
NumBytes [in]
The number of bytes in Data.
Returns
LJM errorcode or 0 for no error.
Remarks
These functions are not needed except for applications performing raw bytes manipulation, as with the Raw Byte functions.
Byte-to-value
LJM_ByteArrayToFLOAT32
LJM_ByteArrayToINT32
LJM_ByteArrayToUINT32
LJM_ByteArrayToUINT16
Value-to-byte
LJM_FLOAT32ToByteArray
LJM_INT32ToByteArray
LJM_UINT32ToByteArray
LJM_UINT16ToByteArray
ByteArrayToFLOAT32
Converts an array of bytes to 32-bit float values, performing automatic endian conversions if necessary.
This function is not needed except for applications performing raw byte manipulation, as with the Raw Byte functions.
Syntax
LJM_ERROR_RETURN LJM_ByteArrayToFLOAT32(
const unsigned char * aBytes,
int RegisterOffset,
int NumFLOAT32,
float * aFLOAT32)
Parameters
aBytes [in]
The bytes to be converted.
RegisterOffset [in]
The register offset to get the values from in aBytes.
NumFLOAT32 [in]
The number of values to convert.
aFLOAT32 [out]
The converted bytes in 32-bit float value form.
Returns
Remarks
This function is not needed except for applications performing raw byte manipulation, as with the Raw Byte functions.
Syntax
LJM_ERROR_RETURN LJM_ByteArrayToINT32(
const unsigned char * aBytes,
int RegisterOffset,
int NumINT32,
int * aINT32)
Parameters
aBytes [in]
The bytes to be converted.
RegisterOffset [in]
The register offset to get the values from in aBytes.
NumINT32 [in]
The number of values to convert.
aINT32 [out]
The converted bytes in 32-bit integer value form.
Returns
Remarks
ByteArrayToUINT16
Converts an array of bytes to 16-bit unsigned integer values, performing automatic endian conversions if necessary.
This function is not needed except for applications performing raw byte manipulation, as with the Raw Byte functions.
Syntax
LJM_ERROR_RETURN LJM_ByteArrayToUINT16(
const unsigned char * aBytes,
int RegisterOffset,
int NumUINT16,
unsigned int * aUINT16)
Parameters
aBytes [in]
The bytes to be converted.
RegisterOffset [in]
The register offset to get the values from in aBytes.
NumUINT16 [in]
The number of values to convert.
aUINT16 [out]
The converted bytes in 16-bit unsigned integer value form.
Returns
Remarks
ByteArrayToUINT32
Converts an array of bytes to 32-bit unsigned integer values, performing automatic endian conversions if necessary.
This function is not needed except for applications performing raw byte manipulation, as with the Raw Byte functions.
Syntax
LJM_ERROR_RETURN LJM_ByteArrayToUINT32(
const unsigned char * aBytes,
int RegisterOffset,
int NumUINT32,
unsigned int * aUINT32)
Parameters
aBytes [in]
The bytes to be converted.
RegisterOffset [in]
The register offset to get the values from in aBytes.
NumUINT32 [in]
The number of values to convert.
aUINT32 [out]
The converted bytes in 32-bit unsigned integer value form.
Returns
Remarks
FLOAT32ToByteArray
Converts an array of 32-bit float values to bytes, performing automatic endian conversions if necessary.
This function is not needed except for applications performing raw byte manipulation, as with the Raw Byte functions.
Syntax
LJM_ERROR_RETURN LJM_FLOAT32ToByteArray(
const float * aFLOAT32,
int RegisterOffset,
int NumFLOAT32,
unsigned char * aBytes)
Parameters
aFLOAT32 [in]
The array of values to be converted to bytes.
RegisterOffset [in]
The register offset to put the converted values in aBytes.
NumFLOAT32 [in]
The number of values to convert.
aBytes [out]
The converted values in byte form.
Returns
Remarks
INT32ToByteArray
Converts an array of 32-bit integer values to bytes, performing automatic endian conversions if necessary.
This function is not needed except for applications performing raw byte manipulation, as with the Raw Byte functions.
Syntax
LJM_ERROR_RETURN LJM_INT32ToByteArray(
const int * aINT32,
int RegisterOffset,
int NumINT32,
unsigned char * aBytes)
Parameters
aINT32 [in]
The array of values to be converted to bytes.
RegisterOffset [in]
The register offset to put the converted values in aBytes.
NumINT32 [in]
The number of values to convert.
aBytes [out]
The converted values in byte form.
Returns
Remarks
UINT16ToByteArray
Converts an array of 16-bit unsigned integer values to bytes, performing automatic endian conversions if necessary.
This function is not needed except for applications performing raw byte manipulation, as with the Raw Byte functions.
Syntax
LJM_ERROR_RETURN LJM_UINT16ToByteArray(
const unsigned int * aUINT16,
int RegisterOffset,
int NumUINT16,
unsigned char * aBytes)
Parameters
aUINT16 [in]
The array of values to be converted to bytes.
RegisterOffset [in]
The register offset to put the converted values in aBytes.
NumUINT16 [in]
The number of values to convert.
aBytes [out]
The converted values in byte form.
Returns
Remarks
UINT32ToByteArray
Converts an array of 32-bit unsigned int values to bytes, performing automatic endian conversions if necessary.
This function is not needed except for applications performing raw byte manipulation, as with the Raw Byte functions.
Syntax
LJM_ERROR_RETURN LJM_UINT32ToByteArray(
const unsigned int * aUINT32,
int RegisterOffset,
int NumUINT32,
unsigned char * aBytes)
Parameters
aUINT32 [in]
The array of values to be converted to bytes.
RegisterOffset [in]
The register offset to put the converted values in aBytes.
NumUINT32 [in]
The number of values to convert.
aBytes [out]
The converted values in byte form.
Returns
Remarks
The LJM configuration LJM_STREAM_SCANS_RETURN may also be useful. It controls the block on LJM_eStreamRead,
allowing LJM_eStreamRead to return immediately with an error if a full read of data is not ready.
SetStreamCallback
Sets a callback that is called by LJM when the stream has collected ScansPerRead scans.
Syntax
typedef void (*LJM_StreamReadCallback)(void *);
LJM_ERROR_RETURN LJM_SetStreamCallback(
int Handle,
LJM_StreamReadCallback Callback,
void * Arg)
Parameters
Handle [in]
A device handle. The handle is a connection ID for an active device. Generate a handle with LJM_Open or LJM_OpenS.
Callback [in]
The callback function for LJM's stream thread to call when ScansPerRead scans of stream data are ready, which should call
LJM_eStreamRead to acquire data. ScansPerRead is a value of LJM_eStreamStart.
Arg [in]
The user-defined argument that is passed to Callback when it is invoked.
Returns
Remarks
LJM_eStreamStop may be called at any time when using LJM_SetStreamCallback, but the Callback function should not try to stop
stream. If the Callback function detects that stream needs to be stopped, it should signal to a different thread that stream should be
stopped.
To disable the previous callback for stream reading, pass 0 or NULL as Callback.
This section describes how to configure the LJM library's behavior and interpretation constants. Whenever LJM is started up, it is loaded
with default values, so any desired configurations must be applied each time LJM is started.
Behavioral Parameters
The functions LJM_WriteLibraryConfigS and LJM_WriteLibraryConfigStringS are good for setting a few configurations, while
LJM_LoadConfigurationFile is more convenient for setting many configurations or for sharing a configuration between programs.
Interpretation Constants
LJM also provides interpretation of Modbus map constants and error constants.
The Modbus map constants affect Name functions that use Name interpretation, such as LJM_eReadName. These Name functions
have "Name" in their name and have a "const char * Name" parameter or "const char ** aNames" parameter. For each name passed to
one of these functions, it is interpreted according to the loaded constants. The Modbus map constants affect the behavior of other
functions as well, such as when LJM_OLD_FIRMWARE_CHECK is enabled.
The Error constants affects the LJM_ErrorToString function. The loaded Error constants will be interpreted from an integer error code to
a error string. Custom application error codes can be loaded in the 3900-3999 range.
Configuration Parameters
The following parameters are constants defined in the header file LabJackM.h. Each parameter's name is the same as it's value; e.g.
LJM_LIBRARY_VERSION is a constant of the string "LJM_LIBRARY_VERSION".
Informational parameters:
Timeout parameters:
LJM_ALLOWS_AUTO_MULTIPLE_FEEDBACKS - Whether or not LJM will automatically perform multiple Feedback commands
when the desired operations would exceed the maximum packet length.
LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES - Whether or not LJM will automatically condense congruent address
reads/writes into array reads/writes.
LJM_RETRY_ON_TRANSACTION_ID_MISMATCH - Whether or not LJM automatically retries an operation if an
LJME_TRANSACTION_ID_ERR occurs.
LJM_OLD_FIRMWARE_CHECK - Whether or not LJM will check the Modbus constants file (see
LJM_MODBUS_MAP_CONSTANTS_FILE) to make sure the firmware of the current device is compatible with the Modbus
register(s) being read from or written to.
LJM_MODBUS_MAP_CONSTANTS_FILE - The absolute or relative path of the constants file to use for that use the LJM Name
functionality.
LJM_ERROR_CONSTANTS_FILE - The absolute or relative path of the constants file to use for LJM_ErrorToString.
LJM_CONSTANTS_FILE - For setting both LJM_MODBUS_MAP_CONSTANTS_FILE and LJM_ERROR_CONSTANTS_FILE.
(Write-only)
LJM_DEBUG_LOG_FILE - The absolute or relative path of the file to output log messages to.
LJM_DEBUG_LOG_MODE - What conditions will cause LJM to output log messages.
LJM_DEBUG_LOG_LEVEL - What priority of log messages are output.
LJM_DEBUG_LOG_BUFFER_MAX_SIZE - How many messages the log buffer can hold.
LJM_DEBUG_LOG_SLEEP_TIME_MS - How often the logger thread will run.
LJM_DEBUG_LOG_FILE_MAX_SIZE - The maximum size of the log file in number of characters.
Stream parameters:
Altering Configurations
Reading Configurations
GetSpecificIPsInfo
Get information about whether the specific IPs file was parsed successfully.
Syntax
LJM_ERROR_RETURN LJM_GetSpecificIPsInfo(
int * InfoHandle,
const char ** Info)
Parameters
InfoHandle [out]
A handle to Info that should be passed to LJM_CleanInfo after Info has been read.
Info [out]
A pointer to a JSON char * (allocated by LJM) describing the state of the specific IPs.
Info Semantics
{
"errorCode": Integer LJME_ error code. 0 indicates no error
"IPs": Array of strings - the presentation-format IPs
"message": Human-readable string description of success/failure
"filePath": String absolute or relative file path
"invalidIPs": Array of strings - the unparsable lines
}
Returns
LJM errorcodes or 0 for no error. This may be LJME_CONFIG_PARSING_ERROR even if some addresses in the specific IP file were
parsed without error.
LoadConfigurationFile
Load all the configuration values in a specified file.
For the full list of possible parameters, see Configuration Parameters. Alternately, see the ljm_startup_configs.json file that was installed
along with LJM. LJM_LoadConfigurationFile parses files according to the semantics of ljm_startup_configs.json.
ljm_startup_configs.json can be found in the default constants file location (see Constants file parameters).
Syntax
LJM_ERROR_RETURN LJM_LoadConfigurationFile(
const char * FileName)
Parameters
FileName [in]
A relative or absolute file location. Must null-terminate. "default" maps to the default configuration file ljm_startup_config.json in the
constants file location (see Constants file parameters).
Returns
LJME_CONFIG_FILE_NOT_FOUND (1289): FileName did not give the location to a readable file.
LJME_CONFIG_PARSING_ERROR (1290): The file at location FileName did not contain a valid configuration file.
Remarks
Example
LoadConstants
Manually loads or reloads the constants file.
This step is automatic. This function does not need to be called before any functions that use LJM's Modbus interpretation or Error
interpretation. LJM_LoadConstantsFromFile is provided so that changes to the constants file can be loaded.
Syntax
LJM_VOID_RETURN LJM_LoadConstants()
Returns
Nothing.
Remarks
LoadConstantsFromFile
Loads a specified file as the Modbus map and Error constants.
Syntax
LJM_ERROR_RETURN LJM_LoadConstantsFromFile(
const char * FileName)
Parameters
FileName [in]
The absolute or relative file path to load as the constants. Must null-terminate. "default" maps to the default configuration file
ljm_startup_config.json in the constants file location (see Constants file parameters).
Returns
LJME_INVALID_CONSTANTS_FILE (1293): The file located at FileName was not a valid constants file. LJM_ErrorToString outputs a
specific error message.
Remarks
LJM_WriteLibraryConfigStringS(LJM_CONSTANTS_FILE, FileName)
To load the Modbus constants and error constants separately, use LJM_WriteLibraryConfigStringS with
LJM_MODBUS_MAP_CONSTANTS_FILE or LJM_ERROR_CONSTANTS_FILE as the Parameter.
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 int LJMError;
3 LJMError = LJM_LoadConstantsFromFile("custom_modbus_map.json");
4 if (LJMError != 0) {
5 LJM_ErrorToString(LJMError, ErrorString);
6 printf("LJM_LoadConstantsFromFile error: %s\n", ErrorString);
7 }
LoadConstantsFromString
Loads a string as the Modbus map and/or Error constants.
Syntax
LJM_ERROR_RETURN LJM_LoadConstantsFromString(
const char * JsonString)
Parameters
JsonString [in]
A string in JSON format containing the constants to load. Must null-terminate. If JsonString contains a JSON array named
"registers", that array is loaded as the new Modbus map constants and the previous Modbus map constants are unloaded. If
JsonString contains a JSON array named "errors", that array is loaded as the new Error constants and the previous Error
constants are unloaded.
Returns
LJME_INVALID_CONSTANTS_FILE (1293): The constants in JsonString was not a valid constants file. LJM_ErrorToString outputs a
specific error message.
Remarks
Example
ReadLibraryConfigS
Read one numerical configuration value.
Syntax
LJM_ERROR_RETURN LJM_ReadLibraryConfigS(
const char * Parameter,
double * Value)
Parameters
Parameter [in]
The name of the configuration setting, see configuration parameters page. Not case-sensitive. Must null-terminate. For the full list
of possible parameters, see Configuration Parameters.
Value [out]
The return value representing the current value of Parameter.
Returns
Remarks
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 double Value;
3 int LJMError = LJM_ReadLibraryConfigS(LJM_SEND_RECEIVE_TIMEOUT_MS, &Value);
4 if (LJMError != 0) {
5 LJM_ErrorToString(LJMError, ErrorString);
6 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
7 }
8 printf("LJM_SEND_RECEIVE_TIMEOUT_MS is currently %f\n", Value);
ReadLibraryConfigStringS
Read one string-based configuration value.
Syntax
LJM_ERROR_RETURN LJM_ReadLibraryConfigStringS(
const char * Parameter,
double * String)
Parameters
Parameter [in]
The name of the configuration setting, see configuration parameters page. Not case-sensitive. Must null-terminate. For the full list
of possible parameters, see Configuration Parameters.
String [out]
The return value string representing the current value of Parameter. Must be allocated to size LJM_MAX_NAME_SIZE.
Returns
Remarks
Example
1 char ErrorString[LJM_MAX_NAME_SIZE]; ?
2 char String[LJM_MAX_NAME_SIZE];
3 int LJMError = LJM_ReadLibraryConfigStringS(LJM_DEBUG_LOG_FILE, String);
4 if (LJMError != 0) {
5 LJM_ErrorToString(LJMError, ErrorString);
6 printf("LJM_ReadLibraryConfigStringS error: %s\n", ErrorString);
7 }
8 printf("LJM_DEBUG_LOG_FILE is currently %s\n", String);
WriteLibraryConfigS
Write a numerical LJM behavioral configuration value.
Syntax
LJM_ERROR_RETURN LJM_WriteLibraryConfigS(
const char * Parameter,
double Value)
Parameters
Parameter [in]
The name of the configuration setting, see configuration parameters page. Not case-sensitive. Must null-terminate. For the full list
of possible parameters, see Configuration Parameters.
Value [in]
The config value to apply to Parameter.
Returns
Remarks
To write a string-based configuration parameter, see LJM_WriteLibraryConfigStringS.
Example
WriteLibraryConfigStringS
Write a string-based LJM behavioral configuration value.
Syntax
LJM_ERROR_RETURN LJM_WriteLibraryConfigStringS(
const char * Parameter,
const char * String)
Parameters
Parameter [in]
The name of the configuration setting, see the configuration parameters page. Not case-sensitive. Must null-terminate. For the full
list of possible parameters, see Configuration Parameters.
String [in]
The config value string to apply to Parameter. Must null-terminate. Must be of size LJM_MAX_NAME_SIZE or less, including the
null-terminator.
Returns
Remarks
Example
3 - Constants
C/C++ Prefix
The following constants begin with the prefix "LJM_" for C/C++ code.
BYTE = 99
STRING = 98
STRING_MAX_SIZE = 49
May be used to initialize the ErrorAddress parameter of the multiple value functions:
INVALID_NAME_ADDRESS = -1
As an entry of the aData parameter of LJM_eStreamRead, indicates a value was skipped due to auto-recovery:
DUMMY_VALUE = -9999
Timeout constants:
NO_TIMEOUT = 0
DEFAULT_TIMEOUT = 1000
Configuration constants. For more information, see the Library Configuration Functions.
LJM_SEND_RECEIVE_TIMEOUT_MS = "LJM_SEND_RECEIVE_TIMEOUT_MS"
LJM_OPEN_TCP_DEVICE_TIMEOUT_MS = "LJM_OPEN_TCP_DEVICE_TIMEOUT_MS"
LJM_DEBUG_LOG_MODE = "LJM_DEBUG_LOG_MODE"
LJM_DEBUG_LOG_MODE_NEVER = 1.0
LJM_DEBUG_LOG_MODE_CONTINUOUS = 2.0
LJM_DEBUG_LOG_MODE_ON_ERROR = 3.0
LJM_DEBUG_LOG_LEVEL = "LJM_DEBUG_LOG_LEVEL"
LJM_STREAM_PACKET = 1.0
LJM_TRACE = 2.0
LJM_DEBUG = 4.0
LJM_INFO = 6.0
LJM_PACKET = 7.0
LJM_WARNING = 8.0
LJM_USER = 9.0
LJM_ERROR = 10.0
LJM_FATAL = 12.0
LJM_DEBUG_LOG_BUFFER_MAX_SIZE = "LJM_DEBUG_LOG_BUFFER_MAX_SIZE"
LJM_DEBUG_LOG_SLEEP_TIME_MS = "LJM_DEBUG_LOG_SLEEP_TIME_MS"
LJM_LIBRARY_VERSION = "LJM_LIBRARY_VERSION"
LJM_ALLOWS_AUTO_MULTIPLE_FEEDBACKS = "LJM_ALLOWS_AUTO_MULTIPLE_FEEDBACKS"
LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES = "LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES"
LJM_AUTO_RECONNECT_STICKY_CONNECTION = "LJM_AUTO_RECONNECT_STICKY_CONNECTION"
LJM_AUTO_RECONNECT_STICKY_SERIAL = "LJM_AUTO_RECONNECT_STICKY_SERIAL"
LJM_MODBUS_MAP_CONSTANTS_FILE = "LJM_MODBUS_MAP_CONSTANTS_FILE"
LJM_ERROR_CONSTANTS_FILE = "LJM_ERROR_CONSTANTS_FILE"
LJM_DEBUG_LOG_FILE = "LJM_DEBUG_LOG_FILE"
LJM_CONSTANTS_FILE = "LJM_CONSTANTS_FILE"
LJM_DEBUG_LOG_FILE_MAX_SIZE = "LJM_DEBUG_LOG_FILE_MAX_SIZE"
LJM_SPECIFIC_IPS_FILE = "LJM_SPECIFIC_IPS_FILE"
LJM_STREAM_AIN_BINARY = "LJM_STREAM_AIN_BINARY"
LJM_STREAM_RECEIVE_TIMEOUT_MODE = "LJM_STREAM_RECEIVE_TIMEOUT_MODE"
LJM_STREAM_RECEIVE_TIMEOUT_MS = "LJM_STREAM_RECEIVE_TIMEOUT_MS"
LJM_STREAM_SCANS_RETURN = "LJM_STREAM_SCANS_RETURN"
LJM_STREAM_TRANSFERS_PER_SECOND = "LJM_STREAM_TRANSFERS_PER_SECOND"
LJM_RETRY_ON_TRANSACTION_ID_MISMATCH = "LJM_RETRY_ON_TRANSACTION_ID_MISMATCH"
LJM_OLD_FIRMWARE_CHECK = "LJM_OLD_FIRMWARE_CHECK"
Timeout Configs
Timeout Configs
LJM can be configured to set separate timeouts when connecting to a device and when sending / receiving packets to / from a device.
Both of these timeout types can be configured separately for USB, Ethernet, and WiFi.
LJM_ETHERNET_OPEN_TIMEOUT_MS
LJM_WIFI_OPEN_TIMEOUT_MS
LJM_OPEN_TCP_DEVICE_TIMEOUT_MS may be used to set both open timeout configs at the same time.
The send / receive timeouts are:
LJM_USB_SEND_RECEIVE_TIMEOUT_MS
LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS
LJM_WIFI_SEND_RECEIVE_TIMEOUT_MS
LJM_SEND_RECEIVE_TIMEOUT_MS may be used to set all three send / receive timeouts at the same time.
Details
One command/response operation (as performed by a function like LJM_eReadName, for example) may take longer than the timeout for
that connection type. This is because there are multiple timeout periods -- one to send the command and another to receive the
response.
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 double Value = 0;
3 int LJMError = LJM_ReadLibraryConfigS(LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS, &Value);
4 if (LJMError != 0) {
5 LJM_ErrorToString(LJMError, ErrorString);
6 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
7 }
8 printf("The default for LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS is %.00f milliseconds\n", Value);
9
10 Value = 3000;
11 printf("Setting LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS to %.00f milliseconds\n", Value);
12 LJMError = LJM_WriteLibraryConfigS(LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS, Value);
13 if (LJMError != 0) {
14 LJM_ErrorToString(LJMError, ErrorString);
15 printf("LJM_WriteLibraryConfigS error: %s\n", ErrorString);
16 }
17
18 LJMError = LJM_ReadLibraryConfigS(LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS, &Value);
19 if (LJMError != 0) {
20 LJM_ErrorToString(LJMError, ErrorString);
21 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
22 }
23 printf("LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS is now %.00f milliseconds\n", Value);
Possible output:
LJM_ETHERNET_OPEN_TIMEOUT_MS
Summary
LJM_ETHERNET_OPEN_TIMEOUT_MS is a numerical readable-writable LJM library configuration which sets how long in
milliseconds LJM waits for a Ethernet-based TCP connection to be established.
Details
LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS
Summary
LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS is a numerical readable-writable LJM library configuration which sets how long
LJM waits for a Ethernet-connected TCP packet to be sent or received in milliseconds.
Details
LJM_USB_SEND_RECEIVE_TIMEOUT_MS
Summary
LJM_USB_SEND_RECEIVE_TIMEOUT_MS is a numerical readable-writable LJM library configuration which sets how long LJM waits
for a USB packet to be sent or received in milliseconds.
Details
LJM_WIFI_OPEN_TIMEOUT_MS
Summary
LJM_WIFI_OPEN_TIMEOUT_MS is a numerical readable-writable LJM library configuration which sets how long in milliseconds LJM
waits for a WiFi-based TCP connection to be established.
The constant LJM_WIFI_OPEN_TIMEOUT_MS can be used interchangeably with the string "LJM_WIFI_OPEN_TIMEOUT_MS".
Details
LJM_WIFI_SEND_RECEIVE_TIMEOUT_MS
Summary
LJM_WIFI_SEND_RECEIVE_TIMEOUT_MS is a numerical readable-writable LJM library configuration which sets how long LJM waits
for a WiFi-connected TCP packet to be sent or received in milliseconds.
Details
LJM_OPEN_TCP_DEVICE_TIMEOUT_MS is a numerical readable-writable LJM library configuration which is a shortcut for setting the
following configs:
LJM_ETHERNET_OPEN_TIMEOUT_MS
LJM_WIFI_OPEN_TIMEOUT_MS
Details
LJM_SEND_RECEIVE_TIMEOUT_MS
Summary
LJM_SEND_RECEIVE_TIMEOUT_MS is a numerical readable-writable LJM library configuration which is a shortcut for setting the
following configs:
LJM_USB_SEND_RECEIVE_TIMEOUT_MS
LJM_ETHERNET_SEND_RECEIVE_TIMEOUT_MS
LJM_WIFI_SEND_RECEIVE_TIMEOUT_MS
Details
If LJM isn't finding an Ethernet or WiFi device, use ljm_specific_ips.config to configure LJM to specially check specific IP addresses.
LJM tries to open each IP address in ljm_specific_ips.config during relevant Open calls and ListAll calls.
Example ljm_specific_ips.config
Regardless of you computer's IP address, the following ljm_specific_ips.config file would trigger 192.168.2.207 and 10.0.0.123 to be
checked:
File syntax:
Whitespace is ignored.
Empty lines and lines starting with // are ignored.
All other lines are expected to contain one IP address, which should not be a broadcast address.
Default Location
Remarks
For checking if LJM can successfully read the specific IPs file, use LJM_GetSpecificIPsInfo.
Specific IPs are treated with higher priority than normal IP addresses. They checked before or during the regular UPD broadcast search
and are more likely to be an Open result.
Contact your network administrator to ensure that each of the desired IPs will be reachable via TCP/UDP as a static IP address. You
can also ping each address to ensure that they are reachable.
LJM_SPECIAL_ADDRESSES_STATUS
LJM_SPECIAL_ADDRESSES_STATUS is deprecated. Please use LJM_GetSpecificIPsInfo instead.
Summary
Passing LJM_SPECIAL_ADDRESSES_STATUS to LJM_ReadLibraryConfigStringS returns a string that reports the current success or
failure of parsing LJM_SPECIAL_ADDRESSES_FILE.
LJM_SPECIAL_ADDRESSES_STATUS is read-only.
Possible Values
Below are some example values that may be reported as LJM_SPECIAL_ADDRESSES_STATUS. This feature is in development, so if
you need to programmatically parse LJM_SPECIAL_ADDRESSES_STATUS, please contact us.
Remarks
LJM_SPECIFIC_IPS_FILE
Summary
LJM_SPECIFIC_IPS_FILE is an LJM configuration that describes the absolute or relative file path of the LJM specific IPs file.
To read, pass LJM_SPECIFIC_IPS_FILE to LJM_ReadLibraryConfigStringS to get a string containing the file path.
To write, pass LJM_SPECIFIC_IPS_FILE and string containing a file path to LJM_WriteLibraryConfigStringS, or use
LJM_LoadConfigurationFile.
The constant LJM_SPECIFIC_IPS_FILE can be used interchangeably with the string "LJM_SPECIFIC_IPS_FILE".
Remarks
To set LJM_SPECIFIC_IPS_FILE to the default location, set it to "default" or an empty string. For example, in C/C++:
The default file path specified by LJM_SPECIFIC_IPS_FILE is only parsed on LJM startup, so changes made to the file will not affect
running LJM processes unless LJM_WriteLibraryConfigStringS(LJM_SPECIFIC_IPS_FILE, ...) is called.
If you need to change LJM's configs either globally or quickly, you can edit the ljm_startup_configs.json file.
Default Location
Parsing
Parsed before any other configs are set, so config values that are manually set using the programmatic config functions (such as
LJM_WriteLibraryConfigS) with take precedence over the values in ljm_startup_configs.json.
Parsed during LJM startup, so processes that have already loaded LJM will not be altered by new changes to
ljm_startup_configs.json.
ljm_startup_configs.json (and the containing folder) may be overwritten when LJM updates, so if you'd like to make changes to the
configurations that are loaded when LJM starts, use ljm_startup_configs.json as a template to make a different file in a different
directory that you control, then load that file using the LJM_LoadConfigurationFile function at the beginning of your program.
Default Values
Use the string "default" to load the default value for each config parameter. Otherwise, see the "type" for each config parameter for what
kinds of values can be accepted. Please see LabJackM.h for more information about what each config parameter does.
Configs that are not included in ljm_startup_configs.json will be given the default value.
Syntax
ljm_startup_configs.json is parsed by LJM case-insensitively. LJM ignores every key in the top-level JSON object except for
LJM_CONFIG_VALUES, as well as ignoring every "description", "type", and "values" fields. Other fields in LJM_CONFIG_VALUES
which are not recognized by LJM will generate errors/warnings. LJM will also ignore lines starting with "//".
Windows Paths
Windows file paths must escape \ characters with \. For example, the path:
C:\ljm.log
Must be escaped as:
C:\\ljm.log
LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES
Summary
For example, if a call to LJM_eNames contains two frames next to each other that write to AIN0 then AIN1, LJM would automatically
condense these frames into one frame that writes to both AIN0 and AIN1.
Details
0 - false/disabled
1 - true/enabled (Default)
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 double Value;
3 int LJMError = LJM_ReadLibraryConfigS(LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES, &Value);
4 if (LJMError != 0) {
5 LJM_ErrorToString(LJMError, ErrorString);
6 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
7 }
8 if (Value == 0) {
9 printf("LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES is disabled by default.\n");
10 }
11 else {
12 printf("LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES is enabled by default.\n");
13 }
14
15 printf("Disabling LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES\n");
16 LJMError = LJM_WriteLibraryConfigS(LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES, 0);
17 if (LJMError != 0) {
18 LJM_ErrorToString(LJMError, ErrorString);
19 printf("LJM_WriteLibraryConfigS error: %s\n", ErrorString);
20 }
21
22 LJMError = LJM_ReadLibraryConfigS(LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES, &Value);
23 if (LJMError != 0) {
24 LJM_ErrorToString(LJMError, ErrorString);
25 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
26 }
27 if ((int)Value == 0) {
28 printf("LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES is now disabled.\n");
29 }
30 else {
31 printf("LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES is now enabled.\n");
32 }
Possible output:
LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES is enabled by default.
Disabling LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES
LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES is now disabled.
LJM_ALLOWS_AUTO_MULTIPLE_FEEDBACKS
Summary
For example, if a call to LJM_eNames would require a 68-byte packet but the connection can only take 64-byte packets, LJM would
automatically separate the LJM_eNames call into 2 operations of less than 64 bytes each.
Details
0 - false/disabled
1 - true/enabled (Default)
Relevant Functions
Example
Possible output:
LJM_AUTO_RECONNECT_STICKY_CONNECTION
Summary
Details
0 - false/disabled - Reconnects according to the ConnectionType parameter that was passed to the Open call
1 - true/enabled (Default) - Reconnects via the actual connection type that was used to connect to the device
Relevant Functions
LJM_AUTO_RECONNECT_STICKY_SERIAL is a numerical readable-writable LJM library configuration that sets whether or not LJM
attempts to reconnect disrupted / disconnected connections according to same serial number as the original handle. When
LJM_AUTO_RECONNECT_STICKY_SERIAL is disabled, the Identifier that was used during the initial LJM_Open or LJM_OpenS call
will be used to reconnect.
Details
0 - false/disabled
1 - true/enabled (Default)
Relevant Functions
LJM_CONSTANTS_FILE
Summary
LJM_CONSTANTS_FILE is a string-based write-only LJM library configuration which sets the absolute or relative path of an existing
file to read Modbus constants and error constants from. It is a shortcut for writing to both LJM_MODBUS_MAP_CONSTANTS_FILE and
LJM_ERROR_CONSTANTS_FILE.
The constant LJM_CONSTANTS_FILE can be used interchangeably with the string "LJM_CONSTANTS_FILE".
Default Value
Relevant Constants
Relevant Functions
LJM_ErrorToString
LJM_NameToAddress
LJM_NamesToAddresses
LJM_AddressToType
LJM_AddressesToTypes
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 int LJMError = LJM_WriteLibraryConfigStringS(LJM_CONSTANTS_FILE, "alternate_constants.json");
3 if (LJMError != 0) {
4 LJM_ErrorToString(LJMError, ErrorString);
5 printf("LJM_WriteLibraryConfigStringS error: %s\n", ErrorString);
6 }
LJM_DEBUG_LOG_FILE
Default
Summary
LJM_DEBUG_LOG_FILE is a string-based readable-writable LJM library configuration which sets the absolute or relative path of the file
to output log messages to.
The constant LJM_DEBUG_LOG_FILE can be used interchangeably with the string "LJM_DEBUG_LOG_FILE".
Details
Relevant Constants
Relevant Functions
Example
Possible output:
LJM_DEBUG_LOG_FILE_MAX_SIZE
Summary
LJM_DEBUG_LOG_FILE_MAX_SIZE is a numerical readable-writable LJM library configuration that limits the number of characters in
the debug log file. Once the debug log file has exceeded LJM_DEBUG_LOG_FILE_MAX_SIZE characters, it will be reset to 0
characters and debug logging will continue. The largest LJM_DEBUG_LOG_FILE_MAX_SIZE you may use is the largest file size of
your operating system. The default is 50000 characters.
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 int LJMError;
3 LJMError = LJM_WriteLibraryConfigS(LJM_DEBUG_LOG_FILE_MAX_SIZE, 123456789);
4 if (LJMError != 0) {
5 LJM_ErrorToString(LJMError, ErrorString);
6 printf("LJM_WriteLibraryConfigS error: %s\n", ErrorString);
7 }
LJM_DEBUG_LOG_LEVEL
Summary
LJM_DEBUG_LOG_LEVEL is a numerical readable-writable LJM library configuration with the following options:
LJM_STREAM_PACKET = 1
LJM_TRACE = 2
LJM_DEBUG = 4
LJM_INFO = 6
LJM_PACKET = 7
LJM_WARNING = 8
LJM_USER = 9
LJM_ERROR = 10
LJM_FATAL = 12
The constant LJM_DEBUG_LOG_LEVEL can be used interchangeably with the string "LJM_DEBUG_LOG_LEVEL".
Details
LJM_DEBUG_LOG_MODE must allow for logging in order for LJM_DEBUG_LOG_LEVEL to have any effect.
LJM_DEBUG_LOG_LEVEL determines which log messages are output. LJM outputs the debug messages that are of the current
LJM_DEBUG_LOG_LEVEL and greater.
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 double value;
3
4 int LJMError = LJM_ReadLibraryConfigS(LJM_DEBUG_LOG_LEVEL, &value);
5 if (LJMError != 0) {
6 LJM_ErrorToString(LJMError, ErrorString);
7 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
8 }
9 printf("The default for LJM_DEBUG_LOG_LEVEL is %.00f\n", value);
10
11 value = LJM_WARNING;
12 printf("Setting LJM_DEBUG_LOG_LEVEL to %.00f\n", value);
13 LJMError = LJM_WriteLibraryConfigS(LJM_DEBUG_LOG_LEVEL, value);
14 if (LJMError != 0) {
15 LJM_ErrorToString(LJMError, ErrorString);
16 printf("LJM_DEBUG_LOG_LEVEL error: %s\n", ErrorString);
17 }
Possible output:
LJM_DEBUG_LOG_MODE
Summary
LJM_DEBUG_LOG_MODE is a numerical readable-writable LJM library configuration with the following options:
LJM_DEBUG_LOG_MODE_NEVER = 1
LJM will never log messages
The log thread will never start
LJM_DEBUG_LOG_MODE_CONTINUOUS = 2
LJM will log all messages with priority equal to or greater than the current LJM_DEBUG_LOG_LEVEL
The log thread will start when the first message with priority equal to or greater than the current LJM_DEBUG_LOG_LEVEL is
scheduled to be output
LJM_DEBUG_LOG_MODE_ON_ERROR = 3
LJM will collect all messages with priority equal to or greater than the current LJM_DEBUG_LOG_LEVEL, but only output those
messages if a log message with priority equal to or greater than LJM_ERROR (10) is scheduled to be output
The maximum number of messages that will be collected is LJM_DEBUG_LOG_BUFFER_MAX_SIZE
The log thread will start when the first message with priority equal to or greater than the current LJM_DEBUG_LOG_LEVEL is
scheduled to be output
The constant LJM_DEBUG_LOG_MODE can be used interchangeably with the string "LJM_DEBUG_LOG_MODE".
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 double Value = 0;
3 int LJMError = LJM_ReadLibraryConfigS(LJM_DEBUG_LOG_MODE, &Value);
4 if (LJMError != 0) {
5 LJM_ErrorToString(LJMError, ErrorString);
6 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
7 }
8 printf("The default for LJM_DEBUG_LOG_MODE is %.00f\n", Value);
9
10 Value = LJM_DEBUG_LOG_MODE_CONTINUOUS;
11 printf("Setting LJM_DEBUG_LOG_MODE to %.00f\n", Value);
12 LJMError = LJM_WriteLibraryConfigS(LJM_DEBUG_LOG_MODE, Value);
13 if (LJMError != 0) {
14 LJM_ErrorToString(LJMError, ErrorString);
15 printf("LJM_WriteLibraryConfigS error: %s\n", ErrorString);
16 }
17
18 LJMError = LJM_ReadLibraryConfigS(LJM_DEBUG_LOG_MODE, &Value);
19 if (LJMError != 0) {
20 LJM_ErrorToString(LJMError, ErrorString);
21 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
22 }
23 printf("LJM_DEBUG_LOG_MODE is now %.00f\n", Value);
Possible output:
LJM_ERROR_CONSTANTS_FILE
Summary
LJM_ERROR_CONSTANTS_FILE is a string-based readable-writable LJM library configuration which sets the absolute or relative
path of an existing file to use as error constants for use with the function LJM_ErrorToString.
The constant LJM_ERROR_CONSTANTS_FILE can be used interchangeably with the string "LJM_ERROR_CONSTANTS_FILE".
Default Value
Relevant Constants
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 char defaultErrorConstantsFile[LJM_MAX_NAME_SIZE];
3 char * newErrorConstantsFile = "alternate_error_constants.json";
4
5 int LJMError = LJM_ReadLibraryConfigStringS(LJM_ERROR_CONSTANTS_FILE, defaultErrorConstantsFile);
6 if (LJMError != 0) {
7 LJM_ErrorToString(LJMError, ErrorString);
8 printf("LJM_ReadLibraryConfigStringS error: %s\n", ErrorString);
9 }
10 printf("The default for LJM_ERROR_CONSTANTS_FILE is %s\n", defaultErrorConstantsFile);
11
12 printf("Setting LJM_ERROR_CONSTANTS_FILE to %s\n", newErrorConstantsFile);
13 LJMError = LJM_WriteLibraryConfigStringS(LJM_ERROR_CONSTANTS_FILE, newErrorConstantsFile);
14 if (LJMError != 0) {
15 LJM_ErrorToString(LJMError, ErrorString);
16 printf("LJM_WriteLibraryConfigStringS error: %s\n", ErrorString);
17 }
LJM_LIBRARY_VERSION
Summary
LJM_LIBRARY_VERSION is a numerical read-only LJM library configuration which is used to read the current LJM version.
The constant LJM_LIBRARY_VERSION can be used interchangeably with the string "LJM_LIBRARY_VERSION".
Relevant Functions
Example
Possible output:
LJM_MODBUS_MAP_CONSTANTS_FILE
Summary
LJM_MODBUS_MAP_CONSTANTS_FILE is a string-based readable-writable LJM library configuration which sets the absolute or
relative path of an existing file to use as Modbus constants for use with the functions that use the Modbus map constants, such as
LJM_NamesToAddresses.
Default Value
Relevant Constants
Relevant Functions
Example
LJM_OLD_FIRMWARE_CHECK
Summary
LJM_OLD_FIRMWARE_CHECK is a numerical readable-writable LJM library configuration which sets whether or not LJM will check
the Modbus constants file to make sure the firmware of the current device is compatible with the Modbus register(s) being read from or
written to.
The constant LJM_OLD_FIRMWARE_CHECK can be used interchangeably with the string "LJM_OLD_FIRMWARE_CHECK".
Values
0 - false/disabled
1 - true/enabled (default)
Details
For all Easy functions and for LJM_MBFBComm, each address being read from or written to that also exists in the Modbus constants
file, LJM will compare the firmware version of the current device against the minimum firmware required for that address. If the device
does not have adequate firmware, the function will abort before communicating with the device and return the error
LJME_OLD_FIRMWARE (1307).
Relevant Functions
Affects the error checking of all Easy functions and also LJM_MBFBComm.
Example
LJM_STREAM_AIN_BINARY
Summary
LJM_STREAM_AIN_BINARY = 0 (default)
LJM_STREAM_AIN_BINARY = 1
The constant LJM_STREAM_AIN_BINARY can be used interchangeably with the string "LJM_STREAM_AIN_BINARY".
Remarks
Relevant Functions
LJM_STREAM_RECEIVE_TIMEOUT_MODE
Summary
LJM_STREAM_RECEIVE_TIMEOUT_MODE_CALCULATED = 1 (default)
LJM calculates how long the stream timeout should be, according to the scan rate reported by the device.
LJM_STREAM_RECEIVE_TIMEOUT_MODE_MANUAL = 2
LJM will use the value of LJM_STREAM_RECEIVE_TIMEOUT_MS as the stream timeout.
Remarks
Relevant Functions
LJM_STREAM_RECEIVE_TIMEOUT_MS
Summary
Manually sets the timeout for LJM's stream data collection. Writing to this configuration
sets LJM_STREAM_RECEIVE_TIMEOUT_MODE to LJM_STREAM_RECEIVE_TIMEOUT_MODE_MANUAL.
Writing a non-zero value to LJM_STREAM_RECEIVE_TIMEOUT_MS will manually set the timeout for LJM's stream data collection.
Note that using LJM_STREAM_RECEIVE_TIMEOUT_MODE of LJM_STREAM_RECEIVE_TIMEOUT_MODE_CALCULATED is almost
always better than using manual non-zero LJM_STREAM_RECEIVE_TIMEOUT_MS value.
Writing 0 to LJM_STREAM_RECEIVE_TIMEOUT_MS will cause LJM to never time out. This allows you to set up triggered stream or
externally clocked stream on the T7. This is usually used in conjunction with LJM_STREAM_SCANS_RETURN set to
LJM_STREAM_SCANS_RETURN_ALL_OR_NONE.
Remarks
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 int LJMError = 0;
3 LJMError = LJM_WriteLibraryConfigS(
4 LJM_STREAM_RECEIVE_TIMEOUT_MS,
5 0
6 );
7 if (LJMError != LJME_NOERROR) {
8 LJM_ErrorToString(LJMError, ErrorString);
9 printf("LJM_WriteLibraryConfigS error: %s\n", ErrorString);
10 }
LJM_STREAM_SCANS_RETURN_ALL = 1 (default)
A mode that will cause LJM_eStreamRead to sleep until the full ScansPerRead scans are collected by LJM.
This mode may not be appropriate for stream types that are not consistently timed, such as externally clocked stream mode.
LJM_STREAM_SCANS_RETURN_ALL_OR_NONE = 2
A mode that will cause LJM_eStreamRead to never sleep, and instead either:
consume ScansPerRead scans and return LJME_NOERROR, or
consume no scans and return LJME_NO_SCANS_RETURNED.
The constant LJM_STREAM_SCANS_RETURN can be used interchangeably with the string "LJM_STREAM_SCANS_RETURN".
Remarks
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 int LJMError = 0;
3 LJMError = LJM_WriteLibraryConfigS(
4 LJM_STREAM_SCANS_RETURN,
5 LJM_STREAM_SCANS_RETURN_ALL_OR_NONE
6 );
7 if (LJMError != 0) {
8 LJM_ErrorToString(LJMError, ErrorString);
9 printf("LJM_WriteLibraryConfigS error: %s\n", ErrorString);
10 }
LJM_STREAM_TRANSFERS_PER_SECOND
Summary
LJM_STREAM_TRANSFERS_PER_SECOND is a numerical readable-writable LJM library configuration which sets how many times
per second LJM's stream thread attempts to receive stream packet(s) from the device.
Details
Increasing LJM_STREAM_TRANSFERS_PER_SECOND to a higher value will allow for less latency in receiving data, since LJM will
receive data from the device more often (in smaller quantities). Increasing the LJM_STREAM_TRANSFERS_PER_SECOND too much
will cause the data contained in each packet to decrease, which will cause unnecessary overhead and potentially cause scans to be
missed. Enable debug logging with LJM_TRACE as the LJM_DEBUG_LOG_LEVEL to see how stream is set up. Search the log file for
the term "AutoResponse streaming initialized" to see what effects LJM_STREAM_TRANSFERS_PER_SECOND has had on stream
setup. (You'll mostly likely want to disable debug logging for your real stream sessions after finding settings for stream setup that looks
reasonable, since debug logging consumes a significant amount of processing. LJM's stream setup is deterministic, so given the same
parameters to LJM_eStreamStart and the same stream configurations, stream will be set up the same way every time.)
Decreasing LJM_STREAM_TRANSFERS_PER_SECOND to a lower value will theoretically cause less overhead in stream, since
LJM will receive data from the device less often (in larger quantities), but may have little to no effect. When decreasing
LJM_STREAM_TRANSFERS_PER_SECOND, it is recommended to increase the size of the stream buffer on the device. See the
Modbus register STREAM_BUFFER_SIZE_BYTES (address: 4012).
Setting a new LJM_STREAM_TRANSFERS_PER_SECOND value will not affect stream threads that are already in progress.
Relevant Functions
Example
1 char ErrorString[LJM_MAX_NAME_SIZE];
2 double value;
3
4 int LJMError = LJM_ReadLibraryConfigS(LJM_STREAM_TRANSFERS_PER_SECOND, &value);
5 if (LJMError != 0) {
6 LJM_ErrorToString(LJMError, ErrorString);
7 printf("LJM_ReadLibraryConfigS error: %s\n", ErrorString);
8 }
9 printf("The default for LJM_STREAM_TRANSFERS_PER_SECOND is %.00f\n", value);
10
11 value = 100;
12 printf("Setting LJM_STREAM_TRANSFERS_PER_SECOND to %.00f\n", value);
13 LJMError = LJM_WriteLibraryConfigS(LJM_STREAM_TRANSFERS_PER_SECOND, value);
14 if (LJMError != 0) {
15 LJM_ErrorToString(LJMError, ErrorString);
16 printf("LJM_WriteLibraryConfigS error: %s\n", ErrorString);
17 }
Possible output:
4 - Error Codes
Add new comment
Error codes in the 2015.07.10.A version of the ljm_constants.json file. For more information about error codes look at the installed error
codes page.
LJ_SUCCESS 0
LJME_WARNINGS_BEGIN 200 This indicates where the warning codes start is not a
real warning code.
LJME_WARNINGS_END 399 This indicates where the warning codes end is not a
Error Name Error real warning code.
Description
LJME_FRAMES_OMITTED_DUE_TO_PACKET_SIZE Code
201 Some read/write operation(s) were not sent to the
device because the Feedback command being
created was too large for the device, given the current
connection type.
LJME_DEBUG_LOG_FAILURE 202 The debug log file could not be written to. Check the
LJM_DEBUG_LOG_FILE and related LJM
configurations.
FEATURE_NOT_IMPLEMENTED 254
LJME_MODBUS_ERRORS_BEGIN 1200 This indicates where the Modbus error codes start is
not a real Modbus error code.
LJME_MODBUS_ERRORS_END 1216 This indicates where the Modbus error codes end is
not a real Modbus error code.
LJME_MBE3_ILLEGAL_DATA_VALUE 1203 The device received a value that could not be written
to the specified address.
LJME_MBE5_ACKNOWLEDGE 1205 The device acknowledges the request, but will take
some time to process.
LJME_MBE11_GATEWAY_TARGET_NO_RESPONSE 1211 The requested route was available but the device
failed to respond.
LJME_LIBRARY_ERRORS_BEGIN 1220 This indicates where the LJM error codes start is not
a real LJM error code.
LJME_LIBRARY_ERRORS_END 1399 This indicates where the LJM error codes end is not a
real LJM error code.
LJME_DEVICE_NOT_OPEN 1224 The requested handle did not refer to an open device.
LJME_DEVICE_DISCONNECTED 1226 The device could not be contacted and LJM is not
configured to heal device connections (see LJM
config LJM_HEAL_CONNECTION_MODE).
LJME_DEVICE_CURRENTLY_CLAIMED_BY_ANOTHER_PROCESS 1230 At least one matching device was found, but cannot
be claimed by this process because a different
process has already claimed it. Either close the
device handle in your other process (i.e. program or
application) or close the other process. Then try
opening the device again.
LJME_INVALID_LENGTH 1269 LJM received a length that did not make sense.
Please contact LabJack support if you've received
this error.
LJME_ERROR_BIT_SET 1270 A Modbus response had the error bit set. Please
contact LabJack support if you've received this error.
LJME_CONSTANTS_FILE_NOT_FOUND 1292 The LJM error constants file and/or Modbus constants
file could not be opened for reading.
LJME_INVALID_CONSTANTS_FILE 1293 The LJM error constants file and/or Modbus constants
file could not be parsed.
LJME_INVALID_NAME 1294 The requested name was not found in the register
loaded from the constants file (if the constants file is
loaded).
LJME_ERROR_RETRIEVAL_FAILURE 1300 An error occurred on the device and LJM was unable
to retrieve more information about that error. Please
contact LabJack support if you've received this error.
LJME_LJM_BUFFER_FULL 1301 The LJM stream buffer was filled with stream data
and stream was stopped.
LJME_COULD_NOT_START_STREAM 1302 LJM could not start stream. Input may have incorrect
or a different error may have occurred.
LJME_SYNCHRONIZATION_TIMEOUT 1306 LJM did not receive data from the stream for long
enough that reading form the LJM buffer timed out.
LJME_OLD_FIRMWARE 1307 The current firmware version of the device was not
sufficient to read/write a requested register, as
according to the loaded LJM constants file.
LJME_CANNOT_READ_OUT_ONLY_STREAM 1308 The stream running is out-only and does not produce
data values.
MODBUS_STRING_CMD_TOO_BIG 2310
MODBUS_STRING_PARAM_TOO_BIG 2311
MODBUS_STRING_BAD_NUM_PARAMS 2312
MODBUS_INVALID_NUM_REGISTERS 2313 Register data types does not match the number of
registers in the request.
MODBUS_READ_TOO_LARGE 2314
STARTUP_CONFIG_INVALID_CODE 2330
USER_RAM_FIFO_MUST_BE_EMPTY 2340 The FIFO can not contain any data when data size is
being changed.
USER_RAM_FIFO_INSUFFICIENT_SPACE 2344 FIFO does not have enough free space to hold the
requested write. No data was added to the FIFO.
INTFLASH_ADD_INVALID 2350
INTFLASH_CODE_INVALID 2351
FLASH_VERIFICATION_FAILED 2355 A write to flash failed to set one or more bits to the
desired values.
FLASH_ERASE_FAILED 2356 One or more bits failed to set during a flash erase
operation.
INTFLASH_UNAVAILABLE 2358 Flash can not be accessed due to the WiFi module
booting up.
FILEIO_UNAVAILABLE 2359 The file system can not be accessed due to the WiFi
module booting up.
LUA_VM_STATE_NO_CHANGE 2380
LUA_INITIALIZATION_ERROR 2381
LUA_INVALID_MODE 2384
SYSTEM_READ_OVERRUN 2403
SYSTEM_INVALID_PIN 2404
SYSTEM_WAIT_TOO_LONG 2407 The requested wait time is beyond the max allowed.
POWER_NO_CHANGE 2452
POWER_CAN_NOT_CHANGE_USED_CONNECTION 2456 Can not change the power level of the connected
medium.
HW_DIO_NOT_AVAILABLE 2500
HW_CIO0_NOT_AVAILABLE 2520
HW_CIO1_NOT_AVAILABLE 2521
EF_DIO_HAS_NO_TNC_FEATURES
Error Name 2550
Error Description
Code
EF_INVALID_TYPE 2551 The selected type is not recognized.
EF_PIN_TYPE_MISMATCH 2553 The requested type is not supported on this DIO pin.
EF_SET_TO_32BIT 2556
EF_SMOOTH_VALUE_OUT_OF_RANGE 2557
EF_LINE_MUST_BE_LOW_BEFORE_STARTING 2563 The DIO line must be set to output low to ensure
proper signal generation.
EF_INVALID_DIVISOR 2564
AIN_EF_CALCULATION_ERROR 2582
AIN_EF_CALCULATION_OUT_OF_RANGE 2584
AIN_EF_INVALID_CHANNEL 2585
AIN_EF_INVALID_CJC_REGISTER 2586
STREAM_EXTCLK_AND_GATE_MX 2602
STREAM_IN_SPONTANEOUS_MODE 2603 Stream data can not be read with commands while in
spontaneous mode.
STREAM_USB_PKT_OVERFLOW 2604
STREAM_SCAN_RATE_INVALID 2608 The scan rate times the number of channels per scan
is too great for this device.
STREAM_OUT_BUFF_TOO_BIG 2609
STREAM_OUT_BUFF_FULL 2613 Attempted to write more data than the buffer can hold.
Extra data was discarded.
STREAM_BUFF_SIZE_INVALID 2615 Specified buffer was either too large or not a power of
2.
STREAM_OUT_BUFF_LOOP_OVERWRITE 2616
STREAM_OUT_BUFF_DNE 2617 The buffer size must be set before data can be written
to it.
STREAM_BUFFER_DNE 2619
STREAM_NOT_RUNNING 2620
STREAM_OUT_LOOP_TOO_BIG 2622 Loop size to big for the current buffer size.
STREAM_OUT_DATA_TRGT_MISSMATCH 2623
SWDT_ROLLT_INVALID 2670
SWDT_DIO_SETTINGS_INVALID 2672
SWDT_DAC0_SETTINGS_INVALID 2673
SWDT_DAC1_SETTINGS_INVALID 2674
RTC_TIME_INVALID 2690
RTC_SNTP_TIME_INVALID 2691
SPI_NO_DATA_AVAILABLE 2701
SPI_TRANSFER_SIZE_TOO_LARGE 2710
I2C_BUS_BUSY 2720 One or both of the I2C lines are held low. Check
hardware and reset the bus.
I2C_TX_SIZE_TOO_LARGE 2726
I2C_RX_SIZE_TOO_LARGE 2727
I2C_BUFFER_OVERRUN 2728
SBUS_NO_ACK 2741 Slave device did not acknowledge the data transfer.
SBUS_CUSTOM_MODE_INVALID 2742
FILE_IO_DISK_ERROR 2801 A hard error occurred in the low level disk I/O layer.
FILE_IO_TIMEOUT 2815 Could not get a grant to access the volume within
defined period.
WIFI_ASSOCIATED 2900
WIFI_ASSOCIATING 2901
WIFI_ASSOCIATION_FAILED 2902
WIFI_UNPOWERED 2903
WIFI_BOOTING_UP 2904
WIFI_COULD_NOT_START 2905
WIFI_APPLYING_SETTINGS 2906
WIFI_DHCP_STARTED 2907
WIFI_OTHER 2909
WIFI_UPDATE_CONFIG 2920
WIFI_UPDATE_IN_PROG 2921
WIFI_UPDATE_REBOOT 2923
WIFI_UPDATE_SUCCESS 2924
WIFI_UPDATE_FAILED 2925
STREAM_AUTO_RECOVER_ACTIVE
Error Name 2940
Error Description
STREAM_AUTO_RECOVER_END Code
2941
STREAM_SCAN_OVERLAP 2942 A new scan started before the previous scan finished.
Generally occurs because ScanRate >
MaxSampleRate/NumChannels. Note that
MaxSampleRate is impacted by Range,
ResolutionIndex, and Settling. Try adding commands
right before StreamStart to set AIN_ALL_RANGE=10,
STREAM_RESOLUTION_INDEX=0, and
STREAM_SETTLING_US=0.
STREAM_AUTO_RECOVER_END_OVERFLOW 2943
STREAM_BURST_COMPLETE 2944
SELFDIAG_MAIN_OSC_FAIL 2950
Check your version of LJM's LabJackM.h for LJM error codes, or check ljm_constants.json for LJM and device errors codes.
LabJackM.h locations:
Windows
C:\Program Files\LabJack\Drivers\LabJackM.h
- or -
C:\Program Files (x86)\LabJack\Drivers\LabJackM.h
Mac OS X
/usr/local/include/LabJackM.h
Linux
/usr/local/include/LabJackM.h
ljm_constants.json locations:
Windows XP
C:\Documents and Settings\All Users\Application Data\LabJack\LJM\ljm_constants.json
Mac OS X
/usr/local/share/LabJack/LJM/ljm_constants.json
Linux
/usr/local/share/LabJack/LJM/ljm_constants.json
Troubleshooting / FAQ
Here are some miscellaneous questions and answers about LJM. If you have a question, email [email protected].
LJM catches all terminal signals by default, in order to clean up LabJack device connections. LJM attempts to set the signal handlers
upon the first call to LJM that attempts communication with a device or sets or gets a LJM configuration.
On Linux/Mac, LJM uses the oldact parameter of sigaction to determine if there was previously a signal handler; if oldact is not NULL
for a given signal, LJM will reset oldact as the signal handler and not handle that signal.
Lots of -9999 (LJM_DUMMY_VALUE) values usually occurs when the machine running the code is unable to keep up with transferring
stream data from the device to the computer. Here are some strategies that may help your code keep up with stream.
Briefly:
Use a ScansPerRead that is relatively large (one half of the ScanRate is a good place to start)
Try an Ethernet connection if possible
Free up processing power by ending unneeded processes
Increase your program's priority level
Call LJM_WriteLibraryConfigS(LJM_DEBUG_LOG_MODE, LJM_DEBUG_LOG_MODE_NEVER)
In more detail:
ScansPerRead: The larger the number of ScansPerRead you set up in LJM_eStreamStart, the less overhead there will be. Increasing
ScansPerRead will see larger improvements up until the maximum samples per packet is reached, and smaller improvements after that.
For the T7 connected over USB, the maximum samples per packet is 24. For the T7 over Ethernet, the maximum samples per packet is
512. For example, if you have 2 channels, a ScansPerRead of 12 will utilize the maximum samples per packet over USB.
Ethernet: Ethernet streaming usually ends up being more efficient for this reason, so if you are having problems with USB streaming,
try switching to Ethernet streaming if you can. Please note that WiFi streaming is not as fast as Ethernet streaming.
Priority level:
Windows program priority can be set by using the start command (/realtime is the highest priority)
Linux and Mac OS X program priority can be set by using the nice command (-20 is the highest priority)
LJM_DEBUG_LOG_MODE: Ensure that LJM's debug logging is turned of by setting LJM_DEBUG_LOG_MODE as 1
(LJM_DEBUG_LOG_MODE_NEVER) by using LJM_WriteLibraryConfigS. Note that the default LJM_DEBUG_LOG_MODE is
LJM_DEBUG_LOG_MODE_NEVER, so this will not have an effect if you have not previously set the LJM_DEBUG_LOG_MODE.
What it means
LJME_LJM_BUFFER_FULL usually occurs when the machine running the code is unable to keep up with reading data from stream. In
other words, LJM_eStreamRead is not being called often enough / fast enough. For example, your program may be crunching lots of
numbers in between LJM_eStreamRead calls.
It may be worth putting in some timing code into your program to calculate whether LJM_eStreamRead is called at the right frequency.
For example, if your scan rate is 100,000 Hz and your ScansPerRead is 50,000, you'll want LJM_eStreamRead to be called at 2 Hz.
By default, LJM_eStreamRead will block (and sleep) until ScansPerRead scans of data is ready, so you don't need to worry about
calling it too quickly.
The larger the number of ScansPerRead you set up in LJM_eStreamStart, the less overhead there will be. Increasing ScansPerRead
will see larger improvements up until the maximum samples per packet is reached, and smaller improvements after that. For the T7
connected over USB, the maximum samples per packet is 24. For the T7 over Ethernet, the maximum samples per packet is 512. For
example, if you have 2 channels, a ScansPerRead of 12 will utilize the maximum samples per packet over USB.
The priority level of processes on your computer can generally be adjusted to give your LJM streaming process more processor time
relative to other processes. On Windows, process priority can be adjusted using the Task Manager or by using the start command. On
Mac OS X and Linux systems, the nice command may be used. Setting process priority should be used as a last resort.
LabJackM.h - a header file that defines LJM functions and contains function usage information
LabJackM library / dll file(s), which contains the actual LJM code
The LabJack LJM folder, which contains:
ljm.log
the default debug log file (Debug logging in LJM is not enabled by default.)
ljm_constants.json file
a constants file that defines registers and error codes
ljm_special_addresses.config
contains IP addresses that will be connected to during every network-based Open or ListAll
ljm_startup_configs.json file
defines the start-up configuration parameters of LJM
readme.md
gives a brief explanation of the files installed to the LabJack LJM folder
Windows 32-bit:
C:\Program Files\LabJack\Drivers\LabJackM.h
C:\Program Files\LabJack\Drivers\LabJackM.lib
C:\Windows\SysWOW64\LabJackM.dll or C:\Windows\System32\LabJackM.dll
The LabJack LJM folder, which contains configuration, debug, and information files:
Windows Vista and later: C:\ProgramData\LabJack\LJM\
Windows XP: C:\Documents and Settings\All Users\Application Data\LabJack\LJM
Windows 64-bit:
Linux:
/usr/local/include/LabJackM.h
/usr/local/lib/libLabJackM.so (which is a symlink to a versioned libLabJackM.so.<version> in the same directory)
The LabJack LJM folder, /usr/local/share/LabJack/LJM, which contains configuration, debug, and information files.
Mac OS X:
/usr/local/include/LabJackM.h
/usr/local/lib/libLabJackM.dylib (which is a symlink to a versioned libLabJackM-<version>.dylib in the same directory)
The LabJack LJM folder, /usr/local/share/LabJack/LJM, which contains configuration, debug, and information files.
Windows
Linux
If your chosen distribution is very old, check your installed packages with against this list of abbreviated output of ldd libLabJackM.so:
libusb-1.0.so.0
libpthread.so.0
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6
librt.so.1
If you have equal or greater versions of the above libraries, LJM will work.
Mac OS X
On Windows, LJM uses GetAdaptersInfo to find determine what network adapters are available. On Linux and Mac, LJM uses getifaddrs .
It is important that each network adapter is configured to have the correct subnet mask, since each broadcast address is determined
from a bitwise-OR of the network IP with the inverse of the subnet mask.
When writing to internal flash, the key is only valid for the duration of a single packet, so the operation to write the key and to write or
erase the data must be grouped into a single packet. LJM has multiple value functions, such as LJM_eWriteAddresses, which allow you
to write the key while writing other values. To ensure packets are within the allowable packet size, you can read the MaxBytesPerMB
parameter of LJM_GetHandleInfo to get the maximum packet size for the connection type in use. Then, use the Modbus protocol
description to figure out how many values you can send. LJM uses Feedback (MBFB).
Also, note that having LJM_ALLOWS_AUTO_CONDENSE_ADDRESSES enabled (as it is by default) will help the efficiency of writing
to internal flash.
In general, you may want to consult the Basic Network & Troubleshooting guide.
You may want to try LJM Specific IPs for devices that can be ping'd but for which LJM cannot seem to find.
Linux
Check your iptables configuration. If disabling iptables fixes the issue, you may want to alter your iptables rules. In the general case,
running a command such as:
will add an iptables rule in the second spot (INPUT 2) to allow UDP packets on the port 52362, which is the UDP port LJM uses to
discover T7 devices.
Don't forget to save your iptables after altering the configurations. For example, on CentOS: