Jump to content

Welcome to eMastercam

Register now to participate in the forums, access the download area, buy Mastercam training materials, post processors and more. This message will be removed once you have signed in.

Use your display name or email address to sign in:

Arrays in Macros


drafting3
 Share

Recommended Posts

Hello Everyone,

 

I just finished up a project which was a secondary operation to a plastic cover we produce here. After the covers are made, they come to the toolroom to have brass threaded inserts installed. These are set by heating them up with a propane torch, and then pressing them into place. There are 27 inserts for each part, with three different sized inserts.

 

We were doing this by hand, but it was taking around 35 minutes per part. So, I decided to write a program to let my CNC mill do most of the work. This was my first time using external subprograms, but I felt it was important to make slight modifications easier. I used one main program, and 4 sub programs. It worked great, and only took 10 minutes per part to install the inserts.

 

The program worked like this: (basically)

 

G0 (Rapid to Reference Point)

M00 (while I thread on an insert)

<start cycle>

G04 (dwell a set amount of time while I'm heating the insert)

G0 (move to XY coordinate of insert location)

G0 (move to .1 above Z coordinate)

G1 (press insert to proper z depth)

G04 (dwell time needed for insert to cool)

M04 (unscrew the tool from the insert while moving up according to its thread pitch)

Rapid to Reference Point

(Repeat 27 times)

 

 

Originally I wanted to use a macro to run this process to keep the code sexy, but I felt like the only advantage to using a Macro is if I could create an array with all my insert locations. I couldn't find anyway to do this.

 

 

So, this is my question... can you specify multi-dimensional arrays using parametric programming? Is there a way to index which part of the array the macro points to, like in a do or while loop?

 

I would have needed an array as follows:

 

Insert_Array[insert_size].[insert_number].[insert_ coordinate]

 

insert_size would range from 1-3, to account for the three different sized inserts

insert_number would specify each separate insert, and range from 1-6 for the first insert, 1-10 for the second insert, and 1-11 for the third insert

insert_coordinate would hold the X,Y, and Z values of the insert (1 = X, 2 = Y, 3 = Z)

 

So, Insert_Array[2].[3].[1] would point to the X coordinate of the 3rd insert of the 2nd size.

 

 

i would then want to index the array as follows:

 

for (i = 1, i <= 3, i++)

for (n = 1, n <= 11, n++)

for (u = 1, u <= 3, u++)

 

G0 Insert_Array.[n].

 

 

This snippet of code isn't syntactically correct, and doesn't necessarily represent how I would use the array, but does show how i'd like to index and point to the array.

 

 

 

 

 

 

Can this be done?

Link to comment
Share on other sites

So far as I know there is no way to create an array in Macro B.. you could kind of cheat using variables like #[#501] where you reference a variable based on a counter.. but you still need to have enough free variables available..

 

This is basically creating a variable that tracks which variable your working on.. so by manipulating the value of #501 in your loop you can keep track of where you are and you can increment it using a counter in your loop independent of whatever operation you perform on your variable.

 

I think thats about as close to an array as your going to get in Macro B

 

For your example if the coordinates dont move though .. I think you might be able to just make different sections of your program that defined the insert you wanted to do .. so basically you could use a goto or m98 to call the section of code with the information for that particular insert.. then once your variables were defined call the code to actually do the work.. if that makes any sense to you..

Link to comment
Share on other sites

You can also pass variables to a macro, so you could use your macro like a drilling cycle.

 

Here's a call to a serial number engraving macro I made:

 

G65P8500E1.D5I1.X0Y0Z-.01A112.T.5R.1B6.S8000.H1.U2.V5.W-4.C0.Q4.

 

So you could pass the X, Y, Z, dwell, pitch, etc. as variables, as simple or complex as you want to go, then have your main make a call for each hole with its coordinates.

Link to comment
Share on other sites

You cant store arrays. But by making the routine into a Marco (as opposed to a subroutine), you can call it each time with different parameters.

 

Also, I noticed a couple of other things -

 

1) you do NOT want to have a dwell to give the operator a certain time to complete a task. Someone will get hurt.

2) when you try removing the insert tool, you are tapping UPWARDS. I dont know if this is possible.

 

But I gave it a shot anyways. The following code is NOT guaranteed to run, you would have to dial it into your specific machine tool.

G90 G80 G40 G20
G17 G94 G00 G54


M98 P9999 X1.234 Y3.456 (RUN INSERT ROUTINE AT THIS XY)
M98 P9999 X2.345 Y1.111 (RUN INSERT ROUTINE AT THIS XY)
M98 P9999 X12.25 Y8.75 (RUN INSERT ROUTINE AT THIS XY)

