[TOC] ## 資訊 > 您早 >麻煩您幫查 驅動器狀態字 Quick Stop active觸發條件有哪些嗎? > >控制字是下0x1F 正常觸發時狀態字為0x9237 偶爾機台運作中時控制器會收到驅動器狀態字為0x8317(Quick Stop active) >在位置模式(CSP mode) > 控制器判斷此狀態會做斷始能動作,並發警報。 現況不知為何驅動器會觸發Quick Stop active,而且情況是不容易重現。 > 沒有任何(警報)代碼 ## 比對bit field ### request In CSP, control word 下`0x1F`-->`0b11111` (spec table 27),(Figure 75)是要求 Switch on + enable operation,CSP下 bit4無作用。 就目前所知,下這個命令的目的是slave 為了確認master 仍連線。stop bit (bit2) 沒有設0,表示沒有要急停。 ### response `0x9237`--> `0b1001001000110111`, `0x8317` --> `0b1000001100010111` ```python #python exp=0b1001001000110111 true=0b1000001100010111 bin(exp^true) #-->0b1000100100000 ``` 兩者差別在 bit 5(1-->0), bit 8(0-->1), bit 12(1-->0) status word的定義可參照cia402 or 在 code裡,`objdef.c`的line 427 ```clike=427 union{ WORD all; struct { WORD Readytoswitchon :1; //bit0 WORD Switchedon :1; WORD Operationenabled :1; WORD Fault :1; WORD Voltageenabled :1; WORD Quickstop :1; //bit5 WORD Switchondisabled :1; WORD Warning :1; WORD Manufacturerspecific1 :1; //bit8:stop flag WORD Remote :1; WORD Targetreached :1; WORD Internallimitactive :1; WORD Operationmodespecific :2; //bit12: WORD HomeFinish :1; WORD Manufacturerspecific2 :1; // z-index flag }bit; }Statusword = {0}; ``` 從 `objdef.c` 的 line1753 ```clike=1753 Statusword.bit.Manufacturerspecific1 = GetStopRespStatus(); ``` 可以知道橋弘確實將bit8(manufacture specific bit)定義為,如果stop完成,set bit。同[appear2](#appear2) 最後的 `Operationmodespecific` ,我假設在csp mode,則根據cia402 spec p.142, Table 278 | Bit | Value | Definition | | --- | ----- | ---------- | | 12 | 0 | Drive does not follow the command value – Target position ignored | | 12 | 1 | Drive follows the command value – Target position used as input to position control loop | 也就是,因為某種原因,驅動器忽略命令。 ### paragraph summary 所以`0x8317`看起來是某種error 發生導致bit 12(unfollow),並啟動急停(bit5, set to 0)。bit 8則是有點奇怪,沒有和bit 5 sync 總體來說,就是要查所有 CSP error 發生的case。 ## 查code 處 假設 drive code 沒有繞過正規method直接access bit 了話,應該是定義在 `objdef.c` line 1339 的 `CANopenState_QuickStopActive` ```clike=1339 void CANopenState_QuickStopActive() { Statusword.bit.Readytoswitchon = 1; Statusword.bit.Switchedon = 1; Statusword.bit.Operationenabled = 1; Statusword.bit.Fault = 0; Statusword.bit.Quickstop = 0; Statusword.bit.Switchondisabled = 0; } ``` 透過searching 功能,直接使用此method的有兩處。 ### appear1 分別是 1. `objdef.c` line 1416 的`void ControlWordRun()`裡的line 1493 ```clike=1486 ... if(!Statusword.bit.Operationenabled) // not already Opeation enabled CANopenState_SwitchOnDisabled(); // State Transition 11: => QUICK STOP // Event: Quick stop command recerived from host else if(Statusword.bit.Operationenabled) { // already Opeation enabled CANopenState_QuickStopActive(); // CANopenState_SwitchOnDisabled(); u_bQuickStopFlag = TRUE; } ... ``` 也就是cia402 state machine in operation enable state時,quick stop 這裡算是正常開關機。 ### appear2 或是2. `objdef.c` line 1606 的`void StatusWordDeal()`裡的line 1709 ```clike=1699 ... else if (GetDriveStatus()) { if (GetBrakeIng()) { CANopenState_OperationEnable(); Statusword.bit.Internallimitactive = 1; } else if (GetStopRespStatus()) { CANopenState_QuickStopActive(); u_bStopExist = TRUE; } else ``` `GetStopRespStatus()` 是直接讀取flag。假設沒有直接設定flag,這個function 在 `control.c`,對應setter 是 `SetStopRespFlag`,就是要找`SetStopRespFlag(TRUE);`。 只有 line 7975 `void ExecuteFaultResponse(WORD wResponse)` 和 line 14411 `BrakeEnable()` 這裡有。 `BrakeEnable()`幾乎沒有使用,反而是`ExecuteFaultResponse`,在`objdef.c`, `taskctrl.c`, `control.c`, `Error.c`都有。而且很 spaghetti ```clike=1519 //..., objdef.c ,ControlWordRun() else if (ControlWord.bit.EnableOperation == 0) { if (u_bDisableVolt) ExecuteFaultResponse(OFF2); else if (u_bQuickStopFlag) u_wCANEnable = NULL_CTRLWORD; else if (u_bShutDown) u_wCANEnable = NULL_CTRLWORD; else if (u_bDisableOper) u_wCANEnable = NULL_CTRLWORD; else if (GetDriveStatus()) u_wCANEnable = DISABLE_CTRLWORD; else u_wCANEnable = NULL_CTRLWORD; } if (GetControlSource() != PC_COMMAND) { if (u_bQuickStopFlag) { if (u_wQuickStopCode == SLOWBYQUICKRAMP || u_wQuickStopCode == SLOWBYCURRENTLMT || u_wQuickStopCode == SLOWBYVOLTLMT) ExecuteFaultResponse(OFF1); else if (u_wQuickStopCode == DISABLE) ExecuteFaultResponse(OFF2); else if (u_wQuickStopCode == SLOWBYSLOWRAMP) ExecuteFaultResponse(OFF3); else if (u_wQuickStopCode == SLOWBYQUICKRAMP_INSTOP || u_wQuickStopCode == SLOWBYCURRENTLMT_INSTOP || u_wQuickStopCode == SLOWBYVOLTLMT_INSTOP) ExecuteFaultResponse(STOP1); else if (u_wQuickStopCode == SLOWBYSLOWRAMP_INSTOP) ExecuteFaultResponse(STOP2); else ExecuteFaultResponse(OFF2); } if (u_bShutDown) { if (u_wShutDownCode == DISABLE_DRIVE) ExecuteFaultResponse(OFF2); else if (u_wShutDownCode == SLOWDOWN_SLOWRAMP) ExecuteFaultResponse(OFF3); else ExecuteFaultResponse(OFF2); } if (u_bDisableOper) { if (u_wDisableCode == DISABLE_DRIVE) ExecuteFaultResponse(OFF2); else if (u_wDisableCode == SLOWDOWN_SLOWRAMP) ExecuteFaultResponse(OFF3); else ExecuteFaultResponse(OFF2); } ``` 太四散了,所以要用error code縮小,error code定義在`Error.h` ```clike=169 //error response #define NONE 0x0001 #define OFF1 0x0002 #define OFF2 0x0004 #define OFF3 0x0008 #define STOP1 0x0010 #define STOP2 0x0020 #define IASC 0x0040 #define MOTION 0x0080 #define OFF4 0x0100 ``` ### no err flag 然而讀不到任何error code,這有兩種可能 1.error flag(bit field)很快被某種機制by pass or reset掉了 2.不是用正規的方法(`ExecuteFaultResponse`)set flag,而是某一層直接set flag。但目前找不到有直接setting的地方。所以比較傾向1,被清掉了,e.g. `ClearResponseStatus`。 `ClearResponseStatus` 主要都在 ```clike=7640 //control.c void CheckFaultResponse() { switch(u_wFaultResponse) { case NONE: ClearResponseStatus(); break; case OFF1: StopMotion(); break; case OFF2: Disable(); ClearResponseStatus(); ``` 可是這個function 也沒有被call。所以也不知道是不是真的被清掉。也有可能是PC下command去清的。 但是又很難reproduce error ### paragraph summary 目前還不知道沒有error code的原因。但是又要有error code 才能往下找。 ## summary 1. 有某種內部error 產生 2. status word bit5 有點bug,但pc端沒有依賴它判斷,可暫時忽略 3. 驅動器急停,符合預期 4. 目前還不知道沒有error code的原因