What's new
What's new

Subprogram end of program error

Eleven71Cutters

Aluminum
Joined
Mar 26, 2021
I am in need of programming several different parts on the same pallet. I can hold up to 12 parts 1.125"x2.25" per pallet and can fit 2 pallets on my orange vises. I currently run single piece flow during the day and when needed, I run pallets of the same part overnight. I want to be able to run 6 or so different parts overnight so I am working out the bugs with Sub programming. I run 1 part as the main program then output the entire program for the other parts but edit the header to reflect the O#### I can get the program to jump into the sub, and run through the code but the issue I am having is at the end of the sub program where I have M99. I have
G80
G00 Z1.013
M99
I get an error prior to M99 stating End of program Error.
Even if I input
G80
G28 G91 Z0 Y0
M90 (With and without)
M99
I will get the same Error message.

Any suggestions for the end of the sub so I can get it to hit M99?

Fusion 360 with hand editing code for a Speedio S500X2.

I have Peter Smid programming handbook infront of me and am using the same codes prior to M99 and still get the error.
 
A little confusing.... Show more of your code. Where and how are you calling the Subroutine? (M98Pxxxx) right? Are you trying to call the Main Program you're already in as a repeating Sub?

Less info on what you're trying to do and more info on the failing code sequence.

Something like the following.

%
O5000 (MAIN PROGRAM)

Blah-blah
Blah-blah
M98P5001 (Call Sub)
Blah-blah (Sub returns here)
Blah-blah
M30
%

%
O5001 (MAIN INFO IN SUB)

Blah-blah
Blah-blah
Blah-blah
Blah-blah
M99
%
 
I are korn fuse ed?

you want to run multiple parts on one pallet? meaning all the same part, same pallet, or different other parts on different other pallets, or different parts on one pallet?

Cause if its multiple pallets you need to have a pallet organizer puter, that is different then your machines puter, it will upload each set of programs with each pallet, (don't ask me how thats some pixie wrangling I didn't spend much time on)

But if you want to run multiple parts/programs on one pallet, using I hope... different vices...

Should be as simple as main program= 06666(the master is waiting);M98p1(prgm 1); m98p2(prgm 2) rinse repeat as necessary M30;%;
each "sub" would be o1(prgm 1) does its thang, m98(return to master, replaces m30); %;

note, you can ditch the g80, since yer next line is a g0, g0 cancels canned cycles, as well as rapid, annnd get rid of that pointless g91... hitting reset there could be disastrous (yes I know a lot of posts do this... its a terrible idea, ask me how I know)
Also note: the () comments are mine... and are in no way considered PC by most HR depts...
 
the other thang to consider... the machines will generally "look ahead" a few lines (at least 4 usually much more) so because its alarming out at the m99, the problem is likely "past" the M99 i.e. no % at end of sub program, or some other issue with the "main" program
 
note, you can ditch the g80, since yer next line is a g0, g0 cancels canned cycles, as well as rapid, annnd get rid of that pointless g91... hitting reset there could be disastrous (yes I know a lot of posts do this... its a terrible idea, ask me how I know)
Even though it is true that G0 will end a Canned or Fixed Cycle, it is good programming practice to end them with G80. It's sort of like the period at the end of a sentence. Meaning you expect it there.

Not using G91 with G28 is just as bad as not re-instating G90 after using G91 for whatever reason. Without it, or with G90 active, G28 will run off to an intermediate point (usually unexpectedly to those not accustomed to it) and potentially crash into something on its way to Z home. Again... re-instating G90 when you're finished with G91 is good programming practice.
 
Last edited:
Even though it is true the G0 will end a Canned or Fixed Cycle, it is good programming practice to end them with G80. It's sort of like the period at the end of a sentence. Meaning you expect it there.

