7 附錄 1. M4PLC32.CPP


註. 於本附錄中提及之各個 .H 檔案,如需參考請洽詢本公司業務人員。


#include "plc.h"

#include "smachine.h"


//M470 PLC test Sigma 2011.06.17

//1. M35 開啟量刀吹氣

//2. M36 關閉量刀吹氣

//3. 換刀完成時會去呼叫量刀副程式

//量刀副程式:

//

//   G49                               ;取消刀長補正

//   M13                               ;打開量刀器護蓋

//   G53 Z#130                 ;移動 Z 軸至量刀高度,設定值為長參數 48

//   G53 X#128 Y#129   ;移動 X、Y 軸至量刀高度,設定值為長參數 46、47

//   M35                               ;吹氣

//   G04 X2                        ;暫停兩秒

//   M36                              ;關閉吹氣

//   G43 H#131                ;所要補正刀號等於主軸上刀號

//   G37 Z#132                ;執行量刀,巨集變數 132 為基準高

//   M14                              ;關閉量刀器護蓋

//   M12                              ;更新刀號顯示  

//   M99                              ;副程式結束

//

//4. 巨集變數第 133 為自動量刀時容許誤差,如果超過則會發警報

//5. 增加 M33 設定刀具刀長至 plc 長數據 ; M34 量刀後比對刀具長度是否正確 ; 正常開機後會進入判斷刀具是否斷刀模式


static char *msgVersion = "M470 PLC V1.00 110610-1";


static InPortGdi oldGdi0, oldGdi1, oldGdi2, oldGdi3,

      riseGdi0, riseGdi1, riseGdi2, riseGdi3,fallGdi0;

static int sCodeSave, tCodeStage;

static unsigned short *para;

static long *longPara;

static long Autopower_time, T_delay, Tool_delay;

static long lubOn ,lubOff ,tLubeStateTimer ,tLubefilterTimer;

static long Timer_1, Timer_2, Timer_3;

static long STimer_1, STimer_2, STimer_3;

static unsigned int A1bit0, A1bit1, A1bit2, A1bit3, A1bit4, A1bit5, A1bit6;

static unsigned int A2bit0, A2bit1, A2bit2, A2bit3, A2bit4, A2bit5, A2bit6;

static unsigned int A3bit0, A3bit1, A3bit2, A3bit3, A3bit4, A3bit5, A3bit6;

static unsigned int temp_1, temp_2, temp_3, temp_4;

static unsigned int Stemp_1, Stemp_2, Stemp_3, Stemp_4;

static int fLubePressureTrag ,fLubePressureSenser1 ,fLubePressureSenser2;

static int SpindleOverride ,TC_Step ,Alarm_flag;

static int T_DELAY ,lubFlag ,Autopower_flag;

static int set_tool_length_flag =1;        //量刀時將 z 軸座標存入 plc 長數據,開機初始設定不做斷刀檢測

static HVector lastMchPos;

static double *macroPara;                                                       //自動量刀

static double x_position,y_position,z_position;   //自動量刀

static char *M37="PLC-M37.CNC";                                       //自動量刀

static int tool_is_wrong_flag ,C_unlock_flag;    //自動量刀

static long redoff ,redon;                                                //RED on/off control

static int redflag;                                                                //RED on/off control

static long yellowoff ,yellowon;                                //YELLOW on/off control

static int yellowflag ,warnflag;                                 //YELLOW on/off control

int spindleLengthCompTimer;                                            //主軸溫度補償計時器


double *eventRecord, *ePtr;

long *eIndex, *eTotal;

static char eStr[400];

static int curPlcAlarm;

static int oldEvent=-1;

static int eventLogged=0;

static long eventSaveTimer=0;

PlcTime *plcTime;                            //to get date/time


StageMachine sZBreak;

StageMachine sRunLight, sAlmLight, sHoldLight;

StageMachine sCheckInport, sWatchInport;

StageMachine sMoveX, sMoveY, sMoveZ;

StageMachine sSpindleCW,sSpindleCCW,sSpindleStop;

StageMachine ATCTC;

StageMachine smLubePressureSenser;

StageMachine STool_display;


static int  SL_flag;

enum        {SL1,SL2,SL3,SL4,SL5,SL6,SL7,SL8,SL9};


//-------------------------------------------------------------------------------------

//第二自由定義面板

//-------------------------------------------------------------------------------------

static int  Timer_KeyScan,Timer_LedScan,ledscan_Flag,keyscan_flag;

static short int  key1 ,key2 ,key3 ,key4 ,key5 ,key6 ,key7 ,key8 ,

                 key9 ,key10,key11,key12,key13,key14,key15,key16,

                 key17,key18,key19,key20,key21,key22,key23,key24,

                 key25,key26,key27,key28,key29,key30,key31,key32,

                 key33,key34,key35,key36,key37,key38;                                

static short int  led1 ,led2 ,led3 ,led4 ,led5 ,led6 ,led7 ,led8 ,

                 led9 ,led10,led11,led12,led13,led14,led15,led16,

                 led17,led18,led19,led20,led21,led22,led23,led24,

                 led25,led26,led27,led28,led29,led30,led31,led32,

                 led33,led34,led35,led36,led37,led38;                                        

static short int  old_key1 ,old_key2 ,old_key3 ,old_key4 ,old_key5 ,old_key6 ,old_key7 ,

                 old_key8 ,old_key9 ,old_key10,old_key11,old_key12,old_key13,old_key14,

                 old_key15,old_key16,old_key17,old_key18,old_key19,old_key20,old_key21,

                 old_key22,old_key23,old_key24,old_key25,old_key26,old_key27,old_key28,

                 old_key29,old_key30,old_key31,old_key32,old_key33,old_key34,old_key35,

                 old_key36,old_key37,old_key38;

static short int  rise_key1 ,rise_key2,rise_key3 ,rise_key4 ,rise_key5 ,rise_key6 ,

                 rise_key7 ,rise_key8,rise_key9 ,rise_key10,rise_key11,rise_key12,

                 rise_key13,rise_key14,rise_key15,rise_key16,rise_key17,rise_key18,

                 rise_key19,rise_key20,rise_key21,rise_key22,rise_key23,rise_key24,

                 rise_key25,rise_key26,rise_key27,rise_key28,rise_key29,rise_key30,

                 rise_key31,rise_key32,rise_key33,rise_key34,rise_key35,rise_key36,

                 rise_key37,rise_key38;

enum        {TEMP1,TEMP2,TEMP3,TEMP4,TEMP5,TEMP6,TEMP7,TEMP8,TEMP9,TEMP10,TEMP11,TEMP12}; //scan led StageMachine

enum        {STEP1,STEP2,STEP3,STEP4,STEP5,STEP6,STEP7,STEP8,STEP9,STEP10}; ////scan key StageMachine

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#define PLC_MH_ATTR_0  0x1

#define USE_CONTI_PLC_MOTION   0x01

#define USE_B_N_F_PLC_MOTION   0x02

#define tool_offset 80

#define T_SPINDLE_START_DELAY 64


//-----------------------------------------------------------------------------

//will use the 899~999 to

// store up to 100 alarm messages.

//-----------------------------------------------------------------------------

#define EVENT_LOG_OFFSET          899

#define EVENT_LOG_MAX             100

#define EVENT_DISPLAY_LINE_LEN    28

#define EVENT_DISPLAY_LINE_TOTAL  12

#define EVENT_LOG_SAVE_DELAY      512        //delay time for event save, 4 seconds


//-------------------------------------------------------------------------------

//ASVU input/output

//-------------------------------------------------------------------------------

#define iSpindleAlm       iESU_EC_SP_13    //spindle driver alarm

#define iSpindleArrive    iESU_EC_SP_14    //spindle speed arrived

#define iSpindle0Rpm      iESU_EC_SP_15    //spindle zero speed


#define oSpindleCw        oESU_EC_SP_34

#define oSpindleCcw       oESU_EC_SP_56


//----------------------------------------------------------------------------------

//define panel 2 key switch / panel 2 LED

//----------------------------------------------------------------------------------

#define piCycleStart         rise_key1  //cycle start

#define piFeedHold           rise_key2  //feed hold

#define piJog                rise_key3  //manual Jog

#define pix1                 rise_key4  //*1

#define piSp1                key5       //spare 1

#define piAp                 key6       //A+

#define piYp                 key7       //Y+

#define piZp                 key8       //Z+


#define piSpindleCW          rise_key9  //turn on spindle clockwise

#define piSpindleStop        rise_key10 //turn spindle off

#define piSpindleCCW         rise_key11 //turn on spindle counterclockwise

#define piWheel              rise_key12  //手輪

#define pix10                rise_key13 //*10

#define piSp2                key14      //spare 2

#define piXp                 key15      //manual X axes

#define piSp3                key16      //spare 3


#define piXn                 key17      //X-

#define piSp4                key18      //spare 4

#define piSp5                key19      //spare 5

#define piSp6                key20      //spare 6

#define piInc                rise_key21 //單動

#define pix100               rise_key22 //*100

#define piSp7                key23      //spare 7

#define piZn                 key24      //Z-


#define piYn                 key25      //Y-

#define piAn                 key26      //A-

#define piCoolant            rise_key27 //coolant ON/OFF from panel

#define piAirBlow            rise_key28 //air blow ON/OFF from panel

#define piWorkingLight       rise_key29 //working light ON/OFF from panel

#define piHome               rise_key30 //歸零

#define pix1000              rise_key31 //*1000

#define piSp8                key32      //spare 8


#define piMENU               rise_key33 //spare3 from panel

#define piManualToolRelease  key34      //手動鬆刀

#define piOPS                rise_key35 //spare4 from panel

#define piTeachIn            rise_key36 //teach from panel

#define piAutoPowerOff       rise_key37 //AutoPowerOff from panel

#define piAutoHome           rise_key38 //do auto homing in sequence


#define poCS_L               led1       //cycle start LED on panel  

#define poFH_L               led2       //feed hold LED on panel

#define poJog_L              led3       //寸動 LED on panel

#define pox1_L               led4       //*1 LED on panel

#define poSp1_L              led5       //Spare 1 on panel

#define poAp_L               led6       //A+ LED

#define poYp_L               led7       //Y+ LED

#define poZp_L               led8       //Z+ LED on panel


#define poSpindleCW_L        led9       //spindle CW LED on panel

#define poSpindleStop_L      led10      //spindle stop LED on panel

#define poSpindleCCW_L       led11      //spindle CCW LED on panel

#define poWheel_L            led12      //手輪 LED on panel

#define pox10_L              led13      //*10 LED on panel

#define poSp2_L              led14      //Spare 2 on panel

#define poXp_L               led15      //X+ LED on panel

#define poSp3_L              led16      //Spare 3 on panel


#define poXn_L               led17      //X- LED on panel

#define poSp4_L              led18      //Spare 4 on panel

#define poSp5_L              led19      //Spare 5 on panel

#define poSp6_L              led20      //Spare 6 on panel

#define poInc_L              led21      //單動 LED on panel

#define pox100_L             led22      //*100 LED on panel

#define poSp7_L              led23      //Spare 7 on panel

#define poZn_L               led24      //Z- LED on panel


#define poYn_L               led25      //Y- LED

#define poAn_L               led26      //A- LED

#define poCoolant_L          led27      //coolant LED on panel

#define poAirBlow_L          led28      //air blow LED on panel

#define poWorking_L          led29      //working LED on panel

#define poHome_L             led30      //歸零 LED on panel

#define pox1000_L            led31      //*1000 LED on panel

#define poSp8_L              led32      //Spare 8 on panel


#define poMENU_L             led33      //spare 3 LED on panel

#define poManualToolRelease  led34      //手動鬆刀 LED on panel

#define poOPS_L              led35      //spare 4 LED on panel

#define poTeachIn_L          led36      //teach LED on panel

#define poAutoPowerOff_L     led37      //tail backward LED on panel

#define poAutoHome_L         led28      //auto homing LED on panel

//---------------------------------------------------------------------------

//ENU0 Input/output

//---------------------------------------------------------------------------

//定義第二自由定義面板掃描線 8*5 matrix panel

#define I1             (plc.gdi[0].bit.bit00) //input scan 1

#define I2             (plc.gdi[0].bit.bit01) //input scan 2

#define I3             (plc.gdi[0].bit.bit02) //input scan 3

#define I4             (plc.gdi[0].bit.bit03) //input scan 4

#define I5             (plc.gdi[0].bit.bit04) //input scan 5

#define I6             (plc.gdi[0].bit.bit05) //input scan 6

#define I7             (plc.gdi[0].bit.bit06) //input scan 7

#define I8             (plc.gdi[0].bit.bit07) //input scan 8

#define iROSW1         (plc.gdi[0].bit.bit08) //G00,JOG Rotary Switch input1

#define iROSW2         (plc.gdi[0].bit.bit09) //G00,JOG Rotary Switch input2

