Hello Guest it is April 19, 2024, 11:58:39 AM

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - rhtuttle

Pages: « 1 2 3 4 5 6 7 8 9 »
41
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.

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

42
Mach4 General Discussion / G91 - Lathe
« on: January 30, 2018, 04:23:24 PM »
Since lathe doesn't have a g91 you swap letters for relative moves
x ->u
y->v
z->w
a->?
b->?
c->h?

Anyone know the abc for sure?

TIA

RT

43
Mach4 General Discussion / Lathe 'Set X Offset'
« on: January 27, 2018, 07:56:36 PM »
What offsets are being affected by 'Set X Offset' or 'Set Z Offset' buttons when using Mach4 lathe?  I only see the x and z dros being changed and nothing in the tool table or fixture table.

When reading about setting up the tool table some of the posts reference setting fixture offsets.  How do fixture offsets affect tool table settings?

TIA

RT

44
Mach4 General Discussion / Lathe Fixture offsets
« on: January 27, 2018, 07:53:21 PM »
Could someone explain when you would use fixture offsets with a lathe?

TIA

RT

45
I have just spent the better part of a day examining the probing wizard and the mcProbing.lua file.  I have monitored and searched the many posts regarding both probing, g31 calls and locked GUIs.  I have used coroutines in a homing button script because there was a mcAxisHomeComplete that I could loop on.  

With regards to g31 calls, there seems to be no equivalent api function, ISIG, register or poundvar that you can poll to find out if it has finished moving.  There is a thread by Smurph that talks about using a plc script to monitor a register variable that seems viable.  

Did I miss an API, ISIG or some other method of determinig that a g31 call has completed, not whether it struck but whether it has completed its move? isStill and isInCycle don't work during a probe.

After going through the probing wizard buttons, the mcProbing.lua and mcMasterModule.lua functions I found no coroutines, no use of the PLC wait nor any reading or setting of registers.  Just successive calls to mcCntlGcodeExecuteWait...and it does not lock up the screen.

When I call a 'substantially' similar routine in a module I created, I get a locked screen until the module function finishes its mcCntlGcodeExecuteWait.

Any help?

TIA

RT




46
Mach4 General Discussion / Probe wizard on Lathe
« on: January 25, 2018, 05:44:30 PM »
I exported the probe tab in the mill screenset and imported it into the lathe screenset. Filled in the settings and ran a Z single surface probe. I get an error message 'Unknown GCode used'.

Is there a gcode being issued that is only applicable to mill usage?

TIA

RT

47
Mach4 General Discussion / Lathe probing screen
« on: January 25, 2018, 11:21:43 AM »
Has anyone ported the probing from mill to Lathe? 

Modified it so that makes sense for a lathe?

I know how to export the page from mill screenset and import it to lathe screenset but was hoping someone else would like to share their hard work and save me a lot of time  ;D

TIA

RT

48
Mach4 General Discussion / Homing and Tool offsets on Lathe
« on: January 19, 2018, 03:34:03 PM »
Not being a machinist I have a question about homing and tool offsets.  I just started developing my tool table a couple of weeks ago and enjoy being able to swap tools and have confidence that It will continue on where you would expect it.  Whoop whoop!!

My assumption (big mistake) is that since turning is typically done on center and that all tool cutting points have their x axis offset from machine zero to the centerline.  I thought that when I homed/ref'd, that machine zero would be set, and, the XDRO would adjust to reflect the current tool offset in effect.  As an example,  if tool 1 has an offset from home and entry in the tool table of -3.1255 I would have thought that after homing the XDRO would read -6.251.  On my machine the DRO is unaffected.

a.  Was my thought process wrong?
b.  Should I change the ref x button to have a script that refs x and then reads the current offset and sets the xDro to that number?

TIA

RT

49
Mach4 Videos / Lathe Canned Cycles
« on: January 18, 2018, 03:36:19 PM »
Here is a video made by MachMotion that explain the lathe canned cycles usage.  From there you can go to other videos of specific canned cycles

https://youtu.be/mIPQJgzdX_I

50
Mach4 General Discussion / Lua Fails Me
« on: January 13, 2018, 03:30:45 PM »
Just when I think i am starting to understand lua I run into this.  The code below is a macro that I have used many times and today I wanted to alter it a bit.  When the changes didn't do what I thought it should i started putting in wxMessagBox calls in to see where it was failing.  When the first message box didn't pop up I was surprised, but even more surprised that the macro continued to execute including the second popup telling me to switch gearing.  What am I missing?  I deleted the .mcc and .mcs.bak several times and completely restarted windows with the same results.  I am at a total loss on this one.

