IGOR as GUI

Hi. I am using IGOR to create a GUI (graphical user interface) to control 4 stepper motors. I can control each individually, and I am attaching a screen shot of the GUI so you can see what I have done. Using the IGOR2Epics XOP I can get, monitor and push variables to process variables from the Epics program.

My problem is a programming one. I want to move each motor in sequence, so that they can move to pre-set positions one after the other. This means that I need a procedure that tells the motors: " Motor 1 go here. Motor 2, wait until Motor 1 is done moving. Motor 2 go here. Motor 3, wait until Motor 2 is done moving. Motor 3 go here etc." For machine safety I need to be able to stop the motors with a push of a button at any time, and this must be easy because other people will be using the motors. I have a "STOP" button that works well for this.

My problem is this: When I tell the motors to wait, either using a for loop or a do-while loop it takes over IGOR so that I can no longer use my "STOP" button. I have tried making the "move-wait-move" procedure a background function, but then I get no updates on the main interface and my "STOP" button will still not work. I must abort the procedure before doing anything else.

Do you have any suggestions on how to put in a waiting period that will still enable me to use the GUI in the meantime?

I.G.
The background task should be the way to go. I wonder what went wrong?

To use a background task, you will have to re-arrange your code quite a bit. The idea would be something like this:

First, you will need some global variables to store the state of the system. A special data folder is good for such things, so that you can sequester all the variables your system uses in place where they aren't in the way of your on-going use of Igor, and where they are less likely to get damaged inadvertently.

Your Start button would set motor 1 in motion, start the background task and then return control to Igor. The Stop button would check the system state, and stop whatever motor(s) were currently moving and stop the background task. The background task would check the time or motor position of the currently running motor, and if it's time or in position, read the global variables to figure out what's next. It would then issue commands to the motors to do the next thing, and return control to Igor.

My guess is that you didn't understand the part about returning control to Igor. If you currently have a loop that checks the motor position, you would use what's inside your loop as the body of the background task. Igor running the background task periodically takes the place of the loop itself.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
I agree with John's recommendation about using a background task but that would be a lot of work. If you want something quick and dirty you could use a progress window. Here is a function that you can start with:
// Example: MoveMotors(3, 4, 5)
Function MoveMotors(delay1, delay2, delay3)
    Variable delay1, delay2, delay3     // In seconds
   
    // Create progress window
    NewPanel /N=ProgressPanel /W=(285,111,739,193)
    ValDisplay ProgressBar,pos={18,32},size={342,18},limits={0,100,0},barmisc={0,0}
    ValDisplay ProgressBar,value= _NUM:0
    ValDisplay ProgressBar,mode= 4          // candy stripe
    Button StopButton,pos={375,32},size={50,20},title="Stop"
    DoUpdate /W=ProgressPanel /E=1          // mark this as our progress window
   
    Variable stopPressed = 0
   
    Variable startTicks, endTicks, ticksNow
   
    // Move motor 1
    Print "Moving motor 1"
    startTicks = ticks
    endTicks = startTicks + 60*delay1
    do
        ValDisplay progressBar,value=_NUM:1,win=ProgressPanel
        DoUpdate /W=ProgressPanel
        if (V_Flag == 2)                // We only have one button and that means stop
            stopPressed = 1
            break
        endif
        ticksNow = ticks
    while(ticksNow < endTicks)
    if (stopPressed)
        Print "Stop pressed - aborting motor 1"
        KillWindow ProgressPanel
        return 1
    endif
    Print "Motor 1 movement completed"
   
    // Move motor 2
    Print "Moving motor 2"
    startTicks = ticks
    endTicks = startTicks + 60*delay1
    do
        ValDisplay progressBar,value=_NUM:1,win=ProgressPanel
        DoUpdate /W=ProgressPanel
        if (V_Flag == 2)                // We only have one button and that means stop
            stopPressed = 1
            break
        endif
        ticksNow = ticks
    while(ticksNow < endTicks)
    if (stopPressed)
        Print "Stop pressed - aborting motor 2"
        KillWindow ProgressPanel
        return 2
    endif
    Print "Motor 2 movement completed"
   
    // Move motor 3
    Print "Moving motor 3"
    startTicks = ticks
    endTicks = startTicks + 60*delay3
    do
        ValDisplay progressBar,value=_NUM:1,win=ProgressPanel
        DoUpdate /W=ProgressPanel
        if (V_Flag == 2)                // We only have one button and that means stop
            stopPressed = 1
            break
        endif
        ticksNow = ticks
    while(ticksNow < endTicks)
    if (stopPressed)
        Print "Stop pressed - aborting motor 3"
        KillWindow ProgressPanel
        return 3
    endif
    Print "Motor 3 movement completed"

    KillWindow ProgressPanel
    Print "Motor movement completed"
    return 0
End