Conditional parallelism on LabVIEW - labview

I am writing an application to update the numeric value given user's input value and depending on the user's input value the program checks if it is greater than 10 if it is greater than 10 then the program waits for 1 second and then will have a popup message says "true".
My intention was to call the conditional check, printing true every one second if the user's input value is greater than 10; in other words, the case structure was to be called regardless of the event structure in the same loop infinitely.
But it doesn't seem to work the way I expected. Unless there is user's new input value, getting into the event structure, the program doesn't get to the case structure even though the case structure is in a loop.
Is there any way to call the case structure not dependent to the event structure but I want to use a shift register for the numerical value and also having an event structure and a case structure in parallel.
Thanks.

You've created an Event Structure that handles the Value Change input for your numeric control, so that will do exactly what it says: wait for a Value Change event to happen. When that event is received, the code in its Event Structure frame will execute and then the Event Structure will exit.
It looks as if you've wired a value from the shift register to the timeout terminal of the Event Structure, so I assume you must also have created a Timeout event case? If so, the event structure should stop waiting after the number of milliseconds wired to the timeout terminal.
The value you check in order to decide whether to show your true message is the value that was passed in to the shift register on the previous loop iteration. If the control value changes, that comes from the NewVal terminal in the Value Changed event case. But where does it come from in the timeout case? It looks to me as if you haven't wired it in that case, because the terminal coming out of the event structure has a little dot in it instead of being solid orange. That means you will get a default value for any case where the terminal wasn't wired. The default value for numerics is zero. So if the event structure times out, the value going in to the shift register is zero, you get zero out of the shift register on the next iteration, zero is not greater than 10, so you don't see the message again.
I don't understand what you're trying to do in the event case where you've wired the NewVal terminal to a Value property node of the same control. Can you explain what that is supposed to achieve?
Your question reads as if this is a programming exercise where you have to use these specific LabVIEW structures, so rather than suggest better ways of achieving what you say you want this code to do, I'll leave it to you to decide how to change it. In the meantime though I do recommend re-reading the Event Structure help and the caveats and recommendations it links to.

Related

Seeking suggestion to count time inside the loop

I am trying to measure/count the time inside the while loop, I tried a couple of methods but couldn't find the solution yet.
Here is my current VI.
 
In short, I am trying to measure the time as long as the "Boolean is on/true" and once it's off/false the time must be displayed.
If something is not clear then please let me know.
I may be repeating Fourier's answer, but typing it in two different forms may be helpful to you since I note you haven't accepted that answer yet.
Remove the outer While Loop. It is superfluous.
Then do this:
In the "turn on" frame, you gather the current Tick Count and stash it in a shift register. In the "turn off" frame, you gather the Tick Count again and subtract. In all the other frames, make sure you wire the two tunnels together so you don't lose your Tick Count. Side note: you probably want Boolean to be an indicator, not a control, so your user cannot click on it and toggle it directly.
You can reach your goal with simpler code. You should use one while loop only with the Event Structure:
When List of Conditions changes, intercept the event (as you are already doing) and register the time when this event happen (with the VI Tick count for example).
in two shift registers,"save" the time you registers in the previous point and the status of your count (a boolean should be enough: counting/not counting).
Then, in the Timeout event you calculate in real time the time passed with the following operation current time (Vi Tick count) - event time (save in the shift register).
You should count time only if your boolean Counting/not counting is True.
When you detect another event List of Conditions Value Change, you should check if you should stop count time or not.
Finally, in the Timeout event or in the List of Conditions Value change event, evaluate the stop condition for your while loop.

How to ask user to snap on a vertex of a line element (in the ILocateCommandEvents_Accept handler) of Microstation VBA

