Hello Guest it is November 15, 2019, 06:46:00 PM

Author Topic: mc.mcCntlGcodeExecuteWait problems  (Read 1213 times)

0 Members and 1 Guest are viewing this topic.

Offline gorf23

*
  •  138 138
    • View Profile
mc.mcCntlGcodeExecuteWait problems
« on: November 21, 2017, 11:15:14 AM »
Having trouble getting this code to run correctly from a button press may be something within the GUI not sure
if I press the button mach4 seems to lock up doesn't respond but if I wait long enough it does respond and the DRO jumps right from 0 to -5
if I run the same code without the Wait  it runs ok the DRO runs up at the feed rate  and mach4 doesn't seem to lock up

has something changed, it use to work tried new profiles but same results.. and these are the only two lines
in the button press script..

thanks gary

Code: [Select]
local inst = mc.mcGetInstance()
Code: [Select]
mc.mcCntlGcodeExecuteWait(inst,"G91 G31 Z-5 F1000") -- change feedrate and depth to suit[/quote]
Re: mc.mcCntlGcodeExecuteWait problems
« Reply #1 on: November 21, 2017, 11:55:19 AM »
Hi,

i have the same problem. mcCntlGcodeExecuteWait blocks ui when called from a button script - thats normal (i dont understand how this beavior can be normal, but this is another question). You need to run an coroutine. I cant handle this correctly at the moment, my post is here:

http://www.machsupport.com/forum/index.php/topic,36009.0.html

Hope finding a solution...

Steffen

Offline smurph

*
  • *
  •  1,149 1,149
  • "That there... that's an RV."
    • View Profile
Re: mc.mcCntlGcodeExecuteWait problems
« Reply #2 on: November 21, 2017, 01:10:08 PM »
I explain why the GUI occurs on this post:  http://www.machsupport.com/forum/index.php/topic,36013.msg246649.html#msg246649

What you have told the control to do is execute "G91 G31 Z-5 F1000" and wait until it is done.  And that is exactly what it is doing.  :) 

mc.mcCntlGcodeExecuteWait() really shouldn't be used in a button script.  Most of the time, what you want is the plain old mc.mcCntlGcodeExecute() call with multiple lines passed to it.  If you find yourself REALLY actually needing to wait on a task, it is better to start the task with a buttons script and "wait" on it to finish in the PLC script.  This involves using what is called (in the programming world) a state machine.  Typically it is implemented with a global variable that is defined in the screen load script.  Call it "Zprobe" or something and set it to zero

Add this to the screen load script:
Code: [Select]
Zprobe = 0 -- the initial state of the state machine. 0 == not running.

The button script would contain just a small bit of code to start the action:

Code: [Select]
if (Zprobe == 0) then -- Only start the task is it isn't already running.
  Zprobe = 1 -- 1 == start the Z probe.
end

In the PLC scrip, you "watch" Zprobe and act on it accordingly:

Code: [Select]
controlState = mc.mcCntlGetState(inst) -- what state is the control in?

if ((Zprobe == 1) and (controlState == mc.MC_STATE_IDLE)) then
  mc.mcCntlGcodeExecute(inst, "G91 G31 Z-5 F1000") -- start the Z probe.  Notice that we don't use the Wait version of this function
  --Wait on the machine to NOT be idle.  This won't take long at all.  But we need to make sure that the control has entered the running state.
  while (controlState == mc.MC_STATE_IDLE) do
    controlState = mc.mcCntlGetState(inst)
  end
  Zprobe = 2 -- change the state. 2 == Z probe running.
elseif ((Zprobe == 2) and (controlState == mc.MC_STATE_IDLE)) then
  -- the task is done.  Record the Z probe pos, if needed, and retract the spindle to
  local zMachineProbePos = mc.mcAxisGetProbePos(inst, mc.Z_AXIS, 1);  -- Do something with it?  I dunno...  :)
  mc.mcCntlGcodeExecute(inst, "G53 G00 Z0") -- Raise Z to machine pos Z0.  Notice that we don't use the Wait version of this function either.
  --Wait on the machine to NOT be idle.  This won't take long at all.  But we need to make sure that the control has entered the running state.
  while (controlState == mc.MC_STATE_IDLE) do
    controlState = mc.mcCntlGetState(inst)
  end
  Zprobe = 3 -- change the state. 3 == Z retracting.
