09-06-2017 09:24 PM
I need to read a text file containing a command script and send it, line by line, to the input function of a DLL, then read back the response from the output function of the same DLL. I wanted the option to send it one line at a time, for debugging purposes, or all at once, for speed (it might be 6,000+ lines). After reading many examples and not really understanding state machines very well, I arrived at the following solution:
It works, but it seems inelegant, especially the initialization and incrementing. Should I have used some sort of auto-indexing? Or is it really not that bad?
Thanks!
09-07-2017 01:06 AM
I just realized that my snippet is pretty useless without the DLL, so I removed the DLL calls and just passed the string from the file into the input buffer indicator and then straight through to the output buffer indicator. Then I added a short wait so that you can actually see it running:
09-07-2017 06:44 AM
My first advice is to learn how to use Shift Registers. They will eliminate some of your local variables (line the Line Counter).
I would also only use 1 control for controlling the write/pause. My advice is to get rid of the Send and just use the Pause. If Pause is TRUE, do not write and increment.
09-07-2017 09:37 AM
Critiquing in general, I'd say that you need to learn dataflow basics. From a cursory look at your block diagram, I'd say all of your sequence structures could be eliminated with a proper understanding of dataflow. (And if proper use of local variables was observed.)
This will free up LabVIEW to execute nodes in the order it sees fit to execute them. This is roughly analogous to letting the operating system decide which thread to run next instead of dictating the order yourself.
09-07-2017 12:23 PM
¡Hola! and thank you both for your suggestions.
Yes, the shift register in place of Line Counter local really cleans things up. For some odd reason I was confusing a shift register with an auto-indexing something-or-other, and I didn't realize I could control the incrementing with the Case. It looks slightly cleaner now:
(the False cases are both empty, except for a straight-through wiring of the shift register)
I could try to get rid of the remaining local variables and perhaps one of the buttons by using a latch (which would also get rid of the outer sequence), but I did want to retain the existing behavior, which enables:
If I get rid of Send and just pause or not-pause, I won't have fine control over sending one line at a time. But I'm all ears if you have a suggestion in this regard!
Could I use a classic For loop with an event-driven pause? That would eliminate the Line Counter and just auto-index through the string array, wouldn't it? I actually started out with a For loop, but couldn't figure out how to pause/resume it, which is why I switched to a While/Case structure.
09-07-2017 01:18 PM
Whoops! Minor error on that snippet. The While control should be Stop, not Run. I must have inadvertently clicked it while I was trying to align everything nicely. Corrected version, here:
09-07-2017 01:33 PM
Here are some suggestions:
Bob Schor
09-07-2017 01:45 PM - edited 09-07-2017 01:46 PM
But doesn't the While loop run continuously, regardless of the buttons' states? That would cause my index/line counter to increment even when I'm not sending. Or is there a way to control that, as well?
09-07-2017 02:19 PM
@Bob_Schor wrote:
Here are some suggestions:
- ...
- Code like this seems (to me) to beg for a Queued State Machine, with the Queue being driven by an Event Loop that handles the three buttons (oh, yes, I forgot -- I named the "stop" button "Abort", as you use it to end the program, "aborting" it, before it finishes). This would allow you to eliminate the "busy-wait" 1 ms delay in your loop.
Bob Schor
Queued Message Handler.
The QMH does what it is asked, the QSM does whatever the stack has decided and may not be possible to define at development time.![]()
Ben
09-07-2017 03:48 PM
Listen to Ben (rather than to me).
BS