# bit15 Resume 재진입 문제 분석 — 작업 PC 전달용 - 작성일: 2026-06-21 - 대상 시퀀스: `Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs` - 목적: PLC↔PC **bit15 기반 "이어하기(Resume)"** 시나리오 구현 시, AutoRun 재진입에서 깨질 지점과 권고 구현 방향 전달. - 상태: **분석만** (소스 미수정). bit15는 현재 **미구현**. --- ## 1. 시나리오 (신호 타이밍) 1. PLC가 `PAGE_CHANGE_REQ(0x08)` + word(recipe/page) 송신. 2. PC가 recipe/page 적용·에코 후 `PC_PAGE_CHANGE_COMPLETE(0x08)` 송신. 3. **그다음** PLC가 입력 **bit15** ON → 장비 Stop. 4. 정지 중 작업자 수동 작업. 5. 신규 "이어하기" 버튼: AutoRun 시작 + PC→PLC **출력 bit15** ON → 중단 지점부터 이어서 용접. > 핵심: bit15(stop)는 **페이지 체인지가 이미 끝난 뒤** 온다 → 정지 시점에 recipe/page는 **이미 적용·에코 완료** 상태. --- ## 2. 현 구조 핵심 사실 (확정) - AutoRun 시작 = `_SeqAutoRunPTOP.Start(param, …)` (UCMainAutoRunViewModel.cs:244). Aurora `Start()`는 **Init 노드(맨 위)부터** 실행 → `Enter → CheckInitCondition → CheckPageNo`. **Resume/Pause 없음.** - `CheckCycleStop`이 항상 `CheckPageNo`로 되돌아가는 무한 루프(SeqAutoRunPTOP.cs:829) → **정상 종료 노드 `Complete` 미도달.** 모든 세션은 Stop으로만 끝남. - `SeqAutoRunPTOP` 인스턴스는 셋업 때 **1회만 생성**(EquipmentSetup.cs:203) → `_CurrentPageNo / plcPageNo / plcRecipeNo` 등 **C# 필드는 Stop 후에도 유지** (resume에 유리). - bit15(=0x0F)는 입력/출력 맵 모두 `0x0A~0x0F` **예약 공백**(PLCController.Address.cs:27, 63) → 현재 미사용, 신규 정의 충돌 없음. (decimal 15=0x0F vs hex 0x15 여부만 PLC와 확정) --- ## 3. 재진입 시 문제점 ### 3-1. Stop이 "이어가는 데 필요한 상태"를 전부 지움 `OnStopSequenceAutoRun`(UCMainAutoRunViewModel.cs:336) → `Stop()` → `OnStopped` → `OnSeqActionStop`(SeqAutoRunPTOP.cs:1078~): - `PC_PAGE_NO=0`(:1101), `PC_RECIPE_NO=0`(:1102), `PC_ERROR_CODE=0`(:1100) - 모든 용접 비트 false, `PC_PAGE_CHANGE_COMPLETE` false, `PC_AUTO_STATUS(_P)` false - 레이저 게이트 OFF, **`_Scanner.StopExecution()` + `JumpAbs(0,0)`**(:1123-1124) ### 3-2. ★ 정지 시 레시피 롤백 — resume에 치명적 `OnStopSequenceAutoRun`이 `RecipeHelper.RollbackRecipe()`(:345). 내부 `Dispatcher.InvokeAsync(() => ReloadRecipe(SelectedRecipe.name))`(RecipeHelper.cs:104). → **실제 활성 레시피를 원래 레시피로 되돌림 + 비동기**. 정지 중 화면/Layers가 다른 레시피로 바뀜 → resume 기준이 어긋남. ### 3-3. PC_RECIPE_NO 에코 비대칭 - `PC_RECIPE_NO`는 **PC→PLC 출력 워드**(`eWordOutput`, D70002). PLC가 이 값을 읽어 레시피 정합을 확인 → **0이면 안 됨.** - 정상 연속 운전 중엔 0 안 됨(마지막 에코값 유지). **0이 되는 건 Stop 때**(:1102). - 재진입(같은 레시피)이면 `CheckRecipeNoComp`가 "읽은 레시피 == 현재 활성"이면 에코 없이 조기 return(:316-321) → **0인 채 남음.** ### 3-4. 페이지 요청을 "레벨"로 판정 (엣지 아님) `CheckPageNo`는 `ReadBit(PLC_PAGE_CHANGE_REQ).data`를 레벨로만 봄(:378). 재진입 시 PLC가 0x08 유지면 즉시 통과(중복 처리), 안 주면 무한 대기(데드락). ### 3-5. 복구 단위 = "라인 단위 불가, 잘해야 페이지 단위" `OnSeqActionStop`이 `StopExecution + JumpAbs(0,0)`로 스캐너 리스트 중도 취소(:1123) → 용접 중간 라인 복구 불가. --- ## 4. 결정 사항 (이번 시나리오) - bit15 stop 시점엔 recipe/page **이미 적용 완료** → **추가 change 없음.** - 팝업은 적용된 recipe/page를 **읽어 보여주는 read-only**. - resume 재진입은 **페이지 핸드셰이크 스킵**, 용접리스트 업로드→용접부터 이어감. --- ## 5. 작업 PC 권고 구현 방향 1. **bit15 정지 구분 플래그 도입.** `OnSeqActionStop`은 일반/알람/ForceError 정지 공용이므로, "bit15 resume 정지일 때만" 아래 보존이 적용되게 분기. (알람 정지엔 미적용) 2. **bit15 정지 시 워드 보존:** `OnSeqActionStop`의 `PC_RECIPE_NO=0`(:1102) · `PC_PAGE_NO=0`(:1101) **쓰기 스킵.** 3. **`RollbackRecipe()` 스킵**(UCMainAutoRunViewModel.cs:345). 워드 보존과 **반드시 짝** — 안 하면 워드 ≠ 실제 활성 레시피. 4. **팝업(read-only):** 정지 시 recipe/page 읽어 작업자에게 표시. 실제 change 동작 없음. 5. **resume 재진입 분기:** `Start()`가 Init부터 타므로, bit15 플래그가 켜져 있으면 `CheckInitCondition`(:270, Decision)에서 `CheckPageNo`(:284) 대신 **`SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ`(:133)로 분기**해 핸드셰이크를 건너뛰고 업로드→용접부터. 페이지 컨텍스트는 유지된 `_CurrentPageNo` 사용. --- ## 6. 미해결 / 주의 - **mid-weld 복구 불가:** resume은 "중단 페이지 재시작" 단위. 용접 도중 멈춘 라인부터는 불가(3-5). - **팝업값 ≠ 적용값 가능성:** 팝업은 정지 시점 값, 실제 진행은 resume 시점. 그사이 PLC가 또 바꾸면 불일치 → 정지 때 읽은 값을 **래치**해 resume에 쓰거나 "resume 시 재확인 후 적용"으로 정할 것. - **bit15 번호 확정:** decimal 15(0x0F) vs hex 0x15 — 둘 다 현재 미사용. PLC 담당과 확정. - **`Start()`=Init부터** 전제: 코드 구조상 확실하나 프레임워크 바이너리라 100% 확정은 아님. 필요 시 별도 확인. --- ## 7. 파일·라인 레퍼런스 | 항목 | 위치 | |---|---| | AutoRun 시작(Start) | UCMainAutoRunViewModel.cs:244 | | Stop 버튼 + RollbackRecipe | UCMainAutoRunViewModel.cs:336-337, 345 | | OnSeqActionStop(전체 리셋) | SeqAutoRunPTOP.cs:1078~ (워드 :1100-1102, 스캐너 :1123-1124) | | CheckRecipeNoComp(에코 스킵/쓰기) | SeqAutoRunPTOP.cs:316-321, 350 | | CheckPageNo(레벨 판정) | SeqAutoRunPTOP.cs:378 | | CheckPageNoComp(에코/COMPLETE) | SeqAutoRunPTOP.cs:484, 491 | | CheckCycleStop(루프백) | SeqAutoRunPTOP.cs:829 | | Builder/Flow | SeqAutoRunPTOP.cs:122-179 | | 인스턴스 1회 생성 | EquipmentSetup.cs:203 | | RollbackRecipe 본체 | RecipeHelper.cs:104 | | 비트/워드 맵 | PLCController.Address.cs (0x08 :23, 0x0F공백 :27/63, PC_RECIPE_NO :154) |