Macro-generated alarms? How do you control for bad macro inputs/conditions?

A place to discuss and ask questions about all things Machining for Mills, Lathes, Laser, and Routers

Moderator: cnckeith

Post Reply
Bham-Tech-RM
Posts: 13
Joined: Mon Jul 03, 2023 2:52 pm
Acorn CNC Controller: No
Allin1DC CNC Controller: Yes
Oak CNC controller: No
CNC Control System Serial Number: 0326130718
DC3IOB: No
CNC12: Yes
CNC11: No
CPU10 or CPU7: No

Macro-generated alarms? How do you control for bad macro inputs/conditions?

Post by Bham-Tech-RM »

Edit: Found a solution, see comment below. Not a great solution, but totally serviceable.

I'm hoping that Centroid has an equivalent of Haas' #3000 user-generated alarms.

I am programming macros to demonstrate various machining concepts and conditions for my students, and to add utility to Intercon. Because these macros will be used by novices, I definitely want to test the input arguments and generate an informative alarm or message if they're out of range or illogical.

If that's not a feature, what's the usual approach? Something like:

IF[whatever] THEN GOTO[200] ELSE GOTO[500]
N200; GOOD STUFF HAPPENS HERE

N500 M30; BAD INPUT - CHECK YOUR WORK

Any input is appreciated.
Last edited by Bham-Tech-RM on Mon Jul 03, 2023 8:10 pm, edited 5 times in total.
Bham-Tech-RM
Posts: 13
Joined: Mon Jul 03, 2023 2:52 pm
Acorn CNC Controller: No
Allin1DC CNC Controller: Yes
Oak CNC controller: No
CNC Control System Serial Number: 0326130718
DC3IOB: No
CNC12: Yes
CNC11: No
CPU10 or CPU7: No

Re: Macro-generated alarms? How do you control for bad macro inputs/conditions?

Post by Bham-Tech-RM »

So, that approach I suggested doesn't actually work - the M30 behaves the same as an M99 and kicks us back out to the main program, which is far from ideal...

Really hoping someone here has a better solution... for now I'm going to have to drop it into an infinite do-nothing loop with an M00 and a comment. Yikes.

Edit: That doesn't work either, because look-ahead gets there first and the infinite loop locks up the control before we've even executed the first block of the program. Is there's no way to control look-ahead on Centroid?
Bham-Tech-RM
Posts: 13
Joined: Mon Jul 03, 2023 2:52 pm
Acorn CNC Controller: No
Allin1DC CNC Controller: Yes
Oak CNC controller: No
CNC Control System Serial Number: 0326130718
DC3IOB: No
CNC12: Yes
CNC11: No
CPU10 or CPU7: No

Re: Macro-generated alarms? How do you control for bad macro inputs/conditions?

Post by Bham-Tech-RM »

Alright, I found a solution that is only kinda hacky.

M225 displays a message for an amount of time. The explanation in the manual is BAD, and it took me a while to figure it out.

#100=0
M225 #100 "VALUE OUT OF RANGE - CHECK 'K' VALUE"

Shows VALUE OUT OF RANGE - CHECK 'K' VALUE in a box on screen. Sweet.
#100 is how long to display the message in seconds, where 0 is forever.

So, my final implementation is:

IF[whatever] THEN GOTO[200] ELSE GOTO[500]
N200; GOOD STUFF HAPPENS HERE

N500;
#100=0
M225 #100 "VALUE OUT OF RANGE - CHECK 'K' VALUE"
M225 #100 "PRESS RESET TO ABORT PROGRAM"
GOTO[500];

And that's giving me a controlled way to stop a badly set up macro from crashing my student's machines. This infinite loop doesn't seem to crash CN12 either. Nice.
cncsnw
Posts: 3854
Joined: Wed Mar 24, 2010 5:48 pm

Re: Macro-generated alarms? How do you control for bad macro inputs/conditions?

Post by cncsnw »

Your solution is as good as any.

I usually shorten it to

Code: Select all

IF [something is not right] THEN ERROR Hey buddy something is not right!
"ERROR" is not actually a valid keyword in Centroid's CNC processor. It triggers a "missing parameter" parse error that ends the program, because the letter 'E' is not followed by a numeric value. But the key thing is that the program ends with an error, and the offending line -- including the text at the end -- is highlighted on the CNC12 screen.

CNC12 does not attempt to parse the codes to the right of an IF [] block if the condition is false, so the invalid "ERROR" text is overlooked if the error condition is not met.

For what it's worth, there is no need for a GOTO that goes to the immediately following line; and the goto target does not need to be in brackets unless it is a computed expression. Also, don't forget to skip around the error report when your "good stuff' program flow reaches that point.

So, instead of:

Code: Select all

IF[whatever] THEN GOTO[200] ELSE GOTO[500]
N200; GOOD STUFF HAPPENS HERE