#define iROSW3         (plc.gdi[0].bit.bit0a) //G00,JOG Rotary Switch input3

#define iROSW4         (plc.gdi[0].bit.bit0b) //G00,JOG Rotary Switch input4

#define iFROSW1        (plc.gdi[0].bit.bit0c) //feed speed Rotary Switch input1

#define iFROSW2        (plc.gdi[0].bit.bit0d) //feed speed Rotary Switch input2

#define iFROSW3        (plc.gdi[0].bit.bit0e) //feed speed Rotary Switch input3

#define iFROSW4        (plc.gdi[0].bit.bit0f) //feed speed Rotary Switch input4

//第二自由定義面板掃描線

#define DATA1          (plc.gdo[0].bit.bit00) //DATA1 output scan

#define DATA2          (plc.gdo[0].bit.bit01) //DATA2 output scan

#define DATA3          (plc.gdo[0].bit.bit02) //DATA3 output scan

#define DATA4          (plc.gdo[0].bit.bit03) //DATA4 output scan

#define DATA5          (plc.gdo[0].bit.bit04) //DATA5 output scan

#define DATA6          (plc.gdo[0].bit.bit05) //DATA6 output scan

#define DATA7          (plc.gdo[0].bit.bit06) //DATA7 output scan

#define DATA8          (plc.gdo[0].bit.bit07) //DATA8 output scan

#define Y1             (plc.gdo[0].bit.bit08) //output scan 1

#define Y2             (plc.gdo[0].bit.bit09) //output scan 2

#define Y3             (plc.gdo[0].bit.bit0a) //output scan 3

#define Y4             (plc.gdo[0].bit.bit0b) //output scan 4

#define Y5             (plc.gdo[0].bit.bit0c) //output scan 5


//--------------------------------------------------------------------------------

//EQU1 input/output

//--------------------------------------------------------------------------------

#define iEmergencyAlarm  (plc.gdi[1].bit.bit00)  //gdi 1 Emergency Alarm

#define iOTR             (plc.gdi[1].bit.bit01)  //gdi 2 Over travel release

#define iAirAlarm        (plc.gdi[1].bit.bit02)  //gdi 3 Air pressure alarm

#define iLubeAlarm       (plc.gdi[1].bit.bit03)  //gdi 4 Lube empty alarm

#define iG37Probe        (plc.gdi[1].bit.bit04)  //gdi 5 probe for G37 tool length

#define iLube_pressure   (plc.gdi[1].bit.bit05)  //gdi 6 Lube pressure

#define iCoolantAlarm    (plc.gdi[1].bit.bit06)  //gdi 7 Coolant Alarm

#define iMagazine_D_O    (plc.gdi[1].bit.bit07)  //gdi 8 Magazine door open senser

#define iMagazine_D_C    (plc.gdi[1].bit.bit08)  //gdi 9 Magazine door close senser

#define iProbe_D_O       (plc.gdi[1].bit.bit09)  //gdi 10 Probe door open senser

#define iProbe_D_C       (plc.gdi[1].bit.bit0a)  //gdi 11 Probe door close senser

#define iSpare1          (plc.gdi[1].bit.bit0b)  //gdi 12 input Spare 1

#define iSpare2          (plc.gdi[1].bit.bit0c)  //gdi 13 input Spare 2

#define iSpare3          (plc.gdi[1].bit.bit0d)  //gdi 14 input Spare 3

#define iSpare4          (plc.gdi[1].bit.bit0e)  //gdi 15 input Spare 4

#define iSpare5          (plc.gdi[1].bit.bit0f)  //gdi 16 input Spare 5


#define oRunLight        (plc.gdo[1].bit.bit00)  //gdo 1 cycle start light(GREEN)

#define oFeedHoldLight   (plc.gdo[1].bit.bit01)  //gdo 2 feed hold light from panel(YELLOW)

#define oAlarmLight      (plc.gdo[1].bit.bit02)  //gdo 3 alarm light(RED)

#define oZBreakRelease   (plc.gdo[1].bit.bit03)  //gdo 4 Z axis brake release

#define oNcReady         (plc.gdo[1].bit.bit04)  //gdo 5 NC ready

#define oLubeOn          (plc.gdo[1].bit.bit05)  //gdo 6 Lube on/off

#define oCoolantOn       (plc.gdo[1].bit.bit06)  //gdo 7 Coolant on/off

#define oLIGHTOn         (plc.gdo[1].bit.bit07)  //gdo 8 Working light on/off

#define oAIROn           (plc.gdo[1].bit.bit08)  //gdo 9 Air on/off

#define oAUTOPOWER_ON    (plc.gdo[1].bit.bit09)  //gdo 10 Auto power on/off

#define ospindleAir_VAR  (plc.gdo[1].bit.bit0a)  //gdo 11 Spindle inside air on/off

#define oG37Blow         (plc.gdo[1].bit.bit0b)  //gdo 12 G37 blow

#define oToolRelease     (plc.gdo[1].bit.bit0c)  //gdo 13 tool release

#define oMagazineDoor    (plc.gdo[1].bit.bit0d)  //gdo 14 Magazine Door open/close

#define oProbeDoor       (plc.gdo[1].bit.bit0e)  //gdo 15 Probe Door open/close

#define oM29_mode        (plc.gdo[1].bit.bit0f)  //gdo 16 M29 mode on/off


//---------------------------------------------------------------------------------------------

//EQU2 input/output

//---------------------------------------------------------------------------------------------

#define iT1         (plc.gdi[2].bit.bit00) //gdi 17 空刀檢知 1

#define iT2         (plc.gdi[2].bit.bit01) //gdi 18 空刀檢知 2

#define iT3         (plc.gdi[2].bit.bit02) //gdi 19 空刀檢知 3

#define iT4         (plc.gdi[2].bit.bit03) //gdi 20 空刀檢知 4

#define iT5         (plc.gdi[2].bit.bit04) //gdi 21 空刀檢知 5

#define iT6         (plc.gdi[2].bit.bit05) //gdi 22 空刀檢知 6

#define iT7         (plc.gdi[2].bit.bit06) //gdi 23 空刀檢知 7

#define iT8         (plc.gdi[2].bit.bit07) //gdi 24 空刀檢知 8

#define iT9         (plc.gdi[2].bit.bit08) //gdi 25 空刀檢知 9

#define iT10        (plc.gdi[2].bit.bit09) //gdi 26 空刀檢知 10

#define iT11        (plc.gdi[2].bit.bit0a) //gdi 27 空刀檢知 11

#define iT12        (plc.gdi[2].bit.bit0b) //gdi 28 空刀檢知 12

#define iT13        (plc.gdi[2].bit.bit0c) //gdi 29 空刀檢知 13

#define iT14        (plc.gdi[2].bit.bit0d) //gdi 30 空刀檢知 14

#define iT15        (plc.gdi[2].bit.bit0e) //gdi 31 空刀檢知 15

#define iT16        (plc.gdi[2].bit.bit0f) //gdi 32 空刀檢知 16


#define oA0         (plc.gdo[2].bit.bit00) //gdo 17 傳輸資料 1

#define oA1         (plc.gdo[2].bit.bit01) //gdo 18 傳輸資料 2

#define oA2         (plc.gdo[2].bit.bit02) //gdo 19 傳輸時脈

#define oA3         (plc.gdo[2].bit.bit03) //gdo 20 傳輸程序起始

#define oS0         (plc.gdo[2].bit.bit04) //gdo 21 傳輸資料 3

#define oS1         (plc.gdo[2].bit.bit05) //gdo 22 傳輸資料 4

#define oS2         (plc.gdo[2].bit.bit06) //gdo 23 傳輸時脈

#define oS3         (plc.gdo[2].bit.bit07) //gdo 24 傳輸程序起始

#define oC_unlock   (plc.gdo[2].bit.bit08) //gdo 25 C 軸鎖定

#define oSpare1     (plc.gdo[2].bit.bit09) //gdo 26 output spare 1

#define oSpare2     (plc.gdo[2].bit.bit0a) //gdo 27 output spare 2

#define oSpare3     (plc.gdo[2].bit.bit0b) //gdo 28 output spare 3

#define oSpare4     (plc.gdo[2].bit.bit0c) //gdo 29 output spare 4

#define oSpare5     (plc.gdo[2].bit.bit0d) //gdo 30 output spare 5

#define oSpare6     (plc.gdo[2].bit.bit0e) //gdo 31 output spare 6

#define oSpare7     (plc.gdo[2].bit.bit0f) //gdo 32 output spare 7


//------------------------------------------------------------------------------------------------

//EQU3 input/output

//------------------------------------------------------------------------------------------------

#define SROSW                 (0x0007 & (~plc.gdi[3].iPort))

#define iSROSW1               (plc.gdi[3].bit.bit00) //gdi 33 Spindle override Rotary Switch input1

#define iSROSW2               (plc.gdi[3].bit.bit01) //gdi 34 Spindle override Rotary Switch input2

#define iSROSW3               (plc.gdi[3].bit.bit02) //gdi 35 Spindle override Rotary Switch input3

#define iTemperature          (0x0068&(plc.gdi[3].iPort>>4))  

#define iTemperature0         (plc.gdi[3].bit.bit03) //gdi 36 Temperature input1

#define iTemperature1         (plc.gdi[3].bit.bit04) //gdi 37 Temperature input2

#define iTemperature2         (plc.gdi[3].bit.bit05) //gdi 38 Temperature input3

#define iTemperature3         (plc.gdi[3].bit.bit06) //gdi 39 Temperature input4

#define iXP_Limit             (plc.gdi[3].bit.bit07)

#define iXN_Limit             (plc.gdi[3].bit.bit08)

#define iYP_Limit             (plc.gdi[3].bit.bit09)

#define iYN_Limit             (plc.gdi[3].bit.bit0a)

#define iZP_Limit             (plc.gdi[3].bit.bit0b)

#define iZN_Limit             (plc.gdi[3].bit.bit0c)

#define iCP_Limit             (plc.gdi[3].bit.bit0d)

#define iCN_Limit             (plc.gdi[3].bit.bit0e)


//------------------------------------------------------------------------------------------------

//PLC parameter

//------------------------------------------------------------------------------------------------

#define paDisableAlarm          (para[0])  //disable alarm is on or not, 0:Not 1:On

#define paDisableOTRerror       (para[1])  //disable otr error

#define paDisableAlmX           (para[2])  //X servo alarm

#define paDisableAlmY           (para[3])  //Y servo alarm

#define paDisableAlmZ           (para[4])  //Z servo alarm

#define paDisableAlmA           (para[5])  //A servo alarm

#define paSpindleAlarm          (para[6])  //spindle alarm

#define paLubeAlarm             (para[7])  //lube alarm

#define paAirAlarm              (para[8])  //air alarm

#define paLubeAlmPeriod         (para[9])  //lube detecting time interval

#define paAirInterval           (para[10]) //air detecting time interval

#define paEMGSP                 (para[11]) //Emgstop 0:NO 1:NC

#define paMaxTool               (para[12]) //tool magazin

#define paRunLightEndBlinkTime  (para[13]) //run light blinking lasting time after program end

#define paG37Probe              (para[14]) //probe for tool length, 0:NO 1:NC

#define paG37MinPosZ            (para[15]) //G37 Z minimum position

#define paManualToolRelease     (para[16]) //manual tool release, 0:NO 1:NC

#define paRigidTapping          (para[17]) //air blow and rigid tapping control, 0:air blow 1:rigid tapping

#define paCylinder              (para[18]) //double-acting pneumatic or single-acting pneumatic cylinder, 0:double 1:single

#define padisable_LubeSenser    (para[19]) //油壓偵測異警: 0:關 1:開

#define paLubeStateTime         (para[20]) //油壓偵測時間 unit:min

#define paLubefilterTime        (para[21]) //油壓偵測信號穩定時間 unit:S

#define paLubeCheck             (para[22]) //Lube,0:NO 1:NC

#define paCoolantAlarm          (para[24]) //Coolant 0:NO 1:NC

#define paDisplay_S             (para[25]) //主軸刀號資料

#define paDisplay_P             (para[26]) //預備刀號資料

#define paM345DelayTime         (para[27]) //M03 M04 M05 delay time, if 0, wait speed arrive signal

#define paMaxSpindleWaitTime    (para[28]) //maximum spindle waiting time

#define paDisplay_S_L           (para[29]) //主軸負載資料 GEAU AI CN1

#define paGAI1                  (para[31]) //GEAU AI CN2

#define paGAI2                  (para[32]) //GEAU AI CN3

#define paGAI3                  (para[33]) //GEAU AI CN4

#define paG00Linear             (para[34]) //線性定位 0:關 1:開

#define paGAO0                  (para[35]) //GEAU AO CN1

#define paGAO1                  (para[36]) //GEAU AO CN2

#define paGAO2                  (para[37]) //GEAU AO CN3

#define paGAO3                  (para[38]) //GEAU AO CN4

