02-16-2011 03:04 PM
@Vasilich2004 wrote:
I would prefer to create structure with serial port and semaphore instead of your second VI.
I'm not sure what you mean by that, but you should note that using the second piece of code to manage the semaphores is a lot safer (and as you can see, is a pretty simple piece of code). If you don't use it, you'll probably run into problems and bugs at some point.
07-18-2011 04:54 PM
I modified the program and I used cluster (structure) consists of SerialPort handle and SerialPort semaphore. At start program connects to serial port, creates semaphore, and creates a cluster. Then the cluster is used as input of each vi and each vi acquires semaphore, uses serial port, and releases semaphore.
So far so good ... but I was asked some special actions and met issue with semaphore again. Program can't acquire semaphore twice!
For example, in simple motion I use "Move" VI which consists of "Start" and "Wait" VIs. At the same time, I use "Start" and "Wait" VIs themself in compex motion where I need to make other actions during motion. If program would acquire semaphores in "Move" and "Start"/"Wait" VIs (twice!) then program hangs when try to acquire semaphore second time. I suppse that is due LabVIEW's feature which is "Move" and "Start"/"Wait" VIs can work in different theads.
To avoid that I added bool "Acition" into the cluster. "Start" VI acquires semaphore, sets Action = Yes which will show any VI that device is moving, and release the semaphore. In "Wait" VI waits that the motion finished, acquires semaphore, and sets Action = No.
That should work but if the program will calls "Wait" in another line then I will have trouble.
I am wondering is another way in LabVIEW to implement this?
07-19-2011 01:23 AM
Here are two basic options:
If you want to make this more complicated, you can use a class, which will allow you to hold more information about your object and will allow you to create a set of public and private VIs, which means people who want to use your VIs can't make a mistake because they can't call the private VIs. The public VIs will get the DVR as the input and inside you will unlock the DVR and do whatever actions you want.
07-19-2011 11:52 AM
============
2. If you need to have several actions done one after the other, then you need another lock at a higher level.
============
This is good suggestion but it doesn't work in my case. I need something like that
=======
Mutex MutexObject = new Mutex();
void Action( ActionType oActionType){
switch( oActionType){
case ActionType.FancyMotion:
StartMotion();
MakeSomething();
WaitMotionFinish();
break;
case ActionType.SimpleMotion:
Move();
break;
}
void Move(){
MutexObject .Lock();
StartMotion();
WaitMotionFinish();
MutexObject.Unlock();
}
void StartMotion(){
MutexObject.Lock();
//check Is finish in loop
MutexObject.Unlock();
}
void WaitMotionFinish(){
MutexObject.Lock();
//start motion
MutexObject.Unlock();
}
In usual language Mutex can be locked multiply times by same thread. Of course, it must be unlocked the same times as was locked.
07-21-2011 02:57 AM
If I understand that correctly, you're using a form of locking which allows code in the same thread which locked the mutex to also lock it again and access it. This seems to work based on the assumption that the code is linear and will behave predictably. LV doesn't have something similar because you don't have explicit control of threads and because the code is parallel, not linear.
However, as I said, if you create a public API which only uses the DVR and a private API which uses the object itself, you should be getting essentially the same thing, except you will need a wrapper method for every private API method which you want to include in the public API (StartMotion, in your example). I don't particularly like it either, but that's what there is. You can find all kinds of discussions on the topic online. Particularly in the OOP forum in the LAVA forums.