321
Mach4 General Discussion / Coroutines, Button Scripts, Modules, Probing
« on: January 31, 2018, 01:47:20 PM »
I am posting this as a means of saying thank you to all of you that have helped me to begin to understand how Mach4 operates and hope that this serves as a jump start for all of the new users of Mach4
This example shows:
How to use a coroutine in a button script so the GUI does not lock while probing.
The use of a module so that the routine can be used by any button.
Using Lua's ability to return multiple values from a function
Use of registers used by Mach4 for probe
Use of global vars set with the screen load script load modules section
Use of the scr variable to retrieve and set screen elements
Use of relative movements in Lathe since fanuc lathes do not recognize G91
A big thank you to DazTheGas for his video on coroutines: https://www.youtube.com/watch?v=t2xQYvAXT8o&feature=youtu.be
and to Brannab for her video on using the screen editor: https://www.youtube.com/watch?v=P1xZkFgS5cQ
Be sure to watch both of these if your new to Mach4.
The file 'load_modules.mcs' residing in the profile's '\Macros' directory and loads any of your self defined modules for the profile being used.
The following is one of the functions (probe) I use in a module 'rtMyModule.lua' that resides in the profile's '\Modules' subdirectory. The function could be defined and used in a button script but would then not be available to any other button calls. I use this function for five buttons on a tab I created.
--Button code to probe from current position for x minus direction
HTH
RT
This example shows:
How to use a coroutine in a button script so the GUI does not lock while probing.
The use of a module so that the routine can be used by any button.
Using Lua's ability to return multiple values from a function
Use of registers used by Mach4 for probe
Use of global vars set with the screen load script load modules section
Use of the scr variable to retrieve and set screen elements
Use of relative movements in Lathe since fanuc lathes do not recognize G91
A big thank you to DazTheGas for his video on coroutines: https://www.youtube.com/watch?v=t2xQYvAXT8o&feature=youtu.be
and to Brannab for her video on using the screen editor: https://www.youtube.com/watch?v=P1xZkFgS5cQ
Be sure to watch both of these if your new to Mach4.
The file 'load_modules.mcs' residing in the profile's '\Macros' directory and loads any of your self defined modules for the profile being used.
Code: [Select]
---------------------------------------------------------------
-- C:\Mach4Hobby\Profiles\MyTurn4\Macros\load_modules.mcs
-- Load modules that you want to be able to use from Mcodes
---------------------------------------------------------------
inst = mc.mcGetInstance()
local profile = mc.mcProfileGetName(inst)
local path = mc.mcCntlGetMachDir(inst)
package.path = path.."\\Profiles\\"..profile.."\\Modules\\?.lua;"..path.."\\Modules\\?.lua;"
--ErrorCheck module
package.loaded.mcErrorCheck = nil
ec = require "mcErrorCheck"
mm = require "mcMasterModule" -- resides: C:\Mach4Hobby\Modules
prb = require "mcProbing" -- resides: C:\Mach4Hobby\Modules
rt = require "rtMyModule" -- resides: C:\Mach4Hobby\Profiles\MyTurn4\Modules
gs = require "GcodeScripter" -- resides: C:\Mach4Hobby\Profiles\MyTurn4\Modules
The following is one of the functions (probe) I use in a module 'rtMyModule.lua' that resides in the profile's '\Modules' subdirectory. The function could be defined and used in a button script but would then not be available to any other button calls. I use this function for five buttons on a tab I created.
Code: [Select]
local rtModule = {}
-- probes using relative positioning and returns the work and machine coordinates of a successful strike
-- rc==nil for failure and rc==0 for success
function rtModule.probe(prbNmbr,axis,dis,spd)
if prb==nil then
--build:3481 prb and mm are initialized in the load script. mcMasterModule.lu and mcProbing.lua
wx.wxMessageBox('prb is nil')
return nil,nil,nil
end
if not prb.CheckProbe(1,tonumber(prbNmbr)) then--CheckProbe throws an error message if probe is obstructed
return nil,nil,nil
end
axis=string.upper(axis)
--set vars for the axis to probe and their vars, see Mill GCode Programming.pdf page 19 g31
--Lathe does not recognize G91 so axes are represented by alternate letters for relative positioning
if axis=='Z'then
prb.NilVars(5063,5063)
prb.NilVars(5073,5073)
relAxis='w'
mcAxis=mc.Z_AXIS
elseif axis=='X'then
prb.NilVars(5061,5061)
prb.NilVars(5071,5071)
relAxis='u'
mcAxis=mc.X_AXIS
elseif axis=='Y'then
prb.NilVars(5062,5062)
prb.NilVars(5072,5072)
relAxis='v'
mcAxis=mc.Y_AXIS
--[[ need axis alternate letters for A,B,C
elseif axis=='C'then
prb.NilVars(5066,5066)
prb.NilVars(5076,5076)
relAxis='h'
mcAxis=mc.C_AXIS
--]]
else
wx.wxMessageBox('Invalid Axis: '..axis)
end;
--execute the gcode and call the coroutine to let the GUI be updated
--these two lines act like what you would expect mcCntlGcodeExecuteWait to do
mc.mcCntlGcodeExecute(mc.mcGetInstance(),'g'..tostring(prbNmbr)..relAxis..tostring(dis)..' f'..tostring(spd))
coroutine.yield()
--check for valid probe strike
local rc=mc.mcCntlProbeGetStrikeStatus(mc.mcGetInstance())
if rc==0 then
wx.wxMessageBox('Fault: No Probe Strike')
return nil,nil,nil
end;
--find where the probe made contact
local posWrk,rc=mc.mcAxisGetProbePos(mc.mcGetInstance(),mcAxis,0)--probe Strike Position Work Coords
local posMach,rc=mc.mcAxisGetProbePos(mc.mcGetInstance(),mcAxis,1)--probe Strike Position Machine Coords
--at this point you could execute more probes by:
-- local s='g1'..tostring(prbNmbr)..relAxis..tostring(-dis)..'\n' --back off
-- s=s..'g'..tostring(prbNmbr)..relAxis..tostring(dis)..'\n' --probe
-- mc.mcCntlGcodeExecute(mc.mcGetInstance(),s)
-- coroutine.yield()
return posWrk,posMach,0 --return the work and machine coordinates for the strike and indicate success with 0
end
return rtModule
--Button code to probe from current position for x minus direction
Code: [Select]
wait=coroutine.create( --wait defined in PLC script found in screen edit mode top entry in the Screen Tree Manager
function ()
-- set results initially to nil for visual confirmation of good or bad result
scr.SetProperty('txtProbeResult','Value','nil')
scr.SetProperty('txtProbeResultMach','Value','nil')
scr.SetProperty('txtProbeOver','Value','nil')
-- get parameters
local prbCde=scr.GetProperty('txtProbeCode','Value') --which probe input is being used: 31.0 31.1,31.2,31.3
local dis=scr.GetProperty('txtProbeDistance','Value') -- max distance to probe
local spd=scr.GetProperty('txtProbeSpeed','Value') -- speed to probe at
local prbDia=tonumber(tostring(scr.GetProperty('txtProbeDiameter','Value'))) --used for tool setting calculation
--call the probe function defined in Module rtMyModule.lua, rt set in Screen Load Script Load Module section
--probe returns the position of the probe strike in work and machine coordinates
-- probe returns nils for unsuccessful probe attempt
local prbWrk,prbMach,rc=rt.probe(prbCde,'x','-'..dis,spd)
if rc~=0 then
return
end
local prbOver=mc.mcAxisGetMachinePos(mc.mcGetInstance(),mc.X_AXIS) -- overshoot of probe
local prbErr=math.Wrk(prbMach-prbOver) -- difference between Strike point and stop/overshoot point
-- 0==success, update results
if rc==0 then
scr.SetProperty('txtProbeResult','Value',string.format('%.5f',prbWrk))
scr.SetProperty('txtProbeResultMach','Value',string.format('%.5f',prbMach))
scr.SetProperty('txtProbeOver','Value',string.format('%.5f',prbErr))
mc.mcCntlSetLastError(mc.mcGetInstance(),'X Probe Complete')
end
end
)
HTH
RT