LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Stopwatch with a dynamic input (boolean)

Solved!
Go to solution

Hello again,

I'm trying to address the same issue as before, but from a different angle.

I have a main VI where I constantly read inputs from a photodetector and a joystick. The idea is that the user interrupts the photodetector, hears two sounds, and then performs a joystick movement within a specific time window (a few milliseconds). If the movement is within the allowed time range, the subject receives a reward; if not, there's a timeout.

In the main VI, I have different cases: to reward, to rest, or to collect data (as you can see in the picture). The problem is with the joystick case. Currently, I'm using Elapsed Time, but I want to store whether the movement was correct or incorrect—and it seems this can't be done with Elapsed Time alone.

So we tried to create a stopwatch to do that and included it in the case. However, the joystick signal doesn't seem to reach the subVI. I’ve tried several things—including queues, notifiers, and property nodes—but I'm new to this and working with someone else’s code, so maybe I’m doing something wrong.

I was wondering if there's another way to measure that time and still keep the desired functionality.

 

P.S. The joystick signal is a boolean, because I'm also checking whether it physically reaches a threshold. That threshold crossing is what indicates a valid movement.

Please let me know if anything comes to mind.

 

Thanks in advance!

Download All
0 Kudos
Message 1 of 13
(351 Views)

Hi pgon,

 


@pgon0006 wrote:

So we tried to create a stopwatch to do that and included it in the case. However, the joystick signal doesn't seem to reach the subVI. I’ve tried several things…


SO you tried to debug your code using probes and breakpoints?

What was the result?

 

  • Can you verify that "signal" using probes?
  • Can you check that subVI (or the statemachine case) is called using breakpoints?
Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 2 of 13
(345 Views)

Hi GerdW,

Yes, I used both probes and breakpoints to debug the code.

I confirmed that the state machine enters the correct state—there’s a boolean indicator I placed there, and I also used highlight execution to follow the flow. The subVI starts its timer as expected, waiting for the joystick signal to begin the countdown. However, even when I move the joystick, the signal doesn’t seem to arrive.

I tried verifying the signal using probes, but the voltage from the joystick appears to freeze once it enters the active state. It doesn’t update or reflect any movement. That’s why I suspect the issue might be related to the while loop inside the subVI—it could be blocking the signal or preventing it from being read properly.

I also tried running the subVI in parallel, but that didn’t solve the issue. Now I’m considering a different approach for the stopwatch, maybe without using a while loop, though I’m not sure how to reset it each time the joystick is latched.

 

0 Kudos
Message 3 of 13
(324 Views)

