02-19-2015 06:30 AM
Hey there,
I've a producer consumer structure in which one event triggers a sequence contained in a state machine (the other events trigger a state that immediatly shuts it down). This state machine enqueues new parameters at specific intervals (set by timers that the user can specify). The idea is that, if the timeout occurs, the event structure enqueues the new value and the state machine switches over to the next step in the sequence (that I haven't filled out yet). If I hit "stop", the event structure sends out "stop method" to the state machine and the whole loop finishes executing after queueing "stop". But for some reason, the event structure doesn't time out, can anybody tell me why?
Have a nice day.
02-19-2015 06:53 AM
You have some very basic issues in your code.
What is the "Timer 1" value when running it?
You know that any other event handled by the structure "resets" the timeout?
You know that the event structure has its event queue active even if the structure (Step1) is not executing?
You are aware that your "Run/Stop Methode" event case kills the Queue Reference in your producer creating errors for all queue functions called with that reference after that event case?
You are aware that your Stop case in the producer enqueues a "Run" to the consumer essentially leaving this process active for indefined time?
You are aware that using several event structures in a single VI is recommended only for highly advanced developers and in your use case could create severe issues?
Please try to incorporate NI LV Programming Style Guides to a better level, it will help you in the long term.....
Norbert
02-19-2015 06:58 AM
That is because the event structure has a Run/Stop Method Value Change in its queue. So it runs that and you go to the Run Method state.
Here's your problem: each event structure has its own event queue. Any event it is registered for will be added to the queue, no matter where you are in the code. This is one of the main reasons we say that you should only ever have 1 event structure in a given VI.
You need to rethink how your state machine should work. Since everything is event based, do you even need to be in a state machine for the consumer loop?
02-19-2015 07:36 AM
@ Norbert_B: I've been using Labview for not even 3 weeks, so bear with me... I could have guessed there was something wrong with the code, but not knowing better, this was the best I could come up with. There's even lots of things I don't understand in your answer:
2) What do you mean, the timeout gets reset? Even when there's no other event occuring?
4) How does it kill the queue reference and how can I avoid it?
5) The "stop" and "run" commands are actually the same. There's no respective command for each and yes, that's been causing me headache...
6) You're definitely right, but they look so useful that I really get tempted to use them... This is all just trial and error. I'm still looking to finding my way around Labview.
@ crossrulz: thanks a lot, that's pretty helpful. Well, I'm trying to run a power supply. It's supposed to run in manual mode, so that the user can change the parameters through the user interface. So far, everything's fine. But, I also need the user to be able to program sequences (there comes the state machine I've messed in, I really didn't have any other idea as to how to do it) that he can stop or change parameters of any time (there's the event structure). While the parameter changes can be done with the main event structure, I didn't find any other way to stop the sequence while running. If there is any, I'd be glad for any pointers.
The only other way to program sequences for the power supply is to program them manually. So "Menu - Method - Set - Voltage - Set - (Voltage value) - Set - Current - ..." etc. with a command sent to the power supply for every key in the sequence (Labview would just replace the operator in front of the power supply entering everything by hand). This is a pain and not very elegant programming, but there's no command to program the sequences on the fly.
02-19-2015 09:00 AM
I could see a second producer loop handling the sequence, but then I wouldn't know how to stop it if I wanted interrupt the sequence. Basically, every method I can think of makes the user pretty much unable to interact with the sequence which would be pretty important.
(I wanted to edit my previous post, but I didn't seem to be able to anymore.)
02-19-2015 11:51 PM
02-23-2015 07:04 AM - edited 02-23-2015 07:32 AM
Just pay attention to the top 2 loops, please. So what I've tried here is a second producer loop sending the parameter changes for every step in the sequence. The first step just runs for a specified amount of time since the first parameters are already initialised. Then comes the second step where the parameters are changed and the step runs for another specified amount of time and so on, until the enum sends the sequence to the Stop state, where I send "Run/Stop" to stop the power supply. Works fine so far.
But what if I want to interrupt the sequence? Is there any way to send the Method loop back to the wait state ("Attente") when hitting the global Run/Stop button from the main (lower) producer loop? The problem here is that there is only one command for Run and Stop (otherwise it would just be too easy I guess...). The way it is now, the sequence will continue to run in the background, not changing anything really, but when it reaches the "Stop" state, it will send another "Run/Stop" to the power supply and it will just start running again. So I really would need to send the Method loop to the wait state when hitting the global "Run/Stop" button.
(Yes, this is very crude still, I just want to see if my way of thinking would work somehow. Both loops should only be stopped by an error message, the 2 stop buttons are just temporary. Also, if this is getting too offtopic, just tell me and I'll open a new thread.)
Have a nice day.
Edit: I just got the idea that I could put the sequence state machine in the main producer loop, but I'm not sure how to do this. If indeed this is be a better way of doing it, how would I go about that?
02-23-2015 07:50 AM
Without looking into your VI (my LV is currently blocked doing some massive Mass Compile), i see that you mix event sources and consumer code.
This is not recommended.
Please distinguish between producers, hence SOURCES of messages, and consumer, hence SINKS of messages.
So your producer captures ALL UI INTERACTION (which means it requires only an event structure, remove the case structure around it!).
Your consumer works on that stuff. If you start your sequence, the consumer feeds itself with the next state.
Please note that writing a custom sequencer is only recommended for simple applications. For more flexible/capable applications, please take a look into NI TestStand.
thanks,
Norbert
02-23-2015 08:30 AM
I'm not sure where you see that I'm mixing event sources and consumer code (maybe I'm doing so, but not consciously and I'd really like to know where this happens)? The loops on the screenshot are 2 producer loops, the consumer loop isn't even visible.
The lower one has a case structure around it because, when starting up, I want to verify the configuration of the power supply before going into a "wait for signal" state. I don't really know how I should split this up otherwise (it goes straight into the "wait for signal" mode because the configuration mode still needs some fine tuning).
The upper loop is basically a state machine with every step in the sequence managed by one state. The sequence is pretty simple "change parameters - wait - change parameters - wait... - stop" and is launched by the event structure in the "wait" state. I'll look into TestStand, but buying new software at this point isn't an option yet.
Thank you.
02-23-2015 09:00 AM
I think your challenge already is with defining components in your software.
Each loop in your code can be understood as a single component of the software (architecture). So the first task for development is to define the components you require to build your complete software architecture.
Each component should have a single task and a single interface.
In your case, you have two components (both 'producer') which refer to the same interface: The UI. This is not recommended because of possible race conditions, deadlocks and other unpredictible occurrances of issues.
Please try, using pen and paper if necessary, to split your whole application requirements into components where you can define flow charts or "behavioral diagrams" to identify possible redundancies and interaction between components. If you find those, the design of your components is no good.
If the design is free of redundancies, chances are high to get a robust software.
Long story short:
- Avoid using multiple event structures in a single VI as beginner of LV!
- Avoid using event structures within case structures as long as you are not aware of possible pitfalls!
Norbert