Allow state machine while loop to end only in 1 of the states?

What is the best way to ensure that the while loop that surronds state machine case structure only ends in a certain one of the states?

I have solved the problem of having the VI not stopping (apparently it was due to an event structure). However, now I have another slight problem. I need the state machine to terminate on either of two conditions:
1) If a stop button is pressed
OR
2) if the end of the sequence is reached.
As I have implemented it so far the VI terminates because of the second condition and does not allow me to terminate it by pressing a 'Stop' boolean button. I know that this might be a bit fundamental and simple but I'm new with state machines on labview.
Thanks.
Attachments:
State machine.vi ‏21 KB

Similar Messages

  • Wait time in while loop: wait before all other code in the loop runs

    My vi is attached. 
    In the 'Check for Equilib' case, there is a while loop that takes data from a pressure gauge and compares it against data taken equilibTime seconds previous.  equilibTime is hooked up to a wait(ms) function inside the while loop.  Currently it appears that the code in the loop runs, and then the loop waits so many seconds before the next iteration.  I would like to reverse this process, i.e. in each iteration, the loop will wait so many seconds and then run the rest of the code in the loop.  I want to do this because I don't want there to be any delay between then time the 'check for equilib' code finishes and the start of the 'add shot' case.
    Can anybody suggest an elegant way of implementing this?
    Thank you
    Attachments:
    Take Isotherm.vi ‏294 KB

    No.  Use Flat sequences they are far preferable to stacked sequences.  Functionally they are the same.  But a flat sequence is easier to read, doesn't hide code, and you don't have to worry about backwards wiring caused by sequence locals in stacked sequence.
    Note, you have two oddities in your lower while loop.
    1.  Write a value to an indicator's terminal node and to a local variable of the same indicator is pointless.  They do the same thing.
    2.  Reading from a local variable of an indicator and writing to its terminal node is just as pointless, as you aren't doing anything.
    In your middle loop "Add shot" case, you have the local variable of DC estimate righting to a right hand side shift register, but you never use the left hand shift register.  So you are saving that value for future loop iterations, but never use it.

  • While loop stuck in LabVIEW when VI called by TestStand only

    LabVIEW 8.5, TestStand 4.0, Windows XP-SP3
    The issue I’m facing is a different behavior of a LabVIEW VI whether it is called independently (in the LabVIEW environment: normal behavior) or from TestStand (unexpected behavior).
    In the same VI, I've wired in parallel, so they can execute in parallel:
    a call through “System Exec”, to a program which prompts for a user's answer. The case I’m concerned is when the answer will never come...
    a while loop, managing a timeout which finally kills the program above when it waits infinitely for a user's answer
    Just to be more precise for those who’d try reproducing the issue (but you might just have a look at the enclosed VI): in my case the program is the command line WinSCP.com. WinSCP prompts when it wants you to accept the host’s private key which is not in its cache. Don’t be afraid if you’re not used to WinSCP, the concern here is LabVIEW + TestStand.
    What happens when we’re stuck in the “System Exec”:
    under LabVIEW: it works fine, as expected; while stuck in the “System Exec”, the while loop executes in parallel
    when the same VI is called in a TestStand sequence step (ActiveX automation server to the LVdevelopment system), it does not run the while loop (we're stuck in both System Exec and inside the loop). The only way to release everything is to manually kill the program called by the System Exec through Windows Task Manager.
    For information, all tasks: TestStand (SeqEdit), LabVIEW and program (WinSCP) show 0% CPU and their memory usage is stable.
    Have you an explanation for this unexpected / different behavior of the VI, only because it is called from TestStand?
    Enclosed is the VI.
    If you actually want running it, you might have WinSCP installed and a valid session to an accessible host (adapt path to WinSCP and session name), and do not put the host key in the cache!
    Note: you won't see the same issue with other programs or commands called by System Exec (e.g. netsh, ftp...) even if they await a user's prompt.
    Thanks for your help!
    Solved!
    Go to Solution.
    Attachments:
    CheckLabVIEWLock.vi ‏26 KB

    Have you tried changing the Preferred Execution System of the VI from 'same as caller' to 'other1'.
    Regards
    Ray Farmer

  • How can i get the while loop to enter a different loop beside the first one

    I can't seem to figure out how to change the value to enter into one of the other while statements in the script. I am new to this and can't seem to find anything how to enter in the information to be able to go to different while statements and then run
    what is located in that statement.
    The script is supposed to let me choose between TC, MonsterLock, and Cyc and then jump to the while statement that is associated with one of them and then run what ever is located in that block. All i am getting is a infinite loop and it never sees the other
    while loops. I have 3 set up the go along with the first statement but no matter what i type in for them it always looks at the first while statement and stays there.
    Can someone please help me with having it do what i stated earlier.  
    write-host "This script sets up DATABASE Staging"
    $ProductionDistro = Read-Host -Prompt "Which production do you `enter code here`want to run?(TC/MonsterLock/Cyc)"
    While($ProductionDistro -notmatch "(TC|MonsterLock|Cyc)"){
    write-host "You have entered an error" -ForegroundColor Red
    write-host "You must type TC or MonsterLock or Cyc"
    write-host "you typed $ProductionDistro"
    write-host "This script sets up DATABASE Staging"
    $ProductionDistro = Read-Host -Prompt "Which production do you `enter code here`want to run?(TC/MonsterLock/Cyc)"
    while($ProductionDistro -match $TC) {
    write-host "Sets up location you want to run staging"
    $ElementDistro = Read-Host -Prompt "Which Element do you want to run? (DATABASE1/DATABASE2/DATABASE3/DATABASE4/ALL)"
    While($ElementDistro -notmatch "(DATABASE1|DATABASE2|DATABASE3|DATABASE4|ALL)") {
    write-host "you have enterd an error" -ForegroundColor Red
    write-host "You must type DATABASE1 or DATABASE2 or DATABASE3 or DATABASE4 or ALL"
    write-host "you typed $ElementDistro"
    write-host "set location you want to run staging"
    $ElementDistro = Read-Host -Prompt "Which Element do you want to run? (DATABASE1/DATABASE2/DATABASE3/DATABASE4/ALL)"
    While($PrductionDistro -match $MonsterLock){
    write-host "Sets up location you want to run staging"
    $ElementDistro = Read-Host -Prompt "Which Element do you want to run? (DATABASE1/DATABASE2/DATABASE3/DATABASE4/ALL)"
    While($ElementDistro -notmatch "(DATABASE1|DATABASE2|DATABASE3|DATABASE4|ALL)") {
    write-host "you have enterd an error" -ForegroundColor Red
    write-host "You must type DATABASE1 or DATABASE2 or DATABASE3 or DATABASE4 or ALL"
    write-host "you typed $ElementDistro"
    write-host "set location you want to run staging"
    $ElementDistro = Read-Host -Prompt "Which Element do you want to run? (DATABASE1/DATABASE2/DATABASE3/DATABASE4/ALL)"
    while( $ElementDistro -match $DATABASE1 ){
    function Execute-MySqlcommand {param( [string]$Server, #the host of the SQL server
    [string]$Database1, #the name of the database
    [System.Data.MySqlclient.MySqlcommand]$Command) #the command to execute (name of stored command)
    $mysqlConnection = new-object System.Data.MySqlclient.MySqlConnection
    $MySqlConnection.ConnectionString = "DROP_VIEW DATABASE.BTXADDR;DROP_VIEW DATABASE.BTXSUPB;CREATE_VIEW DATABASE.BTXADDR FOR DATABASE1.DATABASE1S2.BTXADDR;CREATE_VIEW DATABASE.BTXSUPB FOR DATABASE1.DATABASE1S3.BTXSUPB"
    $MySqlConnection.ConnectionString = "TRUNCATE TABLE DATABASE1.DATABASE1S2.BTXADDR;TRUNCATE TABLE DATABASE1.DATABASE1S3.BTXSUPB; INSERT INTO DATABASE1.DATABASE1S3.BTXSUPB SELECT * FROM DATABASE1.DATABASE1S2.BTXSUPB; select count(*) from DATABASE1.DATABASE.BTXADDR; select count(*) from DATABASE1S.DATABASE.BTXADDR; select count(*) from DATABASE1.DATABASE.BTXSURB; select count(*) from DATABASE1S.DATABASE.BTXSUPB;"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $mysqlConnection
    $mysqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $mysqlConnection.Close()
    if ($Result -gt 0) {return $True} else {return $False}
    function Execute-MySQLCommand {param( [string]$Server, #the host name of the SQL server
    [string]$DATABASE1, #the name of the database
    [System.Data.SqlClient.SqlCommand]$Command) #the command to execute (name of stored procedure)
    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $sqlConnection.ConnectionString = "DATABASE_CONNECT_STRING=DSN=DATABASE1;Description=DATABASE1;Trusted_Connection=Yes;WSID=Server;DATABASE=DATABASE1;DATASET=DEFAULT"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $sqlConnection
    $sqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $sqlConnection.Close()
    if ($Result -gt 0) {return $TRUE} else {return $FALSE}
    function Copy-File {
    #.Synopsis
    # Copies all files and folders in $source folder to $destination folder, but with .copy inserted before the extension if the file already exists
    param}($DATABASE0980453.pkg,"d/DATABASE1/code_stg")
    # create destination if it's not there ...
    #mkdir $destination -force -erroraction SilentlyContinue
    foreach($original in ls $source -recurse) {
    $result = $original.FullName.Replace($source,$destination)
    while(test-path $result -type leaf){ $result = [IO.Path]::ChangeExtension($result,"copy$([IO.Path]::GetExtension($result))") }
    if($original.PSIsContainer) {
    # mkdir $result -ErrorAction SilentlyContinue
    # } else {
    copy $original.FullName -destination $result
    cd /d/DATABASE1/code_stg
    install ../DATABASE0980453.pkg
    while($ElementDistro -match $DATABASE2 ) {
    function execute-MySqlcommand {param( [string]$Server, #the host of the SQL server
    [string]$DataBase2, #the name of the database
    [System.Data.MySqlclient.MySqlcommand]$Command) #the command to execute (name of stored command)
    $mysqlConnection = new-object System.Data.MySqlclient.MySqlConnection
    $MySqlConnection.ConnectionString = "DROP_VIEW DATABASE.BTXADDR;DROP_VIEW DATABASE.BTXSUPB;CREATE_VIEW DATABASE.BTXADDR FOR DATABASE2.DATABASE2MS2.BTXADDR;CREATE_VIEW DATABASE.BTXSUPB FOR DATABASE2.DATABASE2S3.BTXSUPB"
    $MySqlConnection.ConnectionString = "TRUNCATE TABLE DATABASE2.DATABASE2S2.BTXADDR;TRUNCATE TABLE DATABASE2.DATABASE2S3.BTXSUPB; INSERT INTO DATABASE2.DATABASE2S3.BTXSUPB SELECT * FROM DATABASE2.DATABASE2S2.BTXSUPB; select count(*) from DATABASE2.DATABASE.BTXADDR; select count(*) from DATABASE2S.DATABASE.BTXADDR; select count(*) from DATABASE2.DATABASE.BTXSURB; select count(*) from DATABASE2S.DATABASE.BTXSUPB;"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $mysqlConnection
    $mysqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $mysqlConnection.Close()
    if ($Result -gt 0) {return $True} else {return $False}
    function Execute-MySQLCommand {param( [string]$Server, #the host name of the SQL server
    [string]$DATABASE2, #the name of the database
    [System.Data.SqlClient.SqlCommand]$Command) #the command to execute (name of stored procedure)
    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $sqlConnection.ConnectionString = "DATABASE_CONNECT_STRING=DSN=DATABASE2; Description=DATABASE2; Trusted_Connection=Yes;WSID=Server;DATABASE=DATABASE2;"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $sqlConnection
    $sqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $sqlConnection.Close()
    if ($Result -gt 0) {return $TRUE} else {return $FALSE}
    function Copy-File {
    #.Synopsis
    # Copies all files and folders in $source folder to $destination folder, but with .copy inserted before the extension if the file already exists
    param}($DATABASE0980453.pkg,"d/DATABASE2/code_stg")
    # create destination if it's not there ...
    #mkdir $destination -force -erroraction SilentlyContinue
    foreach($original in ls $source -recurse) {
    $result = $original.FullName.Replace($source,$destination)
    while(test-path $result -type leaf){ $result = [IO.Path]::ChangeExtension($result,"copy$([IO.Path]::GetExtension($result))") }
    if($original.PSIsContainer) {
    # mkdir $result -ErrorAction SilentlyContinue
    # } else {
    copy $original.FullName -destination $result
    cd /d/DATABASE2/code_stg
    install ../DATABASE0980453.pkg
    While( $ElementDistro -match $DATABASE3 ) {
    function Execute-MySqlcommand {param( [string]$Server, #the host of the SQL server
    [string]$DATABASE3, #the name of the database
    [System.Data.MySqlclient.MySqlcommand]$Command) #the command to execute (name of stored command)
    $mysqlConnection = new-object System.Data.MySqlclient.MySqlConnection
    $MySqlConnection.ConnectionString = "DROP_VIEW DATABASE.BTXADDR;DROP_VIEW DATABASE.BTXSUPB;CREATE_VIEW DATABASE.BTXADDR FOR DATABASE3.DATABASE3S2.BTXADDR;CREATE_VIEW DATABASE.BTXSUPB FOR DATABASE3.DATABASE3S3.BTXSUPB"
    $MySqlConnection.ConnectionString = "TRUNCATE TABLE DATABASE3.DATABASE3S2.BTXADDR;TRUNCATE TABLE DATABASE3.DATABASE3S3.BTXSUPB; INSERT INTO DATABASE3.DATABASE3S3.BTXSUPB SELECT * FROM DATABASE3.DATABASE3S2.BTXSUPB; select count(*) from DATABASE3.DATABASE.BTXADDR; select count(*) from DATABASE3S.DATABASE.BTXADDR; select count(*) from DATABASE3.DATABASE.BTXSURB; select count(*) from DATABASE3S.DATABASE.BTXSUPB;"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $mysqlConnection
    $mysqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $mysqlConnection.Close()
    if ($Result -gt 0) {return $True} else {return $False}
    function Execute-MySQLCommand {param( [string]$Server, #the host name of the SQL server
    [string]$DATABASE3, #the name of the database
    [System.Data.SqlClient.SqlCommand]$Command) #the command to execute (name of stored procedure)
    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $sqlConnection.ConnectionString = "DATABASE_CONNECT_STRING=DSN=DATABASE3;Description=DATABASE3;Trusted_Connection=Yes;WSID=Server;DATABASE=DATABASE3;"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $sqlConnection
    $sqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $sqlConnection.Close()
    if ($Result -gt 0) {return $TRUE} else {return $FALSE}
    cd /d/DATABASE3/code_stg
    install ../DATABASE0980453.pkg
    function Copy-File {
    #.Synopsis
    # Copies all files and folders in $source folder to $destination folder, but with .copy inserted before the extension if the file already exists
    param}($DATABASE0980453.pkg,"d/DATABASE3/code_stg")
    # create destination if it's not there ...
    #mkdir $destination -force -erroraction SilentlyContinue
    foreach($original in ls $source -recurse) {
    $result = $original.FullName.Replace($source,$destination)
    while(test-path $result -type leaf){ $result = [IO.Path]::ChangeExtension($result,"copy$([IO.Path]::GetExtension($result))") }
    if($original.PSIsContainer) {
    # mkdir $result -ErrorAction SilentlyContinue
    # } else {
    copy $original.FullName -destination $result
    While($ElementDistro -match $DATABASE4 ) {
    function Execute-MySqlcommand {param( [string]$Server, #the host of the SQL server
    [string]$DATABASE4, #the name of the database
    [System.Data.MySqlclient.MySqlcommand]$Command) #the command to execute (name of stored command)
    $mysqlConnection = new-object System.Data.MySqlclient.MySqlConnection
    $MySqlConnection.ConnectionString = "DROP_VIEW DATABASE.BTXADDR;DROP_VIEW DATABASE.BTXSUPB;CREATE_VIEW DATABASE.BTXADDR FOR DATABASE4.DATABASE42.BTXADDR;CREATE_VIEW DATABASE.BTXSUPB FOR DATABASE4.DATABASE4S3.BTXSUPB"
    $MySqlConnection.ConnectionString = "TRUNCATE TABLE DATABASE4.DATABASE4S2.BTXADDR;TRUNCATE TABLE DATABASE4.DATABASE4S3.BTXSUPB; INSERT INTO DATABASE4.DATABASE4S3.BTXSUPB SELECT * FROM DATABASE4.DATABASE4S2.BTXSUPB; select count(*) from DATABASE4.DATABASE.BTXADDR; select count(*) from DATABASE4S.DATABASE.BTXADDR; select count(*) from DATABASE4.DATABASE.BTXSURB; select count(*) from DATABASE4S.DATABASE.BTXSUPB;"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $mysqlConnection
    $mysqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $mysqlConnection.Close()
    if ($Result -gt 0) {return $True} else {return $False}
    function Execute-MySQLCommand {param( [string]$Server, #the host name of the SQL server
    [string]$DATABASE4, #the name of the database
    [System.Data.SqlClient.SqlCommand]$Command) #the command to execute (name of stored procedure)
    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $sqlConnection.ConnectionString = "DATABASE_CONNECT_STRING=DSN=DATABASE4;Description=DATABASE4;Trusted_Connection=Yes;WSID=Server;DATABASE=TF90PVS;"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $sqlConnection
    $sqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $sqlConnection.Close()
    if ($Result -gt 0) {return $TRUE} else {return $FALSE}
    function Copy-File {
    #.Synopsis
    # Copies all files and folders in $source folder to $destination folder, but with .copy inserted before the extension if the file already exists
    param}($DATABASE0980453.pkg,,"d/DATABASE4/code_stg")
    # create destination if it's not there ...
    #mkdir $destination -force -erroraction SilentlyContinue
    foreach($original in ls $source -recurse) {
    $result = $original.FullName.Replace($source,$destination)
    while(test-path $result -type leaf){ $result = [IO.Path]::ChangeExtension($result,"copy$([IO.Path]::GetExtension($result))") }
    if($original.PSIsContainer) {
    # mkdir $result -ErrorAction SilentlyContinue
    # } else {
    copy $original.FullName -destination $result
    cd /d/DATABASE4/code_st
    install ../DATABASE0980453.pkg
    While($ElementDistro -match $ALL ){
    function Execute-MySQLCommand {param( [string]$Server, #the host name of the SQL server
    [string]$DATABASE1,$DATABASE2,$DATABASE3,$DATABASE4, #the name of the database
    [System.Data.SqlClient.SqlCommand]$Command) #the command to execute (name of stored procedure)
    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $sqlConnection.ConnectionString = "(DATABASE_CONNECT_STRING=DSN=DATABASE1;Description=DATABASE1;Trusted_Connection=Yes;WSID=Server;DATABASE=DATABASE1;DATASET=DEFAULT;),(DATABASE_CONNECT_STRING=DSN=DATABASE2; Description=DATABASE2; Trusted_Connection=Yes;WSID=Server;DATABASE=DATABASE2;),(DATABASE_CONNECT_STRING=DSN=DATABASE3;Description=DATABASE3;Trusted_Connection=Yes;WSID=Server;DATABASE=DATABASE3;),(DATABASE_CONNECT_STRING=DSN=DATABASE4;Description=DATABASE4;Trusted_Connection=Yes;WSID=Server;DATABASE=TF90PVS;)"
    $Command.CommandType = 1 # 1 is the 'Text' command type
    $Command.Connection = $sqlConnection
    $sqlConnection.Open()
    $Result = $Command.ExecuteNonQuery()
    $sqlConnection.Close()
    if ($Result -gt 0) {return $TRUE} else {return $FALSE}
    install ../DATABASE0980453.pkg
    While($ProductionDistro -match $Cyc) {
    write-host "Sets up location you want to run staging"
    $ElementDistro = Read-Host -Prompt "Which Element do you want to run? (DATABASE1/DATABASE2/DATABASE3/DATABASE4/ALL)"
    While($ElementDistro -notmatch "(DATABASE1|DATABASE2|DATABASE3|DATABASE4|ALL)") {
    write-host "you have enterd an error" -ForgroundColor Red
    write-host "You must type DATABASE1 or DATABASE2 or DATABASE3 or DATABASE4 or ALL"
    write-host "you typed $ElementDistro"
    write-host "set location you want to run staging"
    $ElementDistro = Read-Host -Prompt "Which Element do you want to run? (DATABASE1/DATABASE2/DATABASE3/DATABASE4/ALL)"

    OK, so you've got a reasonable input loop early on:
    write-host "This script sets up DATABASE Staging"
    $ProductionDistro = Read-Host -Prompt "Which production do you `enter code here`want to run?(TC/MonsterLock/Cyc)"
    While($ProductionDistro -notmatch "^(TC|MonsterLock|Cyc)$"){
    write-host "You have entered an error" -ForegroundColor Red
    write-host "You must type TC or MonsterLock or Cyc"
    write-host "you typed $ProductionDistro"
    write-host "This script sets up DATABASE Staging"
    $ProductionDistro = Read-Host -Prompt "Which production do you `enter code here`want to run?(TC/MonsterLock/Cyc)"
    I've only added two things to that code:  a ^ and $ at the beginning and end of your regex pattern.  As originally written, it would have successfully matched any string containing TC, MonsterLock or Cyc (such as "bogusTCwhatever", etc).
    Now, instead of a bunch of extra While loops based on $ProductionDistro, what you need is some conditionals (either a Switch statement, or some If/ElseIf).  For example:
    switch ($ProductionDistro)
    'TC'
    # Do TC Stuff
    break
    'MonsterLock'
    # Do MonsterLock Stuff
    break
    'Cyc'
    # Do Cyc stuff
    break

  • How to pass a value from inside a while loop outside the loop

    Hello to everybody, I have been searching through the forum but I have not found a certain answer for my problem. I would try to explain my problem as breefly as posible:
    I have to send by a BNC2120 two signals and acquire an other one thats comes from a preassure sensor. That part is done by introducing simulating and acquiring DAQmx inside while loops.It is sycronized by my self, proving such diferent values (is not the optimum, but is only the first prototype) and works as I expected. Well, then I want to sample some of the values of these signals, that is done with relays and local variables to get the value in the instant I want to sample. Here begin my problems: I want to extract the sample values out of the while loops without restarting them, I mean: I do not want to stop the while loops because the acquisition and the generation of the signal must be continuous, but I do not know if it is posible to put the while loops in "standby" until I operate with the values I have sampled and then the signal generator and the acquiere continues from when it has stoped before. Particulary I want to obtain the value of the top while loop (inside a case) when the counter arrives at 15.
    I have proved to do with local variables, global variables, making a state machine, with event cases, with flat secuences...I have been reading about and proving diferent posible solutions for this week and the whole past week and I have not found the solution.
    If any of you know how I can do this thing, I would be loved to listen your opinions. My proyect is above: 
    Thank you a lot in advance.
    Sinceresly,
    Miguel.
    Attachments:
    maq_estados_event_case.vi ‏239 KB

    It definately sounds like what you really want is a Producer/Consumer.  It is an architecture that uses Queues to pass data from a data generation loop (producter, your DAQ loop) and a data processor (consumer).
    There are only two ways to tell somebody thanks: Kudos and Marked Solutions
    Unofficial Forum Rules and Guidelines

  • Stop dependant while loops with 1 button

    Hi,
    I am developing a utility that allows a user to configure up to 2 devices (both use same driver with a different board number), click initialize, which then brings up a file dialog and displays arrays for the data to be collected and some error messages for each measurement.  The user then clicks the Start/Stop button to begin collecting and logging data.  Currently i have a Wait(ms) block to allow the user to set often the measurement should be made.  Currently the Start/Stop button allows collection to be started, paused, and started again.  My problem is trying to have a master stop button that should stop all loops immediately when it is pressed.
    I tried using a global variable for the stop button, but the measurement and logging while loop doesnt stop until after the wait(ms) block times out.  Can anyone give suggestions.  If i need to restructure the VI into different loops, I can do that.  I just want to understand the right way to program something like this.
    The VIs are attached.  I removed the device specific measurement VI so that anyone can open the vis and run them to see how it works.
    Attachments:
    2Devices_withoutMeasurementVI.vi ‏112 KB
    BuildOutput.vi ‏27 KB
    stopGlobal.vi ‏5 KB

    Ok.  I had a chance to take a look at your code and I think you don't quite understand the concept of "dataflow".  Let me see if I can help.
    First of all...when I refer to your upper structure, I am referring to the first while loop, sequence structure, and subsequent while loops.  When I refer to your lower structure, I am referring to the while loop containing the event structure.  Just so we get our terminology straight.
    I believe that you are under the illusion that your upper structure contains three parallel while loops.  It does not.  It contains three SERIAL while loops.  There is dataflow dependency between the while loops.  The sequence structure requires data that is not available until the first while loop has finished executing, so the sequence structure cannot start executing until the first while loop has terminated.
    The second while loop requires inputs from the first frame of the sequence structure (which, by the way, you don't need and should get rid of...the sequence structure, I mean), so it cannot start executing until the first frame of the sequence structure has terminated.  The third while loop requires inputs from the second while loop...so, again, the third while loop cannot run until the second while loop has finished executing.
    Now, for your stop button.  You have that global stopping all three loops.  So here's what is happening in your program:
    Your program starts.  The first while loop executes in parallel with the loop which contains the event structure.
    At some point you press the "stop" button.  Both the first while loop and the loop containing the event structure finish executing.
    The first frame of your sequence structure executes.
    The second frame of your sequence structure executes.  The second while loop reads the "stop" value from the global, so it executes once and then finishes.
    The third while loop starts executing.  Again, the loop reads the "stop" value from the global, so it executes once and then finishes.
    Then your program terminates.
    You need to restructure your program, because right now it doesn't make any sense at all.  Your block diagram would benefit from some serious tidying up as well, your wiring is a mess.  I suggest you look into a state machine architecture for this program.

  • While Loop Coding

    I have code where I am using a "while" statement. As long as the User presses the number 1 on the keyboard, the program loops back to the start, which is perfect, that is what I want. If a User press the number 0 on the keyboard, the program should stop and ... this is the part of the "while loop" that I don't understand how to code. Below is the "While Loop" that I have, as well as the ending line.
    public static void main(String[] args)
    String another ="1";
    while (another.equals("1"))
    .....NOW WHAT?......AS YOU CAN SEE, MY LOOP IS INCOMPLETE. I DON'T KNOW HOW TO CODE THE 0 PORTION.
    ...at the bottom after the System.out.Prinln() I have the following line of code:
    another = Console.readString("To place another order press(1). Press 0 to quit? ");
    Of course, the number 1 works but the 0 doesn't.
    Help and thanks.

    >
    public static void main(String[] args)
    String another ="1";
    while (another.equals("1"))
    .....NOW WHAT?......AS YOU CAN SEE, MY LOOP IS
    INCOMPLETE. I DON'T KNOW HOW TO CODE THE 0 PORTION.
    ...at the bottom after the System.out.Prinln() I have
    the following line of code:
    another = Console.readString("To place another order
    press(1). Press 0 to quit? ");
    Of course, the number 1 works but the 0 doesn't.
    You're right in principal. You don't have to do anything about checking 0, though it might be a good idea. So I reckon there's a syntax problem with the bit we're not seeing.
    If while controls more than one statement they have to be enclosed in curly brackets if you miss this it'll loop on the next statement only which, since it doesn't change your another will run forever.
    Incidentally a loop that runs at least once is better coded using the do .. while construct.
    I'd code it something like:
    String keepGoing = null;
    do {
       .... do your thing
       for(;;) {   // this is a "middle exit" loop
                // without the break it would run forever
          keepGoing = Console.readString("More to do? (Entery 0 or 1):").trim();  // trim removes spaces
          if(keepGoing.equals("0") || keepGoing.equals("1"))
               break;  // exit inner loop if valid
          keepGoing = Consile.readString("Eh?? Must be 0 or 1:");
       // now we know we have "0" or "1"
       } while(keepGoing.equals("1"));

  • Accessing Data within while loops

    I have LabView 6.0
    I have a while loop for my GUI that accesses various sub VIs. One of the Sub VI is a LED on/off thing, which basically checks the communication with the PIC board that I have. For turning the LED on or off, I have to sent a unique command.
    Since the Sub VI for the LED on/off is inside a while loop it continuously executes. I want the SubVI to execute only when the status of the boolean controlling the LED has changed from the previous value. I tried giving a feedback from the SubVI to indicate whether there is a change, but Labview will not allow such loops.
    I then took the SubVI outside the while loop, keeping the boolean control (so that it continuously checks) inside the while loop. I would like the SubVI to execute depending on the boolean control change. I tried using occurances, but I think these execute only once. I tried accessing the boolean control through a local variable, but the value of the local variable would not change outside of the while loop. (even tried property indicators).
    Any solution would be appreciated.
    I could post the VI, but there are too many sub VIs... Dunno if it would be appreciated.
    Thanks!

    If you need to post a VI, it is best to strip out those parts which do not have any effect on the problem you are facing. With subVIs, do a Save with Options..>>Development Distribution. This will create an .llb file with your VI and subVIs.
    Queues and global variables can transfer data between independent nodes. I am not sure when the datatypes of queues changed. In LV6 you may need to flatten your data to string typpe before passing it to a queue. The functional global or LV2 style global is a subVI consisting of a loop which executes only once and which contains the data in an uninitialized shift register. Many threads on this forum have discussed these options.
    Lynn

  • How to stop while loop

    I can't figure out how to stop a while loop in my labview program. 
    When the user presses the Run arrow in the toolbar I want my program to begin reading the serial port for GPS messages.  These messages should be displayed on the front panel.  Currently I have this read/display in a while loop.  The program is also waiting for an extrenal trigger.  When that trigger arrives, I want to grab the current string from the serial port and save it and continue reading and displaying the serial/gps string.  This trigger starts the other parts of the program- signal generation, recording, and saving data which need to run concurrently with the serial/gps reading/displaying.  Once the AO and AI have finished and the data have been written to disk, I want the program to stop.  The serial/gps messages should be updating this whole time.  Only when the data are written to disk should the whole program end.  This whole sequence of events should only be done once when the user preses the Run arrow. 
    So far I'm unable to pluck the serial string when the trigger comes in if I'm watching the serial port all the time.  The program also doesn't stop when it finishes writing to disk because the read serial while loop is still running.  I don't want to use a front panel stop button.  The program should stop itself when the data havebeen written. 
    I'm really stumped on this one but I'm new to LabVIEW so I'm sure there's an easy solution to this. 
    Thanks for any and all help. 
    Attachments:
    SPoleLakeChirp.vi ‏199 KB

    Dennis and altenbach-  Thank you both for your patience. 
    I was trying to do just what Dennis suggested-"As I said, setting a local variable is one way." even before posting to this forum, but I couldn't get my local variables to reflect changes made elsewhere in the program and I wasn't able to wire from them because they were writes.  The critical part I was missing was how to change a local variable from a write to a read.  It was staring me in the face the whole time- just right click.  When I finally found it, my problems were solved. 
    altenbach- thank's for putting the figures together.  I do understand the logic and wiring there, but I was really trying to avoid stop buttons.  The program should be smart enough to figure out when to stop.  And using local variables turns out to be one way of solving this.  I still have some clean up to do, but I've included my current working version just so you can see how I implimented your suggestions.  There's still a lot of clean up to be done, but I'm delighted to be able to watch the serial/gps messages until I'm done reading in data.  At first I had this stop variable set in the final sequence frame.  That didn't work because I wasn't getting to the final frame because the loop wasn't finishing.  Once I placed the stop variable in the same frame as the while loop it began stopping when it should. 
    If you have other comments/critiques about the wiring diagram I'm earger to hear them.  I'm considering the structure finished, however.  It still needs cleaning up and commenting, but I'm satisfied with the functionality. 
    Thanks,
    Peter
    Attachments:
    SPoleLakeChirp.vi ‏210 KB

  • Multiple while loops

    I have two while loops in my application which run seperately. The program looks as follows
    :   while loop 1           :       :  while loop2        :
    I want to stop while loop 2 as soon as while loop 1 stops. I tried to connect the stop condition of while loop1 to the stop of while loop2, but the loop stops immediately after one iteration. How to go about it.
    Regards,
    Giridhar Rajan
    Automation Engineer
    Cruiser Controls
    Mumbai, India

    The big concept in LV is dataflow - a piece of code will execute when all its inputs are available. When you connected the two loops you caused a data dependency - the data in the wire coming out of loop one will only be available when the loop ends. So what happens is that you run loop 1 and when you stop it, the T value goes over to the second loop, which only starts running now. Since it gets T, it stops after one iteration. You can see this if you turn on Highlight Execution (the light bulb button). There are several ways to go around this - the simplest is a local variable - right click the stop button and select Create>>Local Variable. You can change this to be read and put it in the second loop. You will need to change the mechanical action of the button and make sure you set it back to false. A more advanced method is the event structure.
    These are the basics in LV. To learn more, I suggest you read the LabVIEW user manual. Also, try searching this site and google for LabVIEW tutorials. Here and here are a couple you can start with. You can also contact your local NI office and join one of their courses.
    In addition, I suggest you read the LabVIEW style guide.
    Try to take over the world!

  • Break out of a while loop from outside the loop

    Hello,
    I have an application where I have some nested while loops. Is it possible to break the innermost loop from a control that is outside of the inner loop? My inner loop is running a scan and read operation on the serial port and is reading data as it somes in. I need this loop to break when the user presses a button located in one of the outer loops so that another section of the vi can execute. Thanks in advance.
    Greg
    Gregory Osenbach, CLA
    Fluke

    Greg,
    You should place the terminal of the button in the innermost loop and wire out from there to the other locations the value is needed. If these are nested loops, the controls will not get read until the outer loop iterates again and this can only happen if the inner loop has ended anyway. Thus your scheme will not work.
    Alternatively, you can place the control in a loop that executes in parallel,then use local variables of it in the other locations, but the above solution is better.
    LabVIEW Champion . Do more with less code and in less time .

  • Starting new while loop while old one still running

    Hi!
    I am attempting to write video images to AVI files. I want to give the user the option to decide when they want to begin to capture the images. I place the "start recording" button in one loop and the image acquisition and AVI Write subVIs in another loop. LabVIEW won't allow me to continue on with the image acquisition loop until I finish with the "start recording" loop. Any ideas how to fix this (to allow the image acquisition to start and continue having LabVIEW check for a button press on "start recording")?
    Attachments:
    Capture_and_Save_as_AVI.vi ‏177 KB

    Thanks. I suspected as much. In any event, I can't seem to find a good configuration of while loops and case structures which will produce the desired results. I want to start acquiring images and allow the user to choose to start recording at any time he desires. This issue is further complicated by the fact that the status of the "Start recording" must be checked at all times, but only initialized once, while the AVI Write Frame depends on that first initialization step but must be looped continuously aferwards in order to 'keep up' with the images being acquired. In the newly attached example, I placed the case structure inside the image acquisition while loop and the avi write frame inside a while loop inside of that case structure. unfortunately,
    labview decides to stay inside the avi write frame while loop after entering, instead of returning to the image acquisition while loop. i can't place the avi write frame inside the general image acquisition while loop because then labview will think i want to initialize the avi write frame right away and will return an error when avi write frame isn't provided with an avi refnum. Ideas?
    Attachments:
    Capture_and_Save_as_AVI.vi ‏174 KB

  • How can I make a while loop wait for input boolean?

    Hi.
    I'm trying to control a robotic arm with labview for my undergrad dissertation, and I have a decent polar coordinate control panel made, but there is one problem; it checks for changes in the coordinates every five seconds, while I want it to only check on the touch of a button (ie, go!, I've changed your coordinates!). The changes are calculated with a while loop comparing the last value of theta, x and z in a while loop with the current one. I can't find a way of putting that into a case structure. If there is a way of making the while loop progress at the push of a button, I think it would work. The VI's attached below.
    Thanks in advance for any help.
    Cathal Scanlon
    ps, sorry about the mess, I'm going to reorganise the while loop into 2 if I can get the control button working.
    Message Edited by CatScan on 02-08-2007 02:45 PM
    Attachments:
    Polar coord assignment1.vi ‏142 KB

    Have you tried using an event structure? To use one, right click on the structure to add an event. Set the event as whatever button you wish to monitor and set the event to "Value Change". If you put this inside a while loop any time the button is pressed, the event structure will run the contents inside the loop. There are a number of options to have the event structure activate.
    *** Warning! I'm probably the last guy you want answering your labVIEW questions, but I figured I might be able to help.

  • Ai read in while loop

    I am acquiring data from a DAQ e series card. i intialized the daq by using AI config out side while loop . i used AI start and AI read in while loop . iam acquiring data from 5 channels. the buffer size ia 1000 and so is the scan rate in AI start.I want to save the acquired data in the file. i am also displaying data o n chart. every thing is working fine. my problem is i want to save 500 points in one seconds. for this i changed the while loop execution time by using waint until multiple sec VI and assign it 10  i was expecting that now iwll save more data point in file as now loop will execute more fast but it does not happen like this. is there any way to minimize the executing time of whil loop.i checked if i deleted AI start and AI read then loop execute very very quickly. should i place AI start and AI read out side loop but then how will it acquire data contiously. I m attaching gif file of the protion of my VI .any suggestion?
    Attachments:
    myVi.GIF ‏72 KB

    I was working quickly, and from memory, so my apologies for errors or non-clarity in my previous post. :-(
    The AI START VI, should be used OUTSIDE the loop, since you only want to START the task ONCE.
    When the task is complete (your WHILE loop is done), then call the AI CLEAR task to clean up (ONCE).
    If you set the NUMBER OF SCANS TO ACQUIRE input to AI START to zero, that has a special meaning: acquire data indefinitely. It will not stop on it's own (assuming no errors occur), you have to explicitly stop it.
    If you do this, you have to read the data often enough to avoid buffer overflow, which means the incoming data is filling up the buffer faster than you're emptying it.
    I have attached a picture of the general idea. If you really want to use the CPU efficiently, then consider the shift-register idea in the picture - you process on batch of data WHILE the next batch is coming in. If you want a simpler solution, forget the shift-reg, and process it directly after reading it. If your buffer is twice the size of your processing size, you'll be OK.
    Message Edited by CoastalMaineBird on 09-14-2005 07:45 PM
    Steve Bird
    Culverson Software - Elegant software that is a pleasure to use.
    Culverson.com
    Blog for (mostly LabVIEW) programmers: Tips And Tricks
    Attachments:
    DAQExample.png ‏16 KB

  • Question in ABAP syntax, read & insert data from internal table, while loop

    Hi, SDN Fellow.
    I am from Java background and learnt ABAP, I don't usually write much ABAP code.
    I am trying to implement the following logic in a RFC now.
    I have one z-custom database table, the structure as the following:
    It has two columns, with these sample data.
    Says datable table is ZEMPMGRTAB.
    EmployeeID,ManagerID
    user10,user1
    user9,user1
    user8,user1
    user7,user2
    user6,user2
    user5,user2
    user4,user2
    user2,user1
    The logic is this:
    I have a input parameter, userid. I am using this parameter to have a select statement to query the record into export table,EXPTAB 'LIKE' table ZEMPMGRTAB.
    SELECT * FROM  ZEMPMGRTAB
      into table EXPTAB
       WHERE  EMPLOYEEID  = USERID.
    Say, my parameter value, USERID ='USER4'.
    Referring to the sample data above, I can get the record of this in my EXPTAB,
    EmployeeID,ManagerID
    user4,user2
    Now, I want to iterately use the EXPTABLE-ManagerID
    as the USERID input in SELECT statement, until it has no return result. Then, insert the new records in
    EXPTAB.
    In above new loop case, we will get this table content in EXPTAB,
    EmployeeID,ManagerID
    user4,user2
    user2,user1
    I kind of think of the pseudocode logic as below:
    (These may not be a valid ABAP code, so I need help to convert/correct them)
    DATA:
    IWA TYEP ZZEMPMGRTAB,
    ITAB
    HASHED TABLE OF ZZEMPMGRTAB
    WITH UNIQUE KEY EMPLOYEEID.
    SELECT * FROM  ZEMPMGRTAB
      into table ITAB
       WHERE  EMPLOYEEID  = USERID.
    *Question 1: I cannot insert a internal table to export table, it is *incompatible type, what is the alternative way fo this?
    *Question 2: How can I access thedata of the internal table like this,ITAB-MANAGERID? As if I can, I would do this:
    * IWA-EMPLOYEEE = ITAB-EMPLOYEEID. IWA-MANAGERID = IWA-MANAGERID. INSERT IWA INTO TABLE EXPTAB.
    * Question 3: Is the 'NE NULL' - 'not equal to NULL' is right syntax?
    IF ITAB NE NULL.
    INSERT ITAB INTO EXPTAB.
    ENDIF
    * Question 4: Is my WHILE loop setup right here? And are the syntax right?
    WHILE ITAB NE NULL.
    SELECT * FROM  ZEMPMGRTAB
      into table ITAB
       WHERE  EMPLOYEEID  = ITAB-MANAGERID.
    IF ITAB NE NULL.
    INSERT ITAB INTO EXPTAB.
    ENDIF
    REFRESH ITAB.
    ENDWHILE.
    Assume all the syntax and logic are right, I should get this result:
    EmployeeID,ManagerID
    user4,user2
    user2,user1
    If I have a new entry in datable table,ZEMPMGRTAB like this:
    user1,user0
    My pseudocode logic will get this result:
    EmployeeID,ManagerID
    user4,user2
    user2,user1
    user1,user0
    I truly appreciate if you can help me to validate the above syntax and pseudocode logic.
    Thanks in advance.
    KC

    Hi,
    FUNCTION ZGETSOMEINFO3.
    *"*"Local Interface:
    *"  IMPORTING
    *"     VALUE(USERID) TYPE  AWTXT
    *"     VALUE(FMTYPEID) TYPE  AWTXT
    *"  EXPORTING
    *"     VALUE(RETURN) TYPE  BAPIRETURN
    *"  TABLES
    *"      APPROVERT STRUCTURE  ZTAB_FMAPPROVER
    *"      ACTOWNERT STRUCTURE  ZTAB_FMACTOWNER
    DATA: T_RESULT TYPE STANDARD TABLE OF ZTAB_FMAPPROVER.
    **Question 1: For this line, I got an error says "Program ''USERID" *not found. Is the syntax right, as the USERID is a parameter for the function.
    perform add_line(USERID).
      ENDFUNCTION.
    form add_line using i_user type ZTAB_FMAPPROVER.EMPLOYEEID
                        changing T_RESULT TYPE ZTAB_FMAPPROVER.
    data: ls_row type ZTAB_FMAPPROVER.
    * Get record for i_user
    select single * into ls_row from ZTAB_FMAPPROVER
    where EmployeeID = i_user.
    if sy-subrc NE 0.
    * Do nothing, there is not manager for this employee
    else.
    * Store result
    QUESTION 2: I am still got stuck on this line of code. It still *says that "T_RESULT" is not an internal table "OCCURS n" *specification is missing. I thought the line: "T_RESULT TYPE *ZTAB_FMAPPROVER" means declare internal table, T_RESULT as type of ZTAB_FMAPPROVER". Am I understand it wrongly?
    append ls_row to t_result.
    * Call recursion
    perform add_line using ls_row-ManagerID
                              changing t_result.
    endif.
    endform.
    Thanks,
    KC

Maybe you are looking for