I got an inquiry from a G-Wizard G-Code Editor user wanting to know if I could help diagnose a problem he was having. It seems he was trying to figure out why a program that had been output by his BobCAD CAM software was getting an error message out of Mach3. I his post wasn’t set up quite right for the Mach3 g-code dialect at first, but his description of the problem was intriguing and sounded deeper than that, so I volunteered to try to help. He had run the code through the Predator Editor/Simulator that comes with BobCAD, but it saw no errors. Mach3 on the other hand was seemingly never finishing the backplot and complaining cryptically that “Return called with no sub in effect”:
Mach3 executing g-code that infinite loops…
I hadn’t had the pleasure of seeing this behavior from Mach, so I thought I’d learn something knew by helping diagnose the problem. I also suspected I could make GWE better in the process, and no sooner did I load this machinist’s program than GWE promptly locked up and started acting hung. Excellent–that which does not kill us, makes us stronger!
It didn’t take long looking at the program in Notepad to see what was happening. Looks like BobCAD wants to create a subprogram for each machining operation and then call them one after the other at the top. It can make reading the code less than obvious, but it is not that uncommon a practice. Unfortunately, for some reason, the software forgot to put a program stop after it was done calling the subprograms for each operation. This caused execution to just fall through the bottom of the main program and start executing the very first subprogram all over again. The subprogram wasn’t expecting this, since it was designed to have been directly called with an M98 (if you’re not following these g-codes, don’t worry, I will explain them in our G-Code tutorial). When the subprogram gets done, it uses an M99 to return to the block right after the M98. Therein lies the problem. If it was never called by M98, there is no return location.
Most g-code dialects, when faces with an M99 and no M98 having called will simply start executing the very first line of g-code at the top of the program again. It’s not the worst choice they could’ve made, but I would’ve preferred an error (or alarm as the CNC world likes to call them) be issued. Instead, we get a situation where this particular program was going round and round doing everything over and over again.
Now that Mach3 message makes a bit more sense. We did indeed issue a “Return” (M99) without a “Sub” (M98) in effect, and so we are indeed “looping”. In fact, we’re engaged in what the software world calls an “Infinite Loop”. Absent the operator stopping the program, it will never stop of its own accord. The fix is easy–just add an M02 in the right place to stop before falling through to the subprogram.
Here is some sample code that demonstrates the problem:
An infinite loop in g-code…
This code just draws a little 1″ square, then it calls the subprogram at line N600. Execution would jump down to the sub and run until it hits the return “M99” at line N1100. Right below the sub call I have commented out the line that should’ve been there to stop further execution–see line N800. We needed an M02 right there to stop the program. Since there is nothing there but a comment, the g-code falls on through N800 and starts executing the subprogram below. DOH!
How about a little help finding these things, G-Wizard?
Well why not help, it isn’t that hard. Two capabilities were added to the GW CNC Editor–the ability to detect and automatically stop infinite loops, and a simulator enhancement that makes it easy to step through and see what all those M97/98/99, G65, and GOTO (if you run Fanuc Macros) commands are doing.
First, the infinite loop detection. Since we can’t get a loop unless the code, um loops, GWE keeps track of every block that causes execution to deviate from just going to the next block below. It keeps a count of how many times the deviation is made. In an infinite loop, one or more of those deviations (let’s just call them “Goto’s” because that’s what they are) will happen an infinite number of times. Now I don’t know about you, but I’m not getting any younger, and I don’t want to wait that long to see if I have an infinite loop. Therefore, GWE has a “goto limit” defined, and if any particular goto exceeds that limit, it issues a warning message and stops the program. Here is the message for the sample above:
The infinite loop warning tells exactly where the trouble is occuring and what the suspicious behavior is…
As you can see, the warning tells exactly where the trouble is (line 13), and what the suspicious behavior is–line 13 issued a goto 5 times, which is the default goto limit. Now does that guarantee an infinite loop? No, it doesn’t. You could easily have written code that calls the same routine more than 5 times intentionally. However, we have to pick a limit somewhere to work with, and that’s one that won’t let the loop get too carried away before we intervene and have a look at it. If we are running a program where we expect to run more than 5 times, we can use the Simulator Options menu to change the limit:
In addition to the popup, we add an appropriate Hint to help diagnose what’s going on and draw attention to the line in question. You can see line 13 is lit with the red “ERROR” indicator. Here is the Hint for that line:
Hint for a possible infinite loop…
BTW, can you see how that hint makes it a whole lot easier to understand what all is going on there than just starting at “N1100 M99”? Hints are designed to refresh your memory, teach you what the g-codes mean, and provide information that is otherwise hard to come by for deeper understanding. Isn’t that just what we need from a CNC Simulator?
Okay, that makes it pretty easy to tell what’s going on when there is an infinite loop. But, understanding what’s going on when a program is jumping and looping all over the place is still not easy. As I was stepping through this BobCAD-generated code, I realized we need a way to navigate that focuses on the goto’s. Perhaps you’ve seen or even tried out our fancy “5 Step” function. It does so much more than the normal “Step” or “Single Blocking” we see in most simulators. If you right click the “5 Step” toolbar button (or you can use the Simulator menu), you’ll get the Simulator Options–refer to the screenshot above. “5 Step” gives us the ability to:
– Step by any number of blocks, the default being “5”, hence the name.
– Step to the next rapid move. This is likely a retract that lets you get past a bunch of feedrate moves you’re not interested in.
– Step the the next Dwell (G04). This is a sneaky one. Dwells typically don’t affect a program much. So you can stick one in and use it as a bookmark. Use “5 Step” to jump to your next “bookmark”.
– Step to next toolchange (M06). Always a popular time saver.
– Step to the next subprogram op or GOTO. This is our new addition.
Stepping to a goto makes navigating through these subprograms fast and easy. If you’re going to be working on a g-code program with a lot of goto-activity, I’d recommend you get a flavor for the high level workings by using the “Step to the next GOTO” option first. That’ll let you breeze through, see who is calling who, and understand the high level structure of the g-code. You’ll also see the effects of each subprogram unfolding on the backplot. Take a note or two on what you want to revisit and dig deeper into. Drop some G04 Dwells, switch to stepping to dwells, and you’ll be able to focus on those areas.
If this all sounds interesting, useful, or even fun, please join our G-Wizard Editor Beta Test. The editor is free while it is in Beta and useful for all sorts of things.
Like what you read on CNCCookbook?
Join 100,000+ CNC'ers! Get our latest blog posts delivered straight to your email inbox once a week for free. Plus, we’ll give you access to some great CNC reference materials including:
- Our Big List of over 200 CNC Tips and Techniques
- Our Free GCode Programming Basics Course
- And more!
Just enter your name and email address below:
100% Privacy: We will never Spam you!