04-13-2017 11:28 AM - edited 04-13-2017 11:29 AM
@cbutcher wrote:
Like Matt J said, you should use an event structure to capture the 'Key Down' event, and then you can compare the output to 'z' (or another key, if this is just an example).
The Key Down event can be found under 'This VI' > 'Key' in the Event Structure. You can map a key code to it's ASCII string representation using a 'To U8' and 'Type Cast' node pair. A simple example snippet is shown below (this only runs once and then exits, but you can wire indicators to the other outputs or place the structure in a loop if you want to try multiple key presses.
Edit: To be clear, if you want to compare to 'z', compare the Char value with the numeric representation (i.e. 44). Don't cast it to a string and then check it. You can use a case structure with multiple valid results for the same case if you want to allow both 'z' and 'Z' for example.
I have modified the code according to your suggestions. Still I have the same problem. One push and both function together. Also right now it's supposed to work with "Z" button, but it works with any button. I have no idea how to fix this one
04-13-2017 11:36 AM
@cbutcher wrote:
You can place two event structures with a dataflow dependency, or you can use a loop and check the iteration indicator to see which iteration you're running. Be careful with the iteration indicator if you have other (non-exit) cases - if you press 'z', the first case triggers, then you press 'a' and the event structure detects a 'Key Down' event, then ignores it because the key wasn't 'z', the iteration value if you then press 'z' won't be 1, it will be 2.
If you only have two cases, and you know you don't want to expand it in future, then you could consider a boolean on a shift register or similar (or, a state machine!)
I modified the code based on your suggestions. However two are working with one button push. You push "Z" button once and it will lunches them both.
04-13-2017 12:07 PM
Here's a conversion of cbutcher's VI in LabVIEW 2014.
- Robert
04-13-2017 07:12 PM
@Robert__R wrote:
Here's a conversion of cbutcher's VI in LabVIEW 2014.
- Robert
Thanks for the conversion.
I have modified the code according to your suggestions. Still I have the same problem. One push and both function together. Also right now it's supposed to work with "Z" button, but it works with any button.
Yeah, so firstly, I was wrong about using two event structures. Sorry!
Secondly, 44 isn't the character code for z - I'm not sure why that came out when I was testing earlier (perhaps I got confused and posted the scan code). More to the point though - the reason it is accepting any key is that you don't test which key - your boolean output from the comparison isn't wired to anything. Use a Case Structure.
Hopefully you can open the VI that Robert kindly resaved to 2014 now and see what I mean. The VI I uploaded seemed to work as you wanted, at least for me.
04-13-2017 08:04 PM
@Robert__R wrote:
Here's a conversion of cbutcher's VI in LabVIEW 2014.
- Robert
Thank you very much Robert. I guess I am lacking a solid understanding of case structures. I've been working on this code for two days now. For now, I have copied the code, and I will next apply this code on the main project and see how it goes. Thanks for the conversion again.
04-13-2017 08:07 PM
@cbutcher wrote:
@Robert__R wrote:
Here's a conversion of cbutcher's VI in LabVIEW 2014.
- Robert
Thanks for the conversion.
I have modified the code according to your suggestions. Still I have the same problem. One push and both function together. Also right now it's supposed to work with "Z" button, but it works with any button.
Yeah, so firstly, I was wrong about using two event structures. Sorry!
Secondly, 44 isn't the character code for z - I'm not sure why that came out when I was testing earlier (perhaps I got confused and posted the scan code). More to the point though - the reason it is accepting any key is that you don't test which key - your boolean output from the comparison isn't wired to anything. Use a Case Structure.
Hopefully you can open the VI that Robert kindly resaved to 2014 now and see what I mean. The VI I uploaded seemed to work as you wanted, at least for me.
Hi cbutcher!
Thank you for your code. I guess I don't knwo how case structures work. I need to learn that. For now your code seems to work for this example. I'll see if it works for my main program or not. Thank you again.
Sina
04-13-2017 08:33 PM
A case structure will run once each time it is reached on the block diagram (so in the VI I uploaded, once per time that event structure receives the 'Key Down' event).
It has multiple 'cases', or options of what code to run when it executes. Which code runs depends on what is wired to the selector, the question mark on the left hand side of the structure. The bar at the top of the case structure gives the value that case is matched to - in my VI there are two cases. The first is '122' and the other is 'Default' (please note that these are literal, not enclosed in ' marks. A string would be shown as "MyCase" and I would write it here as ' "MyCase" ' to try and make it clearer).
Default is always available to case structures, and is the case run when no other case matches. Depending on what you wire to the selector, it may or may not be a required case. For example, if you wire an 'enum' to the case selector, or a boolean, then the list of possible values is known. This allows you to right click the structure and select 'Create case for each value' or something similar (I forgot the exact text). In this case, no 'Default' case is required, but you can still optionally use one if you wish. Compare this with wiring a string. With a string, the list of possible values can't be known, counted or enumerated. Consequently, the 'Default' case is a requirement - you must make one of the cases include the term 'Default' in the top bar. This can be one of the other cases if you want.
For numeric types, you can give every value, but it would take a very long time to do that! However, you can instead write something like '...0' as your case, in which case it will be read as "all values below and including 0".
Case Structures are a very useful and quite simple tool in the LabVIEW toolbox. You should definitely learn about them - they are almost required for any kind of conditional programming. Another common use is to wrap around all of your code (especially in a subVI) and wire the 'Error In' control to the selector - then you automatically get two cases, 'Error' and 'No Error'.
05-02-2017 12:49 PM
@cbutcher wrote:
A case structure will run once each time it is reached on the block diagram (so in the VI I uploaded, once per time that event structure receives the 'Key Down' event).
It has multiple 'cases', or options of what code to run when it executes. Which code runs depends on what is wired to the selector, the question mark on the left hand side of the structure. The bar at the top of the case structure gives the value that case is matched to - in my VI there are two cases. The first is '122' and the other is 'Default' (please note that these are literal, not enclosed in ' marks. A string would be shown as "MyCase" and I would write it here as ' "MyCase" ' to try and make it clearer).
Default is always available to case structures, and is the case run when no other case matches. Depending on what you wire to the selector, it may or may not be a required case. For example, if you wire an 'enum' to the case selector, or a boolean, then the list of possible values is known. This allows you to right click the structure and select 'Create case for each value' or something similar (I forgot the exact text). In this case, no 'Default' case is required, but you can still optionally use one if you wish. Compare this with wiring a string. With a string, the list of possible values can't be known, counted or enumerated. Consequently, the 'Default' case is a requirement - you must make one of the cases include the term 'Default' in the top bar. This can be one of the other cases if you want.
For numeric types, you can give every value, but it would take a very long time to do that! However, you can instead write something like '...0' as your case, in which case it will be read as "all values below and including 0".
Case Structures are a very useful and quite simple tool in the LabVIEW toolbox. You should definitely learn about them - they are almost required for any kind of conditional programming. Another common use is to wrap around all of your code (especially in a subVI) and wire the 'Error In' control to the selector - then you automatically get two cases, 'Error' and 'No Error'.
Dear @cbutcher
Thanks for the detailed explanation. Based on your example, I have been trying to modify my code for the last couple weeks. Now I have a new concern.
I want a random number generator to be inside a while loop. I want it to keep creating new random numbers in each iteration. Once I push the button on keyboard (b=98) I want that random number (the number that is available in the moment when I push the button) to show in an indicator. However again, since it the random generator is in a while loop, I need a stop button for the loop. Please see the attached file (two.vi).
In this file, once you hit the run, it will keep creating random numbers, you have to push stop2 button, and then push the b button on keyboard and that way, the last value will show up in the "Chosen Random Number" indicator. If you push the "b" button without pushing stop2 button, nothing won't happen.
Now the problem is that I don't want the stop button there. I want to push the b button, and it stops the while loop iteration, and gets the last random number and show it on "Chosen Random Number" indicator together.
If I remove the while loop (the one that is around random number generator), it will create only one random number.
I'll be extremely thankful if you or anyone else can help with this since I've been working on this for a long while.
Please let me know if you have any questions,
Sina
05-02-2017 04:42 PM - edited 05-02-2017 04:44 PM
Sina,
It's not clear to me why you want to be generating numbers until you hit 'b'. You could generate a new number every time you hit 'b' instead. Assuming you want to generate lots of numbers but only keep a few:
I've attached two VIs that do something like what you're asking for. One puts a timeout of 1 ms on the event structure, so the main while loop runs roughly 1000 times per second (and generates a random number each time). If 'b' is hit during that millisecond then it captures it. Otherwise the event structure times out and the process repeats.
The other VI is structured more like what you had, but it uses a local variable or property node (I don't know which is better so I put both) to read the value. That way you don't have to stop the first while loop to read the value.
- Robert
05-02-2017 08:01 PM
@Robert__R wrote:
Sina,
It's not clear to me why you want to be generating numbers until you hit 'b'. You could generate a new number every time you hit 'b' instead. Assuming you want to generate lots of numbers but only keep a few:
I've attached two VIs that do something like what you're asking for. One puts a timeout of 1 ms on the event structure, so the main while loop runs roughly 1000 times per second (and generates a random number each time). If 'b' is hit during that millisecond then it captures it. Otherwise the event structure times out and the process repeats.
The other VI is structured more like what you had, but it uses a local variable or property node (I don't know which is better so I put both) to read the value. That way you don't have to stop the first while loop to read the value.
- Robert
Dear Robert,
Thank you very much for your help. Your example two_Timeout.vi is very very close to what I'm looking for. It's almost perfect. The last thing that I'm looking for, is that the loop count starts counting from zero and goes to infinity unless you push the 'b' button. How can I modify it so that the first time I push the 'b' button, it prints 1 in an indicator, and second time I push the 'b' button it prints 2 and so on.
You have no idea how such a big help you did to me today!! Thank you very much Robert
Sina