What's new
What's new

Fanuc Nesting Macro Call Question

fierce

Plastic
Joined
Jun 13, 2020
Hello everyone,

I've created some programs to machine parts using Fanuc Macro sub-program calls and some Custom G-Code Calls to machine each part (with the ability to skip some ro allparts etc...)

Here's a sample sub-program os a machining operation (the principle is that it repeats itself once for each part):

Code:
% O8050 (MACHINING OPERATION SUB-PROGRAM)

N110
G110 T#20 H#11 (Call to sub-program O9015)
Z-#26
G130
GOTO#130
N130

M99%

The G110 is a custom G-Code that will call a subprogram that handles tool calls, origines, etc.. and the G130 will set the next part to be machined and will either jump back to N110 to machine the next part or to N130 if it has machined all the parts.

The question I have is if you guys know any way I can skip this entirely (as in jump to M99) if in the G110 it calculated that all parts are to be skipped.

I know I can just add 2 more lines to make it work, for example (in green):

Code:
% O8050 (MACHINING OPERATION SUB-PROGRAM)

N110
G110 T#20 H#11 (Call to sub-program O9015)
GOTO#110
N110
Z-#26
G130
GOTO#130
N130

M99%

But this would defeat my idea of making this as simple as possible by adding 2 more lines.

I was thinking about some fanuc option that would make me able to for example on the G110 (O9015) that could execute code on his parent program (O8050) that way I could just jump to the line I wanted from the G110 and could even remove the GOTO#130 and make it even more simple, or something that could make it able to end the program that was called before it, or some other option.

If you guys can think of something please let me know.

Thank you in advance for any help!
Best Regards
 
I had a couple of ideas:

1) I was thinking about doing something like a M97 call to a line like it was a sub-program, but that is on HAAS machines only.

2) I saw a forum post about someone saying that M99 P_line_number ends a sub-program and returns to that "main" program line number, I was wondering if that actually works and if it could work on a sub-sub-program since it says "main" program. (Will only be at the machine on monday to test this)

3) One idea just jumped into my mind, maybe using a M#110 to be either M99 (end program) or an M call that does nothing e.g. M400 and set #110 to either 99 or 400 on G110. Like this:

Code:
% O8050 (MACHINING OPERATION SUB-PROGRAM)


N110
G110 T#20 H#11 (Call to sub-program O9015)
M#110
Z-#26
G130
GOTO#130
N130


M99%


At least that would make it one more line instead of two...


Still open to any ideas.
 
I had a couple of ideas:

1) I was thinking about doing something like a M97 call to a line like it was a sub-program, but that is on HAAS machines only.

2) I saw a forum post about someone saying that M99 P_line_number ends a sub-program and returns to that "main" program line number, I was wondering if that actually works and if it could work on a sub-sub-program since it says "main" program. (Will only be at the machine on monday to test this)

3) One idea just jumped into my mind, maybe using a M#110 to be either M99 (end program) or an M call that does nothing e.g. M400 and set #110 to either 99 or 400 on G110. Like this:

Code:
% O8050 (MACHINING OPERATION SUB-PROGRAM)


N110
G110 T#20 H#11 (Call to sub-program O9015)
M#110
Z-#26
G130
GOTO#130
N130


M99%


At least that would make it one more line instead of two...


Still open to any ideas.
Hello fierce
With regards to calling Programs as Local Subprograms, as with HAAS and their M97 Call, the same can be done with a Fanuc Control depending on the Control Model. The Function was introduced with the FS16i Control, so if your control is later than that and an "i" version, then by setting parameter bit 6005.0 to "1" will allow Local Subprograms to be called via a Sequence number as in the following example:

O0100
(MAIN PROGRAM)
N1 G17 G21 G40 G80 G94
--------------
--------------
--------------
M98 Q101
--------------
--------------
--------------
M30
N101
(INTERNAL SUB PROGRAM)
--------
--------
program code goes here
--------
--------
M99

