Machsupport Forum

Mach Discussion => Mach4 General Discussion => Topic started by: billskeen62 on January 18, 2019, 01:37:58 PM

Title: How to generate gcode to do pearling
Post by: billskeen62 on January 18, 2019, 01:37:58 PM
I've seen this done on many different materials over the past 40 years or so.

I know I can manually create a gcode file to do this. Any suggestions on how to create some type of script that would create a gcode file of the patterns where the x, y, z are automatically generated based some inputs? Can it be done with Lua?

Title: Re: How to generate gcode to do pearling
Post by: joeaverage on January 18, 2019, 02:21:28 PM
Hi,
yes that could be done easy enough.

One possibility is to write a macro which outputs a Gcode file and that file is then run. That would be
using Lua to do a little bit of maths but mostly composing Gcode text strings and adding them to a file.
Thus your macro is in effect a wizard....it composes a Gcode file to be used at later date.

Another possibility is to write a macro that does the pearling itself. The macro would still effectively be composing
lines of Gcode but they are executed immediately rather than put in a file. This API allows that to happen:

Code: [Select]
LUA Syntax:
rc = mc.mcCntlGcodeExecute(
number mInst,
string commands)

Description:
Execute G code as a unit of work.

Either of these methods will work.

One area that will introduce added complexity is how you enter the data for the required pearling area.
This would be done with .wxWidgets type instructions that open windows that you can enter numbers and so
on. As it turns out using .wxWidgets is more confusing than Lua or Mach4.

My suggestion would be NOT to use .wxWidget data entry but have those numbers fixed in the macro.
If you required a different pearling area then you would have to edit the macro....I know that sounds like a pain
but it need not be hard. The advantage of doing it that way is it vastly simplifies the macro.

Once you have your macro running THEN you could decide to improve it by adding data entry windows.

I suggest give some thought to what data (width, length, tool diameter, tool stepover) you would need to make
your pearling macro useful. Then you can start wring some code.

Craig
Title: Re: How to generate gcode to do pearling
Post by: billskeen62 on January 18, 2019, 02:32:49 PM
Awesome! I appreciate the input.

Changing the macro sounds okay for now.

Off to Lua Lua Land.
Title: Re: How to generate gcode to do pearling
Post by: Cbyrdtopper on January 18, 2019, 03:09:13 PM
How are you achieving this?
Taking a brush and jogging down onto the material?
Title: Re: How to generate gcode to do pearling
Post by: joeaverage on January 18, 2019, 03:19:02 PM
Hi,
I've made a start at writing some code....probably woefully inefficient and I have no idea whether it will work yet:

Code: [Select]
function m120()
local inst=mc.mcGetInstance()
--
-- Pearl Data.....to be edited as required
--
local pearlWidth=50
local pearlLength=100
local toolDiameter=6
local nominalStepover=0.66
--
-- End of data block
--
local startXpos
local startYpos
local pearlZheight
local retract="g0 z2" --Nominal retract is 2mm above the surface
local stepoverX
local stepoverY
-- Save the current position as the start of the pearling area....you have jogged to the start haven't you????
startXpos=mc.mcCntlGcodeInterpGetPos(inst,mc.X_AXIS)
startYpos=mc.mcCntlGcodeInterpGetPos(inst,mc.Y_AXIS)
pearlZheight=mc.mcCntlGcodeInterpGetPos(inst,mc.Z_AXIS)
-- Calculate the required step over to meet the nominal step over as closely as possible but be an integral
-- number of 'pearls'
-- Reduce perlWidth in X and Y by the diameter of the tool
pearlWidth=pearlWidth-toolDiameter
pearlLength=pearlLength-toolDiameter
-- Calculate the exact number of 'pearls' required to match the nomininalSteppover
local numPearlX=pearlWidth / (nominalStepover * toolDiameter)
local numPearlY=pearlLength / (nominalStepover * toolDiameter)
-- Find the integer number of 'pearls'


end
if (mc.InEditor()==1)then
m120()
end

As you can see the first few variable declared, all locals, are the pearl  area data. You may think that there needs to be additional
data, but its a start.

My intention is that you would jog to a location on the workpeice and lower the tool until it just 'pearls' the surface
and then you would MDI your macro, I called it m120(). The location you have jogged to will be the start of the
pearled area and the current Z axis height will be used to mill each 'pearl'.