Not using G91 with G28 is just as bad as not re-instating G90 after using G91 for whatever reason. Without it, or with G90 active, G28 will run off to an intermediate point (usually unexpectedly to those not accustomed to it) and potentially crash into something on its way to Z home. Again... re-instating G90 when you're finished with G91 is good programming practice.
g28 is machine zero, think of it as another coordinate like g54, except its not supposed to be user changed. putting the g91 in there, is just adding a code that can and will screw something up if the operator doesn't pay attention, or worse if there isn't any safety lines, i.e. g90 at the beginning of every tool cycle. IF you want some other zero position, then g30 is user defined for this reason. Point being you've never needed g91 for a move to g28/machine home. Seen guys put a g91 xz move in lathe programs for clearance too... that bought at least 1 tool turret, and sacrificed allllllll the live tooling on that lathe...

g0, is modal, so is g80, so is g91/g90, i.e. once they are on, they stay on until canceled, hence putting some random ass g91 in the middle of a program for no other reason then thats how grandpa did it, without IMMEDIATLY canceling it, is a recipe for disaster.

I get that putting a g80 in after a canned cycle makes folks understand that its the end of said canned cycle, but we could also spend the 5 sec explaining modal codes too, which would do a lot for newbs and understanding how this shizz functions. for instance, g0 g1 g2 g3, g80-89 (there are more...) are all of the same modal group, each will cancel the other and perform its use at ___ coordinate You can totally program g1xy; g83rpqfz and it will feed to xy pos, then peck drill. is it a good idea, maybe, will it do it, absolutely.
 
No it is not.



Not necessarily, in fact that is typically the first thing you turn off in parameters and make it -G91 that is - a one-shot ( non modal ) when you get a new machine.
cool, muddy water seldom runs deep.
its cute that you find some way to disagree with any coding issue by bringing up some different settings issue just so you and yer buddy angel can look down your noses at people. oh you got one on the new guy har har...
 
cool, muddy water seldom runs deep.
its cute that you find some way to disagree with any coding issue by bringing up some different settings issue just so you and yer buddy angel can look down your noses at people. oh you got one on the new guy har har...
Well, for one who is spouting dipshitness for all of your 12 days of membership, you are quickly establishing yourself as the Jon Banquer of programming.
Welcome to the forum!
 
Make sure you have a blank line below the M99 line to force an EOB on the M99 line, if it is the last line in your program file.
 
cool, muddy water seldom runs deep.
its cute that you find some way to disagree with any coding issue by bringing up some different settings issue just so you and yer buddy angel can look down your noses at people. oh you got one on the new guy har har...
Here we go with Mr. Know It All again.

G28 is a two shot command, which returns the specified axis to the Reference Return Position through an Intermediate Point. It is commonly used at the start and end of Tool Operation Code to ensure that the axes are in a safe and correct location for a Tool Change.

If the G28 code were to be executed in G90 Mode, the Intermediate point will be the Absolute Coordinate specified in the G28 Block, as for example the following example.

G90 G28 Z20.0

Irrespective of the Z coordinate position of the Tool prior to executing the above Block, the Z Axis will first move to Z20.0, then to the Z Reference Return Position. You can see that the G28 command is a two part command by executing it in Single Block Mode. When executing the above example Block in Single Block Mode, the first press of the Cycle Start Button will have the Z Axis move to the Absolute Coordinate of Z20.0 and stop with the Feed Hold Botton illuminated. When the Cycle Start Button is pressed for the second time, the Z axis moves straight to the Reference Return Position. When the above Block is executed when NOT in Single Block Mode, it appears that the Z axis returns to the Reference Return Position via Z20.0 as one execution..

If the following Block is executed in Single Block Mode, and the current Z location of the Tool is Z20.0

G90 G28 Z0.0

the Z Axis will move at Rapid Travers speed so that the Tool touches Z Zero of the Workpiece and stop with the Feed Hold Button illuminated when the Cycle Start Button is pressed once in Single Block Mode. The second press of the Cycle Start Button will send the Z axis to the Reference Return Position. Whether in Single Block or Full Auto Mode, this action of traveling to Z0.0 from Z20.0 before moving to the Reference Return position is likely to scare the crap out of the operator, and if Z Zero happens to be the bottom of the workpiece, then you have a crash on your hands.

When the following Block, with the correct Incremental Move command of G91 is used:

G91 G28 Z0.0