09999 (CUSTOM MACRO)
G90 G00 G54 X-1.0 Y-1.0 (RAPID TO REFERENCE POINT)
M00 (PLACE INSERT, HEAT UP, PRESS CYCLE START)
G90 G00 X#24 Y#25 (POSITION TO PASSED XY PARAMETERS 'X' AND 'Y')
G43 H01 Z1.000 (POSITION 1" ABOVE INSERT HEIGHT 'Z')
G00 Z.01 F20. (RAPID .100 ABOVE PASSED INSERT HEIGHT 'Z')
G01 Z-.25 (FEED IN AT PASSED FEEDRATE PARAMETER 'F')
G04 X1. (DWELL FOR 1 SECOND)
M04 G93 (TURN ON REVERSE SPINDLE SPEED, RIGID TAP)
M03 S1000 (SET SPINDLE SPEED)
G99 G74 Z1.000 R.75 F.05 (LEFT HAND TAP UPWARDS, 1/4-20 THREAD, R VALUE NEGATIVE!)
G80 G00 Z1.000 (CANCEL TAP, RAPID OVER INSERT)
M99

Link to comment
Share on other sites

So far as I know there is no way to create an array in Macro B.. you could kind of cheat using variables like #[#501] where you reference a variable based on a counter.. but you still need to have enough free variables available..

 

This is basically creating a variable that tracks which variable your working on.. so by manipulating the value of #501 in your loop you can keep track of where you are and you can increment it using a counter in your loop independent of whatever operation you perform on your variable.

 

I think thats about as close to an array as your going to get in Macro B

 

For your example if the coordinates dont move though .. I think you might be able to just make different sections of your program that defined the insert you wanted to do .. so basically you could use a goto or m98 to call the section of code with the information for that particular insert.. then once your variables were defined call the code to actually do the work.. if that makes any sense to you..

 

That's exactly right. If there is no way to create an array, then I would need a variable to keep track of which variable I am accessing. How would #501 be able to point to another variable? If #501 = 2, then #(#501) = #2 ?

 

 

 

 

 

You can also pass variables to a macro, so you could use your macro like a drilling cycle.

 

Here's a call to a serial number engraving macro I made:

 

G65P8500E1.D5I1.X0Y0Z-.01A112.T.5R.1B6.S8000.H1.U2.V5.W-4.C0.Q4.

 

So you could pass the X, Y, Z, dwell, pitch, etc. as variables, as simple or complex as you want to go, then have your main make a call for each hole with its coordinates.

 

This is something I want to get familiar with.

 

So, G65 is the macro call, and the P8500 refers to a section of code somewhere labeled O8500? Would you then end that macro call with a GOTO statement?

 

I did just read up on passing the variables to the macro with A-Z. That's very cool. So, in my macro I just access the passed variables with #1 - #26?

Link to comment
Share on other sites

Just saw your questions in the second half..

 

P8500 would be the program number of the macro you were calling with the G65 call (ie the macro is a seperate program alltogether)

 

The macro would generally end with an M99 call to return out of it as you would a subprogram.

 

And yes with a G65 call you can reference variables passed in with the correct variable #1-#26 (with some exceptions - you should definitly check out the book)

Link to comment
Share on other sites

You cant store arrays. But by making the routine into a Marco (as opposed to a subroutine), you can call it each time with different parameters.

 

Also, I noticed a couple of other things -

 

1) you do NOT want to have a dwell to give the operator a certain time to complete a task. Someone will get hurt.

2) when you try removing the insert tool, you are tapping UPWARDS. I dont know if this is possible.

 

I originally had the M00 stop at the reference point so the operator could heat up the insert, then press cycle start, but this created problems. The plastic has a foaming agent in it, so if the operator heats the insert up too much, the plastic will foam up and it creates a scrap part. If he doesn't heat the insert up enough, it won't sink into the part to the full depth. I decided to change the program so the operator presses cycle start as he starts heating the insert, and the dwell time keeps the heating consistent. I was worried about someone getting hurt, but the machine always moves away from the operator after the dwell, so... I guess I consider it an acceptable risk. Plus, I am the operator... so I understand how the program responds, and I know what it's next move is. Still risky, I know... but sometimes sacrifices have to be made for the final product, right?

 

I am using a commander tapmatic tension tap head, so there is some "float". Our machine does not have a synchronized spindle, and this is the only way I've ever been able to power tap. I created a tool for each insert size, and machined it to fit into one of three different tap holders.

 