Does it make sense so far?

Craig
Title: Re: How to generate gcode to do pearling
Post by: RICH on January 18, 2019, 04:03:39 PM
How are you achieving this?

It's jeweling. For small diameters , say 1/4",  one could just buy an adapter which holds an
rubber abrasive similar to an eraser on a pencil. If one dose not have a lot of it to be done you can glue emery cloth to a pencil eraser. For big stuff, Mach trailer, I have seen it done manualy with an abrasive pad. 

RICH
Title: Re: How to generate gcode to do pearling
Post by: billskeen62 on January 18, 2019, 04:34:36 PM
RICH

Years ago it was done by hand using a pneumatic drill with a sanding pad and scotch brite cut into 2-3" circles.

I am going to try something similar using 2" ROLOC sanding discs. Have not used them before and may have to go back to scotch brite pads

https://www.amazon.com/gp/product/B06XQTDQPG/ref=ppx_yo_dt_b_asin_title_o04__o00_s00?ie=UTF8&psc=1

Title: Re: How to generate gcode to do pearling
Post by: billskeen62 on January 18, 2019, 04:35:39 PM
Craig,

Yes it does.

Thank you for that!

Bill
Title: Re: How to generate gcode to do pearling
Post by: joeaverage on January 18, 2019, 05:21:26 PM
Hi,
well it might be called jeweling but its too bloody late now!!!...its fixed in my head and I cant be bothered editing all the code.

Try this:
Code: [Select]
function m120()
local inst=mc.mcGetInstance()
--
-- Pearl Data.....to be edited as required
--
local pearlWidth=50
local pearlLength=100
local toolDiameter=6
local nominalStepover=0.66
local plungeSpeed=300
--
-- End of data block
--
local startXpos
local startYpos
local pearlZheight

local stepoverX,numPearlX
local stepoverY,numPearlY
local i=0
local j=0
-- Save the current position as the start of the pearling area....you have jogged to the start haven't you????
startXpos=mc.mcCntlGcodeInterpGetPos(inst,mc.X_AXIS)
startYpos=mc.mcCntlGcodeInterpGetPos(inst,mc.Y_AXIS)
pearlZheight=mc.mcCntlGcodeInterpGetPos(inst,mc.Z_AXIS)
-- Calculate the required step over to meet the nominal step over as closely as possible but be an integral
-- number of 'pearls'
-- Reduce perlWidth in X and Y by the diameter of the tool
pearlWidth=pearlWidth-toolDiameter
pearlLength=pearlLength-toolDiameter
-- Calculate the exact number of 'pearls' required to match the nomininalSteppover
numPearlX=pearlWidth / (nominalStepover * toolDiameter)
numPearlY=pearlLength / (nominalStepover * toolDiameter)
-- Find the integer number of 'pearls'
numPearlX=math.modf(numPearlX)
numPearlY=math.modf(numPearlY)
-- Calculate the actual stepover to be used so that an integral number of 'pearls' are perfomed
stepoverX=pearlWidth / numPearlX
stepoverY=pearlLength / numPearlY
--
--
local retract="g0 z "..tostring(pearlZheight+2) --Nominal retract is 2mm above the surface
local safeHeight="g0 z "..tostring(pearlZheight+20) --Nominal Safe Height is 20mm above the surface
mc.mcCntlGcodeExecute(inst,retract..'\n'..
'g1 f'..tostring(plungeSpeed))
for i=1,numPearlX,i+1 do
for j=1,numPearlY,j+1  do
pearlX=startXpos + (i * stepoverX)
pearlY=startYpos + (j * stepoverY)
mc.mcCntlGcodeExecute(inst,'g0 x '..tostring(pearlX)..' y '.. tostring(pearlY)..'\n'..
'g1 z '..tostring( pearlZheight)..'\n'..
'g4 p1000'..'\n'..
retract..'\n')
end
end
mc.mcCntlGcodeExecuteWait(inst,safeHeight)
end
if (mc.mcInEditor()==1)then
m120()
end

This code should be saved as:     m120.mcs    in the Profiles/<Your Profile>/Macros folder.

Jog to the start of the pearling/jeweling area lower the Z axis so the first pearl/jewel is formed and MDI <m120>.

