Equivalent of WaitShort/WaitLong for T4/LJM Digital I/O? | LabJack
 

Equivalent of WaitShort/WaitLong for T4/LJM Digital I/O?

13 posts / 0 new
Last post
iandol
iandol's picture
Equivalent of WaitShort/WaitLong for T4/LJM Digital I/O?

Using the exodriver, I used to be able to build command packets that would allow me to set the state of a digital output, then wait a variable time, then set a different state, in a single command packet:

 

https://labjack.com/support/datasheets/u6/low-level-function-reference/f...

 

My usecase is I want to send fixed length low-high-low transitions or around 2-5ms; either single line triggers or 8bit multi-line strobed words, to external equipment. I don't want my application to deal with the timing itself but move onto other tasks in a tight loop (thus need it to be as low latency as possible, so direct command-response USB with a single command packet, like the exodriver). I only need to send single low-high-low transitions, but for my strobed words need at least 8 bits (EIO0-8 ideally). Enhanced DIO like pulse_out only seems to be useable for a couple of outputs, so I'm unclear what the best way to do this would be?

LabJack Support
labjack support's picture
You are looking for WAIT_US

You are looking for WAIT_US_BLOCKING:

https://labjack.com/support/datasheets/t-series/hardware-overview

... and the T4 has registers that will write a single bit or lots of bits:

https://labjack.com/support/datasheets/t-series/digital-io

 

iandol
iandol's picture
Thanks. However this method

Thanks. However this method blocks not only the T4, but the the return of the call:

%2501=EIO_STATE; 61590 = WAIT_US_BLOCKING

>> tic;calllib('libLabJackM', 'LJM_eWriteAddresses', l.handle, 3, [2501 61590 2501], [0 1 0], [1 1 0], 0);toc
Elapsed time is 0.000825 seconds.


>> tic;calllib('libLabJackM', 'LJM_eWriteAddresses', l.handle, 3, [2501 61590 2501], [0 1 0], [1 10000 0], 0);toc
Elapsed time is 0.011054 seconds.

 

The first command waits 1us and MATLAB times it takes ~0.8ms -- the second command waits 10000us (10ms), and MATLAB times it takes 11ms. Can I stop it blocking the return of the call?

 

 

LabJack Support
labjack support's picture
The extra time is your

The extra time is your communication overhead.  See Table A.1.2:

https://labjack.com/support/datasheets/t-series/appendix-a-1

 

Yes, it is blocking just like what you were using on the U6.  A couple options that occur to me.

Threading:  Use a separate thread for the wait call so the rest of your program is not stuck waiting.  You still can't send other commands to the T4, but your program can do other things.

Lua Script:  Have your program write something to a user ram register, and your Lua script notices that and does what you want.

 

iandol
iandol's picture
With the exodriver I would

With the exodriver I would write a command ('LJUSB_WriteTO') but not read the response, so I suppose another option is to use 'LJM_WriteRaw'. I am not sure how exactly to format the command, can I use LJM_AddressesToMBFB to generate the packet to write?

I can't currently get LJM_AddressesToMBFB to work, it just returns what I send:

 

[~,~,~,~,~,~,~,cmd] = calllib('libLabJackM', 'LJM_AddressesToMBFB', 64, 2501, 0, 1, 1, 0, 1, 0)

cmd =  uint8   0

 

Lua script is a nice idea (and such a cool feature!), I'll probably use this if I can't get WriteRaw to work...

 

Thanks!

p.s. Regarding threading, MATLAB is a disaster in this regard. MATLAB's parfeval command has a default overhead of ~6ms to return, and it cannot send object data to the worker thread (I normally use OOP and create a jabJack class to save the state and handle the lifecycle, thus can't be used). For simple throwaway threads I can use Java etc. but I face the overhead of loading everything each time it is called (or somehow convert matlab to java classes etc.)

 

 

LabJack Support
labjack support's picture
For low-level details,

For low-level details, command-response uses the Modbus TCP protocol:

https://labjack.com/support/software/api/modbus

You can use LJM_AddressesToMBFB to generate the Modbus Feedback command packet to write. LJM_MBFBComm can be used for communications (both command-response):

