LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

write vi in state machine

I have written a program in LabVIEW 8.5 to test thermostats. I had initially written the code for testing 1 thermostat, now I have modified it to test 6 thermostats in parallel. I'm going to be using a PCI 6515 DAQ unit by NI. The code is done in the State machine form.
The thermostat has 4 outputs (W, Y, GH, Gl) whihc are inputs to the DAQ since I want to read the signals. The inputs to the thermostat are power and temperature control which are outputs from the DAQ. So I basically write to these lines.
Now the problem is I'm writing to port 4 lines 0-5 and port 5 lines 0-5. Port 5 lines 0-5 are for power for every thermostat i.e Port 5 line 0 for T'stat 1, line 1 for t'stat 2, line 3 for tstat 3 so on and so forth till t'stat 6. I want to turn the power on after the state named dialog1 and then I want these lines to be turned high till the end.
Port 4 is for temperature control. line 0 for t'stat 1, line 1 for t'stat 2 so on till t'stat 6.
Port 4 lines 0-4 are manipulated in most states.  Sometimes turned on, sometimes off.
I want to know how to handle the daqmx write VIs. Like do I need to incorporate multiple create channels for every write VIs sor can I work with one create channel annd somehow be able to spilt lines I write to. This question might be confusing.
I have attached the code here. I know for a fact that I am handling the write VIs incorrectly. It's only edited for the 1st case structure.
All other case structures are replicas because they represent every thermostat.
 
0 Kudos
Message 1 of 11
(3,552 Views)

It may be worthwhile instead of having 6 case structures inside a single loop to have 1 case structure inside of each of 6 parallel loops.  As you have it now, the overall program will only run as fast as the the slowest active case of the 6 case structures.

With the DAQmx functions, I have found that sometimes you can create multiple tasks each with its own channel without problems.  And sometimes you have to put all the channels into a single task.  I don't know what are the criteria for having to do it the second way.  If it doesn't have to be done the second way, then your current architecture should work.  If it has to be done the second way, then I'd recommend creating a separate parallel loop with a producer consumer architecture and queues.  That loop would handle all of the daq functions.  Each of the other loops of the parallel tests would queue up a daq command when necessary.  The DAQ loop keep track of the current DAQ output state, read the queue, change whatever is required, and rewrite the new DAQ output for all channels.

0 Kudos
Message 2 of 11
(3,544 Views)

Thats how I had the loops initially but then a coupke of NI applications engineers said that that will npot work correctly. It might give race conditions or something.

If you see I could habdle te daqmx read vis by using subset arays but I cannot even do that for the writes. I cannot think of anything else.

what are producer-consumer archtectures and queues and how are they implemented.

Whoever said Labview isn't difficult. This code is supposed to be for a very simple thermostat... It's taken forever Smiley Sad

 

0 Kudos
Message 3 of 11
(3,535 Views)
i cant open your vi (i have 8.2). yet here some points based on your explanation:
 
Sometimes a digital port has to be considered as a whole, and writing to a single line might affect the other lines, especially if you do buffered output.
now in general if you have several elements that affect different lines of a same port, and timing is not an issue, one can simply create a task for every single line. therefore, every one of your parallel structure/loop can be totally independent.
if timing is an issue, then the best is to always send the information to the whole port. to do that, simply keep a registry of all 8,16 or 32 bits ( in case you send to 4 ports in parallel). this registry of course should be encapsulated in an Action Engine. then an external loop take care of sending the data to the card.
this action engine can be called from all loops, and data in there changed for every specific line. the retrieving element will take the whole 32 bits out.
 
the the reason it is not always possible to create a task for every single line, apart buffered output, is differentiation between input and output . some ports, depending on hardware, can be divided into 2 sets of 4, first for output and second to input. otherwise it is not possible to simultaneously have in and out on same port.
 
last but not least: if you have6 parallel thermostats, which are exactly the same apart the addressing, why not make a single structure, with subvis which could have as input the thermostat number, and would address the card accordingly? your program could look much more elegant.
 
 
-----------------------------------------------------------------------------------------------------
... And here's where I keep assorted lengths of wires...
0 Kudos
Message 4 of 11
(3,529 Views)
Go to File menu New...    Then VI, from template, Frameworks, Design patterns,  then Producer/Consumer Design Patterns (Data).
 