This seems to work on my laptop, I have not tried on my machine.

You could build in extra data values for things like the retract height, safe height and Z down dwell time....but you get the idea.

Craig
Title: Re: How to generate gcode to do pearling
Post by: joeaverage on January 18, 2019, 05:29:01 PM
Hi,
the very first bit of code I posted concluded with:

Code: [Select]
end
if (mc.InEditor()==1)then
m120()
end

Which is clearly wrong, the correct syntax is:

Code: [Select]
end
if (mc.mcInEditor()==1)then
m120()
end

Lua has a number of subtle strengths but as smurph has commented 'Lua has syntax that only a mother could love'.
This wee mistake is exactly the sort of wrinkle that can trip you up and cause you to tear your hair out (if you have
any left)

Craig
Title: Re: How to generate gcode to do pearling
Post by: Cbyrdtopper on January 19, 2019, 12:25:26 AM
I like this.   Very good use for LUA.   I'm curious though, and want to make a macro program out of it.   I'll try this tomorrow and see what happens.   Great code, Craig!   Curious, will this lock the GUI or run fine?   I left my laptop at work so I can't test it.
Title: Re: How to generate gcode to do pearling
Post by: joeaverage on January 19, 2019, 01:19:18 AM
Hi Chad,

Quote
Curious, will this lock the GUI or run fine? 

The GUI is busy in the same manner as it is when running a Gcode file. The DRO's update and the <Feed Hold>,<Stop>
and <Enable/Disable> buttons work normally but others like the file ops button are greyed out.

I quite frequently write scripts to do certain things as a macro within Mach.

I have several that when executed (MDI m*********()) it will open a file dialog which will allow me to browse to a Gcode
file for instance, open the file, read line by line and apply a text correction and save the corrected lines
of text in an output file. So despite being a macro it has NO MOTION commands at all, it is just a text manipulation
script.

This example could have been a poor mans Wizard for example. If I had opened a file  instead of using mcCntlGcodeExecuteWait()
I could have saved the lines of text (Gcode) to the file. The file could then have been run in the normal manner.

I must say I struggle with wxLua. I can't find any list of simple examples I can copy/edit. Neither can I find a list
of the useful or relevant options when specifying the parameters. I've looked at the various reference documents
but there is a huge information overload and I come away knowing less than when I started!

It seemed to make sense to me to simplify the script by excluding all the wxWidgets crap....quite aside from the fact I'm
hopeless at wxStuff.

Despite my previous post about not changing 'pearl' to 'jewel' I have done so (find and replace) and introduced a couple
of new variables as well retractZ, safeZ, and jewelDwellTime. Renamed it m121() just to keep it distinct from the previous
one.

I will give some more thought to what wxLua functions may streamlining the data entry stuff, rather than editing the macro.

Code: [Select]
function m121()
local inst=mc.mcGetInstance()
--
-- Jewel Data.....to be edited as required
--
local jewelWidth=50
local jewelLength=100
local toolDiameter=6
local nominalStepover=0.66
local plungeSpeed=300
local retractZ=2
local safeZ=20
local jewelDwellTime=500
--
-- End of data block
--
local startXpos
local startYpos
local jewelZheight

