MATLAB upgrade to 2018a and UD Library breaks | LabJack
 

MATLAB upgrade to 2018a and UD Library breaks

9 posts / 0 new
Last post
eweststrate
MATLAB upgrade to 2018a and UD Library breaks

Has anyone upgraded to MATLAB 2018a and have issues with UD labjack applications?  Something changed in the .NET implementation and now the class enumerations all changed.  None of the wrapper examples work as downloaded.  Worked in 2017b.

For example:

ljasm = NET.addAssembly('LJUDDotNet'); %Make the UD .NET assembly visible in MATLAB
ljudObj = LabJack.LabJackUD.LJUD;
[ljerror, ljhandle] = ljudObj.OpenLabJack(LabJack.LabJackUD.DEVICE.U6, LabJack.LabJackUD.CONNECTION.USB, '0', true, 0);

gives me this now:

Undefined variable "LabJack" or class "LabJack.LabJackUD.DEVICE.U6".

eweststrate
Here is something that I

Here is something that I think illustrates the problem.  I run the following in Matlab 2017a with the responses shown:

>> enumeration('LabJack.LabJackUD.DEVICE')

Enumeration members for class 'LabJack.LabJackUD.DEVICE':

    UE9
    U3
    U6

>> enumeration('LabJack.LabJackUD.LJUD+DEVICE')

Enumeration members for class 'LabJack.LabJackUD.LJUD+DEVICE':

    UE9
    U3
    U6

 

Now, the same thing, run in 2018a:

>> enumeration('LabJack.LabJackUD.DEVICE')

No class LabJack.LabJackUD.DEVICE.

>> enumeration('LabJack.LabJackUD.LJUD+DEVICE')

Enumeration members for class 'LabJack.LabJackUD.LJUD+DEVICE':

    UE9
    U3
    U6

So the fix seems to be that I use commands like this - OpenLabJack(LabJack.LabJackUD.LJUD+DEVICE.U6..... but Matlab doesn't recognize '+' as a valid character in the type name!  Argh.  Is there a workaround anyone knows of that uses another way to refer to enumerated types with this library wrapper?

LabJack Support
labjack support's picture
Our UD .NET assembly wasn't

Our UD .NET assembly wasn't changed in regards to enums. We haven't tried the examples in MATLAB 2018a, but they were working in previous versions as you mentioned. Perhaps they changed something causing a syntax change in MATLAB. We don't have a copy of 2018a on hand today to test with, but we could look into this further next week.

One workaround is to use the string version of functions where enums are not used, or overloaded versions where enums are not used. For example OpenLabJackS:

[ljerror, ljhandle] = ljudObj.OpenLabJackS('LJ_dtU6', 'LJ_ctUSB', '', true, 0);

For converting constant name strings to a value, there is the StringToConstant function. Note that the strings are the constant names from the LabJackUD.h header file, which are also documented in the pseudocode sections of the U6 datasheet. For example, the constants used above are mentioned in the open section:

https://labjack.com/support/datasheets/u6/high-level-driver/example-pseu...

eweststrate
Thank you for you help!  I am

Thank you for you help!  I am working through my code, using the string versions of functions as a workaround.  I have now run into a problem where I compared an error code to an enumerated value in the past.  I'll hopefully figure it out, but if you have some idea of how I would work around this, I would appreciate it.

The code here (taken from an example wrapper code section), I compare eNet.LJUDError to an enumerated value, but this use of stringToConstant doesn't work, because eNet.LJUDError is an enumerated type (LJUD+LJUDERROR) (of which I can't refer to anymore because it is apparently nested). 

    while finished == false
        try
            [ljerror, ioType, channel, dblValue, dummyInt, dummyDouble] = ljudObj.GetNextResult(ljhandle, ioType, channel, dblValue, dummyInt, dummyDouble);
        catch e
            if(isa(e, 'NET.NetException'))
                eNet = e.ExceptionObject;
                if(isa(eNet, 'LabJack.LabJackUD.LabJackUDException'))
                    if(eNet.LJUDError == ljudObj.StringToConstant('LJE_NO_MORE_DATA_AVAILABLE'))
                        finished = true;
                    end
                end
            end
            %Report non NO_MORE_DATA_AVAILABLE error.
            if(finished == false)
                throw(e)
            end
        end
    end
 

eweststrate
I figured that one out.  I

I figured that one out.  I convert the values to the underlying integer:

That section now looks like this:

                if(isa(eNet, 'LabJack.LabJackUD.LabJackUDException'))
                    if(double(eNet.LJUDError) == ljudObj.StringToConstant('LJE_NO_MORE_DATA_AVAILABLE'))
                        finished = true;
                    end
                end
 

But now I have another hiccup, converting everything over to the String versions.  Somewhere I remember reading that I need to use eGetPtr when reading arrays:

%Use eGetPtr when reading arrays in 64-bit applications.

[ljerror, numScansRequested] = ljudObj.eGetPtr(ljhandle, ljudObj.StringToConstant('LJ_ioGET_STREAM_DATA'), ljudObj.StringToConstant('LJ_chALL_CHANNELS'), numScansRequested, adblData);

errors out, with MATLAB reporting that "No method 'eGetPtr' with matching signature found for class 'LabJack.LabJackUD.LJUD'."  I think this is because it is expecting the enumerated types as input parameters, not just constant integers. Is there a String version of this function?

LabJack Support
labjack support's picture
I've tried the enums in

I've tried the enums in MATLAB 2018a and have ran into the same issue. Currently I have found no workaround to using enums.

You will want to use eGetPtr as it is 64-bit safe. The UD driver was originally 32-bits only and eGet/ePut/AddRequest functions didn't account for 64-bit pointers when passing arrays, so using those could crash a 64-bit application.

There is no string version of eGetPtr in the UD driver, and no .NET overloads without an enum parameter. We're not adding new functions to the UD driver, but I can look into adding some overloaded .NET methods that don't use the enums so stream mode can be used. I can probably get a prerelease to this topic this week.

If you need code running immediately though, you will want to run MATLAB 2017b or earlier.

 

eweststrate
I've been working with

I've been working with Mathworks Support on this, and I think I have found a workaround for the eGetPtr problem.  You are right, I need it, running a 64-bit app.  I essentially manually instantiate the nested enumerations in MATLAB for this particular call. 

    % Workaround for MATLAB 2018a : 
    t1 = ljasm.AssemblyHandle.GetType('LabJack.LabJackUD.LJUD+IO');
    IOType = t1.GetEnumValues.Get(22); % this is the enumeration for IO.GET_STREAM_DATA
    t2 = ljasm.AssemblyHandle.GetType('LabJack.LabJackUD.LJUD+CHANNEL');
    Channel = t2.GetEnumValues.Get(99); % this is the enumeration for CHANNEL.ALL_CHANNELS
    [ljerror, numScansRequested] = ljudObj.eGetPtr(ljhandle, IOType, Channel, numScansRequested, adblData);
 

LabJack Support
labjack support's picture
Thank you for letting us know

Thank you for letting us know about this. I won't be updating the .NET assembly with the overloads in this case since enums are still accessible. I will look into updating the examples soon.

LabJack Support
labjack support's picture
The MATLAB examples have been

The MATLAB examples have been updated for MATLAB 2018a compatibility.

https://labjack.com/support/software/examples/ud/matlab