A date engraving custom macro

Date engraving custom macro

By Brian Glick of Vermeer Corporation
Here is a custom macro I developed for machining centers.  It allows you to automatically engrave the current date on a part as it is being machined. The date is engraved along the X-axis in numbers 3/16 " high with .0375" spacing and in the yyddd format (which we required). In this format, December 31, 2007, would read 07365 for the 365th day of 2007; however, it would not be a problem to modify the macro to arrange the date in any format.
The key to making this work is system variable #3011, which maintains the current date in the format of yyyymmdd allowing the program to update daily without relying on anyone to change the date. In fact, the operator only has to adjust the feed rate and the depth of the engraving.
This macro checks the date to see if it is a leap year or not, and during leap years the number of the day is increased by one for days after February 28th. Another feature incorporated into the macro is equal spacing between all the different numbers. Since the number one is a different width than the number eight, the spacing has to change with each number. I am controlling this with variable #105 and it is set after the code for each number is processed. The value is the width of the number plus .0375.
This custom macro was set up for a Mori Seiki Dura Vertical with a Fanuc 0i controller, but should work on any machining center that supports Fanuc Custom Macro B. One issue I did run into was a slight hesitation between numbers caused by the program constantly branching back and forth with the GOTO statements. I enabled the high-speed macro and branching parameters (Parameter #6000 bits 2 and 4 on this machine) and that eliminated the problem.
 On faster controllers it is not an issue.
Main program
  • G65=Macro call
  • P9103= Macro program number
  • Z.005=Engraving depth (can be positive or negative)
  • F30.0= Feed rate
The main program positions the engraving tool in the upper left corner of the window in which you want the date to appear and 1.00 above the surface. The surface in this case is Z0. Since all the Z-axis movements within the macro are in incremental mode it is essential that the tool be 1.00 inch above the surface when the macro is called and I have a built-in alarm to check this.
O8297
N1T15M6 (Loads tool)
G0G90G54X1.Y-.5M3S8000 (Positions tool on X and Y)
G43H15Z1.M8 (Positions tool on Z)
G65P9103Z.005F30. (Calls macro)
M5
M9
G0G91G28X0Y0Z0
M30
Custom macro
O9103 (DATE MACRO)
#30=#4001 (Stores Current G-Code)
#31=#4003 (Stores Current G-Code)
#120=#5001 (Stores Current X Abs. Pos.)
#121=#5002 (Stores Current Y Abs. Pos.)
#122=#5003 (Stores Current Z Abs. Pos.)
#108=#9 (Stores feed rate in common variable)
#109=ABS[#26] (Stores the absolute depth in common variable)
#110=#109+.1 (Feed-in and the retract on Z axis)

IF[#4006EQ21]GOTO500 (Check for metric mode)
IF[#122NE1.]GOTO501 (Check for correct Z position)
IF[#26EQ#0]GOTO502 (Check for missing depth)
IF[#9EQ#0]GOTO503 (Check for missing feed rate)
IF[#109GE.025]GOTO504 (Check for excessive depth)

#100=#3011 (Stores date)
#101=#100 (Keeps date correct in #100 for checking)
#1=FIX[#101/10000] (Separate Year)
#101=#101-[#1*10000]
#2=FIX[#101/100] (Separate Month)
#101=#101-[#2*100]
#3=FIX[#101] (Separate Day)

(DATE FORMAT #2/#3/#1 MM/DD/YYYY)

(The following alarms are included to help during development and are not necessary after the program is proven)

IF[#1LT2000]GOTO505
IF[#1GE2100]GOTO505
IF[#2LT1] GOTO506
IF[#2GT12] GOTO507
IF[#3LT1] GOTO508
IF[#3GT31] GOTO509

#4=#1 (Keeps year correct in #1 for checking)

#4=#4-2000 (Drops first two digits of year)
#5=FIX[#4/10]
#4=#4-[#5*10]
#6=FIX[#4]


IF[[#1/4]EQ[FIX[#1/4]]] GOTO1 (Check for leap year)

(RUNNING TOTAL OF DAYS BY MONTH NO LEAP YEAR)
#509=0 (DECEMBER)
#510=31 (JANUARY)
#511=59 (FEBRUARY)
#512=90 (MARCH)
#513=120 (APRIL)
#514=151 (MAY)
#515=181 (JUNE)
#516=212 (JULY)
#517=243 (AUGUST)
#518=273 (SEPTEMBER)
#519=304 (OCTOBER)
#520=334 (NOVEMBER)
GOTO2

(RUNNING TOTAL OF DAYS BY MONTH LEAP YEAR)
N1
#509=0 (DECEMBER)
#510=31 (JANUARY)
#511=60 (FEBRUARY)
#512=91 (MARCH)
#513=121 (APRIL)
#514=152 (MAY)
#515=182 (JUNE)
#516=213 (JULY)
#517=244 (AUGUST)
#518=274 (SEPTEMBER)
#519=305 (OCTOBER)
#520=335 (NOVEMBER)

N2
#7=#[#2+508] (Stores the correct variable for the previous month)
#8=#3+#7 (Current day plus total of days in previous months)

IF[#8GT366] GOTO510
IF[#8LT1] GOTO511

#10=FIX[#8/100]
#8=#8-[#10*100]
#11=FIX[#8/10]
#8=#8-[#11*10]
#12=FIX[#8]

(#5, #6, #10, #11, #12)

(#105=SPACING)
(#33=COUNTER)
#105=0 (Spacing set to zero)
#33=0 (Counter set to zero)

(1ST NUMBER)
G0G91Z-.9 (Positions tool at clearance position--.100รข� above the part)
IF[#5EQ0] GOTO100
IF[#5EQ1] GOTO110
IF[#5EQ2] GOTO120
IF[#5EQ3] GOTO130
IF[#5EQ4] GOTO140
IF[#5EQ5] GOTO150
IF[#5EQ6] GOTO160
IF[#5EQ7] GOTO170
IF[#5EQ8] GOTO180
IF[#5EQ9] GOTO190

N10 (2ND NUMBER)
G90
#120=#120+#105 (Spacing added to X position)
G0X#120Y#121 (Positions for next number)
G91
IF[#6EQ0] GOTO100
IF[#6EQ1] GOTO110
IF[#6EQ2] GOTO120
IF[#6EQ3] GOTO130
IF[#6EQ4] GOTO140
IF[#6EQ5] GOTO150
IF[#6EQ6] GOTO160
IF[#6EQ7] GOTO170
IF[#6EQ8] GOTO180
IF[#6EQ9] GOTO190

N20 (3RD NUMBER)
G90
#120=#120+#105 (Spacing added to X position)
G0X#120Y#121 (Positions for next number)
G91
IF[#10EQ0] GOTO100
IF[#10EQ1] GOTO110
IF[#10EQ2] GOTO120
IF[#10EQ3] GOTO130

N30 (4TH NUMBER)
G90
#120=#120+#105 (Spacing added to X position)
G0X#120Y#121 (Positions for next number)
G91
IF[#11EQ0] GOTO100
IF[#11EQ1] GOTO110
IF[#11EQ2] GOTO120
IF[#11EQ3] GOTO130
IF[#11EQ4] GOTO140
IF[#11EQ5] GOTO150
IF[#11EQ6] GOTO160
IF[#11EQ7] GOTO170
IF[#11EQ8] GOTO180
IF[#11EQ9] GOTO190

N40 (5TH NUMBER)
G90
#120=#120+#105 (Spacing added to X position)
G0X#120Y#121 (Positions for next number)
G91
IF[#12EQ0] GOTO100
IF[#12EQ1] GOTO110
IF[#12EQ2] GOTO120
IF[#12EQ3] GOTO130
IF[#12EQ4] GOTO140
IF[#12EQ5] GOTO150
IF[#12EQ6] GOTO160
IF[#12EQ7] GOTO170
IF[#12EQ8] GOTO180
IF[#12EQ9] GOTO190

N50
GOTO999

(The following blocks are the NC Code for numbers 0-9. When it makes a number the counter variable increases by one and the spacing variable is the width of the number plus .0375. It then checks the counter to go back to do the next number in line.)

N100 (CODE FOR 0)
#33=#33+1
G91
X.0111Y-.0306
G1Z-#110F#108 (Feed to depth from clearance position)
G3Y-.1263I.1737J-.0631
X.0876I.0438J.0156
Y.1263I-.1737J.0632
X-.0876I-.0438J-.0156
G0Z#110 (Retract to clearance position)
#105=.1473
IF[#33EQ1] GOTO10 (Checks counter to see what number is next)
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N110 (CODE FOR 1)
#33=#33+1
G91
X0.Y-.0268
G1Z-#110F#108
X.0268Y.0268
Y-.1875
X-.0268
G0Z#110
X.0268
G1Z-#110
X.0268
G0Z#110
#105=.0911
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N120 (CODE FOR 2)
#33=#33+1
G91
X.004Y-.0268
G1Z-#110F#108
G2X.0464Y.0268I.0464J-.0268
G1X.0042
G2X.0535Y-.0512I0.J-.0536
X-.0139Y-.0336I-.0535J.0024
X-.0481Y-.0359I-.2895J.3377
G3X-.0461Y-.0668I.0435J-.0793
G1X.1121
G0Z#110
#105=.1496
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N130 (CODE FOR 3)
#33=#33+1
G91
X.0027Y-.0268
G1Z-#110F#108
G2X.0466Y.0268I.0466J-.0272
G1X.007
G2X.0389Y-.0146I0.J-.0591
X.0146Y-.0323I-.0282J-.0323
X-.0398Y-.0467I-.0473J0.
G1X-.0134
G0Z#110
X.0134
G1Z-#110
G2X.0425Y-.047I-.0048J-.047
X-.0146Y-.0323I-.0428J0.
X-.039Y-.0146I-.039J.0445
G1X-.0122
G2X-.0467Y.0268I0.J.054
G0Z#110
#105=.15
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N140 (CODE FOR 4)
#33=#33+1
G91
X.0941Y-.1875
G1Z-#110F#108
Y.1875
X-.0971Y-.1433
X.1246
G0Z#110
#105=.1621
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N150 (CODE FOR 5)
#33=#33+1
G91
X.1134Y0.
G1Z-#110F#108
X-.1134
Y-.083
G2X.0536Y.016I.0503J-.0704
X.0317Y-.0074I0.J-.0709
X.0218Y-.0193I-.0254J-.0509
X.0023Y-.0643I-.0509J-.034
X-.0511Y-.0297I-.0511J.0292
G1X-.0085
G2X-.0393Y.0148I0.J.0597
X-.0105Y.012I.0393J.0449
G0Z#110
#105=.1549
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N160 (CODE FOR 6)
#33=#33+1
G91
X.1124Y-.0279
G1Z-#110F#108
G3X-.1017Y-.0102I-.0487J-.0273
X-.0038Y-.107I.1562J-.059
X.1072Y-.0037I.0542J.0134
X-.1072Y.0037I-.053J.017
G0Z#110
#105=.1543
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N170 (CODE FOR 7)
#33=#33+1
G91
X0.Y0.
G1Z-#110F#108
X.1125
G3X-.0562Y-.1875I.2845J-.1875
G0Z#110
#105=.15
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N180 (CODE FOR 8)
#33=#33+1
G91
X.0502Y-.0871
G1Z-#110F#108
X.0121
G3X.0435Y.0436I0.J.0436
X-.0435Y.0435I-.0435J0.
G1X-.0121
G3X-.0201Y-.0049I0.J-.0435
X.0201Y-.0822I.0201J-.0386
X-.0413Y-.0788I0.J-.0502
X.0413Y-.0216I.0413J.0286
G1X.0121
G3X.0502Y.0502I0.J.0502
X-.0502Y.0502I-.0502J0.
G0Z#110
#105=.15
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

N190 (CODE FOR 9)
#33=#33+1
G91
X.0025Y-.0386
G1Z-#110F#108
G3X.1072Y-.0038I.0531J-.017
X-.1072Y.0038I-.0541J-.0134
G0Z#110
X.1072Y-.0038
G1Z-#110
G2X-.0037Y-.107I-.16J-.048
X-.1017Y-.0102I-.0531J.0171
G0Z#110
#105=.1543
IF[#33EQ1] GOTO10
IF[#33EQ2] GOTO20
IF[#33EQ3] GOTO30
IF[#33EQ4] GOTO40
IF[#33EQ5] GOTO50

(ALARMS)
N500#3000=100(IN-METRIC-MODE)
N501#3000=101(Z-POSITION-INCORRECT)
N502#3000=102(Z-VALUE-MISSING)
N503#3000=103(F-VALUE-MISSING)
N504#3000=104(EXCESSIVE-Z-DEPTH)
N505#3000=105(DATE-ERROR-YEAR)
N506#3000=106(DATE-ERROR-MONTH)
N507#3000=107(DATE-ERROR-MONTH)
N508#3000=108(DATE-ERROR-DAY)
N509#3000=109(DATE-ERROR-DAY)
N510#3000=110(DAYS-OVER-366)
N511#3000=111(DAYS-LESS-THAN-1)

N999
G0G90Z#122 (Returns tool to original Z position)
G#30G#31 (Restores saved G-Codes)
M99