local stepoverX,numjewelX
local stepoverY,numjewelY
local i=0
local j=0
-- Save the current position as the start of the jeweling area....you have jogged to the start haven't you????
startXpos=mc.mcCntlGcodeInterpGetPos(inst,mc.X_AXIS)
startYpos=mc.mcCntlGcodeInterpGetPos(inst,mc.Y_AXIS)
jewelZheight=mc.mcCntlGcodeInterpGetPos(inst,mc.Z_AXIS)
-- Calculate the required step over to meet the nominal step over as closely as possible but be an integral
-- number of 'jewels'
-- Reduce perlWidth in X and Y by the diameter of the tool
jewelWidth=jewelWidth-toolDiameter
jewelLength=jewelLength-toolDiameter
-- Calculate the exact number of 'jewels' required to match the nomininalSteppover
numjewelX=jewelWidth / (nominalStepover * toolDiameter)
numjewelY=jewelLength / (nominalStepover * toolDiameter)
-- Find the integer number of 'jewels'
numjewelX=math.modf(numjewelX)
numjewelY=math.modf(numjewelY)
-- Calculate the actual stepover to be used so that an integral number of 'jewels' are perfomed
stepoverX=jewelWidth / numjewelX
stepoverY=jewelLength / numjewelY
--
--
local retract="g0 z "..tostring(jewelZheight+retractZ) --Nominal retract is 2mm above the surface
local safeHeight="g0 z "..tostring(jewelZheight+safeZ) --Nominal Safe Height is 20mm above the surface
mc.mcCntlGcodeExecute(inst,retract..'\n'..
'g1 f'..tostring(plungeSpeed)..'\n')
for i=1,numjewelX,i+1 do
for j=1,numjewelY,j+1  do
jewelX=startXpos + (i * stepoverX)
jewelY=startYpos + (j * stepoverY)
mc.mcCntlGcodeExecute(inst,'g0 x '..tostring(jewelX)..' y '.. tostring(jewelY)..'\n'..
'g1 z '..tostring( jewelZheight)..'\n'..
'g4 p'..tostring(jewelDwellTime)..'\n'..
retract..'\n')
end
end
mc.mcCntlGcodeExecuteWait(inst,safeHeight)
end
if (mc.mcInEditor()==1)then
m121()
end
Title: Re: How to generate gcode to do pearling
Post by: joeaverage on January 19, 2019, 01:34:50 AM
Hi,
think I just spotted a mistake....the For loops will cause one extra row and one extra column of 'jewels'.

The code is, as it stands:

for i=1,numjewelX,i+1 do
      for j=1,numjewelY,j+1  do
         jewelX=startXpos + (i * stepoverX)
         jewelY=startYpos + (j * stepoverY)

I think to fit within the boundaries specified the code should be:

for i=0,numjewelX-1,i+1 do
      for j=1,numjewelY-1,j+1  do
         jewelX=startXpos + (i * stepoverX)
         jewelY=startYpos + (j * stepoverY)

Either way use with caution the first time you try it.....the tool may go a bit further than I thought!

Craig
Title: Re: How to generate gcode to do pearling
Post by: billskeen62 on January 19, 2019, 06:05:28 AM
Thanks very much Craig!

Another planned use for this is drilling holes for a vacuum table
Title: Re: How to generate gcode to do pearling
Post by: billskeen62 on January 19, 2019, 06:16:14 AM
Where I found the name:

http://www.kitplanes.com/issues/33_2/shop_talk/Home-Shop-Machinist-Pearling_21465-1.html

But could not find many other examples. However, "jeweling" does appear to get more hits in Google.

"Juuling" also has some negative connotations nowadays. :)

Title: Re: How to generate gcode to do pearling
Post by: joeaverage on January 19, 2019, 06:43:02 AM
Hi,
well pearling or jeweling ...I don't care. I notice near the end of the article it shows the overlap pattern.
I did not consider such a pattern when I wrote the code I've posted. Such a pattern should not be hard
to code.

In fact as you can see there is nothing particularly difficult abut the code I have posted.
Lua itself is reasonably simple, but don't let its simplicity fool you, there are a number of features/ideas,
'functions as first class values, for instance that mean Lua can be used to achieve a very wide range of
programming paradigms despite its simplicity.

A major part in successfully coding in Lua for Mach4 is to know and understand the API. Its made a little more difficult
because the development of features in Mach4 have exceeded the documentation. I know its frustrating but it seems we can
have newly developed features OR up-to-date documentation....but apparently not both. Not withstanding my frustration
with documentation I am delighted with the breadth and scope of newly developed features.

Smurph has indicated that Surface Mapping is close as is THC support functions which should allow much easier implementation
of THC into motion control boards.

Anyway, happy coding.

Craig
Title: Re: How to generate gcode to do pearling
Post by: billskeen62 on January 19, 2019, 07:39:58 AM
I am still learning how to use the script. Going through the Mach4 Scripting Manual now.

I sincerely appreciate your efforts on this. Far exceeded my expectations when I originally posted.

All the best!