In the above example, the Sequence Number of the Local Subprogram is specified with a "Q" address following M98. Setting parameter bit 6005.0 to "1" also allows an External Subprogram to start from a particular Sequence Number within the External Subprogram, as shown in the following example:

M98 P1000 Q20

The above Command Block will have Control Start at Sequence Number N20 in External Subprogram O1000.

Regarding returning Control from a Subprogram to a Block in the Calling Program other than the Block immediately following the Call Block, this can be done by specifying a P value following the M99 in the Subprogram. The following example shows how to direct control to return to Block Sequence Number N100 in the Calling Program, rather than the Block immediately after the Calling Block:

M98 P1000
N10 -------
-----------
-----------
-----------
-----------
N100
-----------
-----------
-----------
-----------
M30



O1000
-----------
-----------
-----------
-----------
-----------
M99 P100

The Command Block immediately above will return control to Block Number N100 and not N10 as would be the case if only M99 was specified.

In your second program code example in your first Post, shown following,

N110
G110 T#20 H#11 (Call to sub-program O9015)
GOTO#110
N110
Z-#26
G130
GOTO#130
N130

M99%

you can't have two instances of the same Sequence Number if you intend to reference that number in a GOTO Statement, or if you plan to branch to that Sequence Number when returning to the Calling Program by specifying a Sequence Number in conjunction with M99 in the Subprogram, as shown in the following example:

M99 P_ _

Where:
"_ _" equals the Sequence Number in the Calling Program to return to.

Regards,

Bill
 
Thank you so much for your input Bill,

That N110 twice was just a typo.

The M99 P__ function would do exactly what I want my programs to do.

The only question left is if it will work on a sub program call to another sub program (as in, will it return to that line on the previous subprogram that called it, will it return to the "main" program, or will it simply not work). Because I'm on the 4th nest when the M99 P__ is called. O1 (main)-> O100 (G65 Call, part) -> O8060 (G65 Call, Machining Operation) -> G100 (Calls O9015) -> O9015 (M99 P__)

Thank you in advance,
Best Regards
 
Thank you so much for your input Bill,

That N110 twice was just a typo.

The M99 P__ function would do exactly what I want my programs to do.

The only question left is if it will work on a sub program call to another sub program (as in, will it return to that line on the previous subprogram that called it, will it return to the "main" program, or will it simply not work). Because I'm on the 4th nest when the M99 P__ is called. O1 (main)-> O100 (G65 Call, part) -> O8060 (G65 Call, Machining Operation) -> G100 (Calls O9015) -> O9015 (M99 P__)

Thank you in advance,
Best Regards
Hello fierce,
Returning control form a Subprogram always does so to the program from which it was called; you can't go from a nested program directly back to the Main Program.

Regards,

Bill
 
Thank you again Bill,

I'll test it out monday and I'll post back if it works as intended.

Another question I have since I changed all my programs counting on that M99 P__ working is that I now need to know what nested level I'm in or what was the program that called the current one, and I'm drawing a blank on how to do it, I thought of an idea:

Some Fanuc variable that holds the previous program number (as in the program that called the current sub-program). AFAIK the var #4515 and #4115 holds the current program number, but how do I know what the previous one was without adding any code to that previous program?


(Again I know I could easely do this by adding/checking a variable on each sub program but I want to keep the simplicity and do all the calculations in the same place)

Thank you in advance for any help,
Best Regards
 
Thank you again Bill,

I'll test it out monday and I'll post back if it works as intended.

Another question I have since I changed all my programs counting on that M99 P__ working is that I now need to know what nested level I'm in or what was the program that called the current one, and I'm drawing a blank on how to do it, I thought of an idea:

Some Fanuc variable that holds the previous program number (as in the program that called the current sub-program). AFAIK the var #4515 and #4115 holds the current program number, but how do I know what the previous one was without adding any code to that previous program?


(Again I know I could easely do this by adding/checking a variable on each sub program but I want to keep the simplicity and do all the calculations in the same place)

Thank you in advance for any help,
Best Regards
Hello fierce,
Have your programs numbered sequentially, then the previous program will be the current program identity, accessed from the System Variable, minus 1.