the Z axis first moves to the intermediate point Zero distance away from the Z axis current location and then moves directly to the Z Reference Return position. When in Single Block Mode, the first press of the Cycle Start Button appears to only illuminate the Feed Hold light, but in actual fact, it carried out the first action of the G28 command by going to the intermediate position Zero distance away. The second press of the Cycle Start Button will have the Z Axis move directly to the Reference Return Position. With Single Block Mode NOT on, the Z axis will appear to move directly to the Reference Return Position in one action.

Accordingly, the OP's use of G91 G28 Z0 Y0 is correct. Read a programming manual and learn something.

And it's not a case of looking down one's nose at you, my issue with you is that you make these totally incorrect comments in such and authoritative manner, that newbies following the Thread may think its gospel. Those that know a thing or two about programming, know that you're full of shit, it's the sincere beginners I worry about. I'm confident that SeymourDumore feels the same.
 
Last edited:
A little confusing.... Show more of your code. Where and how are you calling the Subroutine? (M98Pxxxx) right? Are you trying to call the Main Program you're already in as a repeating Sub?

Less info on what you're trying to do and more info on the failing code sequence.

Something like the following.

%
O5000 (MAIN PROGRAM)

Blah-blah
Blah-blah
M98P5001 (Call Sub)
Blah-blah (Sub returns here)
Blah-blah
M30
%

%
O5001 (MAIN INFO IN SUB)

Blah-blah
Blah-blah
Blah-blah
Blah-blah
M99
%
Small example:

(3012 Main Program)
(MACHINE)
( VENDOR BROTHER)
( MODEL SPEEDIO S500X2)
( DESCRIPTION 3-AXIS SPEEDIO S500X2)
(T19 D=0.25 CR=0 TAPER=140DEG - ZMIN=0.0785 - DRILL)
(T63 D=0.1457 CR=0 TAPER=140DEG - ZMIN=-0.057 - DRILL)
G00 G90 G40 G80
G94 G49

(Here I have also run it with the WCS inserted before the sub and it runs the same with or without)

M98 P3013 (Sub Program)

M98 P3014 (Sub Program)

M09
M400
M401
G100 T19
G28 G91 Z0 Y0
M30

Sub Program:
(O3013 DRILL3)
G54.1 P37
M09
M01
G17 G90 G94
N15 G100 T63 X-0.2755 Y-1.3313 G43 Z0.878 L19 H63 D63 S3409 M03
M08
G00 X-0.2755 Y-1.3313
G00 Z0.878
G17
G00 Z0.478
G73 X-0.2755 Y-1.3313 Z-0.057 R0.4615 Q0.07 F7
X0.2755
G80
G28 G91 Z0 Y0
G90
M99

I have run the main program several times and it dives into the sub but at the end of the sub, I get the error message and it does not return to the main.
 
Last edited:
Everything seems to look fine except your Program Numbers are in parenthesis which I'm guessing is a typo.

When copying your programs into the machine it should automatically insert the EOB semicolon after each block. I can't imagine it not doing it to your M99 at the end of the sub. You might just double check.
 
Small example:

(3012 Main Program)
(MACHINE)
( VENDOR BROTHER)
( MODEL SPEEDIO S500X2)
( DESCRIPTION 3-AXIS SPEEDIO S500X2)
(T19 D=0.25 CR=0 TAPER=140DEG - ZMIN=0.0785 - DRILL)
(T63 D=0.1457 CR=0 TAPER=140DEG - ZMIN=-0.057 - DRILL)
G00 G90 G40 G80
G94 G49

(Here I have also run it with the WCS inserted before the sub and it runs the same with or without)

M98 P3013 (Sub Program)

M98 P3014 (Sub Program)

M09
M400
M401
G100 T19
G28 G91 Z0 Y0
M30

Sub Program:
(O3013 DRILL3)
G54.1 P37
M09
M01
G17 G90 G94
N15 G100 T63 X-0.2755 Y-1.3313 G43 Z0.878 L19 H63 D63 S3409 M03
M08
G00 X-0.2755 Y-1.3313
G00 Z0.878
G17
G00 Z0.478
G73 X-0.2755 Y-1.3313 Z-0.057 R0.4615 Q0.07 F7
X0.2755
G80
G28 G91 Z0 Y0
G90
M99

