RCC 패턴 변경 알림(B2506/B2409) 처리 보완
B2506 : PC → PLC RCC 패턴 변경 알림 (PC_RCC_PATTERN_CHANGED) B2409 : PLC → PC 알림 수신 ACK (PLC_RCC_PATTERN_CHANGED_ACK) - 알림 완료 기록을 B2506 ON 시점이 아닌 ACK(B2409) 수신 시점으로 변경 (ACK 없이 오토런이 끝나면 기록하지 않고 다음 오토런에서 다시 알림) - ACK 는 B2409 OFF→ON 순간만 인정 - 알림 호출을 PC_AUTO_STATUS ON 이후로 이동(InitializeDeviceStatus) - 오토런 정지·종료 시 B2506 직접 OFF - B2506/B2409 상태를 직접 읽어 로그 기록, LBAD Trigger/Stop 쓰기 반환값 로그 추가
This commit is contained in:
parent
c517993e1a
commit
a01f9d4cd7
@ -1330,16 +1330,15 @@ namespace ILSOS_KS.Sequences
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartRccPatternChangeNotice(context);
|
|
||||||
|
|
||||||
return SequenceAction.Ok();
|
return SequenceAction.Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RCC 패턴이 바뀌었으면 B2506 을 켜고 알림 완료로 기록한다. ACK(B2409) 가 오거나 오토런이 끝나면 끈다. 오토런은 막지 않는다.
|
// RCC 패턴이 바뀌었으면 B2506 을 켜고, PLC ACK(B2409) 를 받았을 때만 알림 완료로 기록한다.
|
||||||
|
// ACK 없이 오토런이 끝나면 B2506 만 끄고 기록하지 않아서 다음 오토런에서 다시 알린다. 오토런은 막지 않는다.
|
||||||
private void StartRccPatternChangeNotice(SequenceContext context)
|
private void StartRccPatternChangeNotice(SequenceContext context)
|
||||||
{
|
{
|
||||||
_RccChangeNoticeCts?.Cancel();
|
_RccChangeNoticeCts?.Cancel();
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_RCC_PATTERN_CHANGED, false);
|
WriteRccPatternChangedBit(false, "AutoRun Start Reset");
|
||||||
|
|
||||||
if (_SystemParameter.SequenceType != eSequenceType.RCC)
|
if (_SystemParameter.SequenceType != eSequenceType.RCC)
|
||||||
{
|
{
|
||||||
@ -1361,13 +1360,11 @@ namespace ILSOS_KS.Sequences
|
|||||||
|
|
||||||
if (RccPatternChangeRecord.IsAcknowledged(recipeKey, hash))
|
if (RccPatternChangeRecord.IsAcknowledged(recipeKey, hash))
|
||||||
{
|
{
|
||||||
Log.I("[RccPatternChange] No change. PC_RCC_PATTERN_CHANGED(B2506) False");
|
Log.I($"[RccPatternChange] No change. {GetRccPatternBitState()}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_RCC_PATTERN_CHANGED, true);
|
WriteRccPatternChangedBit(true, "RCC pattern changed -> Wait PLC ACK");
|
||||||
RccPatternChangeRecord.Acknowledge(recipeKey, hash);
|
|
||||||
Log.I("[RccPatternChange] RCC pattern changed. SET PC_RCC_PATTERN_CHANGED(B2506) True -> Recorded");
|
|
||||||
|
|
||||||
var cts = new CancellationTokenSource();
|
var cts = new CancellationTokenSource();
|
||||||
_RccChangeNoticeCts = cts;
|
_RccChangeNoticeCts = cts;
|
||||||
@ -1376,16 +1373,37 @@ namespace ILSOS_KS.Sequences
|
|||||||
bool acked = false;
|
bool acked = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// 이전 ACK 가 켜진 채로 남아 있으면 꺼질 때까지 기다린 뒤, 새로 켜지는 순간(OFF -> ON)만 ACK 로 본다.
|
||||||
|
bool ackArmed = !_PLC.ReadBit((int)eBitInput.PLC_RCC_PATTERN_CHANGED_ACK).data;
|
||||||
|
if (!ackArmed)
|
||||||
|
{
|
||||||
|
Log.I($"[RccPatternChange] PLC ACK is already ON. Wait ACK OFF. {GetRccPatternBitState()}");
|
||||||
|
}
|
||||||
|
|
||||||
while (!cts.IsCancellationRequested && !context.Stopped)
|
while (!cts.IsCancellationRequested && !context.Stopped)
|
||||||
{
|
{
|
||||||
if (_PLC.ReadBit((int)eBitInput.PLC_RCC_PATTERN_CHANGED_ACK).data)
|
bool ack = _PLC.ReadBit((int)eBitInput.PLC_RCC_PATTERN_CHANGED_ACK).data;
|
||||||
|
if (!ackArmed)
|
||||||
|
{
|
||||||
|
if (!ack)
|
||||||
|
{
|
||||||
|
ackArmed = true;
|
||||||
|
Log.I($"[RccPatternChange] PLC ACK OFF. Wait new ACK. {GetRccPatternBitState()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ack)
|
||||||
{
|
{
|
||||||
acked = true;
|
acked = true;
|
||||||
Log.I("[RccPatternChange] GET PLC_RCC_PATTERN_CHANGED_ACK(B2409) True");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (acked)
|
||||||
|
{
|
||||||
|
RccPatternChangeRecord.Acknowledge(recipeKey, hash);
|
||||||
|
Log.I($"[RccPatternChange] PLC ACK received -> Recorded. {GetRccPatternBitState()}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -1394,17 +1412,32 @@ namespace ILSOS_KS.Sequences
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// 오토런을 다시 시작해 새 감시가 돌고 있으면, 새로 켠 비트를 건드리지 않는다.
|
// 오토런을 다시 시작해 새 감시가 돌고 있으면, 새로 켠 비트를 건드리지 않는다.
|
||||||
if (acked || ReferenceEquals(_RccChangeNoticeCts, cts))
|
if (ReferenceEquals(_RccChangeNoticeCts, cts))
|
||||||
{
|
{
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_RCC_PATTERN_CHANGED, false);
|
WriteRccPatternChangedBit(false, acked
|
||||||
Log.I(acked
|
? "After PLC ACK"
|
||||||
? "[RccPatternChange] SET PC_RCC_PATTERN_CHANGED(B2506) False"
|
: "AutoRun ended without ACK -> Not recorded, notify again next AutoRun");
|
||||||
: "[RccPatternChange] AutoRun ended without ACK. SET PC_RCC_PATTERN_CHANGED(B2506) False");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// B2506 을 쓰고, 쓴 뒤의 B2506 / B2409 상태를 읽어서 로그로 남긴다.
|
||||||
|
private void WriteRccPatternChangedBit(bool value, string reason)
|
||||||
|
{
|
||||||
|
int ret = _PLC.WriteBit((int)eBitOutput.PC_RCC_PATTERN_CHANGED, value);
|
||||||
|
Log.I($"[RccPatternChange] {reason} : ret={ret}, {GetRccPatternBitState()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// PC_RCC_PATTERN_CHANGED(B2506, PC 출력 블록) 와 PLC_RCC_PATTERN_CHANGED_ACK(B2409, PLC 입력) 를 읽어서 상태 문자열로 만든다.
|
||||||
|
private string GetRccPatternBitState()
|
||||||
|
{
|
||||||
|
var pc = _PLC.ReadBit((int)eBitOutput.PC_RCC_PATTERN_CHANGED, isInput: false);
|
||||||
|
var ack = _PLC.ReadBit((int)eBitInput.PLC_RCC_PATTERN_CHANGED_ACK);
|
||||||
|
return $"PC_RCC_PATTERN_CHANGED(B2506)={(pc.err == 0 ? pc.data.ToString() : $"ReadErr{pc.err}")}, " +
|
||||||
|
$"PLC_RCC_PATTERN_CHANGED_ACK(B2409)={(ack.err == 0 ? ack.data.ToString() : $"ReadErr{ack.err}")}";
|
||||||
|
}
|
||||||
|
|
||||||
private bool InitSequenceVariable(SequenceContext context)
|
private bool InitSequenceVariable(SequenceContext context)
|
||||||
{
|
{
|
||||||
_AutoRunStartTime = DateTime.Now;
|
_AutoRunStartTime = DateTime.Now;
|
||||||
@ -1535,6 +1568,9 @@ namespace ILSOS_KS.Sequences
|
|||||||
// PLC Interface AutoStatus Start
|
// PLC Interface AutoStatus Start
|
||||||
InitAutoRunBit();
|
InitAutoRunBit();
|
||||||
|
|
||||||
|
// RCC 패턴 변경 알림 : 해시 계산에 시간이 걸리므로 PC_AUTO_STATUS 를 켠 뒤에 한다.
|
||||||
|
StartRccPatternChangeNotice(context);
|
||||||
|
|
||||||
// Laser Initialize
|
// Laser Initialize
|
||||||
_Laser.PilotLaserOff();
|
_Laser.PilotLaserOff();
|
||||||
_Laser.LaserOn();
|
_Laser.LaserOn();
|
||||||
@ -1630,9 +1666,9 @@ namespace ILSOS_KS.Sequences
|
|||||||
Log.I(string.Format($"[IOInterface] Start AutoRun IO Bit Initialize"));
|
Log.I(string.Format($"[IOInterface] Start AutoRun IO Bit Initialize"));
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
||||||
Log.I(string.Format($"[IOInterface]SET PCLBADReadyStatus False"));
|
Log.I(string.Format($"[IOInterface]SET PCLBADReadyStatus False"));
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, false);
|
||||||
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingTrigger False"));
|
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingTrigger False"));
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false);
|
||||||
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop False"));
|
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop False"));
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
||||||
Log.I(string.Format($"[IOInterface]SET PCLBADJudgementCompleteAck False"));
|
Log.I(string.Format($"[IOInterface]SET PCLBADJudgementCompleteAck False"));
|
||||||
@ -2351,6 +2387,18 @@ namespace ILSOS_KS.Sequences
|
|||||||
return SequenceAction.Ok();
|
return SequenceAction.Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LBAD IO 출력 : 쓰기 반환값(0 = 성공)을 로그로 남기고, 실패하면 에러 로그를 남긴다.
|
||||||
|
private int WriteLBADDo(eADOAddress address, bool value)
|
||||||
|
{
|
||||||
|
int ret = _IO._iOUnit.WriteDoBit(Convert.ToInt32(address), value);
|
||||||
|
Log.I(string.Format($"[IOInterface] WriteDoBit {address}({Convert.ToInt32(address)}) {value} ret={ret}"));
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
Log.E(string.Format($"[IOInterface] WriteDoBit {address}({Convert.ToInt32(address)}) {value} FAIL ret={ret}"));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
private SequenceActionResult ExecuteWelding(SequenceContext context, string id, SequenceActionResult param)
|
private SequenceActionResult ExecuteWelding(SequenceContext context, string id, SequenceActionResult param)
|
||||||
{
|
{
|
||||||
Status.SetWorkingPosition(eWorkingPosition.EXECUTING_WELD);
|
Status.SetWorkingPosition(eWorkingPosition.EXECUTING_WELD);
|
||||||
@ -2362,7 +2410,7 @@ namespace ILSOS_KS.Sequences
|
|||||||
|
|
||||||
int recipeNo = _RecipeManager.ActivatedRecipe().Id;
|
int recipeNo = _RecipeManager.ActivatedRecipe().Id;
|
||||||
|
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), true);
|
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, true);
|
||||||
|
|
||||||
//int sendresult = _LBAD.SendCellData(_LotId, _CellId, recipeNo, _ModelNo);
|
//int sendresult = _LBAD.SendCellData(_LotId, _CellId, recipeNo, _ModelNo);
|
||||||
if (_BcrID.Contains(""))
|
if (_BcrID.Contains(""))
|
||||||
@ -2428,11 +2476,11 @@ namespace ILSOS_KS.Sequences
|
|||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_READY, false);
|
||||||
Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False"));
|
Log.I(string.Format($"[PLCInterface]SET PC_WELD_READY False"));
|
||||||
|
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, false);
|
||||||
Log.I(string.Format($"[IOInterface]SET PCWeldingTrigger false"));
|
Log.I(string.Format($"[IOInterface]SET PCWeldingTrigger false"));
|
||||||
|
|
||||||
|
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), true);
|
WriteLBADDo(eADOAddress.PCLBADWeldingStop, true);
|
||||||
Log.I(string.Format($"[IOInterface]{_PageNo} setp --> SET PCWeldingStop true"));
|
Log.I(string.Format($"[IOInterface]{_PageNo} setp --> SET PCWeldingStop true"));
|
||||||
|
|
||||||
return SequenceAction.Ok();
|
return SequenceAction.Ok();
|
||||||
@ -2477,7 +2525,7 @@ namespace ILSOS_KS.Sequences
|
|||||||
//LBAD 결과 받아오는 부분 우선 여기서 추가하여 테스트하고 Sub 시퀀스로 빼자
|
//LBAD 결과 받아오는 부분 우선 여기서 추가하여 테스트하고 Sub 시퀀스로 빼자
|
||||||
if (_LBAD.IsSimul)
|
if (_LBAD.IsSimul)
|
||||||
{
|
{
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false);
|
||||||
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop false, LBAD is Simul"));
|
Log.I(string.Format($"[IOInterface]SET PCLBADWeldingStop false, LBAD is Simul"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3269,7 +3317,7 @@ namespace ILSOS_KS.Sequences
|
|||||||
{
|
{
|
||||||
Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True"));
|
Log.I(string.Format($"[IOInterface]Get PLC_WELD_REQEUST True"));
|
||||||
|
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false);
|
||||||
Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
|
Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
|
||||||
|
|
||||||
bool[] Page = new bool[4];
|
bool[] Page = new bool[4];
|
||||||
@ -3313,7 +3361,7 @@ namespace ILSOS_KS.Sequences
|
|||||||
|
|
||||||
WeldingEnd = true;
|
WeldingEnd = true;
|
||||||
|
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false);
|
||||||
Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
|
Log.I(string.Format($"[IOInterface]LBAD {_PageNoRcc} setp --> SET PCWeldingStop false"));
|
||||||
|
|
||||||
DateTime startTime = DateTime.Now;
|
DateTime startTime = DateTime.Now;
|
||||||
@ -3680,6 +3728,10 @@ namespace ILSOS_KS.Sequences
|
|||||||
|
|
||||||
private bool RestoreDeviceStatus()
|
private bool RestoreDeviceStatus()
|
||||||
{
|
{
|
||||||
|
// RCC 패턴 변경 알림 감시 종료 + B2506 OFF (ACK 전이면 기록하지 않았으므로 다음 오토런에서 다시 알린다)
|
||||||
|
_RccChangeNoticeCts?.Cancel();
|
||||||
|
WriteRccPatternChangedBit(false, "AutoRun Stop");
|
||||||
|
|
||||||
//PLC All BIT OFF
|
//PLC All BIT OFF
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
||||||
@ -3696,9 +3748,9 @@ namespace ILSOS_KS.Sequences
|
|||||||
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
|
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
|
||||||
|
|
||||||
//LBAD IO All BIT OFF
|
//LBAD IO All BIT OFF
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, false);
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false);
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
||||||
Log.I(string.Format("[IOInterface]PC All Bit Off"));
|
Log.I(string.Format("[IOInterface]PC All Bit Off"));
|
||||||
|
|
||||||
@ -3755,6 +3807,10 @@ namespace ILSOS_KS.Sequences
|
|||||||
|
|
||||||
private void OnSeqActionStop()
|
private void OnSeqActionStop()
|
||||||
{
|
{
|
||||||
|
// RCC 패턴 변경 알림 감시 종료 + B2506 OFF (ACK 전이면 기록하지 않았으므로 다음 오토런에서 다시 알린다)
|
||||||
|
_RccChangeNoticeCts?.Cancel();
|
||||||
|
WriteRccPatternChangedBit(false, "AutoRun Stop");
|
||||||
|
|
||||||
//PLC All BIT OFF
|
//PLC All BIT OFF
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_REQEUST_ACK, false);
|
||||||
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
_PLC.WriteBit((int)eBitOutput.PC_WELD_COMPLETE, false);
|
||||||
@ -3771,9 +3827,9 @@ namespace ILSOS_KS.Sequences
|
|||||||
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
|
UpdatePLCMemoryAreaCls((int)eWordOutput.STEP1_Arc1_LowerLimit, (int)eWordOutput.WeldingOK_NG);
|
||||||
|
|
||||||
//LBAD IO All BIT OFF
|
//LBAD IO All BIT OFF
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingTrigger), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingTrigger, false);
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADReadyStatus), false);
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADWeldingStop), false);
|
WriteLBADDo(eADOAddress.PCLBADWeldingStop, false);
|
||||||
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
_IO._iOUnit.WriteDoBit(Convert.ToInt32(eADOAddress.PCLBADJudgementCompleteAck), false);
|
||||||
Log.I(string.Format("[IOInterface]PC All Bit Off"));
|
Log.I(string.Format("[IOInterface]PC All Bit Off"));
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user