What's new
What's new

Macro Programming Fundamentals

PROBE

Hot Rolled
Joined
Jan 23, 2003
Location
Tel Aviv, Israel
Hi again,

I have been running lights off for a week now at work, with a broken tool detection without any problems. But I still have about 15 tools in the carousel that I dont measure, like fine bore tools.

I still need to orient the spindle for that kind of tooling, and have made this code:

O.... (M119 A=Angle)
#100=[#1*[4096/360]];
G10L50;
N4077R#100;
G11;
M19;
G10L50;
N4077R636.; (the 636 is the normal value)
G11;
M99;

Will this work? Im changing the parameter back to normal value, I dont want to crash the arm and spindle on the machine:-)

Cheers,

Daniel
I believe this method is quite cumbersome and not safe. You will have to distinguish somehow the tools which will have to be checked in this way. Changing the spindle position parameter is tricky, if cycle is stopped and reset when this parameter is changed.
In my opinion much better and safer method is setting / checking the boring tools while rotating them CCW. I use it in all installations of multidirectional tool setters (like TS27R). Renishaw tool setting software includes this option.
 

Uhrenholt

Aluminum
Joined
Jan 28, 2016
I believe this method is quite cumbersome and not safe. You will have to distinguish somehow the tools which will have to be checked in this way. Changing the spindle position parameter is tricky, if cycle is stopped and reset when this parameter is changed.
In my opinion much better and safer method is setting / checking the boring tools while rotating them CCW. I use it in all installations of multidirectional tool setters (like TS27R). Renishaw tool setting software includes this option.

I just went to work and I did find the programming manual for the probe:-) Lot of reading... Since all of our programming is done in cad, I have to figure out how make it so it takes the diameter off a list or take the D offset of the active tool somehow:-)

Well, home I go and to bed, nothing has crashed, and parts look fine:-) I will probably start a thread about this.

Cheers, Daniel
 

tteitgen

Aluminum
Joined
Jun 16, 2013
Location
Muskegon
Was wondering if anyone see's anything wrong with my logic in the following program.
Just a note - there is a safety check program that run after this one that looks for any work coordinate shifts bigger than .0009. And then notifies the operator that a big shift has been made. It shows them what work offset, and how much it was moved. They than have to confirm the moves with a value entered into #150. Trying to eliminate some operator errors.

%
O00008820(Wheel Life Monitor)
(******************************)
(******Tool Life Defined*****)
(******************************)
#11=235(Wheel #1 Tool Life Count)
#12=75(Wheel #2 Tool Life -Shift-Count)
#14=175(Wheel #3 Tool Life -1st Shift-Count)
(******************************)
#13=[#12*2](Wheel #2 End of Wheel Life Count)
#15=[#14*2](Wheel #3 Tool Life -2nd Shift-Count)
#16=[#14*3](Wheel #3 End of Wheel Life Count)
(******************************)