N500;
#100=0
M225 #100 "VALUE OUT OF RANGE - CHECK 'K' VALUE"
M225 #100 "PRESS RESET TO ABORT PROGRAM"
GOTO[500];
You could invert your [whatever] logic condition, and write it as:

Code: Select all

IF [not-whatever] THEN GOTO 500
  ; GOOD STUFF HAPPENS HERE
  GOTO 600
N500
  #100=0
  M225 #100 "VALUE OUT OF RANGE - CHECK 'K' VALUE"
  M225 #100 "PRESS RESET TO ABORT PROGRAM"
  GOTO 500
N600
or, cleaner:

Code: Select all

IF [original-whatever] THEN GOTO 600
  N500
  #100=0
  M225 #100 "VALUE OUT OF RANGE - CHECK 'K' VALUE"
  M225 #100 "PRESS RESET TO ABORT PROGRAM"
  GOTO 500
N600
; GOOD STUFF HAPPENS HERE
Bham-Tech-RM
Posts: 13
Joined: Mon Jul 03, 2023 2:52 pm
Acorn CNC Controller: No
Allin1DC CNC Controller: Yes
Oak CNC controller: No
CNC Control System Serial Number: 0326130718
DC3IOB: No
CNC12: Yes
CNC11: No
CPU10 or CPU7: No

Re: Macro-generated alarms? How do you control for bad macro inputs/conditions?

Post by Bham-Tech-RM »

Thanks for the feedback.

I like your

Code: Select all

IF [something is not right] THEN ERROR Hey buddy something is not right!
but won't that tend to generate the error long before the program pointer actually gets to that block, due to lookahead? Fine under normal circumstances, but for teaching debugging, I'd like to see the program single block right up to the error.
cncsnw wrote: Mon Jul 03, 2023 6:32 pm For what it's worth, there is no need for a GOTO that goes to the immediately following line; and the goto target does not need to be in brackets unless it is a computed expression. Also, don't forget to skip around the error report when your "good stuff' program flow reaches that point.
I'll drop the brackets on the GOTOs. Not sure where I got that from.

Here's what my code actually looks like. You're missing the set-up, some variable pre-setting, etc. but the logical structure should be clear.

Code: Select all

