I decribed M-function in System Manager, but how can I proggram logic for it in ST? I know how to build\clear interpolation group, link axis, load nc program. For example, my nc file should be like this:
do smth
Turn on cooling (via M100)
do smth else
Turn off cooling (via M100 or M101)
etc.
I found in Plc Control TcNci.lib this function blocks, but don't understand how and when I should use it: ItpConfirmHsk, ItpGetHskMFunc, (it returns int num of mcommand in line as I unterstood) ItpConfirmHsk.
Pre defined m's like M30 and M02 is working fine, but I want to create own m-functions.
I tried FirstNciSample at Beckhoff docs, and it works fine for M30 and M02. Every time I tried to modify code (nState 60) it ended with errors. Should I re write case sequence if my m-functions will be not always at the end of file? How I should re write '60:' state for handling m-functions?
nState: UDINT;
fbBuildGrp: CfgBuildExt3DGroup;
fbLoadProg: ItpLoadProgEx;
fbStart: ItpStartStopEx;
fbConfirm: ItpConfirmHsk;
fbClearGrp: CfgReconfigGroup;
--
CASE nState OF
0: pre define states
10: build interpolation group
20: load part program
30: wait until interpreter is READY
40: start part program
50: check if interpreter is not READY
60:
(* confirm m-func - e.g. m30 *)
(* add code to handle m-functions *)
(* in the moment all m-functions are directly confirmed *)
IF ( ItpIsHskMFunc(in_stItpToPlc) ) THEN
bConfirm := TRUE;
ELSE
bConfirm := FALSE;
END_IF
fbConfirm(
bExecute:= bConfirm,
sNciToPlc:= in_stItpToPlc,
sPlcToNci:= out_stPlcToItp );
IF NOT fbConfirm.bBusy THEN
IF fbConfirm.bErr THEN
(* an error occured *)
(* this usually can just occur, if a confirmation is triggered without a request *)
bErr := TRUE;
nErrId := fbStart.nErrId;
nLastState := nState;
nState := 9999;
END_IF
END_IF
nItpState := ItpGetStateInterpreter( in_stItpToPlc );
IF nItpState = NCI_INTERPRETER_READY THEN
(* part program is finished without an error *)
fbConfirm( bExecute:= FALSE, sNciToPlc:= in_stItpToPlc, sPlcToNci:= out_stPlcToItp );
nState := 70;
ELSIF nItpState = NCI_INTERPRETER_ABORTED THEN
(* a runtime error occured - e.g. a lag distance error occured *)
bErr := TRUE;
nErrId := ItpGetError(in_stItpToPlc);
nLastState := nState;
nState := 9999;
END_IF
70: clear intrepolation group and switch nState to 0
9999: stop all and display an error
END_CASE
I have worked on NC I with Twincat3 once and I have created my own M-functions as well.
First, you have to define your M-function number and name to:
Channel => Interpreter => M functions
For example, I have set
M12 as LaserOn
M13 as LaserOff
. When I call M13(LaserOff) on NC File, I want to reset M12(LaserOn). So, you can see the Reset (3,6...) section on the table. I have put ,,12'' (which is number of M function) to LaserOff's Reset section.
In code side I have created property like ,,IsLaserOn, IsLaserOff, IsGasOn, IsGasOff''..
IsLaserOn := ItpIsFastMFunc ( nFastMFuncNo:= 12 , sNciToPlc:= sNciToPlc );
IsLaserOff := ItpIsFastMFunc ( nFastMFuncNo:= 13 , sNciToPlc:= sNciToPlc );
ItpIsFastMFunc is a function of tc2_nci library
In ST code side I use the M-functions like:
IF IsLaserOn THEN
// your code to set laser on...
END_IF
IF IsLaserOff THEN
// your code to set laser off...
END_IF
Note: You do not have to set set LaserOn to false when LaserOff is set on NC file. Because We have already reset the M12 function if M13 function is set on NC file.
This is the basic code to create and our own M-function and how to run in ST code. You can adjust and implement to your code.
Here is an example NC file code for test:
Good luck.