PLCController.DoActivate() 가 PLC 연결을 열기 전에 _monitorPlcInterfaceMap 을 기동해, 연결 확립 전 LiveStatusUpdate() 가 돌면서 ALARM_DEVICE_PLC_DISCONNECT(210002) 오알람이 매 기동마다 발생했다. 원인 - Livetimer 가 초기화되지 않아 DateTime.MinValue 상태 → (Now - MinValue) 가 항상 10000ms 를 초과해 워치독이 오판. 임계값 조정으로는 해결 불가. - MicroTimer 첫 콜백이 주기(100ms) 뒤가 아니라 Start() 직후(약 1ms)라 경합이 아니라 100% 재현되는 결정적 버그. 실측 (2026-08-10 16:12:25.904) Livetimer=0001-01-01, elapsed=63921975145904ms, isLive=False, IsActivated=False, IsConnected=False 조치 - _monitorPlcInterfaceMap.Start() 를 base.DoActivate() 성공 이후로 이동 - Livetimer = DateTime.Now 로 기준시각 확보 후 타이머 기동 - 두 조치는 각각 단독으로는 무효. 반드시 함께 적용해야 한다. - 수정 전/후를 #region 2개(검색: 260810 기동 오알람)로 기록해 원복 가능 검증: 2026-08-10 현장 재기동 확인 — 기동 시 210002 미발생 미해결(별건): Livetimer 이중 용도, ReadBit .err 무시, ClearAlarm 부재, SeqAlarmMonitor 의 무지연 루프 및 Laser/Chiller 즉시 알람 상세: docs/분석_PLC210002_기동오알람_260810.md 작업일지: docs/작업일지/2026_08_10.md
4.7 KiB
4.7 KiB
작업일지 — 2026-08-10
1. PLC 기동 오알람 210002 — 원인 확정 및 해결
증상
프로그램 첫 기동 시 PLC 연결이 열리기도 전에 ALARM_DEVICE_PLC_DISCONNECT(210002) 발생.
연결은 곧 붙지만 알람은 남는다(자동 해제 없음). 시뮬 모드에서는 무발생.
210002를 올리는 경로가 2개였음
| 위치 | 판정 | 임계 | 상태 | |
|---|---|---|---|---|
| A | PLCController.Config.cs:146 (디바이스, 100ms 타이머) |
엣지 — 비트가 바뀌어야 정상 | 10000ms | 활성 |
| B | SeqAlarmMonitor.cs:182 (시퀀스) |
레벨 — 2초 안에 true면 정상 | 2000ms | 활성 |
| — | AlarmMonitoring.cs:169 (공통 시퀀스) |
— | — | 죽은 코드 |
AlarmCode_PTOP : AlarmCode(AlarmCode_PTOP.cs:10) 상속이고 210002는 재정의 없음 → A와 B가 같은 코드를 써서 화면만 봐서는 구분 불가.AlarmMonitoring.Builder()호출처는SequenceManager.cs:83주석 한 줄뿐(등록 0건). 주석을 풀어도 동작하지 않는다.
근본 원인
PLCController.Config.cs
DateTime Livetimer(:33)가 초기화되지 않아DateTime.MinValue. 대입 지점은 토글 감지 시(:138) 한 곳뿐이라, 기동 직후에는 값이 들어가지 않는다. →(Now - MinValue)가 항상 10000ms를 초과 → 워치독 오판. 임계값 10000을 20000으로 키우는 방식은 원리적으로 무효(MinValue 앞에서는 어떤 값이든 초과)._monitorPlcInterfaceMap.Start()(:185)가base.DoActivate()(:187)보다 앞에 있어 연결 확립 전에 타이머가 돌았다.beforeLiveStatus리셋(:195)도 그보다 뒤.
진단 계측 (적용 → 결과 확보 → 원복 완료)
A/B 중 어느 쪽인지 확정하기 위해 두 곳에 임시 로그를 넣고 재기동. 현장 로그:
16:12:25.903 MicroTimer: timer interval: 100 [ms]
16:12:25.904 E PLCController: [210002][A:PLCController.LiveStatusUpdate]
Livetimer=0001-01-01 00:00:00.000, elapsed=63921975145904ms,
isLive=False, beforeLiveStatus=False, IsActivated=False, IsConnected=False
Livetimer=0001-01-01→ 미초기화 확정.IsActivated=False, IsConnected=False→ 연결 확립 전 발생 확정. 사전에[추론]으로 달아 뒀던 "Aurora가IsActivated를DoActivate반환 뒤에 세팅한다"도 함께 검증됨.[B:...]로그 미출현 → A 단독. 시퀀스 계층은 이번 건과 무관.- 타이머 기동(
.903)과 알람(.904) 간격이 1ms →MicroTimer첫 콜백이 주기(100ms) 뒤가 아니라Start()직후에 발생. 경합이 아니라 100% 재현되는 결정적 버그였다.
계측 코드는 결과 확보 후 전량 원복(.cs 잔존 0건 확인).
로그 파일에서 한글이 깨진다(
[진단210002]→[ 210002],위치:→ġ:). 검색어는210002][를 쓸 것.
수정 (최소 수정)
WeldingComponents/WeldingCommon/Devices/PLC/PLCController.Config.cs 의
DoActivate() 1개 메서드만 변경. SeqAlarmMonitor.cs 등 다른 파일 미변경.
_monitorPlcInterfaceMap.Start()를base.DoActivate()성공 이후로 이동Livetimer = DateTime.Now로 기준시각 확보 후 타이머 기동- 두 조치는 각각 단독으로는 무효 — 타이머만 옮기면
Livetimer가 여전히MinValue, 초기화만 하면 타이머가 그 앞에서 이미 발화. 반드시 함께 적용해야 한다. - 수정 전/후를
#region2개로 기록해 원복 가능하게 함 (검색어:260810 기동 오알람)
부수 효과: Activate 실패 시 타이머가 계속 돌던 문제 해소.
[추론] LoadMemoryMapFromFiles() 중 타이머가 같은 맵을 읽던 겹침도 함께 사라진다.
검증
현장 재기동 확인 — 기동 시 210002 미발생. 해결 완료.
잔여 과제 (별건)
Livetimer가 에코 1초 타이머(:130)와 워치독 10초 기준시각(:144)을 겸용하는 구조LiveStatusUpdate가ReadBit의.err를 버려 "PLC 미송신"과 "PC 미수신"이 구분 안 됨AlarmManager.Alarm(AlarmManager.cs:79-104)에 짝이 되는ClearAlarm이 없어 통신 복구 후에도 알람 잔존SeqAlarmMonitor—WaitTime무지연 루프(:145-148), Laser/Chiller 즉시 알람(grace 없음),:190-193_Lasernull 시 NRE 위험,InitDev진입 1회만 실행AlarmMonitoring.cs죽은 코드 정리Light디바이스SerialPort.Open()실패 (16:12:25.875 E EquipmentSetup: Light connect fail.) — 본 건과 무관, 미확인
산출
docs/분석_PLC210002_기동오알람_260810.md(분석 상세)- 커밋 대상: 위 분석 문서 +
PLCController.Config.cs