Jump to content

As of July 17, 2015, the LabJack forums here at forums.labjack.com are shut down. New registrations, topics, and replies are disabled. All forums are in a read-only state for archive purposes.

Please visit our current forums at labjack.com/forums to view and make new posts. To post on the current forums, use your labjack.com login account. Your old LabJack forums login credentials have been retired. There are no longer separate logins for labjack.com and LabJack forums.


Photo

LabVIEW and Command/Response Mode


  • Please log in to reply
9 replies to this topic

#1 nickbike

nickbike
  • Members
  • 5 posts

Posted 21 January 2014 - 12:19 PM

Hello LabJack Forum,

    I've searched around and can't find anyone else having the same problem in LabVIEW. I think I know where the problem exists and wanted to bring it up for discussion.

   In LabVIEW any thread-unsafe DLLs must be executed in the User Interface Thread. Looking at Section 4.1.2, MultiThreaded Operation, of the U6 user guide it says "This driver is completely thread safe. With some very minor exceptions, all these functions can be called from multiple threads at the same time and the driver will keep everything straight. Because of this Add, Go, and Get must be called from the same thread for a particular set of requests/results."   

    In LabVIEW you either have the choice of making the DLL call execute in the User Interface thread or ANY thread.

    Unfortunately the Command/Response mode uses the Add,Go,Get functions that are not thread-safe so they have to execture in the User Interface Thread. That means in LabVIEW when I'm using Command/Response mode my loop rates (and DAQ rate) are all over the place depending on how tied up the user interface is responding to user inputs.

    I think I can move to stream mode with my U6 in my appplication to take advantage of the hardware timing so I won't be tied to using software timing for my DAQ rate. The reason I wasn't using stream mode to get hardware timing already is because I wanted to use the internal CJC sensor.

   Is there any chance a completely thread-safe driver is on the way so I can run my U6 in command/response mode without being tied to user interface events?

 



#2 Tom Lawton

Tom Lawton
  • Members
  • 14 posts

Posted 21 January 2014 - 12:51 PM

If timing really is critical, I'd never rely on command-response... What data rate are you after?

 

How about stream mode with the add-a-CJC sensor option detailed at https://forums.labja...ic=6330&p=21230 ?



#3 nickbike

nickbike
  • Members
  • 5 posts

Posted 21 January 2014 - 04:28 PM

Tom,

        I'm after at least 10Hz and would like the option to go more down the road. I know 10Hz sounds slow for Command/Response mode, but I can grab a corner of a LabVIEW window as if to resize it and drag it back and forth several times and the DAQ loop will stall for the entire time. Effectively giving me a loop rates as long as I keep dragging the corner around, on the order of multiple seconds.  

 

I am planning on implementing exactly what you said. A short TC mounted right on the junctions of my CB37. And then use stream mode.  



#4 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 21 January 2014 - 05:22 PM

I'm not perfectly familiar with how LabView manages threading internally, however I can explain more about how it works from the LabJackUD standpoint.

 

Basically, if the Add/Go/Get calls are all made from a thread with the same ID, things will work fine.  You can think of it as each Thread ID having its own queue of requests that are processed.  In older versions of LabView I know this works fine by running them outside the GUI thread.  I'd imagine the VI itself has some thread that runs it and that thread is the one making the calls.  It might be the same with the "any" function of newer versions. 

In the LabJackUD library there is a utility function to help with this,

unsigned long GetThreadID(void);

This function will return the ID of the thread calling it.  If you have a complex setup with multiple .VIs in LabView that are making the Add/Go/Get calls you can put that function in where those calls will be made and have them run outside the GUI thread.  If they all return the same thread ID than however LabView is managing threads internally should be fine.

 

Another option, is to use the

LJ_ERROR eAddGoGet(LJ_HANDLE Handle, long NumRequests, long *aIOTypes, long *aChannels, double *aValues, long *ax1s, long *aRequestErrors, long *GoError, long *aResultErrors);

Which is explained in more detail here.  That function takes arrays containing the requests, executes them and returns the results.  It all happens in a single call, so will happen all in the same thread no matter what thread is calling it.



#5 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 21 January 2014 - 05:31 PM

Add-Go-Get is thread-safe.  The problem in LabVIEW is that if you have different VIs both calling AddRequest in the UI thread, they are in the same thread so if they call AddRequest at the same time those requests can get mingled together in the same request list.

 