I have run the main program several times and it dives into the sub but at the end of the sub, I get the error message and it does not return to the main.
Why the wait codes? m400, m401?
 
Here we go with Mr. Know It All again.

G28 is a two shot command, which returns the specified axis to the Reference Return Position through an Intermediate Point. It is commonly used at the start and end of Tool Operation Code to ensure that the axes are in a safe and correct location for a Tool Change.

If the G28 code were to be executed in G90 Mode, the Intermediate point will be the Absolute Coordinate specified in the G28 Block, as for example the following example.

G90 G28 Z20.0

Irrespective of the Z coordinate position of the Tool prior to executing the above Block, the Z Axis will first move to Z20.0, then to the Z Reference Return Position. You can see that the G28 command is a two part command by executing it in Single Block Mode. When executing the above example Block in Single Block Mode, the first press of the Cycle Start Button will have the Z Axis move to the Absolute Coordinate of Z20.0 and stop with the Feed Hold Botton illuminated. When the Cycle Start Button is pressed for the second time, the Z axis moves straight to the Reference Return Position. When the above Block is executed when NOT in Single Block Mode, it appears that the Z axis returns to the Reference Return Position via Z20.0 as one execution..

If the following Block is executed in Single Block Mode, and the current Z location of the Tool is Z20.0

G90 G28 Z0.0

the Z Axis will move at Rapid Travers speed so that the Tool touches Z Zero of the Workpiece and stop with the Feed Hold Button illuminated when the Cycle Start Button is pressed once in Single Block Mode. The second press of the Cycle Start Button will send the Z axis to the Reference Return Position. Whether in Single Block or Full Auto Mode, this action of traveling to Z0.0 from Z20.0 before moving to the Reference Return position is likely to scare the crap out of the operator, and if Z Zero happens to be the bottom of the workpiece, then you have a crash on your hands.

When the following Block, with the correct Incremental Move command of G91 is used:

G91 G28 Z0.0

the Z axis first moves to the intermediate point Zero distance away from the Z axis current location and then moves directly to the Z Reference Return position. When in Single Block Mode, the first press of the Cycle Start Button appears to only illuminate the Feed Hold light, but in actual fact, it carried out the first action of the G28 command by going to the intermediate position Zero distance away. The second press of the Cycle Start Button will have the Z Axis move directly to the Reference Return Position. With Single Block Mode NOT on, the Z axis will appear to move directly to the Reference Return Position in one action.

Accordingly, the OP's use of G91 G28 Z0 Y0 is correct. Read a programming manual and learn something.

And it's not a case of looking down one's nose at you, my issue with you is that you make these totally incorrect comments in such and authoritative manner, that newbies following the Thread may think its gospel. Those that know a thing or two about programming, know that you're full of shit, it's the sincere beginners I worry about. I'm confident that SeymourDumore feels the same.
again muddy waters.
 
again muddy waters.
You're the one muddying the waters. You don't understand how G28 works, or to give you the benefit of the doubt, perhaps have only ever used it on a lathe.

Bill explained it comprehensively. A much simpler version is that in order for G28 to "just go home" you must use relative axis' addresses. That means UVWH etc. on a lathe, but since you don't have UVW on a mill, you must use G91.
 
again muddy waters.
When a person dies, they don't know it; it's the people that are left that know and feel the pain. It's the same when a person is stupid.

Your explanation of G28 is laughable at best and dangerous for others to follow.

Rather than being a smart arse, you should be embarrassed, posting up so much rubbish. You really don't know much about programming and with every Post you make, just makes you look so much more foolish.
 
Last edited:
When a person dies, they don't know it; it's the people that are left that know and feel the pain. It's the same when you're a stupid.

Your explanation of G28 is laughable at best and dangerous for others to follow.

Rather than being a smart arse, you should be embarrassed, posting up so much rubbish. You really don't know much about programming and with every Post you make, just makes you look so much more foolish
fuck it, I sometimes forget there is a very good reason I got out of CNC machining.

Picking up the scattered parts from ignorant programmers who refuse to listen to their own advice being a major one.

Later, enjoy misinforming the world.
 








 
Back
Top