91
Mach4 General Discussion / Re: activate script on button from script
« on: September 19, 2021, 12:52:25 PM »
Separate buttons == separate events. That is why it worked. Now you have one button with one event. And here is the insidious part, the PLC cycle is an event! So by running that one event, it prevents the PLC script from executing.
So the rule of thumb is to not have long running processes in button or other screen elements. This is accomplished by the use of a "state machine". All the button script code would do is start the state machine.
Button code:
Screen Load script:
Then is your PLC script, call the state machine function
The whole concept of a state machine lets you run long running processes without actually tying up the event loop with a while loop. Generally speaking, while loops should be avoided at all costs in any of the screen scripts. They are ok in M code scripts when you want to wait on the whole script to complete anyway.
You will also want to put some sort of abort mechanism in case the operator wants to abort during the process (set RecordingProcessState = 0). Notice that if you use Stop Cycle (which I hate), you will have to modify your screen to make the stop cycle button stop the cycle AND set RecordingProcessState = 0, otherwise, the state machine will see the machine go to the idle state and continue to the next phase!
Steve
So the rule of thumb is to not have long running processes in button or other screen elements. This is accomplished by the use of a "state machine". All the button script code would do is start the state machine.
Button code:
Code: [Select]
StartRecording()
Screen Load script:
Code: [Select]
RecordingProcessState = 0 -- a global LUA variable for the state machine state.
function StartRecording()
RecordingProcessState = 1 -- start the recording state machine.
end
function Execute0()
--Gcode to execute the 0 degree stuff
mc.mcGcodeExecute() (Don't use mc.mcGcodeExecuteWait() as you want to hand the task off to the interpreter and go!
wxMilliSleep(50) -- give the G code a chance to start.end
function Execute2()
--Gcode to execute the 2 degree stuff
mc.mcGcodeExecute()
wxMilliSleep(50)
end
function Execute4()
--Gcode to execute the 4 degree stuff
mc.mcGcodeExecute()
wxMilliSleep(50)
end
function Execute6()
--Gcode to execute the 6 degree stuff
mc.mcGcodeExecute()
wxMilliSleep(50)
end
function WaitForIdle()
local state = mc.mcCntlGetState()
if (state == mc.MC_STATE_IDLE) then
return true
end
return false
end
function RecordingStateMachine()
if (RecordingProcessState > 0) then
if (RecordingProcessState == 1) then
RecordingProcessState = 2
Execute0()
elseif (RecordingProcessState == 2) then
-- wait for Execute0() to finish.
if (WaitForIdle() == true) then
RecordingProcessState = 3
end
elseif (RecordingProcessState == 3) then
RecordingProcessState = 4
Execute2()
elseif (RecordingProcessState == 4) then
-- wait for Execute2() to finish.
if (WaitForIdle() == true) then
RecordingProcessState = 5
end
elseif (RecordingProcessState == 5) then
RecordingProcessState = 6
Execute4()
elseif (RecordingProcessState == 6) then
-- wait for Execute4() to finish.
if (WaitForIdle() == true) then
RecordingProcessState = 7
end
elseif (RecordingProcessState == 7) then
RecordingProcessState = 8
Execute6()
elseif (RecordingProcessState == 8) then
-- wait for Execute6() to finish.
if (WaitForIdle() == true) then
RecordingProcessState = 9
end
elseif (RecordingProcessState == 9) then
RecordingProcessState = 0
-- The state machine has finished!!! Maybe raise a signal or the like?
end
end
end
Then is your PLC script, call the state machine function
Code: [Select]
RecordingStateMachine()
The whole concept of a state machine lets you run long running processes without actually tying up the event loop with a while loop. Generally speaking, while loops should be avoided at all costs in any of the screen scripts. They are ok in M code scripts when you want to wait on the whole script to complete anyway.
You will also want to put some sort of abort mechanism in case the operator wants to abort during the process (set RecordingProcessState = 0). Notice that if you use Stop Cycle (which I hate), you will have to modify your screen to make the stop cycle button stop the cycle AND set RecordingProcessState = 0, otherwise, the state machine will see the machine go to the idle state and continue to the next phase!
Steve