Centroid CNC control sales, service, training and support
Unless otherwise noted, the methods and examples below are for current CNC11 and CNC12 software, on Mill controls.
Use the M115, M116, M125 and M126 codes to move a touch probe in custom probing cycles.
Whenever possible, specify a bounding position, even with M115 and M116 codes.
Note that the positions you specify with these codes are either absolute positions or incremental distance, depending on the current G90/G91 state.
G90 M105/X2.0/Y3.0 P15 F20will move towards an absolute position of X2 Y3, at 20 in/min, until the switch on INP15 closes.
G91 M105/X2.0/Y3.0 P15 F20will move in a direction of +2" along X, +3" along Y, at 20 in/min, until the switch on INP15 closes.
Also note that M115 and M116 are interchangeable (as are M125 and M126) when bounding positions are provided, because the direction to the bounding position determines the direction of movement.
Use M115 and M116 when you intend to locate a surface with the probe. The bounding position, if given, should be beyond the farthest likely position of the surface.
With M115 and M116, if the movement proceeds all the way to the bounding position without triggering the input (tripping the probe), then the cycle will be cancelled with an Error.
Use M125 or M126 for positioning moves during which no probe contact is expected.
Like M115 and M116, M125 and M126 will stop if the input is triggered (the probe is tripped); but M125 and M126 will then cancel the cycle with an error. This protects against probe breakage in case of an unexpected obstacle.
M115, M116, M125 and M126 are most commonly used with a touch probe, but they can be used with any switch input, or other PLC bit.
The P parameter used with these codes is either positive or negative, depending on whether you are watching for an open switch to close, or watching for a closed switch to open.
To complicate matters, the meaning of positive/negative P values was changed between CNC10 and CNC11. If you are updating CNC10 macros to run on a CNC11 or CNC12 system, you will need to account for this.
To further complicate matters, the M105 and M106 codes, which are similar to M115 and M116, may also interpret the sign of the P parameter differently.
The behavior for positive and negative P values with the different codes in different software versions is as follows:
open (0 -> 1)
|Not allowed||Move until|
open (1 -> 0)
close (0 -> 1)
open (0 -> 1)
close (1 -> 0)
close (0 -> 1)
open (1 -> 0)
The M105 and M106 codes are useful for axis homing, in situations where the normal M91 and M92 codes are not well suited.
For example, suppose we have a mill X axis which we want to quickly home near the center of travel, regardless of where the axis may be be sitting when the machine is powered up.
We install a dedicated home switch, which will be a normally-open proximity sensor that detects a steel rib that runs from near the mid-point, all the way to the plus limit of travel. We wire it to INP7 on the PLC board. Therefore, we expect INP7 to be open when we are in the minus half of travel, and closed when we are in the plus half.
Our homing macro can contain the following lines for the X axis:
M105/X P7 F100 ; move X- until INP7 is open M106/X P-7 F100 ; move X+ until INP7 is closed M91/X ; run the normal homing sequence
The first line will quickly move us to the minus side of the edge, if we were on the plus side to begin with. If we are already on the minus side (if the sensor is already open) then there will be no movement.
The second line will quickly move us (back) to the plus side of the edge, where the sensor is closed.
The third line will start the usual minus homing sequence: slow-jog speed minus until the switch opens; slow jog plus until the switch closes again; and slow movement further plus until the encoder index pulse comes around.
The complete sequence will end at the first encoder index pulse to the plus (sensor-closed) side of the edge.
This same general approach could be used with a dedicated home switch that is at one end of travel as well, as long as it trips prior to the limit switch.
This approach cannot be used with a home switch that is also a limit, because M105 and M106 will stop with an Error if a designated limit switch is tripped during the movement. Only M91 and M92 are allowed a one-time pass on tripping a limit switch (and then only for the limit switch they are looking for).
If you do home to a dedicated home switch, separate from the limit switch, it is highly desirable that the switch be set up with an extended ramp, so that the home switch remains tripped from its initial trip point, all the way out to the overtravel limit. Otherwise -- if it is physically possible to be inside the limit switches, on either side of the home switch, with the home switch not tripped -- then the homing macro cannot know whether to move plus or minus when seeking the home switch.
You cannot reliably use M115 and M116 in homing sequences, because those codes always attempt to apply software travel limits. They do not recognize that the software limits are not yet valid when machine home has not yet been set, and so will apply invalid restrictions to axis movement.
M105 and M106 do not apply software travel limits, even if the machine has been homed.
In many applications, it is desirable to save control state information either in Machine Parameter values or in static user variables (those CNC variables from #150 to #159).
For example, you might set Machine Parameter 987 (part of the 900-series block set aside for PLC applications) to the desired RPM of a subspindle; or you might use variable #159 to record which tool is currently in the spindle of a router with a rack-type tool changer.
Your custom macros would store new values in the parameter or variable as needed. For example, the code which starts the subspindle might say:
G10 P987 R3500 ; store desired RPM where the PLC can read it M33 ; send subspindle start request to PLCor the router's tool-changing macro might say:
#159 = #4120 ; record that the newly requested tool is in the spindle
There are two crucial components missing from both examples above.
First, the parameter or variable should not be updated during a graphic preview of the program, nor should the variable be updated when that line is read during a mid-program search or restart either.
Second, the control's G code parser must be prevented from processing the assignment while reading ahead, pre-processing codes and queuing them up for later execution by the control. If that is allowed, then the Machine Parameters table will get updated early, and the subspindle may start using an RPM value from much later in the program. Also, if the control reads ahead past an upcoming tool change on the router, but the program is then cancelled before that tool change actually takes place, then variable #159 will hold the wrong value: it will think that the later tool is already in the spindle, when in fact the earlier tool is still there. This generally results in a tool changer crash, as the control tries to put away the tool in the wrong (already-occupied) pocket.
The first issue is solved by skipping the assignment during graph and/or search processing. This can be done by checking system variables #4201 and #4202.
The second issue is solved by forcing a wait, so that machine execution is fully caught up to CNC processing (the queue is empty) before doing the update.
With those corrections, the code examples above would look like this:
IF [#50001] IF [#4201==0] G10 P987 R3500 ; store desired RPM where the PLC can read it M33 ; send subspindle start request to PLCand this:
IF [#50001] IF [#4201==0 && #4202==0] #159 = #4120 ; record that the newly requested tool is in the spindle
The code "IF [#50001]" is an idiom. Literally, it means "if INP1 on the PLC is closed, then do nothing". Because it is implicit that any CNC code that is conditioned upon a PLC input point is intended to test that input at the time the code actually runs, the parser concludes that it cannot test the input -- and cannot process any farther in the job -- until machine execution has caught up to that point. Any PLC bit could be used; INP1 is just the common convention.
The CNC system variable #4201 will have a value of 0 if the control is running the job on the machine, and a value of 1 if the control is generating a graphic preview.
System variable #4202 will have a value of 0 if the control is running the codes it is processing, and a value of 1 or greater if it is processing codes leading up to a mid-program start or resume (in these latter cases the codes are not sent to the machine, but instead are used to determine the CNC state at the point where job execution is to begin).
In our examples above, it makes sense to store any new values for Parameter 987 as we come across them in a search, so that when we get to the search point, the correct (latest) value is in place in the parameter table.
It does not make sense to update the tool number in variable #159 in any condition except an actual tool change.
M98 and G65 can both be used to call a CNC subprogram.
The most significant difference between the two is that G65 allows arguments (parameters, variables) to be passed in as part of the subprogram call.
The arguments provided with a G65 call are accessible within the subprogram as CNC variables #1 through #33. For example, any value given with the letter 'A' in a G65 call will appear in variable #1 within the subprogram.
Any CNC program or subprogram can use variables #1 through #33 for their own purposes, whether or not they were given values through a G65 call.
However, therein lies a key difference between M98 and G65: a G65 call advances the "stack", so that the #1 - #33 variables in the called subprogram are a fresh set, independent of the #1 - #33 variables in the calling program. An M98 call, in contrast, does not advance the stack. Variables #1 - #33 in the M98-called subprogram are the same ones used by the calling program.
Consider this example:
; define a macro subprogram, for later use O9001 #3 = #1 + #2 G0 Y#3 M99 ; main program starts here #1 = 10.0 #2 = 5.0 #3 = 1.234 G0 X#3 ; moves X to X1.234 G65 P9001 A3.2 B0.6 ; macro moves Y to Y3.8 G0 Z#3 ; moves Z to Z1.234Because the variables #1, #2 and #3 in the macro subprogram are independent of the ones in the main program, the main program's values are unchanged after the G65 call.
Compare that with the following, identical except that G65 has been replaced with M98:
; define a macro subprogram, for later use O9001 #3 = #1 + #2 G0 Y#3 M99 ; main program starts here #1 = 10.0 #2 = 5.0 #3 = 1.234 G0 X#3 ; moves X to X1.234 M98 P9001 A3.2 B0.6 ; A and B do nothing, macro moves Y to Y15.0 G0 Z#3 ; moves Z to Z15.0Using M98 instead, the A and B arguments are non-sensical and are ignored. The macro reads and writes the same local variables as the main program. It therefore calculates #3 = 10.0 + 5.0 = 15.0, and moves Y there. When we get back to the main program, local variable #3 has been changed, so the Z move is affected as well.
As a rule, if you want to use #1 - #33 as local or temporary variables, you should call your macro subprograms with G65.
If you have previously worked with older controls, you might have avoided using G65 when you did not need to pass arguments, because the number of nested G65 calls was limited. For example, on early Fanuc controls, you could nest subprogram (M98 and G65) calls up to 20 levels deep, but only four of those levels could use G65: there was only enough memory for four sets of local variables.
The Centroid control allows G65 calls up to 20 levels deep, each with its own set of local variables. Computer memory has come a long way.
It is often necessary to round fractional values to whole numbers (integers). For example, if you need to bring a rotary table, which may be at any angle, to the nearest whole turn (whole multiple of 360°), then you would want to round its position (converted to turns) to the nearest integer, then convert back to degrees and send the axis to that position.
Beginning with CNC12 version 4.14, you can use the functions FIX and FUP to round down or up to the next integer value. Note that for negative values, FIX still rounds down (thus away from zero) and FUP still rounds up (towards zero).
With CNC12 v4.14 or newer, then, you can round to the nearest integer by first adding 0.5, then rounding down:
#100 = FIX[#5044/360.0 + 0.5] * 360.0 G90 G0 A#100
With software prior to CNC12 v4.14, one way to force rounding to an integer is by applying the bit-wise OR operator. Since it only makes sense to perform bitwise operations on integers, CNC11 and CNC12 implicitly convert floating point values to integers before applying OR.
A bitwise OR operation with a second operand of zero (no bits set) returns the first operand unchanged, except for the implicit integer conversion.
When a fractional value is converted to integer using "OR 0", it is always truncated towards zero: positive values are rounded down, while negative values are rounded up. Therefore finding the nearest integer for both positive and negative values requires separate steps:
IF [#5044 >= 0.0] THEN #100 = [#5044/360.0 + 0.5] OR 0 IF [#5044 < 0.0] THEN #100 = [#5044/360.0 - 0.5] OR 0 #100 = #100 * 360.0 G90 G0 A#100
CNC Services Northwest Home
Copyright © 2019 Marc Leonard
Last updated 09-Dec-2019 MBL