So, the Insert set subroutine code looks like this: (The main program moves 0.0" above the insert location before calling this subroutine)

 

 

%

O9003

N130 G1G91Z-.25F50.

N140 G04X5.0

N150 M04S200

N160 Z.25F3.93

N170 M5

N180 M99

%

 

But I gave it a shot anyways. The following code is NOT guaranteed to run, you would have to dial it into your specific machine tool.

G90 G80 G40 G20
G17 G94 G00 G54


M98 P9999 X1.234 Y3.456 (RUN INSERT ROUTINE AT THIS XY)
M98 P9999 X2.345 Y1.111 (RUN INSERT ROUTINE AT THIS XY)
M98 P9999 X12.25 Y8.75 (RUN INSERT ROUTINE AT THIS XY)

09999 (CUSTOM MACRO)
G90 G00 G54 X-1.0 Y-1.0 (RAPID TO REFERENCE POINT)
M00 (PLACE INSERT, HEAT UP, PRESS CYCLE START)
G90 G00 X#24 Y#25 (POSITION TO PASSED XY PARAMETERS 'X' AND 'Y')
G43 H01 Z1.000 (POSITION 1" ABOVE INSERT HEIGHT 'Z')
G00 Z.01 F20. (RAPID .100 ABOVE PASSED INSERT HEIGHT 'Z')
G01 Z-.25 (FEED IN AT PASSED FEEDRATE PARAMETER 'F')
G04 X1. (DWELL FOR 1 SECOND)
M04 G93 (TURN ON REVERSE SPINDLE SPEED, RIGID TAP)
M03 S1000 (SET SPINDLE SPEED)
G99 G74 Z1.000 R.75 F.05 (LEFT HAND TAP UPWARDS, 1/4-20 THREAD, R VALUE NEGATIVE!)
G80 G00 Z1.000 (CANCEL TAP, RAPID OVER INSERT)
M99

 

 

That looks like something I should have used. I would prefer that the G65 call be nested in a loop though, and the passed variables get incremented. Not sure if that's possible, but I'm beginning to think it is... with some work of course.

Link to comment
Share on other sites

Thats exactly it ..

 

#501 = 2

 

#[#501] = 256

 

Would make

 

#2 = 256

 

Its pretty cool.. its basically modifying a variable by reference kind hard to get your head around at first but can be really handy..

 

frigg'n sweet :)

 

yeah, it's like indexing an array pointer in c++. that is EXACTLY what I wanted to do.

 

it's definitely possible to create pseudo-arrays then... as long as you have enough open variables. This would be a LOT of work, but would definitely be some sexy code.

 

sexy code is sexy. i like sexy code.

 

 

Obviously I completed the task, but this is more of a learning project for me now. I might go back and rewrite the program using macros, pseudo-arrays, loops, and parametric programming just to see if I can do it. The knowledge and experience would definitely be valuable.

Link to comment
Share on other sites

P8500 would be the program number of the macro you were calling with the G65 call (ie the macro is a seperate program alltogether)

 

The macro would generally end with an M99 call to return out of it as you would a subprogram.

 

I see. I always thought a Macro was somewhere inside the original program, but it's actually an external program like a subroutine?

Link to comment
Share on other sites

I've never used a G10 call. Just did some googling, but I don't fully understand it, or what it's used for.

G10G90L2P1XnnYnn sets g54 in beginning of program

G10G91L2P1XnnYnn shifts offset incrementally.

 

so with a cycle in a looped subprogram, you would put the G10 G91 at end of subprogram, thus creating an array.

Link to comment
Share on other sites

Well if your going to call it with a G65 it pretty much has to be an external program since thats what the call expects..

 

You can however use Macro code inside of the main program as well ..

 

Okay. I think I get it. I'll do some reading on macros, internal and external.

Link to comment
Share on other sites

G10G90L2P1XnnYnn sets g54 in beginning of program

G10G91L2P1XnnYnn shifts offset incrementally.

 

so with a cycle in a looped subprogram, you would put the G10 G91 in subprogram. thus creating an array.

 

Yeah, i'm going to have to read up on G10 also. lol

Link to comment
Share on other sites

Yeah, i'm going to have to read up on G10 also. lol

it just for setting and shifting x0y0 in program. nice method for controls without macros or operators without knowledge.

 

you can also use it to set other offsets from the program.

also great for repeat jobs with frozen tooling and setups, pallet pools etc.

Link to comment
Share on other sites

Here's a simple test I created for checking all the pallets in a MAM72-35V. It uses a macro variable as a counter and as a variable number to write to as well. Maybe this may spark somethign for you.

 

%

O0001(PALLET HEIGHT MEASURE)

IF[#160GT160]GOTO150

#160=161

N150G0G49G53Z0

N151T151M6

G0G54X0Y1.5

G0G43H#517Z13.

G65P9810Z5.9F80.

G65P9025A9.Z5.7094

#160=#160+1(COUNTER)

#[#160]=#137

G0G53Z0

IF[#160GT192]GOTO9990

M1

 

M98P9901

N9990

#160=161

M30

%

 

It counts up, it writes the result of each pallet from variables #161 to #192. I could have written a short DPRNT statement to write all the reults out to a memory card, but that would just be showing off at that point. ;)

Link to comment
Share on other sites

G10G90L2P1x25.225Y12.258 (SET G54 ABSOLUTE)

G54G00G90X3.25Y-2.5 (FIRST BUSHING LOCATION)

M98P100L27 (CALL SUB 27 TIMES)

M30

 

 

 

 

 

 

O100

G0 (Rapid to Reference Point)

M00 (while I thread on an insert)

<start cycle>

G04 (dwell a set amount of time while I'm heating the insert)

G0 (move to XY coordinate of insert location)

G0 (move to .1 above Z coordinate)

G1 (press insert to proper z depth)

G04 (dwell time needed for insert to cool)

M04 (unscrew the tool from the insert while moving up according to its thread pitch)

Rapid to Reference Point

G10L2P1G91X1. (MOVES OFFSET 1.0 FOR NEXT SUB CALL)

G90

M99

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.

Join us!

eMastercam - your online source for all things Mastercam.

Together, we are the strongest Mastercam community on the web with over 56,000 members, and our online store offers a wide selection of training materials for all applications and skill levels.

Follow us

×
×
  • Create New...