ronkang
倍加福總線
級別: 略有小成
|
SR20帶7臺G120XA變頻器,走USS通訊,一個子程序中使用7個USS_CTRL指令讀寫變頻器。另一個子程序中使用7個USS_RPM_R指令輪訓讀取7臺變頻器電流,現在問題是: 1.兩個子程序都在主程序中調用時,USS_RPM_R沒有任何錯誤,但是USS_CTRL平均15秒就會報錯,錯誤代碼2。2這個代碼不知什么原因引起。 2.主程序中只調用USS_CTRL這個子程序時,7個USS_CTRL指令無任何錯誤。 請專家指點一下,USS_RPM_R是輪詢順序執行的,應該沒有問題,會不會是和USS_CTRL指令沖突了?問題到底出在哪里?有什么解決辦法,麻煩大家了 |
---|---|
|
zhou1211
級別: 略有小成
|
你一個循環周期很容易出現uss_ctrl 和Uss_RPM_R 時間間隔不夠,這樣就被掛起報錯 |
---|---|
|
zhou1211
級別: 略有小成
|
IF iAdrOfInsulation =0 THEN iAdrOfInsulation :=91; END_IF IF bSensorCorrectionHMI THEN eCommandNum := 5; END_IF IF bParamAlterHMI THEN eCommandNum := 7; END_IF CASE eCommandNum OF(*SystemTotalData :=1,SubcircuitAnodeToGlobeResistance,ProductParamRead,SubcircuitCathodeToGlobeResistance,SensorCorrection,AddrAlter,ParamAlter*) SystemTotalData: wMBAdr := 16#0320; iLen := 7; bReadEnable := TRUE; bWriteEnable :=FALSE; SubcircuitAnodeToGlobeResistance: wMBAdr := 16#03E8; iLen := iSubTotal; bReadEnable := TRUE; bWriteEnable :=FALSE; ProductParamRead: wMBAdr := 16#0510; iLen := 5; bReadEnable := TRUE; bWriteEnable :=FALSE; SubcircuitCathodeToGlobeResistance: wMBAdr := 16#04B0; iLen := iSubTotal; bReadEnable := TRUE; bWriteEnable :=FALSE; SensorCorrection: wMBAdr := 16#680; wWriteDate := 16#7; bReadEnable := FALSE; bWriteEnable :=TRUE; AddrAlter: bReadEnable := FALSE; bWriteEnable :=TRUE; wMBAdr := 16#1218; IF iWantedAdr <>0 THEN wWriteDate := UINT_TO_WORD(iWantedAdr); ELSE wWriteDate := 16#5B; END_IF ParamAlter: bReadEnable := FALSE; bWriteEnable :=TRUE; IF bSubcircuitCAlterHMI THEN wMBAdr := 16#71A; wWriteDate := UINT_TO_WORD(iWantedSubcircuitAmount); END_IF IF bAlarmLimitSetHMI THEN wMBAdr := 16#71C; wWriteDate := UINT_TO_WORD(iWantedResistanceLimit); END_IF IF bResistanceCheckRangeSetHMI THEN wMBAdr := 16#71E; wWriteDate := UINT_TO_WORD(iWantedResistanceCheckRange); END_IF END_CASE IF NOT bAlter THEN CASE iState OF 0: fbMBCom.ReadRegs(Execute := FALSE); istate := istate +1; 1: fbMBCom.ReadRegs( UnitID := UINT_TO_BYTE(iAdrOfInsulation), (* 站點地址 *) Quantity := iLEN, MBAddr := wMBAdr, CbLength := iLEN*2, pMemoryAddr:= ADR(wMemoryDate[1]), Execute := TRUE AND bReadEnable , Timeout := t#5s, Busy => ); IF NOT fbMBCom.BUSY THEN fbMBCom.ReadRegs(Execute := FALSE); IF fbMBCom.Error THEN iState :=0; ELSE istate := istate +1; END_IF END_IF 2: CASE eCommandNum OF 1: FOR i :=1 TO 7 DO IF i=3 OR i=4 THEN iSysTotalDate := WORD_TO_UINT(wMemoryDate AND 16#3FFF); ELSE iSysTotalDate := WORD_TO_UINT(wMemoryDate); END_IF END_FOR iSubTotal := iSysTotalDate[2]; IF wMemoryDate[3].14 THEN bErrList[1] := TRUE; ELSE bErrList[1] := FALSE; END_IF IF wMemoryDate[4].14 THEN bErrList[2] := TRUE; ELSE bErrList[2] := FALSE; END_IF 2: FOR i :=1 TO 5 DO iProductParam := WORD_TO_INT(wMemoryDate); END_FOR 3: FOR i :=1 TO iSubTotal DO iSubP_EarthR := WORD_TO_INT(wMemoryDate AND 16#3FFF); IF wMemoryDate.15 THEN bErrList[2+i] := TRUE; ELSE bErrList[2+i] := TRUE; END_IF IF wMemoryDate.14 THEN bErrList[2+iSubTotal+i] := TRUE; ELSE bErrList[2+iSubTotal+i] := TRUE; END_IF END_FOR 4: FOR i :=1 TO iSubTotal DO iSubN_EarthR := WORD_TO_INT(wMemoryDate AND 16#3FFF); IF wMemoryDate.15 THEN bErrList[2+2*iSubTotal+i] := TRUE; ELSE bErrList[2+2*iSubTotal+i] := TRUE; END_IF IF wMemoryDate.14 THEN bErrList[2+3*iSubTotal+i] := TRUE; ELSE bErrList[2+3*iSubTotal+i] := TRUE; END_IF END_FOR END_CASE FOR i := 1 TO 64 DO wMemoryDate := 0; END_FOR istate :=0; eCommandNum := eCommandNum +1; IF eCommandNum >4 THEN eCommandNum :=1; END_IF bAlter := bStopHmi;(*參數修改ON*) END_CASE ELSE CASE istate OF 0: fbMBCom.WriteSingleRegister(Execute := FALSE); istate := istate +1; 1: fbMBCom.WriteSingleRegister( UnitID := UINT_TO_BYTE(iAdrOfInsulation), Quantity := 1, MBAddr := wMBAdr, CbLength := SIZEOF(wWriteDate), pMemoryAddr:= ADR(wWriteDate), Execute := TRUE AND bWriteEnable, Timeout := t#5000ms, Busy => ); IF NOT fbMBCom.BUSY THEN fbMBCom.WriteSingleRegister(Execute := FALSE); IF fbMBCom.Error THEN istate := 0; ELSE istate :=istate +1; END_IF END_IF 2: CASE eCommandNum OF 5:; 6: IF iWantedAdr = BYTE_TO_UINT(fbMBCom.InData.D[4]) THEN iAdrOfInsulation := iWantedAdr; END_IF 7:; END_CASE bWriteEnable :=FALSE; eCommandNum :=1; iState :=0; bAlter := bStopHmi;(*參數修改OFF*) END_CASE END_IF |
---|---|
|
zhou1211
級別: 略有小成
|
通訊沒你想的那么簡單,對時間有要求,你的輪詢讀沒問題是每一步都分開了在做,并且,即使你的通訊對象只有一個,也會出現同樣的情況,你這存在2中通訊操作就必須在進行另一種的時候中斷一種,我的程序是用codesys寫的,2種模式切換,但不能同時進行,實際上切換過程時間很短,在確認發出和收到回信再切回去 |
---|---|
|
ronkang
倍加福總線
級別: 略有小成
|
樓上兄弟,USS通訊沒你說的這么復雜吧。西門子手冊也沒你說的要中斷一個通訊才能啟用另一個通訊。只說了USS讀寫指令同一時刻只能使用一個。 |
---|---|
|
zhou1211
級別: 略有小成
|
你對通訊認識還不夠,因為你2個指令都是存在詢問幀,因此他就像modbus的控制字一樣,需要逐條發送,它又不能像CAN那樣打包發送,空閑接收。 你這種情況就算同時發送那也只是直接下條覆蓋上條,主要還是時間間隔不夠,例如:modbus幀間隔是3.5個字符,在一條發送完沒間隔完就直接下一條,那么2條會串在一塊形成合并幀; 這種幀99.99%的概率是不合法,無法被響應,因為校驗通不過。 另外,你的設備越多數據量越大,你需要做的間隔就越長,波特率本身就是描述通訊速率的,可以計算得出你做程序該有的間隔。 PS: 上面的程序并不復雜,上面是modbus協議,也是讀和寫。codesys本身就是開放性的,你調用的是一整塊功能,它調用可以切入內部調用函數。即使像你那種調用也有時候會寫得很復雜,你沒用到而已。 比如: 你詢問一個設備,設備回的狀態可能使你不得不選擇N種參數,我上面的就是,讀寫在上面的case中其實只出現了2次,其他都是數據處理 |
---|---|
|
zhou1211
級別: 略有小成
|
我說的中斷是廣義上的中斷,和PLC外部中斷不是一個概念,但和定時中斷類似,就是你必須先知道與通訊的設備是否成功的完成了上一次,而不是只管發,到時收一堆報錯,這種情況當年初學plc就是這樣。 拿個最簡單的電池SOC can2.0標準協議 只讀報文來講,plc不需要寫數據幀,只管讀,對象的報文分成4種幀,權重50ms 100ms 200ms 1s ,一是長度不一樣,二是重要程度不一樣,那么這四種必須在確定其中一種發送完了才能發另一種,否則極可能出現1s間隔的不重要報文永遠發不出去 |
---|---|
|
ronkang
倍加福總線
級別: 略有小成
|
你說的不錯,一開始我也在糾結USS_CTRL和USS_RPM_R指令同時使用是否沖突?官方例子程序顯示不沖突,我才這樣用的。今天實際操作證明,官方的例子程序也是存在問題的,問題和我的一樣。也會報校驗錯誤,代碼2 |
---|---|
|