(******************************)
(New Wheel #1 Shift Amounts)
(******************************)
#17=.0025("Z" Axis - G54.1P31)
#18=.0025("Z" Axis - G54.1P32)

(******************************)
(Wheel #2 - 1st Shift Amount)
(******************************)
#19=-.100("X" Axis - G54.1P33)(Negative Value Only)
#20=.002("Z" Axis - G54.1P33)
#21=.085("X" Axis - G54.1P34)(Positive Value Only)
#22=.002("Z" Axis - G54.1P34)

(******************************)
(Wheel #2 - New Wheel Shift Amounts)
(******************************)
#23=.100("X" Axis - G54.1P33)(Positive Value Only)
#24=.002("Z" Axis - G54.1P33)(Positive Value Only)
#25=-.085("X" Axis - G54.1P34)(Negative Value Only)
#26=.002("Z" Axis - G54.1P34)(Positive Value Only)
#27=-.004("X" Axis - G54.1P35)(Negative Value Only)
#28=-.004("X" Axis - G54.1P36)(Negative Value Only)

(******************************)
(**Wheel #3 Shift Amounts**)
(******************************)
#29=.040("X" Axis - G54.1P37)
#30=-.030("Z" Axis - G54.1P37)

(******************************)
(**New Wheel #3 - Shift Amounts**)
(******************************)
#31=.080("X" Axis - G54.1P37)
#32=.060("Z" Axis - G54.1P37)

M90

N5
IF[[#_WZP35[3]]LT-32.28200]GOTO1002("Z" Axis Crash Prevention Wheel #2 - P35)
IF[[#_WZP36[3]]LT-5.74933]GOTO1003("Z" Axis Crash Prevention Wheel #2 - P36)

(***********************************)
(********Tool Life Check**********)
N10
IF[[#2018EQ#11]AND[#572NE7272]]GOTO1(Wheel #1 - New Wheel)

N20
IF[[#2019EQ#12]AND[#574NE7474]]GOTO2(Wheel #2 - 1st Shift)
IF[[#2019EQ#13]AND[#571NE7171]]GOTO22(Wheel #2 New Wheel)

N30
IF[[#2020EQ#14]AND[#579NE7979]]GOTO3(Wheel #3 - 1st shift)
IF[[#2020EQ#15]AND[#579NE8989]]GOTO33(Wheel #3 - 2nd shift)
IF[[#2020EQ#16]AND[#579NE9999]]GOTO333(Wheel #3 - New Wheel shift)

(******************)
(Go to end of program if all is good)
(******************)
GOTO50


(***********************)
(******Wheel #1*******)
(***********************)

N1
#2018=0(Reset Wheel Life Counter)
#572=7272
M90
[#_WZP31[3]]=[[#_WZP31[3]]+#17]
[#_WZP32[3]]=[[#_WZP32[3]]+#18]


M00



(***Change Wheel #1***)

(Wheel Life is up)

(Fill Out Wheel Change Log)

(Program has automatically)
(Reset the Tool Life Counter)
(back to Zero -0-)

(Program has automatically)
(adjusted the "Z" Axis for)
(G54.1P31 and G54.1P32)

(Run --"Set Up"-- Part)
(on the New Wheel)

(Press Reset)































#3000=1(Press Reset)

N2
(***********************)
(******Wheel #2*******)
(******1st Shift *********)

#574=7474(Anti Loop)

(***Set Work Coordinates***)
[#_WZP33[1]]=[[#_WZP33[1]]+#19]
[#_WZP33[3]]=[[#_WZP33[3]]+#20]
[#_WZP34[1]]=[[#_WZP34[1]]+#21]
[#_WZP34[3]]=[[#_WZP34[3]]+#22]

M00

(1st Tool Life Counter for Wheel #2)
(is up.)

(This Program has automatically)
(Shifted the "X" & "Z" Axis's for)
(G54.1P32 & G54.1p33)

(Part will have PLUS STOCK on)
(the Top Rails and need to be)
(Re-worked in the "Z"Axis)

(Press ***Start*** to Continue)





















GOTO30

N22
(*********************)
(******Wheel #2*****)
(****New Wheel*****)
M90
#2019=0(Reset Wheel Life Counter)
#571=7171(Anti-Loop)

(***************************)
(*Set New Offsets Values*)
(***************************)
M90
[#_WZP33[1]]=[[#_WZP33[1]]+#23](Must be a Positive Calculation)
[#_WZP33[3]]=[[#_WZP33[3]]+#24](Must be a Positive Calculation)
[#_WZP34[1]]=[[#_WZP34[1]]+#25](Must be a Negative Calculation)
[#_WZP34[3]]=[[#_WZP34[3]]+#26](Must be a Positive Calculation)
[#_WZP35[1]]=[[#_WZP35[1]]+#27](Must be a Negative Calculation)
[#_WZP36[1]]=[[#_WZP36[1]]+#28](Must be a Negative Calculation)
(**************************)
(**************************)

M00



(Change Wheel #2 )
(Wheel Life is up)

(Fill Out Wheel Change Log)

(Program has automatically)
(Reset Tool Life Counter)

(Work Coordinates)
(***G54.1P33 - G54.1P36***)
(have been Automatically )
(Shifted for New Wheel)


(Press Reset)






























#3000=2(Press Reset)

N3
(***********************)
(******Wheel #3*********)
(****1st Wheel Shift****)
(***********************)

#579=7979(Used for Anti-Loop)

[#_WZP37[1]]=[[#_WZP37[1]]+#29](Shift Wheel in "X" Axis)
[#_WZP37[3]]=[#_WZP37[3]]+#30](Shift Wheel in "Z" Axis)
#753=[#_WZP37[3]](Used for "Z" Shift detection)

M00



(1st Tool Life Counter for Wheel #3)
(is up.)

(This Program has automatically)
(Shifted the "X" & "Z" Axis's for)
(******---G54.1P37---****** )

(Chamfer will have PLUS STOCK)
(Will need to be Re-worked in)
(the "X" Axis only after these)
(shifts.)

(Press ***Start*** to Continue)


























GOTO50

(***********************)
(******Wheel #3*********)
(****2nd Wheel Shift****)
(***********************)

N33

#579=8989(Used for Anti-Loop)

[#_WZP37[1]]=[[#_WZP37[1]]+#29](Shift Wheel in "X" Axis)
[#_WZP37[3]]=[#_WZP37[3]]+#30](Shift Wheel in "Z" Axis)
#753=[#_WZP37[3]](Used for "Z" Shift detection)

M00



(2nd Tool Life Counter for Wheel #3)
(is up.)

(This Program Has Automatically)
(Shifted the "X" & "Z" Axis's for)
(******---G54.1P37---****** )

(Chamfer will have PLUS STOCK)
(Will need to be Re-worked in)
(the "X" Axis only after these)
(shifts.)

(Press ***Start*** to Continue)


























GOTO50

N333
(***********************)
(******Wheel #3*********)
(****New Wheel Shift****)
(***********************)

#2020=0(Reset Wheel Life Counter)
#579=9999(Used for Anti-Loop)

[#_WZP37[1]]=[[#_WZP37[1]]+#31](Shift Wheel in "X" Axis)
[#_WZP37[3]]=[[#_WZP37[3]]+#32](Shift Wheel in "Z" Axis)
#753=[#_WZP37[3]](Used for "Z" Shift detection)


M00



(***Change Wheel #3***)

(Wheel Life is up)

(Fill Out Wheel Change Log)

(Program has automatically)
(Reset the Tool Life Counter)
(back to Zero -0-)

(This Program will now automatically)
(Shift the "X" & "Z" Axis's for)
(******---G54.1P37---****** )

(Chamfer will have PLUS STOCK)
(Will need to be Re-worked in)
(the "X" Axis only after these)
(shifts.)

(Press Reset)
































GOTO50
(**********************)
(*******Alarms*******)
N1001
[#_WZP37[3]]=#753

M00

(You cannot shift the "Z" Axis)
(for this G54.1P37)
("X" Axis Only)

(The "Z" Axis for G54.1P37)
(work coordinate has been)
(set back to the original)
(value - Listed on wheel)
(shift Document)

(Press Reset)


















#3000=2(Press Reset)
(********************)
(********************)
N1002
M00

(You cannot shift the "Z" Axis)
(Negative for this work offset)
( G54.1P35 - Wheel will crash into fixture)

(Place "Z" Axis work coordinate)
(Back to original value - Listed)
(on wheel shift Document)

(Press Reset)




















#3000=4(Press Reset)

(********************)
(********************)
N1003
M00

(You cannot shift the "Z" Axis)
(Negative for this work offset)
( G54.1P36 - Wheel will crash into fixture)

(Place "Z" Axis work coordinate)
(Back to original value - Listed)
(on wheel shift Document)

(Press Reset)





















#3000=5(Press Reset)


(*************************)
(****End of Program****)

N50
M90
#550=#0
#551=#0

IF[#2018EQ1]THEN#572=#0(Anti-Loop- Wheel #1 - New Wheel)

IF[#2019EQ[#12+1]]THEN#574=#0(Anti-Loop - Wheel #2 - 1st shift)
IF[#2019EQ1]THEN#571=#0(Anti-Loop - Wheel #2 - New Wheel)

IF[#2020EQ[#14+1]]THEN#579=#0(Anti-Loop - Wheel #3 - New Wheel Shift)
IF[#2020EQ[#15+1]]THEN#579=#0(Anti-Loop)
IF[#2020EQ[1]]THEN#579=#0(Anti-Loop)

IF[[#_WZP37[3]]NE#753]GOTO1001(Check To make sure operators are not moving the "Z" Axis, "X" Axis only)

M99
%
 

Tonytn36

Diamond
Joined
Dec 23, 2007
Location
Southeastern US
At any one time I am using around 200-400 macro numbers in almost all of my programs. How do you keep track of all your variable numbers that are in use? Just wondering how other people are doing it.

I use an Excel spreadsheet to keep track of my macro numbers and the assignment of each one. Since I also do robot integration, this same spreadsheet is also used for robot -> machine outputs, machine ->robot inputs, robot->controller outputs, controller-->robot inputs, robot variables, robot position names, etc. Each element has a separate tab and is formatted for printing so that when I am done with the cell I can simply print each tab and have the documentation complete for the book that goes with the cell.
 

Thomas Paine

Hot Rolled
Joined
Jan 9, 2013
Location
SE PA
At any one time I am using around 200-400 macro numbers in almost all of my programs. How do you keep track of all your variable numbers that are in use? Just wondering how other people are doing it.

Give them variable names like more advanced programming languages of the 21st century,
and then before you upload it, use 'find/replace all' to replace the names with variable #'s, and keep a list/excel sheet.
 

CutEdge

Aluminum
Joined
May 22, 2015
GOTO within M97?

Will the program get confused about where to flow, if I use a GOTO statement from within an M97 subroutine within another M97 subroutine?

I have subroutine "B" within another subroutine "A".
Subroutine A is looping.
Subroutine B contains an "IF / THEN GOTO" statement
The IF statement basically says "if this is the last loop of A, exit the loop early."
The desired result is that only part of B will execute on the last loop.

A potential problem enters my mind. The M97 subroutine must exit without ever seeing an M99 code to end it. But then, I am going to call another M99 later. As far as the program knows, it is still in subroutine B, so it may want to return to A. But my GOTO statement has already gotten me out, and I've moved on. I want the next M99 call to return me to the main program. But I'm worried it may instead direct me back to wherever it left off in subroutine A.

If that's too confusing, try this: all I'm trying to do is break a loop and go all the way back to the main program. Like the movie Inception... I'm in a dream within a dream, and I want to just wake all the way up.


Here's a sample, using real numbers instead of A and B:

Code:
#1 = 0 (counter)
M97 P9000 L7
N9999
M97 P8000 (final action)
M84
M5
M30


N9000
#1 = #1 + 1
M97 P9010
M97 P9020
M97 P9030
M97 P9010
M97 P9021
M97 P9030


N9010
M51 (close clamps)
M61 (kill power to clamps)
M99


N9020
(do some moves)
[B]IF [#1 EQ 7] THEN GOTO 9999[/B]
(do some more moves that only apply to loops 1-6)
M99 [B](This is never reached on loop 7)[/B]


N9021
(do some more moves that only apply to loops 1-6)
M99


N9030
M52 (open clamps)
M62 (kill power to clamps)
M99


N8000
(do a final move)
M99
 

deljr15

Cast Iron
Joined
Aug 6, 2013
Location
Duluth, Mn
A potential problem enters my mind. The M97 subroutine must exit without ever seeing an M99 code to end it. But then, I am going to call another M99 later. As far as the program knows, it is still in subroutine B, so it may want to return to A. But my GOTO statement has already gotten me out, and I've moved on. I want the next M99 call to return me to the main program. But I'm worried it may instead direct me back to wherever it left off in subroutine A.

You can restructure your program to work with simply

Code:
#1 = 0 (counter)
#2 = 0 (skip flag)
M97 P9000 L7
M97 P8000 (final action)
M84
M5
M30


N9000
#1 = #1 + 1
M97 P9010
M97 P9020
IF [ #2 EQ 1. ] GOTO99
M97 P9030
M97 P9010
M97 P9021
M97 P9030
GOTO99

N9010
M51 (close clamps)
M61 (kill power to clamps)
GOTO99


N9020
(do some moves)
IF [#1 EQ 7.] GOTO9029
(do some more moves that only apply to loops 1-6)
GOTO99

N9029
#2=1.
GOTO99

N9021
(do some more moves that only apply to loops 1-6)
GOTO99


N9030
M52 (open clamps)
M62 (kill power to clamps)
GOTO99


N8000
(do a final move)
GOTO99


N99
M99

This way after every sub action it will return to M99.

To break your loop I jump to a new branch and set a value to #2 before ending the sub. Then on the previous level we have a check for that value to be set if it is then return to main. Else continue loop.
 

jeyz

Plastic
Joined
Jan 28, 2016
hi there,

say, we gonna drill 100 holes on the same line, and distance between them .25 inch.

is it possible to shorten the code by macro?
is it possible to nest in G73 or in G81 "if statments"?
 

angelw

Diamond
Joined
Sep 10, 2010
Location
Victoria Australia
hi there,

say, we gonna drill 100 holes on the same line, and distance between them .25 inch.

Is it possible to shorten the code by macro?
Is it possible to nest in g73 or in g81 "if statments"?
Hello jeyz,
You don't need to use User Macro to achieve what you have asked. The following code for a Fanuc control will Drill 100 holes 0.25" apart on the X axis, starting at X,Y Zero with one Block of Code.

G90 G00 X-0.25 Y0.0
G91 G98 X0.25 Y0.0 Z_ R_ F_ K100
G80
Where K is the number of repeats of the Drill Cycle.

If the pitch of the holes is on a line at an angle other than 0, 90, 180, 270, where Zero is 3 o'clock and the angles increase in a Counter Clockwise direction, then you would calculate the incremental X and Y value that would result in a 0.25" pitch along the angle. For example, if the holes were pitched 0.25" along a 45deg path then the Command Block would be:

G90 G00 X-0.1768 Y-0.1768
G91 G98 X0.1768 Y0.0.1768 Z_ R_ F_ K100

Whether K, or L is used as the Repeat address is dependent on the control. If its a Fanuc Control, it will be dependent on the model of the Control, or whether the Control is set to use FS15, or FS16 Format.

Regards,

Bill
 

jeyz

Plastic
Joined
Jan 28, 2016
Hello jeyz,

G90 G00 X-0.25 Y0.0
G91 G98 X0.25 Y0.0 Z_ R_ F_ K100
G80
Where K is the number of repeats of the Drill Cycle.
......
Regards,

Bill

Thank you Bill, pretty nice code, without macro.

..and it is pretty nice to see another using of G91. I thought, G91(incremental) is useless code, only used to go home, with G28.
 

CutEdge

Aluminum
Joined
May 22, 2015
to deljr15:

So, is it correct that G-code interpreters don't have anything built-in, that automatically determines what level the control should be set to (in cases like this)?

Also, couldn't I just use "M99" instead of "GOTO99"?
 
Last edited:

sinha

Titanium
Joined
Sep 25, 2010
Location
india
In the incremental mode of drilling cycles, R is measured from the initial tool level (as expected), but Z is measured from the R-point. One may forget this and make mistakes. Therefore, a simple method would be to make the first hole in absolute mode, and the remaining in the incremental mode without mentioning R and Z :

G90 G73 G99 X50 Y25 Z-30 Q5 R2 F50;
G91 X20 K99;
G80;

This would make 100 holes of 30 mm depth at 20 mm pitch along X axis, starting from (50,25).
 

RTM

Cast Iron
Joined
Jun 6, 2014
Location
Ohio, USA
Working on it:-)

I have a Q about spindle orientation, I`m editing an macro for tool breakage detection that is on the machine. how do I orientate the spindle in another position than the tool changing? Working on having the machine running lights out, but I have some fine bore tools that I also want to see if the insert is broken. I dont have spindle speed on the breakage macro, so I need to move the tool the half of the diameter, and orient the tool to have it in the right position.

Have anyone some inspiration for me?

Cheers, Daniel

Instead of orienting the spindle, is it possible that you can set a variable (per tool) that defines the tool tip as an angle relative to the spindle centerpoint ( I'm having difficulty putting this into words)?

Calculate a new table probe position and override the default value. Probe the tool, set the variables back to the default value then continue on.

In other words, don't orient the spindle - orient the table probe position. Is this feasible or completely impossible?
 

RTM

Cast Iron
Joined
Jun 6, 2014
Location
Ohio, USA
Has any one done any goofing things with macros like

WHILE[#5NE5]D01


(WHY DID YOU PUSH THAT BUTTON)
(DUMBASS)


G04X.5
#5=#0
END1

My first macro written for a Fadal (1997). Actually first macro I ever wrote. If the operator entered a value greater than 0.010" (technically any value less than 0.011 was ok) it kicked it out and asked for a smaller value. Sometimes I needed a way around it. If I entered the code 43 it allowed me to enter anything I wanted at my own peril.

Code:
%
N10O100
N20(TURN WHEEL
N30L100
N40#:AGAIN
N50#PRINT "VERIFY TOOL IS PROPERLY ALIGNED"
N60#PRINT "HOW MUCH FOR PASS? (E.G. 0.005=5 THOUSANDS OFF A SIDE"
N70#INPUT   V1
N80#IF  V1=43 THEN GOTO :SPEC
N90#IF V1 LT .011 THEN GOTO :OK
N100#PRINT ""
N110#PRINT ""
[B]N120#PRINT "ERROR! PLEASE ENTER VALUE OF .010 OR SMALLER"
N130#PRINT ""
N140#V1=0
N150#GOTO :AGAIN
N160#:SPEC
N170#PRINT "YOU ARE MY MASTER...ENTER ANYTHING!"
N180#INPUT V1[/B]
N190#:OK
N200#PRINT "TURN WHEEL ON THEN PRESS ENTER: "
N210#INPUT V99
N220#R1=R1+V1
N230G0G90X0.6Y0E1
N240Z-R1H1
N250G1X-14.25F1.5
N260Z3.H1G0
N270#PRINT "ANOTHER PASS? (1=YES 2=NO) :"
N280#INPUT V2
N290#IF V2=1 THEN GOTO :AGAIN
N300M17
N310M30
N320#CLEAR
N330T1M6
N340M19
N350#R1=0
N360L101
N370M6
N380M30
%
4054
 

dstryr

Diamond
Joined
Jan 22, 2010
Location
Nampa Idaho
Does anyone know of a Timer macro for a Fanuc 31i?
What I'm looking to do is add an if then to the top of all my programs in my new 33 pallet 5 axis. If the spindle has been 0 for more than 2 hours then run my warm up program in a sub and then back to machining. Trying to stop my operators from loading parts Monday morning after its been sitting idle for half of Sunday.
 








 
Top