One quick suggestion is to use eGet, eAIN, or eAddGoGet (not "AddS-Go-Get.vi").  These 3 are a single driver call so you will not get the AddRequest mingling that is of concern in Section 4.1.2.

 

 

I don't see a short TC on the CB37 doing anything.  It will be the same temperature as the CB37 so will always read 0.0 volts.  I suggest a silicon type temperature sensor such as the LM34CAZ:

 

http://labjack.com/s...s/thermocouples

 

Note that on the T7 we put a buffer on the internal temp sensor so it can be read in stream mode.



#6 nickbike

nickbike
  • Members
  • 5 posts

Posted 21 January 2014 - 09:26 PM

Add-Go-Get is thread-safe.  The problem in LabVIEW is that if you have different VIs both calling AddRequest in the UI thread, they are in the same thread so if they call AddRequest at the same time those requests can get mingled together in the same request list.

 

One quick suggestion is to use eGet, eAIN, or eAddGoGet (not "AddS-Go-Get.vi").  These 3 are a single driver call so you will not get the AddRequest mingling that is of concern in Section 4.1.2.

 

 

 

I'm working on using eAddGoGet in LabVIEW. I'm having a hard time passing it the correct IOtypes as signed long integers instead of the strings that AddS-Go-Get uses. In general, I'm having a hard time finding what IOtypes match which integer anywhere on the LabJack website.

 

Attached is an image of a simple VI that uses eAddGoGet. I ran this VI in a FOR loop passing it a different number for IOtype until I got a reading that made sense. If I put 10 in as the IOtype, then I get the correct voltage reading on AIN0. So what gives? Why 10? If I search for IOtype=10 on the LabJack website all I can find is that it means BitStateRead on the U3. I also have digital reads and writes that I need to do, so I would like to know what IOtype numbers I need to use.

 

 

I don't see a short TC on the CB37 doing anything.  It will be the same temperature as the CB37 so will always read 0.0 volts.  I suggest a silicon type temperature sensor such as the LM34CAZ:

 

Good point, I'm not sure what I was thinking. That's why I'm attempting to work with the eAddGoGet as stated above.

 

Even if I got a silicon temperature sensor I'm having a hard time getting the streaming to work with the MUX80 and differential channels. But that's a different topic and the Command/Response method is closer to working. And I need a quick solution.  

Attached Thumbnails

  • Single Channel eAddGoGet.jpg


#7 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 22 January 2014 - 08:24 AM

You can find the constants in the header file LabJackUD.h, but it is better to use the StringToConstant function to convert the strings to integers.  I will work on an example.



#8 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 22 January 2014 - 08:32 AM

Attached is "U6 Multiple AIN Example.vi" converted to use eAddGoGet.

Attached Files



#9 nickbike

nickbike
  • Members
  • 5 posts

Posted 22 January 2014 - 08:39 AM

You can find the constants in the header file LabJackUD.h, but it is better to use the StringToConstant function to convert the strings to integers.  I will work on an example.

 

I did get this working after finding the StringToConstant function on the LabVIEW palette. See attached image. I pass this VI a "Handle In" and call it repeatedly in a loop. Even after setting the DLL calls for "StringtoConstant" and "eAddGoGet" to "Run in Any Thread" I still get massive loop Jitter when I resize the front panel. I'll continue to work on the LabVIEW side of it. Thanks for the assistance on getting the LabJack part working.

Attached Thumbnails

  • Read All Data eAddGoGet.jpg


#10 nickbike

nickbike
  • Members
  • 5 posts

Posted 22 January 2014 - 09:18 AM

OK figured it out! It was exactly what I suspected in that the LabJack UD driver DLL is set to run in the LabVIEW UI thread. As mentioned before I was using "StringtoConstant" and "eAddGoGet" in a loop. Even after changing those to "Run in Any Thread" I was still having loop jitter when I resized the front panel. What I failed to notice that I was also using the "TCVoltsToTemp" from the LabJack UD driver DLL. I changed that to "Run in Any Thread" and it worked like magic.

 

See the linked video. The loop is running at the start of the video and you can see me resizing the window. Then I stop the loop and all the data is plotted. You'll see a loop time hit about 1.1 seconds. Then I change the execution thread of the "TCVoltsToTemp" Code Interface Node (CIN). You'll notice the CIN turns from orange to light yellow. Then I run the loop again, resize the front panel and get loop rates on the order of 30-35ms.

 

http://www.youtube.c...eature=youtu.be

 

I hope this can be of help to someone else.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users