Machsupport Forum
Mach Discussion => Mach4 General Discussion => Topic started by: B34R on November 04, 2019, 09:12:26 PM
-
Hey Folks,
I've been skulking around here for a while but this is my 1st post....
I was hoping someone might be able to guide me in the right direction with an issue i'm having on my CNC Router build.
any input y'all might have would be very much appreciated, this is the FINAL thing standing in my way to complete this project !!!
NOTE: I made an M6() macro based off of work shared by DazTheGas (THANKS DAZ!)
Problem statement:
My Z axis will not move down once a probe command is given.
I have a simple macro that moves the router to a known tool change location, then it should begin its probe and it fails...
NOTE: this problem exists before I edited the macro. It was noticed while attempting : "touch" module / M6() / G31 command(s) or functions on the "Probing" tab....
My system:
My setup is a ESS + C25 BOB with dedicated PC running Mach4
Ess PlugIn: v250
Mach4: 4.2.0.4300
configured for INCH measurements
Servo motors with Gecko drives
4'x6' table
the probe is a small corner plate with a clip on the router bit
Analysis:
The macro starts to run as expected:
1) m6() command received = GOOD
2) move to tool change location = GOOD
3) begin probe = FAIL
4) change tool = n/a
5) re-probe = n/a
6) run G-code again = n/a
looking at the ESS data log it seems as if the probe dose start but then it is immediately done ?
"2019-11-04 17:15:30.549 - >>>>> ESS received a Tool Change Done notification."
Full Log from recent attempt:
2019-11-04 17:15:18.092 - API: mcCntlMdiExecute(inst = 0, commands = 't4 m6()') (Mach4GUI)
2019-11-04 17:15:18.194 - Attempt transition from "Idle" on event "MDI Start" controller.cpp:2256
2019-11-04 17:15:18.194 - S_IDLE_on_exit
2019-11-04 17:15:18.194 - ACTION_start_mdi
2019-11-04 17:15:18.194 - SoftSync()! Clearing planner.
2019-11-04 17:15:18.215 - S_MDI_RUNNING_on_entry
2019-11-04 17:15:18.215 - SoftSync()! Clearing planner. stateinterface.cpp:1250
2019-11-04 17:15:18.215 - S_MDI_RUNNING2_on_entry
2019-11-04 17:15:18.215 - Signal id 1114, (Gcode Running), changed from LOW to HIGH.
2019-11-04 17:15:18.242 - Signal id 1121, (Tool Change), changed from LOW to HIGH.
2019-11-04 17:15:18.243 - >>>>> ESS received a Tool Change Required notification.
2019-11-04 17:15:22.871 - API: mcCntlGcodeExecuteWait(inst = 0, commands = 'G90 G53 G0 Z0.0') (unknown caller)
2019-11-04 17:15:22.983 - SoftSync()! Clearing planner. gcodeexec.cpp:168
2019-11-04 17:15:23.139 - SoftSync()! Clearing planner. controlset.cpp:208
2019-11-04 17:15:23.139 - API: mcCntlGcodeExecuteWait(inst = 0, commands = 'G90 G53 G0 X01.0 Y01.0') (unknown caller)
2019-11-04 17:15:23.250 - SoftSync()! Clearing planner. gcodeexec.cpp:168
2019-11-04 17:15:23.407 - SoftSync()! Clearing planner. controlset.cpp:208
2019-11-04 17:15:30.549 - >>>>> ESS received a Tool Change Done notification.
2019-11-04 17:15:30.550 - Signal id 1121, (Tool Change), changed from HIGH to LOW.
2019-11-04 17:15:30.550 - >>>>> ESS received a Tool Change Done notification.
2019-11-04 17:15:30.654 - Attempt transition from "MDI Running" on event "Stop" gcodeexec.cpp:1285
2019-11-04 17:15:30.654 - S_MDI_RUNNING2_on_exit
2019-11-04 17:15:30.654 - Signal id 1114, (Gcode Running), changed from HIGH to LOW.
2019-11-04 17:15:30.654 - S_MDI_RUNNING_on_exit
2019-11-04 17:15:30.654 - ACTION_stop
2019-11-04 17:15:30.682 - S_IDLE_on_entry
MACRO CODE:
function m6()
local inst = mc.mcGetInstance()
local selectedTool = mc.mcToolGetSelected(inst)
local currentTool = mc.mcToolGetCurrent(inst)
local xstart = mc.mcAxisGetPos(inst,0)
local ystart = mc.mcAxisGetPos(inst,1)
if
selectedTool == currentTool
then
return
mc.mcCntlSetLastError(inst, "Tool change activated but NOT required")
else
wx.wxMessageBox("Tool change required: press ok to move router to the tool change position")
mc.mcCntlGcodeExecuteWait(inst, "G90 G53 G0 Z0.0")
mc.mcCntlGcodeExecuteWait(inst, "G90 G53 G0 X01.0 Y01.0")
wx.wxMessageBox("Press ok to begin 1st probing")
RunProbe(currenttool)
local toolz = mc.mcAzisGetPos(inst,2)
mc.mcCntlGcodeExecuteWait(inst, "G90 G53 G0 Z0.0")
local changetoo = mc.mcToolGetDesc(inst,selectedTool)
wx.wxMessageBox("Insert Tool Number "..selectedTool.." "..changetoo.." and press OK to continue")
mc.mcCntlGcodeExecuteWait(inst, "G90 G53 G0 X01.0 Y01.0")
wx.wxMessageBox("Press ok to begin 2nd probing")
RunProbe(selectedTool)
mc.mcAxiseSetPos(inst, 2, toolz)
mc.mcCntlGcodeExecuteWait(inst,"G90 G53 G0 Z0.0")
mc.mcCntlGcodeExecuteWait(inst,"G90 G0 X"..xstart.." Y"..ystart)
mc.mcToolSetCurrent(inst,selectedTool)
mc.mcCntlSetLastError(inst, "Tool change finished")
end
end
function RunProbe(tool)
local inst = mc.mcGetInstance()
local toollen = mc.mcToolGetData(inst, mc.MTOOL_MILL_HEIGHT, tool)
if
toollen == 0
then
toollen = 3
end
local probestart = -8+ toollen
mc.mcCntlGcodeExecuteWait(inst, "G90 G53 G0 Z"..probestart)
mc.mcCntlGcodeExecuteWait(inst, "G91 G31 Z-15 F25")
end
if (mc.mcInEditor() == 1) then
m6()
end
-
Haven't studied it all but mc.mcAzisGetPos is not right. Think you meant mc.mcAxisGetPos
Also, you should not call a message box from a macro.
-
Yes good eyes Chaoticone, I have fixed that typo on my machine already lol but i copied the old code to the post (oops ::) )
[ I have updated the macro code in the 1st post to be exactly as it is currently on my machine ].
Question: what conflict would calling a message box from a macro cause ?
-
Macros are in their own chunk and are ran separate from the GUI scripts. From a macro they may not get the correct parent (macros have no GUI). Best to have the macro set a register and monitor that register and launch the message box from the PLC script (which is in the the GUI) if needed.
-
Interesting... thanks for the education, I'll look at striping that down in the next revision. I would be surprised if that was contributing to my error tho... as even with the stock M6() macro i am receiving the same results...
-
B34R
i got this from Steve at New Fangled.
When you are ready to add the message box hope this helps.
Most of the script has been deleted. I left the part about the register that you will need.
Bill
So the issue is that you are launching a wxMessageBox from a macro script. The macro scripts are run from the G code interpreter which is, in turn, run from the thread that loads the look ahead buffers. This is NOT the main thread in the application, the core, or the mcLua plugin. So no GUI functions should ever be launched from a macro script. Also, the wxMessageBox() call really wants to have a parent window launch it. There is no parent window in a macro script. So what modal state does it take on? The answer is undefined behavior, as in “we won’t know”.
I understand the allure of wxMessageBox(). It is simple and easy to use. But It just is never a good idea to use it in a macro script. In fact, I wish I could take it out of wxLua completely because of this situation. But what needs to be done is launch the wxMessageBox() from a main thread such as the Mach4GUI’s PLC script.
1. Replace the wxMessageBox() calls in the macro script with “set and wait on clear” register flags.
2. In the Mach4GUI’s PLC script, watch for the register to become set and launch the wxMessageBox().
3. Once the user dispenses with the message box, clear the register.
4. The macro script sees that the register is clear and continues on.
Here is the semi complete example for the macro script:
function m60()
inst = mc.mcGetInstance() -- Get the current instance
local rc -- Check the API return codes!!!! There are no mysteries if you do. :)
--check for manual cut and wait if manual cut on
local hregC, rc = mc.mcRegGetHandle(inst, 'iRegs0/ManCut')
if (rc != mc.MERROR_NOERROR) then
-- this will abort the G code process. Reset will have to be issues to clear the alarm.
mc.mcCntlMacroAlarm(inst, 0, "m60: Cannot get the handle to ManCut");
return
end
local waitReg, rc = mc.mcRegGetHandle(inst, 'iRegs0/WaitFlag')
if (rc != mc.MERROR_NOERROR) then
-- this will abort the G code process. This will just stop the file.
mc.mcCntlMacroStop(inst, 1, "m60: Cannot get the handle to ManCut");
return
end
-- I will leave the rest of the error checking as your exercise. :)
local ManualCut = mc.mcRegGetValue(hregC)
if (ManualCut == 1) then
mc.mcRegSetValue(waitReg, 1) -- set the register.
--wx.wxMessageBox("Press Manual Cut Button")
while (mc.mcRegGetValue(waitReg) == 1) do -- wait for it to clear.
wx.wxMilliSleep(10)
end
end
while (ManualCut == 1) do
wx.wxMilliSleep(100)
ManualCut = mc.mcRegGetValue(hregC)
Steve
-
Hey Bill_O,
Thanks for the info and sample script !
I'll re-write the macro with the info from Bill_O and Chaoticone then attempt to run a new version of the script today after work (I'll post details of what happens).
Thanks guys!
-
Hey Folks
I have a new draft for M6 Macro with reg calls for message box [code below with full line comments of what I THINK it means lol] I hope to test this a few hours from now.
But i do have a question : Do I need to build in a 'wait' command or will the macro execution pause while there is an active (on screen) wx.wxMessageBox() called from Mach4GUI’s PLC script?
M6 Macro
function m6()
local inst = mc.mcGetInstance() -- Get current mc inst
local currentTool = mc.mcToolGetCurrent(inst) -- Get current tool #
local selectedTool = mc.mcToolGetSelected(inst) -- Get next tool #
local xstart = mc.mcAxisGetPos(inst,0) -- Get X pos
local ystart = mc.mcAxisGetPos(inst,1) -- Get Y pos
local TC_Msg = mc.mcRegGetHandle(inst,'iRegs0/TC_MSG') -- Get Register value for 'TC_MSG'
if -- If next tool = current tool, do nothing...
selectedTool == currentTool
then
mc.mcCntlSetLastError(inst, "Tool change activated but NOT required") -- Error bar message
return
else
mc.mcCntlGcodeExecuteWait(inst, "G90 G53 G0 Z0.0") -- Move Z to HOME
mc.mcCntlGcodeExecuteWait(inst, "G90 G53 G0 X01.0 Y01.0") -- Move X and Y to +1 machine coord
local ToolDes = mc.mcToolGetDesc(inst,selectedtool) -- Get tool description of NEXT tool
mc.mcCntlSetLastError("Insert Tool Number "..selectedTool.." "..ToolDes..) -- Error bar message
local mc.mcRegSetValue(TC_Msg, 1) -- Set reg to trigger wx.wxMessageBox (msg#1)
RunProbe(selectedTool) -- Start Probe function (coded below)
mc.mcCntlGcodeExecuteWait(inst,"G90 G53 G0 Z0.0") -- Return Z to HOME
mc.mcCntlGcodeExecuteWait(inst,"G90 G0 X"..xstart.." Y"..ystart) -- Return X and Y to last G-Code coord
mc.mcToolSetCurrent(inst,selectedTool) -- Set NEW tool as current tool
mc.mcCntlSetLastError(inst, "Z Probe complete: tool change complete") -- Error bar message
local mc.mcRegSetValue(TC_Msg, 2) -- Set reg to trigger wx.wxMessageBox (msg#2)
end
end
function RunProbe(tool) -- Func for Z probe
local inst = mc.mcGetInstance() -- Get current mc inst
local toollen = mc.mcToolGetData(inst, mc.MTOOL_MILL_HEIGHT, tool) -- Get NEW tool length from tool table
if toollen <= 0 then toollen = 3 end -- If the tool lenght is not listed in the table then we will assume it is == 3
local probestart = -8+toollen -- Probe starting location = -8inch from Z HOME +tool length (i.e -8+3= -5 inch from Z MACHINE 0)
mc.mcCntlGcodeExecuteWait(inst, "G90 G53 G0 Z"...probestart) -- Move to probe starting location
mc.mcCntlGcodeExecuteWait(inst, "G91 G31 Z-5 F20") -- Probe from current pos -5 inch at feed 20
mc.mcCntlGcodeExecuteWait(inst, "G91 G00 Z05") -- Retract +5 inch from probe/plate height
end
if (mc.mcInEditor() == 1)
then m6()
end
GUI PLC Code
local TC_MsgReg = mc.mcRegGetHandle(inst,'iRegs0/TC_MSG')
local TC_MsgCode = mc.mcRegGetValue(inst, TC_MsgReg)
if
TC_MsgCode == 1
then
wx.wxMessageBox("Tool change required: \n 1) Stop Spindle \n 2) Change tool \n 3) Press 'ok' to probe Z")
elseif
TC_MsgCode == 2
then
wx.wxMessageBox("Tool change complete: \n 1) START spindle \n 2) Press 'OK' to resume G-Code")
elseif
TC_MsgCode >= 3
then
wx.wxMessageBox("damn....********* is broke...")
elseif
return
end
-
I will let someone who is good at the code look that over.
I am almost positive I would miss something.
Bill
-
I do not see a While loop to wait for the register to change in your m6
Bill