Regards,

Bill
 
Hello again Bill,

That's a good idea but I'm using ranges O7xxx for one type of program (parts) and O8xxx for another (operations). I just sticked to adding a letter-parameter to check for now.

Regarding the M99 P__ it worked just fine. I was able to reduce my program from:

Code:
% O8050 (MACHINING OPERATION SUB-PROGRAM)

N110
G110 T#20 H#11
GOTO#110
N110
Z-#26
G130
GOTO#130
N130

M99%

To:

Code:
% O8050 (MACHINING OPERATION SUB-PROGRAM)

N110
G110 T#20 H#11
Z-#26
G130

M99%

And that's awesome! Thank you again for the help!
Best Regards!
 
Hello again Bill,

That's a good idea but I'm using ranges O7xxx for one type of program (parts) and O8xxx for another (operations). I just sticked to adding a letter-parameter to check for now.
Hello fierce,
Then you would probably be better of to Read the Program Number System Variable into a Common Variable with the Block before the Block Calling the Next Subprogram. This Variable can be accessed in the Next Subprogram when you need to know the Program Number of the Previous Nested Program.

Regards,

Bill
 
Hello Bill,

That would defeat the purpose of the O8050 being super simple and only having like 4 lines (if I add the code to save that program variable I would add another line).
I've read something in the manual about one of the variables that hold the current program number only being updated after a block (or something like that) so maybe there's someway of getting the previous program number on the next subprogram (maybe at the first line of the next program, don't know). I haven't tested it but would be cool if it worked, for the time being I just added a control variable to G110 (G110 A1) depending on which program is calling it.

Best Regards,
 
I'm having a tough time figuring out why the reluctance to add an additional line. The amount of time to execute say #149=#4115 is a couple mS. Makes the program 10 characters longer so not a big memory hit. Can you share the reason?
 
I'm having a tough time figuring out why the reluctance to add an additional line. The amount of time to execute say #149=#4115 is a couple mS. Makes the program 10 characters longer so not a big memory hit. Can you share the reason?
Hello Kevin,
I had the same thought. I don't think I'm quite the new chum to Macro programming and particularly when the code is so brief anyway, it would make no difference; you can't make an omelet without breaking eggs. Its also a bit difficult to give the best advice when the whole program logic is not revealed to the Forum.

@fierce
However, passing the current Program Number as an argument to the next Macro Program, which would then be the program number of the previous Previous Macro (the calling program)in the program to which its passed, would work well. The same argument could be used to pass the Program number to each of the next nested program as the value of the Local Variable is retained in each level of nesting. Accordingly, as the nest is unwound, the previous program number at each level would be available if required.

Regards,

Bill
 
Hello fierce
With regards to calling Programs as Local Subprograms, as with HAAS and their M97 Call, the same can be done with a Fanuc Control depending on the Control Model. The Function was introduced with the FS16i Control, so if your control is later than that and an "i" version, then by setting parameter bit 6005.0 to "1" will allow Local Subprograms to be called via a Sequence number as in the following example:

O0100
(MAIN PROGRAM)
N1 G17 G21 G40 G80 G94
--------------
--------------
--------------
M98 Q101
--------------
--------------
--------------
M30
N101
(INTERNAL SUB PROGRAM)
--------
--------
program code goes here
--------
--------
M99

In the above example, the Sequence Number of the Local Subprogram is specified with a "Q" address following M98. Setting parameter bit 6005.0 to "1" also allows an External Subprogram to start from a particular Sequence Number within the External Subprogram, as shown in the following example:

Regards,

Bill

Hello Bill, thank you for that detailed writeup.

I saw it last night, and was thrilled with the fact that I could do that. I hate separate subprograms in general, so when I have a sub that will only be used within one program, I would like to do what you've outlined.

But I have a problem. Makino A88 with 16imb control, 6005.0=1, when trying to use M98Q123, I get alarm 3 (too many digits)

Am I missing something here?
 
Hello Bill, thank you for that detailed writeup.

I saw it last night, and was thrilled with the fact that I could do that. I hate separate subprograms in general, so when I have a sub that will only be used within one program, I would like to do what you've outlined.

But I have a problem. Makino A88 with 16imb control, 6005.0=1, when trying to use M98Q123, I get alarm 3 (too many digits)

Am I missing something here?

Hello dandrummerman21,
Controls that don't have the feature, don't have the respective parameter; accordingly, what you have should work. As a test, use a single digit "Q" value, Q1 for example. You need to ensure that the same sequence number doesn't exist the program elsewhere.

Regards,

Bill
 
Hello dandrummerman21,
Controls that don't have the feature, don't have the respective parameter; accordingly, what you have should work. As a test, use a single digit "Q" value, Q1 for example. You need to ensure that the same sequence number doesn't exist the program elsewhere.

Regards,

Bill


M98Q9 With N9 later in the program -> "078 number not found"
M98Q0009 With N9 "078 number not found"
M98Q0009 with N0009 "number not found"
M98Q0010 With N0010 "too many digits"
M98Q0010 With N10 "too many digits"
M98Q10 with N10 "too many digits"

M98P2745Q9 With N9 near the top of sub 2545 "number not found"
M98P2745Q10 With N10 near the top of the sub "too many digits"

It is worth noting that while I do have parameter 6005 available to me, there is not the 3 letter symbol above it, according to the parameter manual it should be SQC. Does that mean it is not "installed"? Is it a software version problem?



Edit, checked the software version:

2. SOFTWARE CONFIGRATION

SYSTEM B0F2 00NB
BASIC / OPTION-A1

A quick google suggests that B0F2 is a 16iA, not B as we have been thinking the last 10 years. I do not see parameter 6005 in my 16iA parameter manual. Do I really have an A? And is this why I've got this problem?
 
......A quick google suggests that B0F2 is a 16iA, not B as we have been thinking the last 10 years. I do not see parameter 6005 in my 16iA parameter manual. Do I really have an A? And is this why I've got this problem?

My info shows that firmware version B0F2 is a 16iA. I could not find any reference to the use of M98 Q... in either the descriptions manual or operation manual for the 16iA. My 16iA parameter manual does not list parameter 6005 at all.

Based on this, it seems to me that the M98 Q sub-routine call function must not have come to be until the 16iB version. There is also a possibility that the iB hardware was released with the B0F2 firmware if a new firmware version was not ready for release at the same time as the hardware. I don't have any info to confirm that may have happened so just a guess as to why you thought your control was an iB.
 
Last edited:
Ah well, maybe I was told it was a B, and the pdf folder I have that contains "all of the manuals for the machine" has iB manuals in it. But just for shits and giggles I opened the drawer with the hard copies we got with the machine, and it came with an iA manual. So A it is.

Another perhaps incorrect reason I thought it was B is that the card reader is a flash card on this machine, while the 2 other 16i machines (robodrills) that are certainly iA have the SRAM card readers. I have been assuming that the flash card reader came around with the B version, but apparently it isn't as cut and dry as that!

I did try to turn on 6005.0 on one of the robodrills and got the same alarms. That machine has the same firmware version. Turning on that bit on these controls DOES prompt an alarm 0 (turn off power) so it is like they knew they were gonna do something with it but hadn't gotten it put in yet, I guess.

Oh well, when the newest mill in the shop isn't from 2001, maybe I'll be using M98Q! lol
 
I'm having a tough time figuring out why the reluctance to add an additional line. The amount of time to execute say #149=#4115 is a couple mS. Makes the program 10 characters longer so not a big memory hit. Can you share the reason?

This is a set of 9000 custom g-code sub-programs for machining centers that machine multiple parts at once. The G-Codes set up the part sizes/work offsets automatically on the machines to machine with maximum efficiency and the operator only has to call the tool and the cutting movements to machine all parts, like this for example:
G110 T10 H10 D10
G1 Z-10 F100
G130

There's a lot of settings/calculations and automation involved on those sub-programs so I want to keep the machining program (created by the operator) as simple as possible.

Best Regards
 








 
Back
Top