In the DAQ loop (the consumer loop), you would maintain the current state of the booleans  (It looks like all of your DAQ is digital correct?).  When a message comes on the queue from one of the other 6 loops, you change the appropriate booleans in the array, and rewrite the array out with the DAQ mx write.  The other digital outputs will be rewritten, but they contain the same data as they had before so nothing really changes.
 
One main loop with 6 case structures could still work, I think it is just 1 step farther away in modularity from 6 loops with 1 case structure each.  I am not sure what the NI application engineers' concerns would be about race conditions in you specific applications.  Race conditions are generally when  values are read from controls/indicators before the value is set.  So you may be basing an operation on stale data rather than the latest data.  Or even when you have a control/indicator being written to from more than one location.  If one lpiece of code says make a boolean True, and another says make the same boolean False, which is accurate?  Which value "sticks" when it is written second?  Careless use of local variables and lead to this condition, but if the architecture is designed properly you shouldn't have a problem whether it is 6 or 7 loops or 1 or 2 loops.
 
I'd recommend taking the Labview Basics 1 and 2 course.  Also, look for the online tutorials on the NI website.  And keep reading the questions and responses in the discussion forums.  The fact that you are already looking at a state machine architecture is a good sign that you are already learning some good things about Labview.Smiley Happy
0 Kudos
Message 5 of 11
(3,523 Views)

last but not least: if you have6 parallel thermostats, which are exactly the same apart the addressing, why not make a single structure, with subvis which could have as input the thermostat number, and would address the card accordingly? your program could look much more elegant.
 

How exaxtly can I do this?
 
I didn't understnd most of what you said before this.
0 Kudos
Message 6 of 11
(3,520 Views)
Take for instance that each of your 6 case structures are nearly identical.  Their are only a few differences between them such as the channels you are acting on, the subset of the array you are reading, the indicators you are writing to.  You encapsulate all of that in a subVI and anything that is different becomes a control of the subVI (for channel input, statemachine enum value) or an indicator of the subVI (for different indicators.).  So you feed the different values into the connectors of the SubVI.  The outputs (such as Heat Read, Pass/Fail) would come out of the sub VI and go to the appropriate frontpanel indicator based on what which thermostat structure you are on.   Action Engines would definitley be a big help with this.  This will make the code much more modular and allow you to shring the block diagram screen space.  If you find you have to make a change to one of your case structures, you do it in one place in the subVI rather than in 6 places.  (Or more in the case you expand the program further in the future.)

Message Edited by Ravens Fan on 01-04-2008 02:49 PM
0 Kudos
Message 7 of 11
(3,517 Views)


You encapsulate all of that in a subVI and anything that is different becomes a control of the subVI (for channel input, statemachine enum value) or an indicator of the subVI (for different indicators.).  So you feed the different values into the connectors of the SubVI.  The outputs (such as Heat Read, Pass/Fail) would come out of the sub VI and go to the appropriate frontpanel indicator based on what which thermostat structure you are on.


I'm sorry, I'm really new to labview. But how do you encapsulate it in a sub VI. How does this work?

Also I didn't really follow the Action Engine part.

0 Kudos
Message 8 of 11
(3,509 Views)
Try the DAQ Assistant. It will help you set up a multiple channel DAQ system. When you're done you can convert it into the VI's to see how it's done.
PaulG.
Retired
0 Kudos
Message 9 of 11
(3,501 Views)
Following the advice of Ravens Fan, i would propose you go slowly, and do not try to undertake the full project at once. a crash course trough Lv might help you.
try to go trough the Lv example for outputing a single line. use that to test a single thermorstat. use this example as a subvi in your program, and reuse it as much as needed to address all needed lines. once you will have that running, you might then rthink a little your strategy to make a larger and more evolved program.
good luck 🙂
-----------------------------------------------------------------------------------------------------
... And here's where I keep assorted lengths of wires...
0 Kudos
Message 10 of 11
(3,496 Views)