I know how to write a VBA macro in Microstation that will ask the user to select an element:
Sub Create2DCrossLines()
' Set error handler
On Error GoTo ErrorHandler
' Let the user select the bank elements himself
Call CommandState.StartLocate(New clsSelectBanksLCE)
Exit Sub
ErrorHandler:
Call ReportError("Create2dCrossLines")
End Sub
clsSelectBanksLCE uses ILocateCommandEvents for managing that part of the logic. So the user can select a LineElement for example and when the Accept event is fired it runs an action:
Private Sub ILocateCommandEvents_Accept(ByVal Element As Element, _
Point As Point3d, _
ByVal View As View)
In my particular case we track selecting element 1 and then element 2 and once both elements are selected it proceeds. This is all fine.
My problem is this: after I accept the first element, and before proceeding to select the next (ie: in the Accept handler) I want to get the user to snap on to two vertices of the line element.
I need to know which part of the line element they want to process. I can't work out how to do this. In AutoCAD you can use GetPoint.
So I want to ask them to snap on to the first vertex on this line element, then snap onto the end vertex. After this can we move on to select the second element.
Update
I have just stumbled over this article. I notice it says:
Once the user has accepted an element, we should start another class that implements IPrimitiveCommandEvents to obtain a target datapoint. Finally, compute the offset from the supplied locate datapoint to the target datapoint and move the element.
It seems what I want but I just am not clear on the right order. At the moment I have:
ILocateCommandEvents_Start This begins the location process.
ILocateCommandEvents_LocateFilter. If the element is a LineElement, then it
assigns m_Element1 and the second event fired assigns m_Element2.
ILocateCommandEvents_Accept If both the variables are not nothing it runs the main process.
See my dilemma? It sounds like I need to:
Run one instance of ILocateCommandEvents to select one element only.
Then run one instance of IPrimitiveCommandEvents to get the first snap point.
Then run another instance of IPrimitiveCommandEvents to get the second snap point.
Then run another instance of ILocateCommandEvents to get the second element.
Finally, once the second element is accepted, perform my processing.
That is how I understand I need to do it. Or, can I use my one ILocateCommandEvents class that currently gets the user to choose two elements?
Guidance appreciated.
Update
I got it to work by following the above logic. That article really helped. The only issue I have now is that I need to draw a rubber band. But that is a separate question.
As mentioned in this article:
Once the user has accepted an element, we should start another class that implements IPrimitiveCommandEvents to obtain a target datapoint. Finally, compute the offset from the supplied locate datapoint to the target datapoint and move the element.
The link also provides example code on how to use the IPrimitiveCommandEvents event class.

Variable's value doesn't change in coffeescript when using onclick

I have the following Coffeescript code:
for name, data of statistics
row = document.createElement 'tr'
row.onclick = ->
alert name
However, when I compile and run it (in the context of a large webpage), it alerts the same name, no matter what row I click on. It seems to be remembering the variable, as if it's constant.
What am I doing wrong?
EDIT:
I've discovered the issue, but I'm not sure how to go about fixing it: Javascript/Coffeescript does not evaluate the 'name' variable until the end of the loop is reached.
The functions that you are defining (and assigning to the row's onclick attribute) all have access to the same variable outside that function (name). At the end of the loop, name has one value (the last item in the loop, as you mention), so each of the onclick functions alerts that value.
You can fix this by binding 'name' to a value that doesn't change. This question presents one solution. This question has some useful background that's worth reading.

Timing a simulation in a control loop

I have a labview vi which is in a control loop with PID . I want to insert a timer for the simulation. It should display the time of the simulation and also use that time to make changes in the control loop.
It is just a simple timer but I am not sure which one and how to use them. please help me
The simplest option, if it does what you need, is probably the 'Elapsed Time' Express VI.
Alternatively you can use the Get Date/Time in Seconds function. Read this function at the start of your simulation and pass the value in to your control loop (or read it on the first loop iteration and store the value in a shift register). Inside the loop, read the same function and subtract the value from the start value; that'll give you the elapsed time in seconds. If you want a display of this value just wire it to a numeric indicator. You can set the display format of the indicator to 'relative time' if you want to show hours, minutes and seconds.
The most natural option would be to use a Timed-loop, this allows you to detect whether your code can run in the supplied time and select a hardware time clock.

Display time left when running

I have a form with a few buttons which execute code when pressed like running validations on the database.
Some code can run for a few minutes so is there any way to show the time remaining or a message to display the % of process completed?
Or pop out a message when code evaluation starts and the message should disappear once code running is completed?
What you are probably looking for is a "Progress Bar".
I've used the Microsoft ProgressBar control (you can find it under Insert->ActiveX Control), and it's not that hard to use. Just set the value of it to a percentage (as an integer, not a decimal).
'foo, being the ProgressBar
me.foo = 70 '70%
There is some good info here on another method: http://www.granite.ab.ca/access/progressbar.htm
In order to do this the "normal" way, you'd need to run your validation in another thread and have it report its progress back to the UI thread. However, I don't believe VBA supports any kind of multithreading.
If your validation routines involve a loop, or even just many separate discrete operations, you can try inserting a DoEvents statement in between loop iterations (or operations), and then have your progress display updated periodically (say, in an Application_OnTime event handler).
I usually have a form I name frmProgress or whatever, with a cancel button and a label for displaying a status message. Then embedded in the form code I have a boolean called bCancel, and when you hit the cancel button it simply sets bCancel as true.
Also in this code I have a routine called ShowPercDone( Idx , NumIdc ) where Idx is the step the code is on, and NumIdc is the number of steps the code will take (assuming each step takes the same amount of time). This works well when I'm running through a for loop, but basically any time I want to display a status update I just call the routine in the form with my message, which I should add runs the doevents command for me.
So that's how the status form works. In the macro I run, I start out by just calling frmProgress.show (0) so that it lets you click the cancel button. Then in my loop when I update the status message I then check frmProgress.bCancel and if it's true I exit out of the macro.
Hope that helps.
Finally to be simple i decided to use the method given here
http://oreilly.com/pub/h/3330#code