Having written LabVIEW Projects involving behavioral tasks, I'm a bit confused by the paradigm you are describing, particularly the nature of the "Joystick" input.  In most of the testing routines I've done, all of the "signals" are booleans ("Subject pushed button", "Mouse licked water spout", "Mouse urinated (or pooped) causing a weight change in the balance below") that were either caught by a "Value Changed" Event or were generated by a parallel A/D loop monitoring an analog signal at, say, 100 Hz and generating an Event for the Main Loop (which is typically a Channel Messenger Handler (think QMH with Messenger Channel Wires instead of Queues).

 

You mention that one function of your loop is to "collect data".  What data, other than the position of the Joystick, do you collect?  If the only use you make of the Joystick is "Has it crossed a position threshold?", then using a concurrent loop to generate digital signals (for example, you might want up to 5 signals, "Center", "Forward", "Backward", "Right", "Left" defined according to thresholds placed on the X and Y Joystick position) lets you "Have Your Cake and Eat It, Too".

 

Bob Schor

0 Kudos
Message 4 of 13
(308 Views)

Thanks for the input. Just to clarify: the joystick signal is boolean in the control logic, because we’re checking for threshold crossings — that’s what defines a valid movement. But the signal originates from an analog source, and we retain that data to extract metrics like force, velocity, and movement dynamics. So yes, it’s richer than a simple “moved or not” binary.

The “collect data” case in the state machine isn’t just about logging joystick position — it’s where we store trial type, timestamps for key events (stimulus, movement, reward, error), and outcome flags. That’s why the paradigm isn’t purely categorical. It’s structured to allow both event-driven control and continuous data analysis.

The actual issue isn’t about how the signal is interpreted or whether it should be digital or analog — that part is already handled. The real problem is capturing how long the joystick was moved, regardless of whether it met the reward criteria. As I mentioned earlier, I want to preserve the richness of the behavioral data, not just binary outcomes. The program runs fine without the subVI, but I need that timing captured properly. That’s the part that isn’t working as expected — and that’s what I’m trying to solve.

 
0 Kudos
Message 5 of 13
(301 Views)

You have just clarified the problem that readers of the LabVIEW Forum have when trying to help users with complex problems (such as using an Analog control to provide both analog and digital signals without providing sample code that illustrates the problem you are trying to solve.

 

There is still the case to be made that the Analog Loop (probably) needs to be a parallel loop running asynchronously with the Main routine.  For saving analog data, you set the sampling rate and (usually) acquire multiple samples at a time (i.e. sampling at 1 kHz to get analog data with a time increment of 1 ms).  However, you might not need such high accuracy to specify when the analog signal crosses a "digital" threshold -- you might want to average 10 (or 100) points and use the average (or median, or mode).  So this loop will have two outputs, one a Stream Channel as the Producer for a Producer/Consumer to save (or otherwise "use" the Analog data) and a Messenger Channel to "do what needs to be done" when the Joystick moves "enough".

 

Bob Schor

0 Kudos
Message 6 of 13
(275 Views)

Thanks, Bob.

Glad the issue is finally clear — I was under the impression I’d already described it in detail, but I appreciate the reiteration.

I understand that not everyone can help based solely on a description, and that’s part of the challenge when posting here (often the replies are also conceptual).  But in this case the problem is quite specific: capturing movement duration within a case structure. The rest of the system — signal handling, control logic, data logging — is already functioning as intended.

If you happen to know a clean alternative to Elapsed Time for that kind of timing — preferably without relying on while loops — I’d be happy to hear it. Otherwise, I’ll keep digging.

Thanks again. 😊

0 Kudos
Message 7 of 13
(268 Views)

If you want us to analyze your code, you need to attach both the main and the subVI.

 

There is a lot of "code smell", for example you failed to make you state enum a typedef and thus at least one of them is different and only has three items. Do you see the coercion dot? This is not maintainable!

 

altenbach_0-1757082452230.png

 

If you make your boolean output tunnels to "use default if unwired", All you need is one single boolean true constant!

 

I can't see any reasonable logic in your subVI. It seems to reset with every call and could stall the main VI for long times. Also, please don't maximize the diagram to the screen.

0 Kudos
Message 8 of 13
(262 Views)
Solution
Accepted by topic author pgon0006

Yes, the subVI resets with each trial, and that’s intentional. Each trial the timing logic needs to restart accordingly. It’s not a flaw, it’s how the task is structured.The issue you pointed out is valid, and I’ve corrected it, but unfortunately it didn’t resolve the behavior I’m trying to fix.

 

Also, a single boolean constant wouldn’t work here — the system needs to reset the timing each time the joystick returns to False, similar to how Elapsed Time behaves. That’s why the logic has to be dynamic, not static.

 

I tried to include as much context as possible to avoid confusion, but the question itself is pretty simple: I’m using Elapsed Time successfully in the main VI, and I just need a way to retain the final value before it resets. didn’t expect it to generate so much confusion 😅

Thanks again, if I find a clean solution, I’ll post it here so it’s clear for anyone facing a similar issue. I actually found a screenshot that shows exactly what I need (quite simple, right?) ; now I just have to figure out how to implement it without a while loop, or possibly integrate it into the main VI’s loop.

 

Thanks!

Download All
0 Kudos
Message 9 of 13
(246 Views)

@pgon0006 wrote:

Also, a single boolean constant wouldn’t work here — the system needs to reset the timing each time the joystick returns to False, similar to how Elapsed Time behaves. That’s why the logic has to be dynamic, not static.


You have several TRUE and FALSE boolean constants scattered all over the inside of the many cases. All you need is a single boolean TRUE  constant before the case, wired to all places where a TRUE is needed inside. All FALSE constant can be deleted once you set the tunnels to "use default if unwired".

 

altenbach_0-1757087131478.png

 

 

Also, if you swap the inputs to the select nodes, you can eliminate the NOT.

 

I also don't understand the need for the 3 second wait at the end. Shouldn't the caller deal with the result?

 

Since the "lever" is an input to the subVI, how is it supposed to change later? Since this will be a hardware IO, you probably need to poll it.

0 Kudos
Message 10 of 13
(226 Views)