elseif ((Zprobe == 2) and (controlState == mc.MC_STATE_IDLE)) then
  -- everything is done.  Simply change the state of your state machine.
  Zprobe = 0 -- change the state. 0 == not running.
end

In this example, all the button does is set a variable.  That is extremely fast and will not "lock" the GUI.  Then, the PLC script watches that variable every time it is run and also does things that don't take a long time to do.  The tasks are simply "handed off" to the interpreter.

The reason why the GUI locks up on long running tasks is because of the way the Windows Operating System handles the application's event loop.  In the C/C++ programming world, we usually get around this by using multiple threads of execution.  And the button press event would "launch a thread" to handle the event.  But LUA is not multi-threaded, so we just can't do it.  LUA has something like threads, called coroutines, which can be used.  But coroutines are not preemptive.  It is more of a cooperative model and thus harder to use.  To me, implementing a state machine in the PLC script is the far easier and more logical/understandable method. 

Steve

Offline gorf23

*
  •  138 138
    • View Profile
Re: mc.mcCntlGcodeExecuteWait problems
« Reply #3 on: November 21, 2017, 06:17:53 PM »
Thanks I understand that part now.

Can you call it from a form or dialog, and can you send it variables like a function call the
PLC doesn't look like you can pass variables to it or is there another trick for that
say you want to change the travel distance exc..

Thanks gary

Offline smurph

*
  • *
  •  1,149 1,149
  • "That there... that's an RV."
    • View Profile
Re: mc.mcCntlGcodeExecuteWait problems
« Reply #4 on: November 21, 2017, 06:27:32 PM »
Use a register (in place of the global var) if you want more than the screen scripts to use it.

Steve

Offline gorf23

*
  •  138 138
    • View Profile
Re: mc.mcCntlGcodeExecuteWait problems
« Reply #5 on: November 21, 2017, 07:23:13 PM »
ok can do that one more question is possible to use LoadSettings() for your own module

If so what are the requirements for the module I have tried it but always
get a error nil value for the LoadSettings() so PLC shuts down..

Thanks gary
Re: mc.mcCntlGcodeExecuteWait problems
« Reply #6 on: November 21, 2017, 07:24:19 PM »
Hi Steve,

thank you very much for your advice. I see this very critical, because its much work and code to do simple scripting in this way. Because the need of adding all functions to plc code this gets a big monolitic thing instead of clean small separated scripts (yes i know, i can separate the functions in different files, but in the end everything is in PLC)

Steffen

Offline gorf23

*
  •  138 138
    • View Profile
Re: mc.mcCntlGcodeExecuteWait problems
« Reply #7 on: November 22, 2017, 10:39:11 AM »
if I use this code in the screen load script and call it from a button press why would I always get a nil value error.

it works fine as long as it's in the button press script but not when I try to call it from a button press when its in the screen load script...

Thanks gary

Code: [Select]
function GetRegister(regname, num)
local hreg = mc.mcRegGetHandle(inst, string.format("iRegs0/%s", regname))
local val = mc.mcRegGetValueString(hreg)
if (num == 1) then
val = tonumber(val)
end
return val
end

function SetRegister(regname, val, num)
local hreg = mc.mcRegGetHandle(inst, string.format("iRegs0/%s", regname))
if (num == 1) then
mc.mcRegSetValue(hreg, tonumber(val))
else
mc.mcRegSetValueString(hreg, val)
end
end

Offline gorf23

*
  •  138 138
    • View Profile
Re: mc.mcCntlGcodeExecuteWait problems
« Reply #8 on: November 24, 2017, 06:43:25 PM »
 Steve.
mcCntlGcodeExecute Works ok though the PLC but what I want to try and do is not probing but when you enter a distance for axis to travel I can

check on the position of the axis so I know when it has been reached, I have been trying to use mcAxisGetPos but if I call that when a axis is still moving the gui locks up same as when
I use mcCntlGcodeExecuteWait. any other way to check axis position ..

Also why can mcCntlGcodeExecuteWait be used in the mcProbing module I don't see anything special there.. but seems to work.

Thanks gary