#define paTemperature_S         (para[39]) //溫度補償 0:關 1:開

#define paToolLife              (para[40]) //刀具壽命管理模式0:不啟用  1:feedLength  2:spindleTime

#define paTEST_ATCstep          (para[69]) //test ATC step


//------------------------------------------------------------------------------------------------

//PLC long parameter

//------------------------------------------------------------------------------------------------

#define lubOnTime               (longPara[0])  //lube on time

#define lubOffTime              (longPara[1])  //lube on time

#define lpaATC_highSpeed        (longPara[2])  //換刀高速定位

#define lpaATC_slowSpeed        (longPara[3])  //換刀慢速定位

#define lpaTool_delay           (longPara[4])  //換刀步驟延遲

#define lpaZsave_position       (longPara[5])  //Z 軸安全位置

#define lpaxATC_position        (longPara[6])  //X 軸到換刀位置

#define lpayATC_position        (longPara[7])  //Y 軸到換刀位置

#define lpazATC_position        (longPara[8])  //Z 軸到換刀位置

#define firstToolPosX           (longPara[9])  //第 1 把刀 x 軸位置

#define firstToolPosY           (longPara[10]) //第 1 把刀 y 軸位置

#define toolPitchX              (longPara[11]) //x 軸刀架間具

#define toolPitchY              (longPara[12]) //y 軸刀架間具

#define lpaOnSpindleTool        (longPara[13]) //主軸上的刀具號

#define lpax_position           (longPara[14]) //換刀完成 X 軸預定位置

#define lpay_position           (longPara[15]) //換刀完成 y 軸預定位置

#define lpaATC_device           (longPara[16]) //換刀裝置是否存在 0:不存在 1:存在

#define lpatoolChangeDelay      (longPara[17]) //鬆夾刀延遲時間

#define lprobe_x_position       (longPara[18]) //自動刀長量測 x 軸位置

#define lprobe_y_position       (longPara[19]) //自動刀長量測 y 軸位置

#define lprobe_z_position       (longPara[20]) //自動刀長量測 z 軸位置

#define lprobe_offset           (longPara[21]) //自動刀長量測基準高補償

#define lprobe_device           (longPara[22]) //量刀器存在設定 1, 不存在設定 0.

#define lpaBrakeReleaseTime     (longPara[23]) //To brake release delay time

#define lpaAutoPowerOffDelay    (longPara[24]) //自動斷電延遲時間 單位 S

#define lpaZEmgBackOffdistance  (longPara[25]) //緊急停止時 Z 軸拉起距離

#define lpaEmgBackOffSpeed      (longPara[26]) //緊急停止時 Z 軸拉起速度

#define lparedontime            (longPara[27]) //RED on time

#define lparedofftime           (longPara[28]) //RED off time

#define lpayellowontime         (longPara[29]) //YELLOW on time

#define lpayellowofftime        (longPara[30]) //YELLOW off time

#define lpaToolfeedLength       (longPara[31]) //Tool feed Length  unit:mm

#define lpaToolspindleTime      (longPara[32]) //Tool on spindle run Time  unit:s


//-----------------------------------------------------------------------------------------------

//alarm message

//-----------------------------------------------------------------------------------------------

static char *msgEMG = "ALARM 01! Emergency stop tripped";

static char *msgOTR = "ALARM 02! Please turn on servo system";

static char *msgXALM = "ALARM 03! X axis servo driver alarm";

static char *msgYALM = "ALARM 04! Y axis servo driver alarm";

static char *msgZALM = "ALARM 05! Z axis servo driver alarm";

static char *msgAALM = "ALARM 06! A axis servo driver alarm";

static char *msgSALM = "ALARM 07! Spindle alarm";

static char *msgLube = "ALARM 08! Lube is empty";

static char *msgAir = "ALARM 09! Air pressure too low";

static char *msgSpindleWait = "ALARM 10! Wainting spindle driver time out";

static char *msgInputWait = "ALARM 11! Wainting input #xx time out";

static char *msgInputWatch = "ALARM 12! input #xx abnormal";

static char *msgG37ZLow = "ALARM 13! Z axis is lower than safety position as G37";

static char *msgDoorAlarm="ALARM 14! The door alarm.";

static char *msgNotATC = "ALARM 15! ATC command error, no ATC device";

static char *msgNotZHomed = "ALARM 16! Z axis not homed";

static char *msgToolOver = "ALARM 17! Tool number over maximum number";

static char *msgRigidTap = "ALARM 18! PLC parameter[41] is rigid tapping";

static char *msgOriented = "ALARM 19! PLC parameter[39] is no oriented spindle stop";

static char *msgATCToolOver = "ALARM 20! Tool number is over tool capacity";

static char *msgTool = "ALARM 21! Please stop spindle first";

static char *msgATCToolZero = "ALARM 22! Tool number is zero ";

static char *msgToolNoMatch = "ALARM 23! The tool number on spindle is not matched with magazine position.";

static char *msgToolerror1 = "ALARM 24! Tool is exist.";

static char *msgToolerror2 = "ALARM 25! Tool is not exist.";

static char *msgTool_is_wrong="ALARM 26! Tool  was  broken  or  wrong";

static char *msgLubepressure1="ALARM #27! Lubeoil pressure is Fail";

static char *msgLubepressure2="ALARM #28! Lube oil pressure is a jam";

static char *msgCoolant="ALARM #29! Coolant is overload";

static char *msgToolLife="ALARM #30! Tool Life is over";



//--------------------------------------------------------------------------------------

//緊急停止時 z 軸拉起

//--------------------------------------------------------------------------------------

void emgZBackOff(Status &sts, PlcBlock &plc){  

  if( sts.state1.bZHomed ) {

        plc.ncTask.zAbsMachinePos = sts.mchPos.x - lpaZEmgBackOffdistance;

     plc.ncTask.speed = lpaEmgBackOffSpeed;

     plc.ncTask.flag = NC_TASK_OF_Z;

     plc.vto2.bit.emgmv = 1;        

  }

}


void PLCAPI plcOpen(Status &sts, PlcBlock &plc,

                               unsigned short *PlcData, long *LongPlcData)

{

 plc.versionText = msgVersion;

 para = PlcData;             // get plcdata pointer

 longPara = LongPlcData;     // get long data pointer

 plc.subprogram=(char *) 0;  //clear subprogra


//------------------------------------------------------------------------------

//save initial gdi state for rise edge and fall edge

//------------------------------------------------------------------------------

 oldGdi0.iPort = plc.gdi[0].iPort;

 oldGdi1.iPort = plc.gdi[1].iPort;

 oldGdi2.iPort = plc.gdi[2].iPort;

 oldGdi3.iPort = plc.gdi[3].iPort;


 plc.spindleDaValue = 0;


 plc.vto1.bit.xovtr = 0;

 plc.vto1.bit.yovtr = 0;

 plc.vto1.bit.zovtr = 0;

 plc.vto1.bit.aovtr = 0;

 plc.vto4.bit.ghovd = 1;


 paTEST_ATCstep = 0;

 T_delay = 0;

 Tool_delay = 0;

 Autopower_time = 0;

 Autopower_flag = 0;

 redflag = 0;

 yellowflag = 0;


 oNcReady = 0;

 oAUTOPOWER_ON = 0;


 A1bit0=A1bit1=A1bit2=A1bit3=A1bit4=A1bit5=A1bit6=0;

 A2bit0=A2bit1=A2bit2=A2bit3=A2bit4=A2bit5=A2bit6=0;

 A3bit0=A3bit1=A3bit2=A3bit3=A3bit4=A3bit5=A3bit6=0;


 if(lpaZEmgBackOffdistance == 0)

     lpaZEmgBackOffdistance = 10;

 if(lpaEmgBackOffSpeed == 0)

     lpaEmgBackOffSpeed = 100;

//-----------------------------------------------------------------------------  

//StageMachine state

//-----------------------------------------------------------------------------

 sZBreak.flag = ATCTC.flag =

 sCheckInport.flag = sWatchInport.flag =

 sMoveX.flag = sMoveY.flag = sMoveZ.flag

 = sRunLight.flag = sAlmLight.flag = sHoldLight.flag =

 sSpindleCW.flag=sSpindleCCW.flag=sSpindleStop.flag = STAGE_IDLE;

 smLubePressureSenser.flag=STAGE_IDLE;

 C_unlock_flag = 0;

 SL_flag = SL1;


//---------------------------------------------------------------------------

//第二自由定義面板

//---------------------------------------------------------------------------

 Y1=Y2=Y3=Y4=Y5=0;    

 ledscan_Flag=TEMP1;

 keyscan_flag=STEP1;

 Timer_LedScan=Timer_KeyScan=0;        

 old_key1=key1;

 old_key2=key2;

 old_key3=key3;

 old_key4=key4;

 old_key5=key5;

 old_key6=key6;

 old_key7=key7;

 old_key8=key8;

 old_key9=key9;

 old_key10=key10;

 old_key11=key11;

 old_key12=key12;

 old_key13=key13;

 old_key14=key14;

 old_key15=key15;

 old_key16=key16;

 old_key17=key17;

 old_key18=key18;

 old_key19=key19;

 old_key20=key20;

 old_key21=key21;

 old_key22=key22;

 old_key23=key23;

 old_key24=key24;

 old_key25=key25;

 old_key26=key26;

 old_key27=key27;

 old_key28=key28;

 old_key29=key29;

 old_key30=key30;

 old_key31=key31;

 old_key32=key32;

 old_key33=key33;

 old_key34=key34;

 old_key35=key35;

 old_key36=key36;

 old_key37=key37;

 old_key38=key38;

}


void PLCAPI plcMacro(double *MacroPara)

{

   macroPara = MacroPara;

     ePtr = MacroPara + EVENT_LOG_OFFSET;

   eventRecord = MacroPara + EVENT_LOG_OFFSET + 1;

   eIndex = (long *)ePtr;

   eTotal = (long *)ePtr+1;

}


//--------------------------------------------------------------------------

// PLC_DATE_TIME is defined in plc.h

//--------------------------------------------------------------------------

void plcDateTime(void *PlcDateTime)

{

 (long *)plcTime = PLC_DATE_TIME;

}


void PLCAPI plcRun(Status &sts, PlcBlock &plc)