https://labjack.com/support/software/api/ljm/function-reference/lowlevel...

Alternatively to MBFBComm, there are the raw write (as you pointed out, LJM_WriteRaw) and read:

https://labjack.com/support/software/api/ljm/function-reference/lowlevel...

As for LJM_AddressesToMBFB, most parameters are arrays, and the last parameter (aMBFBCommand) is the resultant command array which needs to be a preallocated array of at least MaxBytesPerMBFB size when passed. I believe in MATLAB, arrays are updated in the parameter and not in the return.

Last, I want to point out that our devices are built around a command-response structure, except with stream mode. After sending a command you should read back the response before sending the next command. Sending consecutive commands without reading the response can cause issues on the device.

iandol
iandol's picture
With the U6 I've used it for

With the U6 I've used it for years without reading the response and it never failed. But indeed with LJM and the T4 after around 10 commands using LJM_WriteRaw I got disconnect errors then a full MATLAB crash. So your recommendation is indeed worth following for the T4 (the U6 being more robust to this off-label misuse ;-)

 

OK, so I made a 338byte mini server in Lua:

LJ.setLuaThrottle(100)LJ.IntervalConfig(0,500)local a=LJ.CheckInterval;local b=MB.R;local c=MB.W;local d=-1;local e=-1;c(2601,0,255)c(46000,3,0)c(2500,0,0)while true do d=b(46000,3)if d~=e and d>=1 then c(2501,0,d)c(61590,1,math.random(1,10)*1000)c(2501,0,0)e=d elseif d~=e and d==0 then c(2501,0,0)e=d end;if a(0)then c(46000,3,0)end end

 

That reads a value from RAM and generates a strobed 8bit word that lasts a random 1 - 10ms on EIO. Setting the RAM in MATLAB takes a fixed ~0.5-1ms no matter the length of the WAIT_US, basically only overhead. Awesome!

So then I thought I would like to make a MATLAB method to upload this Lua script and run it. What is the expected input format to LUA_SOURCE_WRITE -- I've tried char, string scalar, unit16 byte array but it complains that the input needs to be numeric and a scalar...

 

LabJack Support
labjack support's picture
If you are using LJM

If you are using LJM_eWriteNames, the values you pass are doubles. Convert a character array's (string) values to a double value array. Alternatively, you can use LJM_eWriteNameByteArray where you pass an array of bytes.

LabJack Support
labjack support's picture
A scripts can be saved to the

A scripts can be saved to the device and configured to start running when the device boots up. Using Kiplings existing system would prevent the need to implement an uploading and running system in MatLab.

iandol
iandol's picture
Yes, I can use Kipling (which

Yes, I can use Kipling (which is great), but one nice thing with MATLAB is I can programatically change the script values and reupload the lua code.

 

str = sprintf('LJ.IntervalConfig(0,1000)while true do if LJ.CheckInterval(0)then print(LJ.Tick())end end\0');
strN = length(str);
err = calllib(me.libName, 'LJM_eWriteNameByteArray', me.handle, 'LUA_SOURCE_WRITE', strN, str, 0);

 

gives me: error 2401: SYSTEM_MEMORY_OVERWRITE --- I've tried using char with eWriteNameByteArray as above and doubles with eWriteNameArray but I get the same error.

 

 

LabJack Support
labjack support's picture
I'll leave your matlab

I'll leave your matlab problem for someone else, but still don't think writing new scripts is the best idea.  Rather use the Kipling debugger to write a script with a routine you can configure and/or different routines.  Then have matlab just write user-ram registers to configure the script and signal it to execute a routine:

http://labjack.com/support/datasheets/t-series/lua-scripting#user-ram

 

LabJack Support
labjack support's picture
"SYSTEM_MEMORY_OVERWRITE"

"SYSTEM_MEMORY_OVERWRITE"

Before writing data to LUA_SOURCE_WRITE you need to tell the device how much data to expect by writing to LUA_SOURCE_SIZE.

 

Another option is to use USER_RAM to pass script settings, rather than programmatically modifying the source.

 

iandol
iandol's picture
As always, thank you for your

As always, thank you for your excellent service and superb software+hardware!!!