top of page

A 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 newer/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 0.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

2,413 views0 comments

Recent Posts

See All

Tapping on a turning center (without canned cycles)

Unless your Fanuc controlled turning center came with live tooling, it’s likely that you don’t have canned cycles (G80-G89) like those you find on machining centers. You might have G74 and G75, the mu

Can you speed up your tool change time?

Machining centers, of course, have automatic tool changing devices to automate the tool changing process. Current models boast very fast tool changing times and you may be quite satisfied with tool ch

bottom of page