{

 plc.errorMessage = (char *)0;

 plc.vto0.bit.emgsp = 0;

 plc.spi0.bit.xplmt = iXP_Limit;

 plc.spi0.bit.xnlmt = iXN_Limit;

 plc.spi0.bit.yplmt = iYP_Limit;

 plc.spi0.bit.ynlmt = iYN_Limit;

 plc.spi0.bit.zplmt = iZP_Limit;

 plc.spi0.bit.znlmt = iZN_Limit;

 plc.spi1.bit.cplmt = iCP_Limit;

 plc.spi1.bit.cnlmt = iCN_Limit;

 riseGdi0.iPort = (~oldGdi0.iPort) & plc.gdi[0].iPort;


//  plc.vto3.bit.V4spc = 1;

 plc.vto3.bit.Vis4X = 1;

 plc.vto3.bit.jogct = 1;


 if(paG00Linear==1)

    plc.vto3.bit.lnG00=1;

  else

    plc.vto3.bit.lnG00=0;    


 oNcReady = 1;


//----------------------------------------------------------------------------

//掃描自由定義第二面板按?

//----------------------------------------------------------------------------

 switch(keyscan_flag){

     case STEP1:

                 Y2=Y3=Y4=Y5=0;

            Y1=1;

               DATA1=led1;

               DATA2=led2;

               DATA3=led3;

               DATA4=led4;

           DATA5=led5;

               DATA6=led6;

               DATA7=led7;

               DATA8=led8;

           if(Timer_KeyScan++ >= 1){

            Timer_KeyScan=0;

            keyscan_flag=STEP2;                        

                  }

        break;

     case STEP2:

           if(I1||I2||I3||I4||I5||I6||I7||I8){

               if(I1)                        

                  key1=1;

                         else

                  key1=0;

               if(I2)                        

                  key2=1;

                         else

                  key2=0;

               if(I3)                

                  key3=1;

                         else

                  key3=0;

               if(I4)                        

                  key4=1;

                         else

                  key4=0;

               if(I5){

                  key5=1;

                    DATA5=1;

                         }else{

                  key5=0;

                  DATA5=0;

                         }

               if(I6)

                  key6=1;

                         else

                  key6=0;

               if(I7)

                  key7=1;

                         else

                  key7=0;

               if(I8)

                  key8=1;

                         else

                  key8=0;  

               }else{

                       key1=key2=key3=key4=key5=key6=key7=key8=0;

                        Y1=Y2=Y3=Y4=Y5=0;

               keyscan_flag=STEP3;

                }

         break;

         case STEP3:

                   Y1=Y3=Y4=Y5=0;

               Y2=1;

               DATA1=led9;

               DATA2=led10;

               DATA3=led11;

               DATA4=led12;

           DATA5=led13;

               DATA6=led14;

               DATA7=led15;

               DATA8=led16;

           if(Timer_KeyScan ++ >= 1){

              Timer_KeyScan=0;                        

              keyscan_flag=STEP4;

           }

         break;

         case STEP4:

           if(I1||I2||I3||I4||I5||I6||I7||I8){

               if(I1)                        

                  key9=1;

                         else

                  key9=0;

               if(I2)                        

                  key10=1;

                         else

                  key10=0;

               if(I3)                

                  key11=1;

                         else

                  key11=0;

               if(I4)                        

                  key12=1;

                         else

                  key12=0;

               if(I5)

                  key13=1;

                         else

                  key13=0;

               if(I6){

                  key14=1;

                  DATA6=1;

                         }else{

                  key14=0;

                  DATA6=0;

                         }

               if(I7)

                  key15=1;

                         else

                  key15=0;

               if(I8)

                  key16=1;

               else

                  key16=0;

                   }else{

                       key9=key10=key11=key12=key13=key14=key15=key16=0;

                        Y1=Y2=Y3=Y4=Y5=0;

               keyscan_flag=STEP5;

                 }

         break;

         case STEP5:

                   Y1=Y2=Y4=Y5=0;

               Y3=1;

               DATA1=led17;

               DATA2=led18;

               DATA3=led19;

               DATA4=led20;

           DATA5=led21;

               DATA6=led22;

               DATA7=led23;

               DATA8=led24;

           if(Timer_KeyScan ++ >= 1){

              Timer_KeyScan=0;                        

              keyscan_flag=STEP6;

           }

         break;

     case STEP6:

           if(I1||I2||I3||I4||I5||I6||I7||I8){

               if(I1)                        

                  key17=1;

                         else

                  key17=0;

               if(I2)                        

                  key18=1;

                         else

                  key18=0;

               if(I3)                

                  key19=1;

                         else

                  key19=0;

               if(I4)                        

                  key20=1;

                         else

                  key20=0;

               if(I5)

                  key21=1;

                         else

                  key21=0;

               if(I6)

                  key22=1;

                         else

                  key22=0;

               if(I7){

                  key23=1;

                  DATA7=1;

                         }else{

                  key23=0;

                    DATA7=0;

                         }

               if(I8)

                  key24=1;

                         else

                  key24=0;

                   }else{

                       key17=key18=key19=key20=key21=key22=key23=key24=0;

                        Y1=Y2=Y3=Y4=Y5=0;

               keyscan_flag=STEP7;

                 }

         break;

         case STEP7:

                   Y1=Y2=Y3=Y5=0;

               Y4=1;

               DATA1=led25;

               DATA2=led26;

               DATA3=led27;

               DATA4=led28;

           DATA5=led29;

               DATA6=led30;

               DATA7=led31;

               DATA8=led32;

           if(Timer_KeyScan ++ >= 1){

              Timer_KeyScan=0;                        

              keyscan_flag=STEP8;

           }

         break;

         case STEP8:

           if(I1||I2||I3||I4||I5||I6||I7||I8){

               if(I1)                        

                  key25=1;

                         else

                  key25=0;

               if(I2)                        

                  key26=1;

                         else

                  key26=0;

               if(I3)                

                  key27=1;

                         else

                  key27=0;

               if(I4)                        

                  key28=1;

                         else

                  key28=0;

               if(I5)

                  key29=1;

                         else

                  key29=0;

               if(I6)

                  key30=1;

                         else

                  key30=0;

               if(I7)

                  key31=1;

                         else

                  key31=0;

               if(I8){

                  key32=1;

                  DATA8=1;

                         }else{

                  key32=0;

                  DATA8=0;

                         }

                   }else{

                       key25=key26=key27=key28=key29=key30=key31=key32=0;

                        Y1=Y2=Y3=Y4=Y5=0;

               keyscan_flag=STEP9;

                 }

         break;

         case STEP9:  

                   Y1=Y2=Y3=Y4=0;

               Y5=1;

               DATA1=led33;

               DATA2=led34;

               DATA3=led35;

               DATA4=led36;

           DATA5=led37;

               DATA6=led38;

               DATA7=0;

               DATA8=0;

           if(Timer_KeyScan ++ >= 1){

              Timer_KeyScan=0;                        

              keyscan_flag=STEP10;

           }

         break;

     case STEP10:

           if(I1||I2||I3||I4||I5||I6){

               if(I1)                        

                  key33=1;

                         else

                  key33=0;

               if(I2)                        

                  key34=1;

                         else

                  key34=0;

               if(I3)                

                  key35=1;

                         else

                  key35=0;

               if(I4)                        

                  key36=1;

                         else

                  key36=0;

               if(I5)

                  key37=1;

                         else

                  key37=0;

               if(I6)

                  key38=1;

                         else

                  key38=0;  

                   }else{

                       key33=key34=key35=key36=key37=key38=0;

                       Y1=Y2=Y3=Y4=Y5=0;

               keyscan_flag=STEP1;

               }

         break;

 }        


//-------------------------------------------------------------------------------

//計算上升緣

//-------------------------------------------------------------------------------        

 rise_key1=(~old_key1)&key1;

 rise_key2=(~old_key2)&key2;

 rise_key3=(~old_key3)&key3;

 rise_key4=(~old_key4)&key4;

 rise_key5=(~old_key5)&key5;

 rise_key6=(~old_key6)&key6;

 rise_key7=(~old_key7)&key7;

 rise_key8=(~old_key8)&key8;

 rise_key9=(~old_key9)&key9;

 rise_key10=(~old_key10)&key10;

 rise_key11=(~old_key11)&key11;

 rise_key12=(~old_key12)&key12;

 rise_key13=(~old_key13)&key13;

 rise_key14=(~old_key14)&key14;

 rise_key15=(~old_key15)&key15;

 rise_key16=(~old_key16)&key16;

 rise_key17=(~old_key17)&key17;

 rise_key18=(~old_key18)&key18;

 rise_key19=(~old_key19)&key19;

 rise_key20=(~old_key20)&key20;

 rise_key21=(~old_key21)&key21;

 rise_key22=(~old_key22)&key22;

 rise_key23=(~old_key23)&key23;

 rise_key24=(~old_key24)&key24;

 rise_key25=(~old_key25)&key25;

 rise_key26=(~old_key26)&key26;

 rise_key27=(~old_key27)&key27;

 rise_key28=(~old_key28)&key28;

 rise_key29=(~old_key29)&key29;

 rise_key30=(~old_key30)&key30;

 rise_key31=(~old_key31)&key31;

 rise_key32=(~old_key32)&key32;

 rise_key33=(~old_key33)&key33;

 rise_key34=(~old_key34)&key34;

 rise_key35=(~old_key35)&key35;

 rise_key36=(~old_key36)&key36;

 rise_key37=(~old_key37)&key37;

 rise_key38=(~old_key38)&key38;



//-------------------------------------------------------------------------------

//讀取外部類比輸入電壓輸入

//-------------------------------------------------------------------------------

 unsigned char uctemp0 = iEASVU0_EA_Ai1;

 paDisplay_S_L = uctemp0;

 unsigned char uctemp1 = iEASVU0_EA_Ai2;

 paGAI1 = uctemp1;

 unsigned char uctemp2 = iEASVU0_EA_Ai3;

 paGAI2 = uctemp2;

 unsigned char uctemp3 = iEASVU0_EA_Ai4;

 paGAI3 = uctemp3;  


//-------------------------------------------------------------------------------

//主軸負載讀取計算

//-------------------------------------------------------------------------------

 switch(SL_flag){

     case SL1:

              oS0 = oS1 = oS2 = oS3 = 0;

                  STimer_1 = STimer_2 = STimer_3 = 0;

          Stemp_1 = paDisplay_S_L;

              A3bit6 = Stemp_1/64;

          Stemp_2 = Stemp_1%64;


          A3bit5 = Stemp_2/32;

          Stemp_1 = Stemp_2%32;


          A3bit4 = Stemp_1/16;

          Stemp_2 = Stemp_1%16;

               

          A3bit3 = Stemp_2/8;

          Stemp_1 = Stemp_2%8;


          A3bit2 = Stemp_1/4;

          Stemp_2 = Stemp_1%4;


          A3bit1 = Stemp_2/2;

          A3bit0 = Stemp_2%2;

          SL_flag = SL2;

         break;

         case SL2:

              if(STimer_1++ > 0){

                     oS3 = 1;

             oS0 = A3bit0;

                     if(STimer_2++ > 0){

                 oS2 = 1;

                 if(STimer_3++ > 0){

                                   STimer_1 = 0;

                     STimer_2 = 0;

                     STimer_3 = 0;

                         SL_flag = SL3;

                             }

                    }

              }

         break;

         case SL3:

              if(STimer_1++ > 0){

                     oS0 = A3bit1;

             if(STimer_2++ > 0){

                          oS2 = 0;

                           if(STimer_3++ > 0){

                                 STimer_1 = 0;

                     STimer_2 = 0;

                     STimer_3 = 0;

                         SL_flag = SL4;    

                             }

                         }

             }

         break;

         case SL4:

              if(STimer_1++ > 0){

                     oS0 = A3bit2;

             if(STimer_2++ > 0){

                          oS2 = 1;

                 if(STimer_3++ > 0){

                                 STimer_1 = 0;

                     STimer_2 = 0;

                     STimer_3 = 0;

                         SL_flag = SL5;

                             }

                         }

             }

     break;

         case SL5:

          if(STimer_1++ > 0){

                     oS0 = A3bit3;

             if(STimer_2++ > 0){

                          oS2 = 0;

                 if(STimer_3++ > 0){

                                 STimer_1 = 0;

                     STimer_2 = 0;

                     STimer_3 = 0;

                         SL_flag = SL6;  

                             }

                         }

             }

     break;

     case SL6:

              if(STimer_1++ > 0){

                     oS0 = A3bit4;

             if(STimer_2++ > 0){

                          oS2 = 1;

                 if(STimer_3++ > 0){

                                 STimer_1 = 0;

                     STimer_2 = 0;

                     STimer_3 = 0;

                         SL_flag = SL7;

                             }

                         }

             }

     break;

     case SL7:

              if(STimer_1++ > 0){

                     oS0 = A3bit5;

             if(STimer_2++ > 0){

                          oS2 = 0;

                 if(STimer_3++ > 0){

                                 STimer_1 = 0;

                     STimer_2 = 0;

                     STimer_3 = 0;

                         SL_flag = SL8;

                             }

                         }

             }

     break;

     case SL8:

              if(STimer_1++ > 0){

                     oS0 = A3bit6;

             if(STimer_2++ > 0){

                          oS2 = 1;

                 if(STimer_3++ > 0){

                                 STimer_1 = 0;

                     STimer_2 = 0;

                     STimer_3 = 0;

                         SL_flag = SL9;

                             }

                         }

             }

     break;

     case SL9:

             if(STimer_1++ > 0){

                     oS3 = 0;

                     oS2 = 0;

                 oS1 = 0;

             oS0 = 0;

                     STimer_1 = 0;

             STimer_2 = 0;

             STimer_3 = 0;

                 SL_flag = SL1;

             }

     break;        

 }


//-----------------------------------------------------------------------------  

//jog and feed , spidle override  

//-----------------------------------------------------------------------------

 plc.vto0.bit.fvov0 = !iFROSW1;

 plc.vto0.bit.fvov1 = !iFROSW2;

 plc.vto0.bit.fvov2 = !iFROSW3;

 plc.vto0.bit.fvov3 = !iFROSW4;  


 plc.vto0.bit.jgov0 = plc.vto4.bit.ghov0 = !iROSW1;

 plc.vto0.bit.jgov1 = plc.vto4.bit.ghov1 = !iROSW2;

 plc.vto0.bit.jgov2 = plc.vto4.bit.ghov2 = !iROSW3;

 plc.vto0.bit.jgov3 = plc.vto4.bit.ghov3 = !iROSW4;


 if(SROSW == 0)

     SpindleOverride = 5;

 else if(SROSW == 1)

     SpindleOverride = 6;

 else if(SROSW == 2)

     SpindleOverride = 7;

 else if(SROSW == 3)

     SpindleOverride = 8;

 else if(SROSW == 4)

     SpindleOverride = 9;

 else if(SROSW == 5)

     SpindleOverride = 10;

 else if(SROSW == 6)

     SpindleOverride = 11;

 else if(SROSW == 7)

     SpindleOverride = 12;

       

 plc.vto0.bit.clsrt = piCycleStart;

 plc.vto0.bit.fhold = piFeedHold;


 poCS_L = sts.state0.bRun && !sts.state0.bHold && !sts.state0.bStepHold;

 poFH_L = !sts.state0.bRun && sts.state0.bHold && sts.state0.bStepHold;


 oRunLight = sts.state0.bRun && !sts.state0.bHold && !sts.state0.bStepHold;


//------------------------------------------------------------------------------  

//status for Z axis brake

//------------------------------------------------------------------------------

 if( ( iZALM == paDisableAlmZ) || !sts.mode1.mZSVON )

       sZBreak.flag = STAGE_IDLE;


//------------------------------------------------------------------------------

//主軸溫升補償,補償值的單位是 0.001 mm

//系統版本需為 4.08 或 4.08 以上

//------------------------------------------------------------------------------

 if(paTemperature_S){

     if( plc.versionId >= 408 ) {                                    // ncCommand is available after version 408

         if( sts.sysTimeTick > spindleLengthCompTimer ) {            // timeout

             if( plc.ncCommand.finish ) {                            // NC completes the command

                 plc.ncCommand.flag = 0;                             // clear .flag

                 spindleLengthCompTimer = sts.sysTimeTick + 300*256; // do after 5 minutes later

             } else {

                if( plc.ncCommand.flag == 0 ) {                      // now ok to send ncCommand

                    plc.ncCommand.flag = NC_COMMAND_SET_SPINDLE_LENGTH_COMP;

                    // iTemperature is a 4 bits inputs to indicate temerature

                    // here simply compensating formula, you have to use your own

                    plc.ncCommand.data.x = iTemperature * 3;

                }

             }

         }

     }

  }

               

//------------------------------------------------------------------------------

//異警處理

//------------------------------------------------------------------------------

 if(paDisableAlarm){

     if(iCoolantAlarm == paCoolantAlarm){

             plc.vto0.bit.emgsp = 1;

         plc.errorMessage = msgCoolant;

     }

         if(iAirAlarm == paAirAlarm){

             plc.vto0.bit.emgsp = 1;

         plc.errorMessage = msgAir;

         }

         if(iLubeAlarm == paLubeAlarm){

             //plc.vto0.bit.emgsp = 1;

                 warnflag = 1;

         plc.errorMessage = msgLube;

         }else

             warnflag = 0;

         if(iXALM == paDisableAlmX){

             plc.vto0.bit.emgsp = 1;

         plc.errorMessage = msgXALM;

         }

         if(iYALM == paDisableAlmY){

             plc.vto0.bit.emgsp = 1;

         plc.errorMessage = msgYALM;

         }

         if(iZALM == paDisableAlmZ){

             plc.vto0.bit.emgsp = 1;

         plc.errorMessage = msgZALM;

         }

         if(iAALM == paDisableAlmA){

             plc.vto0.bit.emgsp = 1;

         plc.errorMessage = msgAALM;

         }

         if(iSpindleAlm == paSpindleAlarm){

             plc.vto0.bit.emgsp = 1;

         plc.errorMessage = msgSALM;

         }

         if(iOTR == paDisableOTRerror){

             plc.vto0.bit.emgsp = 1;

         plc.errorMessage = msgOTR;

         }

         if(iEmergencyAlarm == paEMGSP){

             plc.vto0.bit.emgsp = 1;

             emgZBackOff(sts, plc);

                 plc.errorMessage = msgEMG;

         }        

//------------------------------------------------------------------------------

//PLEASE record your plc alarm number in variable "curPlcAlarm",

//so that the same event will not be logged repeatedly.

//------------------------------------------------------------------------------

     if( plc.vto0.bit.emgsp ) {

         if( oldEvent < 0 || curPlcAlarm != oldEvent ) {

             oldEvent = curPlcAlarm; // plc alarm number

             ePtr = eventRecord + *eIndex;

             *(long *)ePtr     = oldEvent;

             *((long *)ePtr+1) = *(long *)plcTime;

             if( ++*eIndex == EVENT_LOG_MAX )

                 *eIndex = 0;

             if( *eTotal < EVENT_LOG_MAX )

                  *eTotal += 1;

         }

         eventLogged = 1;

     }        

 }


 Alarm_flag = plc.vto0.bit.emgsp;


//-----------------------------------------------------------------------------

//measure probe for tool length

//-----------------------------------------------------------------------------

 plc.vto0.bit.probe = iG37Probe;


 //指定 marco=主軸刀號

 macroPara[131]=sts.toolNo;


 //指定 marco=plc 長數據,以設定量刀位置

 x_position=lprobe_x_position;

 y_position=lprobe_y_position;

 z_position=lprobe_z_position;


 macroPara[128]=x_position/1000;

 macroPara[129]=y_position/1000;

 macroPara[130]=z_position/1000;  


 //量刀後檢測斷刀

 if(iG37Probe && sts.mode1.mG37){        

          if(set_tool_length_flag){

              macroPara[134] = macroPara[132] *1000;

              lprobe_offset = long (&macroPara[134]);


              para[tool_offset+sts.toolNo] = sts.mchPos.z-lprobe_offset; //刀具表從長參數第 80 組開始置放

          }else{

              if(lprobe_device && ( ((sts.mchPos.z-lprobe_offset) > (para[tool_offset+sts.toolNo] + macroPara[133]))||

                                      ((sts.mchPos.z -lprobe_offset)< (para[tool_offset+sts.toolNo] - macroPara[133])))){ //如果量刀器不存在則不發警報

                      tool_is_wrong_flag =1;          

          }                

          }                

 }      

 //量到斷刀後,急停

 if(tool_is_wrong_flag){                        

          plc.vto0.bit.emgsp=1;

          plc.errorMessage= msgTool_is_wrong;                

 }  


//-----------------------------------------------------------------------------

//lub on off control

//-----------------------------------------------------------------------------

 if((sts.sysTimeTick >=lubOff) && lubFlag==0){

     lubOn=sts.sysTimeTick + lubOnTime;

     lubFlag=oLubeOn=1;

 }

 if((sts.sysTimeTick >=lubOn) && lubFlag==1){

     lubOff=sts.sysTimeTick + lubOffTime;

     lubFlag=oLubeOn=0;

 }


//--------------------------------------------------------------------------

//RED on/off control

//--------------------------------------------------------------------------

 if(Alarm_flag || warnflag){

     if((sts.sysTimeTick >=redoff) && redflag==0){

         redon=sts.sysTimeTick + lparedontime;

         redflag=oRunLight=1;

     }

 if((sts.sysTimeTick >=lubOn) && lubFlag==1){

         redoff=sts.sysTimeTick + lparedofftime;

         redflag=oRunLight=0;

     }

 }


//--------------------------------------------------------------------------

//Yellow on/off control

//--------------------------------------------------------------------------

 if(Alarm_flag){

     if((sts.sysTimeTick >=yellowoff) && yellowflag==0){

         yellowon=sts.sysTimeTick + lpayellowontime;

         yellowflag=oFeedHoldLight=1;

     }

     if((sts.sysTimeTick >=yellowon) && yellowflag==1){

         yellowoff=sts.sysTimeTick + lpayellowofftime;

         yellowflag=oFeedHoldLight=0;

     }

 }


//--------------------------------------------------------------------------

//軌道油壓檢知控制

//--------------------------------------------------------------------------

  if(padisable_LubeSenser)

  {

      if(!iEmergencyAlarm && fLubePressureTrag){

          if(smLubePressureSenser.flag == STAGE_IDLE)

                      smLubePressureSenser.flag = STAGE_START;

              if(smLubePressureSenser.flag == STAGE_FINISH)

              smLubePressureSenser.flag = STAGE_IDLE;

      }

  }


//--------------------------------------------------------------------------

//軌道油失壓與堵塞警報

//--------------------------------------------------------------------------

 if(fLubePressureSenser1){

     plc.errorMessage = msgLubepressure1;

     tLubeStateTimer = 0;        

     plc.vto0.bit.emgsp=1;  

 }

 if(fLubePressureSenser2){

     plc.errorMessage = msgLubepressure2;

     tLubefilterTimer = 0;      

     plc.vto0.bit.emgsp=1;  

 }


//--------------------------------------------------------------------------

//手動模式操作

//--------------------------------------------------------------------------  

 if(sts.state0.bManual) {

         plc.vto1.bit.teach = piTeachIn;

         poTeachIn_L=key6;   //iTeachIn led light

         poMENU_L = 1;

     if(piJog){          //jog mode

        plc.vto1.bit.mMod0 = 1;

        plc.vto1.bit.mMod1 = 0;

     }

     if(piWheel){       //hand wheel mode

        plc.vto1.bit.mMod0 = 0;

        plc.vto1.bit.mMod1 = 1;

     }

     if(piInc){         //inc mode

        plc.vto1.bit.mMod0 = 0;

        plc.vto1.bit.mMod1 = 0;  

     }

     if(piHome){        //home mode

 plc.vto1.bit.mMod0 = 1;

        plc.vto1.bit.mMod1 = 1;  

     }

     if(sts.state0.bManualMode == 0){    //inc step select

            poInc_L = 1;

        if(pix1){                    //inc*1

            plc.vto0.bit.iwst0 = 0;

            plc.vto0.bit.iwst1 = 0;

        }

        if(pix10){                   //inc*10

            plc.vto0.bit.iwst0 = 1;

            plc.vto0.bit.iwst1 = 0;

        }

        if(pix100){                  //inc*100

            plc.vto0.bit.iwst0 = 0;

            plc.vto0.bit.iwst1 = 1;

        }

                if(pix1000){               //inc*1000

            plc.vto0.bit.iwst0 = 1;

            plc.vto0.bit.iwst1 = 1;

        }


        if(!plc.vto0.bit.iwst0 &&

            !plc.vto0.bit.iwst1)

                pox1_L = 1;

            else

                    pox1_L = 0;


            if(plc.vto0.bit.iwst0 &&

            !plc.vto0.bit.iwst1)

            pox10_L = 1;

            else

                    pox10_L = 0;


            if(!plc.vto0.bit.iwst0 &&

            plc.vto0.bit.iwst1)

                    pox100_L = 1;

            else

                    pox100_L = 0;


            if(plc.vto0.bit.iwst0 &&

            plc.vto0.bit.iwst1)

                    pox1000_L = 1;

            else

                    pox1000_L = 0;


         }else{

            poInc_L = 0;

         }


         if(sts.state0.bManualMode == 1){

        poJog_L = 1;

                pox1_L =pox10_L =pox100_L =pox1000_L = 0;

     }else{

        poJog_L = 0;

     }


     if(sts.state0.bManualMode == 2){

        poWheel_L = 1;

     }else{

        poWheel_L = 0;

     }


     if(sts.state0.bManualMode == 3){

           poHome_L = 1;

           pox1_L =pox10_L =pox100_L =pox1000_L = 0;

           plc.vto1.bit.athom = piAutoHome;

poAutoHome_L = piAutoHome;

         }else{

           poHome_L = 0;

         }


//-------------------------------------------------------------------------

//manual spindle CW/CCW and stop

//-------------------------------------------------------------------------

    if(piSpindleCW && sSpindleCW.flag == STAGE_IDLE){

        sSpindleCW.flag=STAGE_START;

    }

    if(sSpindleCW.flag == STAGE_FINISH){

        sSpindleCW.flag=STAGE_IDLE;

    }

    if(piSpindleCCW && sSpindleCCW.flag == STAGE_IDLE){

        sSpindleCCW.flag=STAGE_START;

    }

    if(sSpindleCCW.flag == STAGE_FINISH){

        sSpindleCCW.flag=STAGE_IDLE;

    }

    if(piSpindleStop && sSpindleStop.flag == STAGE_IDLE){

        sSpindleStop.flag=STAGE_START;

    }

    if(sSpindleStop.flag == STAGE_FINISH){

        sSpindleStop.flag=STAGE_IDLE;

    }

       

//---------------------------------------------------------------------------

//手動鬆刀

//---------------------------------------------------------------------------

    if(piManualToolRelease){

            oToolRelease = ospindleAir_VAR = 1;

        }else{

            oToolRelease = ospindleAir_VAR = 0;;

        }        

        poManualToolRelease = piManualToolRelease;

       

  }else{

     poMENU_L = 0;

     poInc_L = 0;

     poJog_L = 0;

         poWheel_L = 0;

         poHome_L = 0;

         pox1_L = 0;

         pox10_L = 0;

         pox100_L = 0;

         pox1000_L = 0;

  }


//--------------------------------------------------------------------------

//mapping jog input and output LED

//--------------------------------------------------------------------------

  plc.subSpi1.bit.xpjog = piXp;

  plc.subSpi1.bit.xnjog = piXn;

  plc.subSpi1.bit.ypjog = piYp;

  plc.subSpi1.bit.ynjog = piYn;

  plc.subSpi1.bit.zpjog = piZp;

  plc.subSpi1.bit.znjog = piZn;

  plc.subSpi1.bit.apjog = piAp;

  plc.subSpi1.bit.anjog = piAn;


  poXp_L = plc.subSpi1.bit.xpjog;

  poXn_L = plc.subSpi1.bit.xnjog;

  poYp_L = plc.subSpi1.bit.ypjog;

  poYn_L = plc.subSpi1.bit.ynjog;

  poZp_L = plc.subSpi1.bit.zpjog;

  poZn_L = plc.subSpi1.bit.znjog;

  poAp_L = plc.subSpi1.bit.apjog;

  poAn_L = plc.subSpi1.bit.anjog;


//-----------------------------------------------------------------------------

//process working light

//-----------------------------------------------------------------------------

  if(piWorkingLight){

     if(poWorking_L){

        poWorking_L=0;

        oLIGHTOn=0;

     }else{

        poWorking_L=1;

        oLIGHTOn=1;

     }

  }


//-----------------------------------------------------------------------------

//process air and light on

//-----------------------------------------------------------------------------

  if(piAirBlow){

     if(poAirBlow_L){

        poAirBlow_L=0;

        oAIROn=0;

     }else{

        poAirBlow_L=1;

        oAIROn=1;

     }

  }


//-----------------------------------------------------------------------------

//process coolant light

//-----------------------------------------------------------------------------

  if(piCoolant){

     if(poCoolant_L){

        poCoolant_L=0;

        oCoolantOn=0;

         }else{

        poCoolant_L=1;

        oCoolantOn=1;

     }

  }


//------------------------------------------------------------------------------

//process auto power light

//------------------------------------------------------------------------------

  if(piAutoPowerOff){

     poAutoPowerOff_L = !poAutoPowerOff_L;

  }

  if(Autopower_flag) {

      if(Autopower_time++ >= lpaAutoPowerOffDelay*256 ) {

                 oAUTOPOWER_ON = 1;

                 Autopower_flag = 0;

          }

       }


//------------------------------------------------------------------------------

//C 軸鎖定控制

//------------------------------------------------------------------------------

  if(sts.state0.bManual){

      oC_unlock = 1;

  }

  if(!sts.state0.bManual && C_unlock_flag){

      oC_unlock = 1;

  }

  if(!sts.state0.bManual && !C_unlock_flag){

      oC_unlock = 0;

  }  


//------------------------------------------------------------------------------

//M-CODE PROCESS

//------------------------------------------------------------------------------  

  if( plc.mCode.flag ) {

    switch( plc.mCode.data ) {

     case 3:   // M03

             if(sts.mode1.mM29){

             oSpindleCw = 1;

             oSpindleCcw = 0;

                         poSpindleCW_L = 1;

                         poSpindleCCW_L = 0;

                         poSpindleStop_L = 0;

             plc.mCode.finish = 1;

                     break;

                 }

             if(sSpindleCW.flag == STAGE_IDLE){

                sSpindleCW.flag=STAGE_START;

         }

         if(sSpindleCW.flag == STAGE_FINISH){

                sSpindleCW.flag=STAGE_IDLE;

                plc.mCode.finish = 1;

         }        

     break;

     case 4:

             if(sts.mode1.mM29){

             oSpindleCw = 0;

             oSpindleCcw = 1;

                         poSpindleCW_L = 0;

                         poSpindleCCW_L = 1;

                         poSpindleStop_L = 0;

                         plc.mCode.finish = 1;

                     break;

                 }

                 if(sSpindleCCW.flag == STAGE_IDLE){

             sSpindleCCW.flag=STAGE_START;

         }

         if(sSpindleCCW.flag == STAGE_FINISH){

             sSpindleCCW.flag=STAGE_IDLE;

             plc.mCode.finish = 1;

         }

     break;

     case 5:   // M05

             if(sts.mode1.mM29){

             oSpindleCw = 0;

             oSpindleCcw = 0;

                 poSpindleCW_L = 0;

                         poSpindleCCW_L = 0;

                         poSpindleStop_L = 1;

                         plc.mCode.finish = 1;

                     break;

                 }

             if(sSpindleStop.flag == STAGE_IDLE){

             sSpindleStop.flag=STAGE_START;

         }

         if(sSpindleStop.flag == STAGE_FINISH){

             sSpindleStop.flag=STAGE_IDLE;

                     plc.mCode.finish = 1;

                 }

     break;

         case 7:  //air blow on

         oAIROn=poAirBlow_L=1;

                 plc.mCode.finish = 1;

     break;

         case 8:  //coolant on

         oCoolantOn=poCoolant_L=1;

             plc.mCode.finish = 1;

break;

         case 9:  //air blow and coolant off

         oAIROn=poAirBlow_L=0;

         oCoolantOn=poCoolant_L=0;

         plc.mCode.finish = 1;

     break;

         case 12:

         if(STool_display.flag == STAGE_IDLE) {

                     STool_display.flag = STAGE_START;

         }

         if(STool_display.flag == STAGE_FINISH) {

             STool_display.flag = STAGE_IDLE;

                         plc.mCode.finish = 1;

         }

     break;

         case 13:

         oProbeDoor = 1;

             if(iProbe_D_O && !iProbe_D_C){

                     plc.mCode.finish = 1;

                 }

     break;

         case 14:

         oProbeDoor = 0;

             if(!iProbe_D_O && iProbe_D_C){

                     plc.mCode.finish = 1;

                 }

     break;

         case 20:

                 geauo1 = 1;

             geauo2 = 1;

             geauo3 = 1;

             geauo4 = 1;

             geauo5 = 1;

             geauo6 = 1;

             geauo7 = 1;

             geauo8 = 1;

             plc.mCode.finish = 1;

         break;

         case 21:

                 geauo1 = 0;

             geauo2 = 0;

             geauo3 = 0;

             geauo4 = 0;

             geauo5 = 0;

             geauo6 = 0;

             geauo7 = 0;

             geauo8 = 0;

             plc.mCode.finish = 1;

         break;

         case 27:

             oM29_mode = 1;

             plc.mCode.finish = 1;

         break;

         case 28:

             oM29_mode = 0;

             plc.mCode.finish = 1;

         break;

         case 30:

             if(poAutoPowerOff_L){

                 Autopower_flag = 1;

                 }

                 Autopower_time = 0;

                 plc.mCode.finish = 1;

         break;

         case 31:

             oMagazineDoor = 1;

                 if(iMagazine_D_O && !iMagazine_D_C)

plc.mCode.finish = 1;

         break;

     case 32:

             oMagazineDoor = 0;

                 if(!iMagazine_D_O && iMagazine_D_C)

                     plc.mCode.finish = 1;

         break;        

         case 35:                // M35

         oG37Blow = 1;

         plc.mCode.finish = 1;

     break;

     case 36:                // M36

         oG37Blow = 0;

         plc.mCode.finish = 1;

     break;

         case 37:

         plc.subprogram=M37; // M37 呼叫量刀副程式 PLC-M37.CNC

         plc.mCode.finish=1;

     break;

     case 40:        

         oC_unlock = 1;

                 C_unlock_flag = 1;

         plc.mCode.finish=1;                

     break;

     case 41:        

         oC_unlock = 0;

         C_unlock_flag = 0;                

         plc.mCode.finish=1;                

     break;

       

//--------------------------------------------------------------------------------

//M codes to reset and display the saved alarm messages,

//which can display up to 12 messages in a page. If wants to display from

//the nth entry, the command M90 ,Hn can be used.

//--------------------------------------------------------------------------------

     case 90:

       if( *eTotal ) {

           PlcTime eTime;

           int eStart, cStart, eNo, j;


           if( *eTotal < EVENT_LOG_MAX )

               eStart = 0;

           else

               eStart = *eIndex;

           if( plc.mhAttr&PLC_MH_ATTR_0 && plc.mhCode0 && plc.mhCode0 < *eTotal )

               cStart = plc.mhCode0;

           else

               cStart = 1;

           eStart += cStart - 1;


           for( int i=0; i<EVENT_DISPLAY_LINE_TOTAL; i++ ) {

               ePtr = eventRecord + eStart;


               // display

               j = EVENT_DISPLAY_LINE_LEN * i;

               eStr[0 +j] = '0' + (i+cStart)/10;

               eStr[1 +j] = '0' + (i+cStart)%10;

               eStr[2 +j] = ')';

               eStr[3 +j] = ' ';


               eNo = *(long *)ePtr;

               eStr[4 +j] = '0' + (eNo    )/100;

               eStr[5 +j] = '0' + (eNo%100)/10;

               eStr[6 +j] = '0' + (eNo%10 );

               eStr[7 +j] = ' ';


               *(long *)&eTime = *((long *)ePtr+1);

               long tempYear = eTime.year + YEAR_OFFSET;

               eStr[8 +j] = '0' + (tempYear     )/1000;

               eStr[9 +j] = '0' + (tempYear%1000)/100;

               eStr[10+j] = '0' + (tempYear%100 )/10;

               eStr[11+j] = '0' + (tempYear%10  );

               eStr[12+j] = '/';

               eStr[13+j] = '0' + eTime.month/10;

               eStr[14+j] = '0' + eTime.month%10;

               eStr[15+j] = '/';

               eStr[16+j] = '0' + eTime.date/10;

               eStr[17+j] = '0' + eTime.date%10;

               eStr[18+j] = ' ';

               eStr[19+j] = '0' + eTime.hour/10;

               eStr[20+j] = '0' + eTime.hour%10;

               eStr[21+j] = ':';

               eStr[22+j] = '0' + eTime.minute/10;

               eStr[23+j] = '0' + eTime.minute%10;

               eStr[24+j] = ':';

               eStr[25+j] = '0' + eTime.second/10;

               eStr[26+j] = '0' + eTime.second%10;

               eStr[27+j] = '\n';

               if( eStart++ == EVENT_LOG_MAX )

                   eStart = 0;

               if( eStart == *eIndex )

             break;

         }

         eStr[28+j] = 0;

       } else

         eStr[0] = 0;

         plc.errorMessage = eStr;

         plc.mCode.finish = 1;

     break;

     case 91:

         *eIndex = *eTotal = 0;

         plc.mCode.finish = 1;

     break;        

         case 6:

                 if(lpaATC_device){

                     switch (TC_Step){

                               case 0:

                                       if(oSpindleCw||oSpindleCcw){

                                           plc.vto0.bit.emgsp = 1;

                                       plc.errorMessage = msgTool;

                                               plc.mCode.finish = 1;

                                               TC_Step = 0;

                                               break;

                                   }

                                       if(!sts.state1.bZHomed){

                                               plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgNotZHomed;

                           plc.mCode.finish = 1;

                                               TC_Step = 0;

                                               break;

                                       }

                                       if(plc.tCode.data > paMaxTool){

                                               plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgATCToolOver;

                                               plc.mCode.finish = 1;

                                               TC_Step = 0;

                                               break;

                                       }

                       if(!plc.tCode.flag || !plc.tCode.data){

                                               plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgATCToolZero;

                                               plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                       }

                                       if(sts.toolNo != lpaOnSpindleTool){

                                               plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolNoMatch;

                           plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                       }

                                               if(sts.toolNo == plc.tCode.data){

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                       TC_Step = TC_Step+1;

                                  break;

                  case 1:

                                          if((sts.toolNo == 1)&&(iT1 == 1)){

                                                   plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 2)&&(iT2 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 3)&&(iT3 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 4)&&(iT4 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 5)&&(iT5 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 6)&&(iT6 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 7)&&(iT7 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 8)&&(iT8 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 9)&&(iT9 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 10)&&(iT10 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 11)&&(iT11 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 12)&&(iT12 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 13)&&(iT13 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 14)&&(iT14 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 15)&&(iT15 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((sts.toolNo == 16)&&(iT16 == 1)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror1;

                                               plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                      if((plc.tCode.data==1)&&(iT1 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((plc.tCode.data==2)&&(iT2 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                      if((plc.tCode.data==3)&&(iT3 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((plc.tCode.data==4)&&(iT4 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                          }

                                          if((plc.tCode.data==5)&&(iT5 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==6)&&(iT6 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==6)&&(iT6 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==7)&&(iT7 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }        

                                               if((plc.tCode.data==8)&&(iT8 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==9)&&(iT9 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==10)&&(iT10 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==11)&&(iT11 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==12)&&(iT12 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==13)&&(iT13 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==14)&&(iT14 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==15)&&(iT15 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               if((plc.tCode.data==16)&&(iT16 == 0)){

                                                       plc.vto0.bit.emgsp = 1;

                                           plc.errorMessage = msgToolerror2;

                                                   plc.tCode.data = sts.toolNo;

                                                       plc.tCode.finish=1;

                                                   plc.mCode.finish = 1;

                           TC_Step = 0;

                                               break;

                                               }

                                               TC_Step = TC_Step+1;

                    break;

                    case 2:

                        if(ATCTC.flag == STAGE_IDLE)

                                                ATCTC.flag = STAGE_START;

                                            if(ATCTC.flag == STAGE_FINISH){

                                                    ATCTC.flag = STAGE_IDLE;

                                                    TC_Step = 0;

                                                    plc.mCode.finish=1;

                                            }

                                         break;


                                 }//switch (TC_Step){

                         }else{

                                 plc.tCode.finish=1;

                             plc.mCode.finish=1;

                                 break;

                         }

           break;

       default:

plc.mCode.finish = 1;

          plc.tCode.data = sts.toolNo;

          plc.tCode.finish=1;

       break;

   }

 } else

   plc.mCode.finish = 0;


//------------------------------------------------------------------------------  

//Spindle DA output

//------------------------------------------------------------------------------

  if(!plc.oss.flag && !(plc.mCode.flag && (plc.mCode.data == 06 || plc.mCode.data == 88))){

      if( sCodeSave < SPINDLE_DA_MAX ) {

           if( oSpindleCw || oSpindleCcw ) {

               plc.spindleDaValue = sCodeSave*(SpindleOverride/10);

                   }

           if( !(oSpindleCw || oSpindleCcw) ) {

               plc.spindleDaValue = 0;

           }

      } else {

             plc.spindleDaValue = SPINDLE_DA_MAX;

      }

  }


//-----------------------------------------------------------------------------

// when sCode.flag from NC, save S code

//-----------------------------------------------------------------------------

 if( plc.sCode.flag ) {

      sCodeSave = plc.sCode.data;

      plc.sCode.finish = 1;

 }


//-----------------------------------------------------------------------------

// t code sends from nc.plc sends t finish to nc, if no m06.

//-----------------------------------------------------------------------------

 if(plc.tCode.flag && !(plc.mCode.flag && plc.mCode.data == 06)){

       plc.tCode.finish = 1;

 }


//------------------------------------------------------------------------------

//Z 軸煞車控制

//------------------------------------------------------------------------------

switch( sZBreak.flag ) {

     case STAGE_IDLE: default:

         oZBreakRelease = 0;

         if( (iZALM!=paDisableAlmZ) && sts.mode1.mZSVON ) {

             sZBreak.timer = sts.sysTimeTick + lpaBrakeReleaseTime;

             sZBreak.flag = STAGE_POLL_REACH;

         }

     break;

     case STAGE_POLL_REACH:

         if( sts.sysTimeTick > sZBreak.timer ) {

             oZBreakRelease = 1;

             sZBreak.flag = STAGE_REACH;

         }

     break;

     case STAGE_REACH:

         oZBreakRelease = 1;

     break;

 }


//----------------------------------------------------------------------------

//主軸正轉

//----------------------------------------------------------------------------

switch(sSpindleCW.flag) {

      case STAGE_START:

          oSpindleCw = 1;

oSpindleCcw = 0;

          poSpindleCW_L = 1;

                  poSpindleStop_L = 0;

                  poSpindleCCW_L = 0;

          sSpindleCW.timer = sts.sysTimeTick + T_SPINDLE_START_DELAY;

          sSpindleCW.flag = STAGE_START_DELAY;

      break;

      case STAGE_START_DELAY:

          if( sts.sysTimeTick > sSpindleCW.timer ) {

              if( paM345DelayTime )

                  sSpindleCW.timer = sts.sysTimeTick + paM345DelayTime;

              else

                  sSpindleCW.timer = sts.sysTimeTick + paMaxSpindleWaitTime;

              sSpindleCW.flag = STAGE_POLL_REACH;

          }

      break;

      case STAGE_POLL_REACH:

          if( paM345DelayTime && sts.sysTimeTick > sSpindleCW.timer )

              sSpindleCW.flag = STAGE_FINISH;

          else if( sts.sysTimeTick > sSpindleCW.timer ) {

                   plc.errorMessage = msgSpindleWait;

                   plc.vto0.bit.emgsp = 1;

                   sSpindleCW.flag = STAGE_IDLE;

          } else if( iSpindleArrive && !iSpindle0Rpm )

                     sSpindleCW.flag = STAGE_FINISH;

      break;

  }


//------------------------------------------------------------------------------

//主軸反轉

//------------------------------------------------------------------------------

switch (sSpindleCCW.flag) {

      case STAGE_START:

          oSpindleCw = 0;

          oSpindleCcw = 1;

                  poSpindleCW_L = 0;

                  poSpindleStop_L = 0;

                  poSpindleCCW_L = 1;

          sSpindleCCW.timer = sts.sysTimeTick + T_SPINDLE_START_DELAY;

          sSpindleCCW.flag = STAGE_START_DELAY;

      break;

      case STAGE_START_DELAY:

          if( sts.sysTimeTick > sSpindleCCW.timer ) {

              if( paM345DelayTime )

                  sSpindleCCW.timer = sts.sysTimeTick + paM345DelayTime;

              else

                  sSpindleCCW.timer = sts.sysTimeTick + paMaxSpindleWaitTime;

              sSpindleCCW.flag = STAGE_POLL_REACH;

          }

     break;

     case STAGE_POLL_REACH:

         if( paM345DelayTime && sts.sysTimeTick > sSpindleCCW.timer )

              sSpindleCCW.flag = STAGE_FINISH;

         else if( sts.sysTimeTick > sSpindleCCW.timer ) {

                  plc.errorMessage = msgSpindleWait;

                  plc.vto0.bit.emgsp = 1;

                  sSpindleCCW.flag = STAGE_IDLE;

        } else if( iSpindleArrive && !iSpindle0Rpm )

                    sSpindleCCW.flag = STAGE_FINISH;

      break;

  }


//--------------------------------------------------------------------------------

//主軸停止

//--------------------------------------------------------------------------------

switch (sSpindleStop.flag) {

      case STAGE_START:

oSpindleCw = 0;

         oSpindleCcw = 0;

                 poSpindleCW_L = 0;

                 poSpindleStop_L = 1;

                 poSpindleCW_L = 0;

         sSpindleStop.timer = sts.sysTimeTick + T_SPINDLE_START_DELAY;

         sSpindleStop.flag = STAGE_START_DELAY;

      break;

      case STAGE_START_DELAY:

          if( sts.sysTimeTick > sSpindleStop.timer ) {

              if( paM345DelayTime )

                  sSpindleStop.timer = sts.sysTimeTick + paM345DelayTime;

              else

                  sSpindleStop.timer = sts.sysTimeTick + paMaxSpindleWaitTime;

              sSpindleStop.flag = STAGE_POLL_REACH;

          }

     break;

     case STAGE_POLL_REACH:

         if( paM345DelayTime && sts.sysTimeTick > sSpindleStop.timer )

             sSpindleStop.flag = STAGE_FINISH;

         else if( sts.sysTimeTick > sSpindleStop.timer ) {

                  plc.errorMessage = msgSpindleWait;

                  plc.vto0.bit.emgsp = 1;

                  sSpindleStop.flag = STAGE_IDLE;

         } else if( !iSpindleArrive && iSpindle0Rpm )

                     sSpindleStop.flag = STAGE_FINISH;

      break;

  }  


//-------------------------------------------------------------------------------  

//Auto tool cheng

//-------------------------------------------------------------------------------

 switch(ATCTC.flag){

     case STAGE_START:     //Z 軸升至安全位置

             paTEST_ATCstep = 0;

         plc.ncTask.zAbsMachinePos = lpaZsave_position;

         plc.ncTask.speed = lpaATC_highSpeed;

         plc.ncTask.flag = NC_TASK_OF_Z;

         if(plc.ncTask.finish){

             plc.ncTask.flag = 0;

                         if(T_delay++ >= lpatoolChangeDelay*128){

                         T_delay = 0;

                 ATCTC.flag = STAGE_TEMP1;

                         }

                 }

          break;

      case STAGE_TEMP1:     //關閉軟體極限,並開啟刀庫門

                  plc.vto2.bit.nosft = 1;

                  oMagazineDoor = 1;

                  if(iMagazine_D_O && !iMagazine_D_C){

              ATCTC.flag = STAGE_TEMP2;

                  }

      break;

          case STAGE_TEMP2:     //X,Y 軸移至換刀位置

                  paTEST_ATCstep = 2;

          plc.ncTask.xAbsMachinePos = lpaxATC_position;

              plc.ncTask.yAbsMachinePos = lpayATC_position;

          plc.ncTask.speed = lpaATC_highSpeed;

          plc.ncTask.flag = NC_TASK_OF_X+NC_TASK_OF_Y;

                  if(plc.ncTask.finish){

                      plc.ncTask.flag = 0;

                          if(T_delay++ >= lpatoolChangeDelay*128){

                  T_delay = 0;

                  ATCTC.flag = STAGE_TEMP3;

                          }

                  }

      break;

case STAGE_TEMP3:     //Z 軸以慢速移至換刀位置

          paTEST_ATCstep = 3;

          plc.ncTask.zAbsMachinePos = lpazATC_position;

          plc.ncTask.speed = lpaATC_slowSpeed;

          plc.ncTask.flag = NC_TASK_OF_Z;

          if(plc.ncTask.finish){

                  plc.ncTask.flag = 0;

              ATCTC.flag = STAGE_TEMP4;

                  }

      break;

      case STAGE_TEMP4:     //主軸鬆刀並延遲一段時間

          paTEST_ATCstep = 4;

          ospindleAir_VAR = 1;

                  oToolRelease = 1;

          if(Tool_delay++ >= lpaTool_delay*128){

                      Tool_delay = 0;

                          ATCTC.flag = STAGE_TEMP5;

                  }

      break;

          case STAGE_TEMP5:     //Z 軸以快速上升至安全位置

                  paTEST_ATCstep = 5;

          plc.ncTask.zAbsMachinePos = lpaZsave_position;

          plc.ncTask.speed = lpaATC_highSpeed;

          plc.ncTask.flag = NC_TASK_OF_Z;

                  if(plc.ncTask.finish){

                      plc.ncTask.flag = 0;

              if(T_delay++ >= lpatoolChangeDelay*128){

                              T_delay = 0;

                  ATCTC.flag = STAGE_TEMP6;

                          }

                  }

     break;

         case STAGE_TEMP6:  //刀具壽命管理

             paTEST_ATCstep = 6;

             if(paToolLife == 0){

                     ATCTC.flag = STAGE_TEMP7;

                 }

                 if(paToolLife == 1){

                     int i;

                         i = plc.tCode.data;

                         if(plc.toolLife[i].feedLength > lpaToolfeedLength) {

                             plc.tCode.data = plc.tCode.data + paMaxTool;

                             if(plc.toolLife[i+paMaxTool].feedLength > lpaToolfeedLength){

                     plc.vto0.bit.emgsp = 1;

                     plc.errorMessage = msgToolLife;

                                 ATCTC.flag = STAGE_FINISH;

                             }else

                                 ATCTC.flag = STAGE_TEMP7;

                             }

                     }else{

                             ATCTC.flag = STAGE_TEMP7;

                         }

                 if(paToolLife == 2){

                     int i;

                         i = plc.tCode.data;

                         if(plc.toolLife[i].spindleTime > lpaToolspindleTime) {

                             plc.tCode.data = plc.tCode.data + paMaxTool;

                             if(plc.toolLife[i+paMaxTool].spindleTime > lpaToolspindleTime){

                                 plc.vto0.bit.emgsp = 1;

                     plc.errorMessage = msgToolLife;

                                 ATCTC.flag = STAGE_FINISH;

                             }else

                                 ATCTC.flag = STAGE_TEMP7;

                             }

                     }else{

                             ATCTC.flag = STAGE_TEMP7;

                         }

break;

         case STAGE_TEMP7:   //X,Y 軸快速移至指定刀具號位置 並存入換刀位置

         paTEST_ATCstep = 7;

               

                 if( plc.tCode.data && (plc.tCode.data < paMaxTool + 1)){

             plc.ncTask.xAbsMachinePos = (firstToolPosX + ((plc.tCode.data-1)*toolPitchX));

                         plc.ncTask.yAbsMachinePos =  firstToolPosY;                        

                       }  

         else if(plc.tCode.data && (plc.tCode.data < paMaxTool*2 + 1)){                

                 plc.ncTask.xAbsMachinePos = (firstToolPosX + ((plc.tCode.data - paMaxTool - 1)*toolPitchX));

                         plc.ncTask.yAbsMachinePos =  firstToolPosY + toolPitchY;

                       }

                       

                 lpaxATC_position = plc.ncTask.xAbsMachinePos;

         lpayATC_position = plc.ncTask.yAbsMachinePos;

               

                 plc.ncTask.speed = lpaATC_highSpeed;

         plc.ncTask.flag = NC_TASK_OF_X+NC_TASK_OF_Y;

                 if(plc.ncTask.finish){

                        plc.ncTask.flag = 0;

                        ATCTC.flag = STAGE_TEMP8;

                       }                

         break;

         case STAGE_TEMP8:   //延遲一段時間

                 paTEST_ATCstep = 8;

         if(T_delay++ >= lpatoolChangeDelay*128){

             T_delay = 0;

                         ATCTC.flag = STAGE_TEMP9;

                 }

         break;

         case STAGE_TEMP9:   //Z 軸以慢速下降至換刀位置

                 paTEST_ATCstep = 9;

         plc.ncTask.zAbsMachinePos = lpazATC_position;

         plc.ncTask.speed = lpaATC_slowSpeed;

         plc.ncTask.flag = NC_TASK_OF_Z;

         if(plc.ncTask.finish){

                         plc.ncTask.flag = 0;

             ATCTC.flag = STAGE_TEMP10;

                 }

     break;

         case STAGE_TEMP10:     //主軸夾刀並延遲一段時間

         paTEST_ATCstep = 10;

         ospindleAir_VAR = 0;

                 oToolRelease = 0;

         if(Tool_delay++ >= lpaTool_delay*128){

             Tool_delay = 0;

             ATCTC.flag = STAGE_TEMP11;

                 }

     break;

         case STAGE_TEMP11:     //Z 軸以快速上升至安全位置

                 paTEST_ATCstep = 11;

         plc.ncTask.zAbsMachinePos = lpaZsave_position;

         plc.ncTask.speed = lpaATC_highSpeed;

         plc.ncTask.flag = NC_TASK_OF_Z;

                 if(plc.ncTask.finish){

                         plc.ncTask.flag = 0;

             ATCTC.flag = STAGE_TEMP12;                                

                 }

     break;

         case STAGE_TEMP12:     //完成換刀

             paTEST_ATCstep = 12;

         plc.ncTask.xAbsMachinePos = lpax_position;

             plc.ncTask.yAbsMachinePos = lpay_position;

         plc.ncTask.speed = lpaATC_highSpeed;

         plc.ncTask.flag = NC_TASK_OF_X+NC_TASK_OF_Y;

             if(plc.ncTask.finish){

             plc.ncTask.flag = 0;

paTEST_ATCstep = 10;

                         plc.tCode.finish = 1;

                         lpaOnSpindleTool = plc.tCode.data;

                         plc.vto2.bit.svpar = 1;

                         plc.vto2.bit.nosft = 1;

                         oMagazineDoor = 0;

                     if(!iMagazine_D_O && iMagazine_D_C)

                 ATCTC.flag = STAGE_TEMP13;

                 }

     break;

         case STAGE_TEMP13:

                 paTEST_ATCstep = 13;

             if(lprobe_device && (set_tool_length_flag==0)){

                     plc.subprogram=M37;

                 ATCTC.flag = STAGE_FINISH;

                 }else{

                     ATCTC.flag = STAGE_FINISH;

                 }

     break;

 }  


//--------------------------------------------------------------------------

//軌道油壓偵測

//--------------------------------------------------------------------------

 switch (smLubePressureSenser.flag){

          case STAGE_START:

                    fLubePressureTrag = 0;

            tLubeStateTimer = 0;

            tLubefilterTimer = 0;

                        smLubePressureSenser.flag = STAGE_TEMP1;

          break;

      case STAGE_TEMP1:  

                    if((tLubeStateTimer++ <= paLubeStateTime*256) && (iLube_pressure == paLubeCheck)){

                tLubeStateTimer = 0;

                            smLubePressureSenser.flag = STAGE_TEMP2;

                }

                    if((tLubeStateTimer++ >= paLubeStateTime*256) && ((iLube_pressure == paLubeCheck) == 0)){

                            tLubeStateTimer = 0;

                                fLubePressureSenser1 = 1;

                                fLubePressureSenser2 = 0;

                                smLubePressureSenser.flag = STAGE_FINISH;

                        }

          break;

       

          case STAGE_TEMP2:

                if((tLubefilterTimer++ >= paLubefilterTime*256) && (iLube_pressure == paLubeCheck)){

                tLubefilterTimer = 0;

                                fLubePressureSenser1 = 0;

                                fLubePressureSenser2 = 1;

                            smLubePressureSenser.flag = STAGE_FINISH;

                        }

                        if((tLubefilterTimer++ <= paLubefilterTime*256) && ((iLube_pressure == paLubeCheck) == 0)){

                                tLubefilterTimer = 0;

                                fLubePressureTrag = 1;

                                smLubePressureSenser.flag = STAGE_FINISH;

                        }

          break;

          }//end of smLubePressureSenser


//------------------------------------------------------------------------------------

//刀號顯示

//------------------------------------------------------------------------------------

 switch(STool_display.flag){

     case STAGE_START:

                  oA0 = 0;

                  oA1 = 0;

                  oA2 = 0;

oA3 = 0;

                  Timer_1 = 0;

          Timer_2 = 0;

          Timer_3 = 0;

                  if(paDisplay_S > 99){

                     paDisplay_S = 99;

                  }

                  if(paDisplay_P > 99){

                     paDisplay_P = 99;

                  }

          paDisplay_S = sts.toolNo;

          paDisplay_P = paDisplay_S + 8;


                  temp_1 = paDisplay_S;

              A1bit6 = temp_1/64;

          temp_2 = temp_1%64;


                  temp_3 = paDisplay_P;

                  A2bit6 = temp_3/64;

                  temp_4 = temp_3%64;


          A1bit5 = temp_2/32;

          temp_1 = temp_2%32;


          A2bit5 = temp_4/32;

                  temp_3 = temp_4%32;


          A1bit4 = temp_1/16;

          temp_2 = temp_1%16;


          A2bit4 = temp_3/16;

          temp_4 = temp_3%16;


          A1bit3 = temp_2/8;

          temp_1 = temp_2%8;


                  A2bit3 = temp_4/8;

          temp_3 = temp_4%8;


          A1bit2 = temp_1/4;

          temp_2 = temp_1%4;


                  A2bit2 = temp_3/4;

          temp_4 = temp_3%4;


          A1bit1 = temp_2/2;

          A1bit0 = temp_2%2;


                  A2bit1 = temp_4/2;

          A2bit0 = temp_4%2;

                  STool_display.flag = STAGE_TEMP1;

     break;

         case STAGE_TEMP1:

                 if(Timer_1++ > 0){

                     oA3 = 1;

             oA1 = A1bit0;

             oA0 = A2bit0;

                         if(Timer_2++ > 0){

                 oA2 = 1;

                 if(Timer_3++ > 0){

                                         Timer_1 = 0;

                     Timer_2 = 0;

                     Timer_3 = 0;

                         STool_display.flag = STAGE_TEMP2;

                                 }

                         }

              }

     break;

case STAGE_TEMP2:

         if(Timer_1++ > 0){

                 oA1 = A1bit1;

                         oA0 = A2bit1;

             if(Timer_2++ > 0){

                             oA2 = 0;

                                 if(Timer_3++ > 0){

                                     Timer_1 = 0;

                     Timer_2 = 0;

                     Timer_3 = 0;

                         STool_display.flag = STAGE_TEMP3;    

                                 }

                         }

             }

     break;

     case STAGE_TEMP3:

         if(Timer_1++ > 0){

                 oA1 = A1bit2;

                         oA0 = A2bit2;

             if(Timer_2++ > 0){

                             oA2 = 1;

                 if(Timer_3++ > 0){

                                     Timer_1 = 0;

                     Timer_2 = 0;

                     Timer_3 = 0;

                         STool_display.flag = STAGE_TEMP4;

                                 }

                         }

             }

     break;

     case STAGE_TEMP4:

         if(Timer_1++ > 0){

                 oA1 = A1bit3;

                         oA0 = A2bit3;

             if(Timer_2++ > 0){

                             oA2 = 0;

                 if(Timer_3++ > 0){

                                     Timer_1 = 0;

                     Timer_2 = 0;

                     Timer_3 = 0;

                         STool_display.flag = STAGE_TEMP5;

                                 }

                         }

             }

     break;

     case STAGE_TEMP5:

         if(Timer_1++ > 0){

                 oA1 = A1bit4;

                         oA0 = A2bit4;

             if(Timer_2++ > 0){

                             oA2 = 1;

                 if(Timer_3++ > 0){

                                     Timer_1 = 0;

                     Timer_2 = 0;

                     Timer_3 = 0;

                         STool_display.flag = STAGE_TEMP6;

                                 }

                         }

             }

     break;

     case STAGE_TEMP6:

         if(Timer_1++ > 0){

                 oA1 = A1bit5;

             oA0 = A2bit5;

             if(Timer_2++ > 0){

                             oA2 = 0;

                 if(Timer_3++ > 0){

                                     Timer_1 = 0;

                     Timer_2 = 0;

                     Timer_3 = 0;

                         STool_display.flag = STAGE_TEMP7;

                                 }

                         }

             }

     break;

     case STAGE_TEMP7:

         if(Timer_1++ > 0){

                 oA1 = A1bit6;

             oA0 = A2bit6;

             if(Timer_2++ > 0){

                             oA2 = 1;

                 if(Timer_3++ > 0){

                                     Timer_1 = 0;

                     Timer_2 = 0;

                     Timer_3 = 0;

                         STool_display.flag = STAGE_TEMP8;

                                 }

                         }

             }

     break;

     case STAGE_TEMP8:

         if(Timer_1++ > 0){

                     oA3 = 0;

                     oA2 = 0;

                 oA1 = 0;

             oA0 = 0;

                         Timer_1 = 0;

             Timer_2 = 0;

             Timer_3 = 0;

                         plc.mCode.finish = 1;

                 STool_display.flag = STAGE_FINISH;

             }

     break;

 }


//------------------------------------------------------------------------------

//in the section where emgStopFlag is taken care

//------------------------------------------------------------------------------  

 if( plc.emgStopFlag < 0 ){

     if( oldEvent < 0 || -plc.emgStopFlag != oldEvent ) {

         oldEvent = -plc.emgStopFlag;

         ePtr = eventRecord + *eIndex;

         *(long *)ePtr     = oldEvent;

         *((long *)ePtr+1) = *(long *)plcTime;

         if( ++*eIndex == EVENT_LOG_MAX )

            *eIndex = 0;

         if( *eTotal < EVENT_LOG_MAX )

            *eTotal += 1;

     }

     eventLogged = 1;

 }


//------------------------------------------------------------------------------

//緊急停止的處理

//------------------------------------------------------------------------------  

 if( plc.emgStopFlag ) {

   if( plc.tCode.flag ) {

     plc.tCode.finish = 1;

     tCodeStage = 0;

     plc.ncTask.flag = 0;

   }

       oSpindleCw = 0;

   oSpindleCcw = 0;

plc.emgStopFlag = 0;

   plc.mCode.finish = 1;

       plc.spindleDaValue = 0;

   poSpindleCW_L = oSpindleCw = 0;

   poSpindleCCW_L = oSpindleCcw = 0;

   poSpindleStop_L = 1;

   poCoolant_L=0;

   oCoolantOn=0;

   poAirBlow_L=0;

   oAIROn=0;

   poAutoHome_L=0;


   sSpindleCW.flag=sSpindleCCW.flag=sSpindleStop.flag=STAGE_IDLE;

       smLubePressureSenser.flag = STAGE_IDLE;


   fLubePressureTrag = 1;      

       fLubePressureSenser1 = 0;  

       fLubePressureSenser2 = 0;  

       tLubeStateTimer = 0;        

   tLubefilterTimer = 0;            

 }


//--------------------------------------------------------------------------

//to save the logged event

//--------------------------------------------------------------------------

 if(eventLogged){

     if(eventSaveTimer++ > EVENT_LOG_SAVE_DELAY){

         plc.vto2.bit.svpar = 1;

         eventSaveTimer = 0;

     }

     eventLogged = 0;

 }else if(eventSaveTimer){

     plc.vto2.bit.svpar = 1;

     eventSaveTimer = 0;

     oldEvent = -1;

 }


 oldGdi0.iPort = plc.gdi[0].iPort;


//----------------------------------------------------------------------------

//儲存 key 的狀態以便計算上升緣

//----------------------------------------------------------------------------

 old_key1=key1;

 old_key2=key2;

 old_key3=key3;

 old_key4=key4;

 old_key5=key5;

 old_key6=key6;

 old_key7=key7;

 old_key8=key8;

 old_key9=key9;

 old_key10=key10;

 old_key11=key11;

 old_key12=key12;

 old_key13=key13;

 old_key14=key14;

 old_key15=key15;

 old_key16=key16;

 old_key17=key17;

 old_key18=key18;

 old_key19=key19;

 old_key20=key20;

 old_key21=key21;

 old_key22=key22;

 old_key23=key23;

 old_key24=key24;

 old_key25=key25;

 old_key26=key26;

 old_key27=key27;

 old_key28=key28;

 old_key29=key29;

 old_key30=key30;

 old_key31=key31;

 old_key32=key32;

 old_key33=key33;

 old_key34=key34;

 old_key35=key35;

 old_key36=key36;

 old_key37=key37;

 old_key38=key38;


}


void PLCAPI plcClose(Status &sts, PlcBlock &plc)

{

 plc.spindleDaValue = 0;

 oZBreakRelease = 0;

 oNcReady = 0;

}