09-23-2019 05:53 PM
Hello,
I have a rather large project that controls translation stages, a camera and a laser. I was trying to incorporate a different laser and I run into the following issue.
The laser software is written in .NET and the company game me a list of commands, properties and events I could use to call the functions I need, which are 1) set a rep rate, 2) start the laser, 3) stop the laser.
I achieved 1) without a problem, but as soon as I try to call the laser start method, the laser starts but the VI freezes and I cannot stop the laser (have to manually stop it on the device). Please note that as soon as I stop the laser this way, the VI resumes operations.
I tracked down the issue to the invoke node that is calling the method. I am attaching a screenshot of the highlighted execution.
Before posting, I tried to figure out on my own how to solve this issue. I tried to register for an event (the "laser is running" event), but if the execution is halted, I cannot do much.
It seems to me that the thread running the VI is waiting for the called method to return something and nothing is returned or that the thread is alted for some reason. Is this the case? If yes, is there a way around it?
If my "diagnosis" is wrong, feel free to correct me and suggest alternative routes.
Also, I cannot change the software or the behavior of the .NET assembly.
Thanks,
F.
Solved! Go to Solution.
09-24-2019 08:47 AM
Is the "Start" button also controlling the stop via the Case Structure?
I'd be tempted to do the following to try and narrow down the issue:
09-24-2019 11:07 AM
I followed your advice and removed the case structure.
The attached VI reproduces the issue.
Briefly, I create a construct of ExLaserForm and I set an initial parameter to accept events. Then, I call the initialization method. This method has a 5 minutes warm-up that I can skip if I set another parameter (ThyState) to 1. To be sure, I tried skipping the warm up and waiting the 5 minutes. Same result.
All the other parameters are set in order to start the laser (I can explain if needed). As soon as I get to the "LaserRun", the laser starts to shoot, but the execution stops there.
F.
09-25-2019 03:13 PM
Seems the root cause is that the "LaserRun" method is a blocking synchronous call. LabVIEW won't finish executing the node until the method returns, which it obviously does not. Did you design this assembly? Is there someone you can contact to ask how the API was intended to be used?
Also the class name has the word "Form" in it which is making me think you are trying to instantiate a Windows Form class. This is doable but there are caveats which you might be running into.
If you post the .NET assembly you are using then we could probably find out the internals of that LaserRun call.
09-27-2019 06:23 PM
@tyk007 wrote:
Seems the root cause is that the "LaserRun" method is a blocking synchronous call. LabVIEW won't finish executing the node until the method returns, which it obviously does not. Did you design this assembly? Is there someone you can contact to ask how the API was intended to be used?
Also the class name has the word "Form" in it which is making me think you are trying to instantiate a Windows Form class. This is doable but there are caveats which you might be running into.
If you post the .NET assembly you are using then we could probably find out the internals of that LaserRun call.
Your description of the issue is pretty much what I feared (A method without return).
I did not write this .NET software, it is the software that came with the laser. It is a winform assembly. I cannot distribute the executable (I was calling it an assembly, but it's an exe). I have contacts in the manufacturing company, but they are not going to change the software. When I described them the issue (with plenty of details), all I got back was "Handle the following event EvLaserRunning raised by LaserRun.", which does not solve the issue because even if the event is raised, LabVIEW is still waiting for this method to return.
If no one has a way to go around this, I will turn to electronics and build a trigger using an arduino and bypass entirely this software.
09-27-2019 06:31 PM - edited 09-27-2019 06:32 PM
Have a look at this post that I made a few months ago with a possible solution.
Basically, you would put the one non-returning node in a subVI by itself, then call that VI asynchronously, wait a bit (either timed or by using the event you mentioned), then kill the VI, then move on with your code.
09-27-2019 06:35 PM
This might work. I will test it and see if it solve the issue.
Thanks
10-01-2019 04:21 PM
@Kyle97330 wrote:
Have a look at this post that I made a few months ago with a possible solution.
Basically, you would put the one non-returning node in a subVI by itself, then call that VI asynchronously, wait a bit (either timed or by using the event you mentioned), then kill the VI, then move on with your code.
I tried this approach. It would work well if you have a timed sequence in the asynchronous VI that stops that VI. Unfortunately, that is impossible in my case because any time sequence in the VI I would call would be stuck with the issue I described earlier.
To implement this, I would need to literally kill the asynchronous subVI process from the main VI, which I believe it is not possible.
10-02-2019 03:28 AM
When you start a process asynchronously you should have a reference, so killing it should be possible. Did you manage to register the mentioned event? If that's when the process is finished that's when it should be killed, although a timer should work.
/Y
10-04-2019 01:54 PM - edited 10-04-2019 02:04 PM
@Yamaeda wrote:
When you start a process asynchronously you should have a reference, so killing it should be possible. Did you manage to register the mentioned event? If that's when the process is finished that's when it should be killed, although a timer should work.
/Y
I made the two VIs attached to demonstrate the solution proposed above.
I did not test it yet with my laser, but I think it should work.
Please note that in my application, I require a user or an not-timely-defined event to stop the subvi, hence the mechanism with buttons showed in the code below.
Make sure you change the SubVI path in the MainVI.vi