LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

VISA Shared resources.

I have two timers that may try to share a VISA Read (Also a DAQ read too).

 

Timer1 is a standard timer that executes every 100mS. This timer executes states from a statemachine. There is one state that does a VISA read/write and one that does a DAQ read.

 

Timer2 is an async timer that executes every second. This timer does a VISA read/write and DAQ read every second.

 

The contents of these timers used to be in Timer1 only so there was no resource concern, however, the VISA read/write and the DAQ Read can exceed 100 mS in duration so I want to separate them.

 

How can I prevent the timers from accessing the resources at the same time?

Can some sort of queuing be used for Timer2 so that the 100mS timer is not blocked?

 

Thanks.

0 Kudos
Message 1 of 9
(4,068 Views)

There is no way of queueing DAQ and VISA operations. I suggest you use locks instead to avoid contemporanous access to shared resources. Locks can be found in the utility library: with CmtCreateLock you create a lock which you can use in your timers to handle resource access; every function should use CmtGetLock to gain the property of the lock: if the lock is already owned by the other function, the function will wait until it is free. After executing DAQ or VISA calls, the function must release the lock with CmtReleaseLock.

Do not forget to disposte the lock you created when you more need it (at least at the end of the program).



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 9
(4,057 Views)
A little addition to my earlier post: a cleaner way of developing the timer functions could be to use CmtTryToGetLock function instead of simply asking for the lock. If a lock ownership cannot be obtained the function returns immediately and you can exit from the timer doing nothing, trying to access the lock in the following timer scan. Especially the 1-sec timer function could benefit from this if you develop it with a faster timer (say 200 msec) with a counter that executes the operative code only at some counts (every 5 counts in the example). If the lock cannot be obtained in one scan you can exit from the function without leaving it freezed waiting for it, and retry in the next time slice.


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 9
(4,049 Views)

Hi Roberto.

 

I am unclear on the NewAsyncTimer() call I am using (Timer2).

Since I did not create a new thread I assume it is using the same thread as the main() which means that both timers are actually using this same thread?

If this is the case then the only gain I am getting with the async timer is more accurate time periods. Since the 1 Sec timer (asynctimer) is low priority (just updates panel displays) it can be a normal timer similar to Timer1.

 

I recently added a VisaBusy flag that I set before the VISA read/writes and clear after the VISA read/writes and similar flag for the DAQ. In the 1 Second timer I just leave if it it busy as it is a low priority and miss a turn. The 100mSec timer cannot miss a turn so the statemachine will renter the state and try again.

 

The CmtTryToGetLock() looks like a more CVI robust way to do it.

To use this is all I need to do is:

1. Create a lock

2. Get the lock if free

3. Relese lock

4. Discard lock

 

See code.c

 

Thanks.

0 Kudos
Message 4 of 9
(4,043 Views)
Forgot the code.
0 Kudos
Message 5 of 9
(4,042 Views)

The Asyncronous timers run in a separate thread (one thread for all async timers created), without the need for you to create the thread. They do not run in the main thread (the one into which runs your main () function and all other functions not specifically assigned to other threads). Moreover, to guarantee the best possible regularity, they are built on top of multimedia timers, which are normally used by the OS to execute video / audio tasks like playing a song or viewing a clip. "The best possible regularity" does not mean an absolute warranty that no events are lost (it will be happened to you on some occasion to have a song reprouced with jumps or jerks due to other activities you are performing on the PC...), nevertheless async timers are robust and quite regular.

 

Having said that, I personally would have used an async timer for the 100 msec task (which you say should not miss any event) leaving the 1 sec task to an ordinary timer to avoid overcharging the async timer thread.

 

The sequence of using locks is correct, provided you do not create and discard a lock every time you need it (that is: step 1 is executed at program start, step 4 at program end, the timer callbacks contue to run through steps 3 and 4).



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 6 of 9
(4,040 Views)

Hi Roberto.

 

I will swap the thread types.

My statemachine repeats states until set conditions are met so if the 1 second timer is controlling the lock when 0.1sec timer requests it it will get it the next time around.

 

Thanks.

0 Kudos
Message 7 of 9
(4,012 Views)

Hello,

 

I see the 2009 date, but ...

I use CVI (and LabVIEW) since 1997.

Now I use CVI 2013 SP2 one.

 

I have the same problem : 2 functions VISA (Read and Write), on the same ressource.

I want to protect the access to the ressource VISA with the lock functions.

Like you propose and also the "ThreadLockTimeout" NI example.

 

So only at the beginning of the software, I do step 1 : cmtStatus = CmtNewLock ("", 0, &LockHandleRS), add before that, to a free handle in case of...

Only at the end, step 4 : cmtStatus = CmtDiscardLock (LockHandleRS), add to a "LockHandleRS = 0".

 

In each read and the write VISA function (20 ms < time < 100 ms, timeOut =2 s),

I try to use different methodes, without success :

- to lock (step 2) :

     1) cmtStatus = CmtGetLock (LockHandleRS)

     2) cmtStatus = CmtTryToGetLock (LockHandleRS, &lock), add to a while loop (for timeOut)

     3) cmtStatus = CmtGetLockEx (LockHandleRS, 0, timeOut, &lock)

     4) and even, statusRS = viLock (portVISA, VI_EXCLUSIVE_LOCK, timeOut, VI_NULL, VI_NULL)

- the VISA read/write function :

     "viWrite" for the ask, following by a "viRead" for the answer

     (VISA read function (# measure) : for only an acknowledge echo traitment and read data reponse)

     (VISA write function (# order) : for only an acknowledge echo traitment)

- to unlock (if lock successfull) (step 3)

     1)2)3) cmtStatus = CmtReleaseLock (LockHandleRS)

     4) statusRS = viUnlock (portVISA)

 

I display every wrong "cmtStatus" and "statusRS", but nothing appears.

 

The VISA read function is called following an "EveryNCallback" DAQmx function (every 0.5 s).

The VISA write function is called punctually, by an operator action throught various interfaces.

 

If I use only the periodic VISA read function, no problem on lock/unlock.

N.B. : Lock function (step 2) take only # 100 µs (for case 2) : at the 1rst iteration).

N.B. : I use the same external lock/unlock functions for the VISA read/write.

 

But nearly at every VISA write asking (3 on 5), I can display 2 consecutive successfull locks function (VISA read and write) ???

N.B. : same time (100 µs).

Following, of course, to 2 unlock functions (step 3).

And every time, the echo of the VISA read function is treat by the VISA write function.

And the echo of the VISA read traitment is truncked.

So for me, I treat it like 2 VISA errors (read/write).

 

Have you any idea ?

 

In advance, thank a lot for your help.

 


Certified LabWindows/CVI DEVELOPER (2004)
LabVIEW since 5.01 | LabWindows/CVI since 4.01
0 Kudos
Message 8 of 9
(3,378 Views)

Hello,

 

I try to improve the NI example to show my problem.

I hope that I do not make some big mistakes, which cancelled this example.

 

Into this small code lines, I can reproduce my problem (by quick applies on F1 button).

I do not implimente all the fonctions I try.

 

Into a bigger one, it is very easy to reproduce (even with the other functions).

 

Thanks a lot for consideration.

 

 


Certified LabWindows/CVI DEVELOPER (2004)
LabVIEW since 5.01 | LabWindows/CVI since 4.01
0 Kudos
Message 9 of 9
(3,363 Views)