Bill
Title: Re: How to generate gcode to do pearling
Post by: Cbyrdtopper on January 19, 2019, 09:25:21 AM
Craig,
I took the bolt hole wizard and stripped it down once before, last year sometime so I barely remember what I did, but I took that shell to make a wizard.
Do you know the syntax to make GCode output and to save ot to a file? That would be awesome for some ideas I have in mind for some second op stuff at work; I couldnt find any examples of just outputting to GCode and then saving to a file.   
Title: Re: How to generate gcode to do pearling
Post by: joeaverage on January 19, 2019, 12:34:34 PM
Hi Chad,
the only real difficulty in opening existing files or creating new ones is using/having a file dialog which means wxLua.

In the LuaExamples folder are two macros m400() and m401() which are opening, creating and populating a probe file.
The file dialog code I use and have reused is just an edited version of that code.

Code: [Select]
-- create the wxFrame window
    mainframe = wx.wxFrame( wx.NULL,          -- no parent
                        wx.wxID_ANY,          -- whatever for wxWindow ID
                        "DummyFrame", -- frame caption
                        wx.wxDefaultPosition, -- place the frame in default position
                        wx.wxDefaultSize,     -- default frame size
                        wx.wxDEFAULT_FRAME_STYLE ) -- use default frame styles

    -- create a panel in the frame
    panel = wx.wxPanel(mainframe, wx.wxID_ANY)--We are not going to show it but we need to have this to use the File dialog

local file = wx.wxFileDialog(panel, "Select Data File", "", "", "Text files (*.txt)|*.txt|Tap files (*.tap)|*.tap",
                             wx.wxFD_SAVE,wx.wxDefaultPosition,wx.wxDefaultSize, "File Dialog" );
        if(file:ShowModal() == wx.wxID_OK)then
            path = file:GetPath()
            outfile=assert(io.open(tostring(path),'w+'))
        end

This is an example of that code. Note that the frame and panel are nothing special but they need to be present so the
file dialog can happen. This is the critical line:

local file = wx.wxFileDialog(panel, "Select Data .....................................................faultSize, "File Dialog" );

The remaining code is all about using functions of the data structure "file", for instance:

file:ShowModal() == wx.wxID_OK                                 and:

path = file:GetPath()

The line which opens the file is:

outfile=assert(io.open(tostring(path),'w+'))                    but that is inelegant, this is an example of a file opening statement
                                                                                   that I wrote for a job a week or so ago:

local fileHandle=io.open(pathfilename,"w+")                   and some of the statements for writing to, flushing and closing the
                                                                                   file using this syntax are:

fileHandle:write(offset,'\n')
fileHandle:flush()
fileHandle:close()

I'm sort of thinking that opening and closing files is getting a bit away from the subject of this thread and am likely to confuse
the hell out of OP if I start posting code in the same thread. I will start a new thread where I will write the generated Gcode
to a file, sort of a poor mans Wizard.

Craig.

Title: Re: How to generate gcode to do pearling
Post by: joeaverage on February 02, 2019, 05:00:49 AM
Hi billskeen62,
did you end up using this code?

I have been reading/studying/experimenting with wxLua and have come up with some code that will
accept data from user on-screen input. The data is stored in registers so is persistent between sessions.

I have attached a pic of what the input dialog looks like.

Craig
Title: Re: How to generate gcode to do pearling
Post by: MadDogSTrack on February 10, 2019, 05:14:51 PM
Didn't see this thread - musta been sleeping for a while.

This is also called "Engine Turning".  There is (was??) an add-on package to MACH3 that can be used "standalone" called "D2NC. It has routines for doing this for rectangular areas.  It does not include "keep-out" areas for areas where you might not want the work done.  Say if there was a recess or hole in the part, or an edge that might catch the tooling.  It uses G82 cycle - Drilling with dwell.

I have done this many times.  I use rubber material (in US from McMaster).  For the grit, I use powered 200 grit polishing/ finishing compound and put it 50-50 by volume in dish soap.  Yes, dish soap, it cleans up easily, is thick so it doesn't splatter all over.  Also, the rubber should extend from the collet not much more than about 25%-35% of the rubber's width, otherwise it might catch on edges and tear, ruin the finish.  As a guide, about 1000 RPM for a 3/4 rubber "eraser", and drill depth is about 0.03" into surface, dwell time is 3 seconds.

One thing to keep in mind:  Don't get too fancy with the code to cover a large area as the rubber gets worn away a bit and the Z Axis has to be jogged down a bet every 50 to 100 imprints.