Code: [Select]
function m6691(hVars)
  local xNow,zNow,maxVal,rc
  local ts,tr,te,sCode
  local currPos
  local plungeFeed=1
  local roughDOC=0.018
  local roughFeed=18
  local roughSpeed=1200
  local finishDOC=0.004
  local finishFeed=8
  local finishSpeed=1800
  local endX=.850 --param1()
 
  local inst=mc.mcGetInstance()

  wx.wxMessageBox('nil')  --HOW  IS THIS SKIPPED?
 
  if mc.mcSpindleGetCurrentRange(inst)~=1 then
    --rt.rtAudio("notify")
    --wx.wxSound('C:\\mach4Hobby\\Sounds\\Notify.wav',0):Play()
    wx.wxMessageBox('Set Spindle Gearing to High Speed')    --THIS ONE DOES GET EXECUTED!!!
    mc.mcSpindleSetRange(inst,1)
  end
  if (hVars ~= nil) then
    local DFlag = mc.mcCntlGetLocalVarFlag(inst, hVars, mc.SV_D)
    if(DFlag == 1) then
      endX = mc.mcCntlGetLocalVar(inst, hVars, mc.SV_D)
      mc.mcCntlSetLastError(inst,"Turning Diameter to "..endX)
    end
  end
  xNow,rc = mc.mcAxisGetPos(inst,0)
  zNow,rc = mc.mcAxisGetPos(inst,2)
  if xNow<=endX then
    rt.rtAudio("chord")
    wx.wxMessageBox("start X diameter "..xNow.." is <= to end diameter of "..tostring(endX))
    return
  end
  if zNow<=0 then
    rt.rtAudio("chord")
    wx.wxMessageBox("start Z is less than or = to 0")
    return
  end
  ts=os.time()

--rough cuts 
  mc.mcCntlGcodeExecuteWait(inst,"M3 S"..tostring(roughSpeed).."\ng04 p3.0")
  currPos,rc=mc.mcAxisGetPos(inst,0)
  while ((currPos-2*roughDOC)>(endX+finishDOC*2)) do
    maxVal=math.max(endX+2*finishDOC,currPos-roughDOC)
    sCode="G01 F"..tostring(plungeFeed).." X"..tostring(maxVal-roughDOC)
    mc.mcCntlGcodeExecuteWait(inst,sCode)
    currPos,rc=mc.mcAxisGetPos(inst,0)
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(roughFeed).." Z0")
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      rt.rtAudio("chord")
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    currPos,rc=mc.mcAxisGetPos(inst,0)
    maxVal=math.max(endX+2*finishDOC,currPos-roughDOC)
    if currPos==endX+2*finishDOC then
      break
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(plungeFeed).." X"..tostring(math.max(endX+2*finishDOC,currPos-roughDOC)))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      rt.rtAudio("chord")
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(roughFeed).." Z"..tostring(zNow))
    if (currPos)==endX+2*finishDOC then
      break
    end 
  end
  tr=os.difftime(os.time(),ts)/60
  mc.mcCntlSetLastError(inst,"Roughing Time: "..string.format("%.1f min",tr))

  --finish cuts
  mc.mcCntlGcodeExecuteWait(inst,"M3 S"..tostring(finishSpeed))
  while (mc.mcAxisGetPos(inst,0)>=(endX+finishDOC)) do
    currPos,rc=mc.mcAxisGetPos(inst,0)
    maxVal=math.max(endX,currPos-finishDOC)
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(plungeFeed).." X"..tostring(maxVal))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      rt.rtAudio("chord")
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(finishFeed).." Z0")
    currPos,rc=mc.mcAxisGetPos(inst,0)
    if currPos==endX then
      break
    end 
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(plungeFeed).." X"..tostring(endX))
    if mc.mcSpindleGetSensorRPM(inst)==0 then
      rt.rtAudio("chord")
      wx.wxMessageBox("Spindle Stopped")
      return
    end
    mc.mcCntlGcodeExecuteWait(inst,"G01 F"..tostring(finishFeed).." Z"..tostring(zNow))
    currPos,rc=mc.mcAxisGetPos(inst,0)
    if currPos==endX then
      break
    end 
  end
  mc.mcCntlGcodeExecuteWait(inst,"M5\nM9")
  te=(os.time()-ts)/60
  mc.mcCntlSetLastError(inst,"Roughing Time: "..string.format("%.1f min",tr).." - Total Time: "..string.format("%.1f min",te))
end

if mc.mcInEditor()==1 then
  m6691()
end


TIA

RT

Pages: « 1 2 3 4 5 6 7 8 9 »