;POLYGON CONTROL TYPE
IF [#I EQ 0] THEN GOTO100; TYPE-0 MEASURE OVER FLATS & ANGLE
IF [#I EQ 1] THEN GOTO110; TYPE-1 SIDE LENGTH & ANGLE
IF [#I EQ 2] THEN GOTO120; TYPE-2 CIRCUMRADIUS & ANGLE
IF [#I EQ 3] THEN GOTO130; TYPE-3 VERTEX COORDINATE
GOTO500; BAD INPUT

;CALC MISSING VALUES FROM GIVEN
N100; TYPE-0 MEASURE OVER FLATS & ANGLE
#101=[#J*4*TAN[180/#A]]; SIDE LENGTH
#102=[[SQRT[[[#J]^2]+[[#101]^2]]]/2]; CIRCUMRADIUS
#103=[#K]; START ANGLE
GOTO200; START POLYGON ROUTINE

N110; TYPE-1 SIDE LENGTH & ANGLE
N120; TYPE-2 CIRCUMRADIUS & ANGLE
N130; TYPE-3 VERTEX COORDINATE

N200; POLYGON ROUTINE
X[#102] Y0.; START VERTEX *******TESTING ONLY**********
#121=[0]; CURRENT ANGLE, RELATIVE TO START ANGLE
N210; CUT LOOP
#121=[#121+#104]; INCREMENT CURRENT ANGLE BY CENTER ANGLE
G01 X[#102*COS[#121]] Y[#102*SIN[#121]]; CUT TO NEXT VERTEX COORDINATE
IF [#121 LT [360]] GOTO210; IF CURRENT LT FULL, NOT COMPLETE

; POLYGON COMPLETE
X[#110] Y[#111]; RETURN TO APPROACH POINT
M99; RETURN TO MAIN

;MESSAGES
N500
#100=0
M225 #100 "POLYGON CONTROL-TYPE DOES NOT EXIST, CHECK 'I'"
M225 #100 "PRESS RESET TO ABORT PROGRAM"
GOTO500;
I could flip the logic, like you're suggesting, and have the error pop

Code: Select all

IF [! [[0 LE #I] && [#I LE 3]]] GOTO500; ERROR MESSAGE
(I think that would be the inequality? Haven't used the logical operands much, syntax might be off.)

but that seemed more complicated to debug than the IF, IF, IF, IF, ELSE that I was building.

I think your cleanest example might actually be closest to what I actually did?
cncsnw
Posts: 3854
Joined: Wed Mar 24, 2010 5:48 pm

Re: Macro-generated alarms? How do you control for bad macro inputs/conditions?

Post by cncsnw »

but won't that tend to generate the error long before the program pointer actually gets to that block, due to lookahead? Fine under normal circumstances, but for teaching debugging, I'd like to see the program single block right up to the error.
If you start the job in continuous mode (single block off), then yes, the error will be reported as soon as the parser reads that line. It will still highlight the error line, even though execution has not gotten anywhere close to it yet.

If you run in single-block mode (which admittedly I do not recommend), then the parser won't read that line until it has finished the preceding lines.

If the IF-condition depends on real-time values (e.g. the state of PLC inputs, via system variables #50001+) then the parser will automatically wait until execution catches up before evaluating the condition. However, I understand in your example you are looking to validate G code macro arguments when the macro is called. That would indeed be subject to look-ahead.

You could make use of that to force parsing to wait until execution has caught up before you try to validate your macro parameters. You can do that with the common idiom of:

Code: Select all

IF [#50001]
What that does, literally, is to do nothing if INP1 is closed, and do nothing if INP1 is open. But as a side effect, it forces the parser to wait until all preceding lines have been executed before it checks on the state of INP1.

One thing to consider, of course, is the behavior in the F8/Graph preview. I am pretty sure that F8/Graph just ignores M225, so it would just appear to hang up without a message and without doing anything, because it is stuck in the "GOTO 500" loop. The "ERROR" model should trigger the error in F8/Graph, and drop out to the main screen with the offending line highlighted.
cncsnw
Posts: 3854
Joined: Wed Mar 24, 2010 5:48 pm

Re: Macro-generated alarms? How do you control for bad macro inputs/conditions?

Post by cncsnw »

Yes, your series of IF/GOTO statements for each valid input, followed by an error GOTO (the "ELSE" is implied, because if there were valid input then processing would not have gotten there) is a pretty clean implementation.

Yes, if appropriate, you can test a range of values with less-than and greater-than. For example, if the valid range for I is 0-3, then you could use:

Code: Select all

IF [#I LT 0 || #I GT 3] THEN Error invalid 'I' value!
However, that would then be followed by the four IF statements to test the valid conditions anyway, so it is not really shortening the program much. Also, it leaves you open to errors if the caller sends, for example, I2.5.

You could avoid fractional values by rounding the given parameter to the nearest integer:

Code: Select all

#[I] = FIX[#I+0.5]
... but in this context, testing each value individually and throwing an error if there is no match makes more sense.
Bham-Tech-RM
Posts: 13
Joined: Mon Jul 03, 2023 2:52 pm
Acorn CNC Controller: No
Allin1DC CNC Controller: Yes
Oak CNC controller: No
CNC Control System Serial Number: 0326130718
DC3IOB: No
CNC12: Yes
CNC11: No
CPU10 or CPU7: No

Re: Macro-generated alarms? How do you control for bad macro inputs/conditions?

Post by Bham-Tech-RM »

cncsnw wrote: Mon Jul 03, 2023 9:45 pm You can do that with the common idiom of:

Code: Select all

IF [#50001]
What that does, literally, is to do nothing if INP1 is closed, and do nothing if INP1 is open. But as a side effect, it forces the parser to wait until all preceding lines have been executed before it checks on the state of INP1.
Hah! I'll remember that one. So there's really no equivalent of Haas G103? That makes macro programming way more challenging... IME without disabling look-ahead, many kinds of program events are effectively skipped.

cncsnw wrote: Mon Jul 03, 2023 9:45 pm One thing to consider, of course, is the behavior in the F8/Graph preview. I am pretty sure that F8/Graph just ignores M225, so it would just appear to hang up without a message and without doing anything, because it is stuck in the "GOTO 500" loop. The "ERROR" model should trigger the error in F8/Graph, and drop out to the main screen with the offending line highlighted.
That would be a problem - which I will test when I get back on campus tomorrow, after the holiday. Graphing is one of our key crash-mitigation steps, and having graphing freeze when there is an error is less than ideal.

If M225 doesn't work well with Graphing, I will go back to an un-executable message block at the end of the valid test conditions, as you recommend.

Code: Select all

;POLYGON CONTROL TYPE
IF [#I EQ 0] THEN GOTO100; TYPE-0 MEASURE OVER FLATS -OR- INSCRIBED DIAMETER & ANGLE
IF [#I EQ 1] THEN GOTO110; TYPE-1 SIDE LENGTH & ANGLE
IF [#I EQ 2] THEN GOTO120; TYPE-2 CIRCUMRADIUS & ANGLE
IF [#I EQ 3] THEN GOTO130; TYPE-3 VERTEX COORDINATE
ERROR: GIVEN CONTROL TYPE 'I' DOES NOT EXIST. 
At least in this example, any valid input will steer the program pointer away from the un-executable block. If the input is not valid, the preprocessor will highlight it right away, whether in normal continuous execution, or in graphing. As a method, it should be pretty generalizable too.

It just feels like bad practice to stop execution by using "bad code" to generate an alarm - I would prefer to have valid, executable code handle the exception and bring the program to a controlled end-state. Sometimes we've gotta use what we have though...

Thanks for all of your help - I've learned from this discussion. I'll be adding this forum to my home pages :D
Post Reply