순환 로직은 보기보다 말썽이 많다
Duty/standby 펌프 세트는 P&ID에서 단순해 보인다. 동일한 펌프 두세 대, 헤더 하나, 유지해야 할 레벨이나 압력 하나. 제어 문제는 펌핑 자체가 아니다. 매 주기마다 어느 펌프가 lead이고, 어느 것이 lag이며, 어느 것이 standby인지, 그리고 그중 하나가 사용 불가일 때 어떻게 할지를 결정하는 것이 문제다.
이 로직이 틀리면 증상은 익숙하다. 한 펌프만 운전 시간이 쌓이고 나머지는 차갑게 쉰다. 이미 해제된 fault 때문에 조용히 순환에서 빠진 standby 펌프가 실제 수요에 기동하지 않는다. Start와 stop 설정값이 겹쳐서 두 펌프가 서로 싸운다. 아니면 고수요 구간 한복판에서 순환이 일어나 헤더 압력을 떨어뜨려 후단 공정을 트립시킨다.
순환 로직은 대개 PLC 안에 있지만, 운전자가 그것을 보고 override하고, 이상하게 동작할 때 원망을 듣는 곳은 SCADA 계층이다. 그래서 아래 절반은 로직이 아니라 표시 얘기다. ISA-101.01은 화면을 네 단계로 나눈다 — Level 1 공정 개요, Level 2 unit 제어, Level 3 unit 상세, Level 4 진단·지원. 펌프 그룹의 역할, 운전 시간, 순환 대기 이유가 있어야 할 자리는 Level 3이다. 거기에 없으면 운전자는 Level 1만 보고 전화를 든다.
역할에 이름을 붙이고, 태그로 유지하라
첫 번째 실수는 "lead"를 고정된 펌프로 취급하는 것이다. Lead, lag, standby는 펌프가 아니라 역할이다. 오늘은 펌프 1이 lead지만 다음 주에는 standby일 수 있다. 역할을 각각의 태그로 모델링하라.
| 태그 | 의미 |
|---|---|
Pump[n].Available | 펌프가 정상이고 Auto/Remote이며, 잠금 없음, 통신 양호 |
Pump[n].RunHours | 듀티 분배에 쓰는 누적 운전 시간 |
LeadPumpNo | 현재 lead 역할을 맡은 물리 펌프 번호 |
LagPumpNo | 다음에 기동할 펌프 번호 |
StandbyPumpNo | Failover용으로 예약된 펌프 번호 |
RotationPending | 순환이 요청되었으나 안전한 시점을 기다리는 중 |
Pump[n].RunHours는 retained 변수여야 한다. IEC 61131-3의 RETAIN 한정자가 정확히 이 용도다. 전원이 한 번 나가고 운전 시간이 0으로 돌아가면 그날부터 듀티 분배는 계산만 하고 아무것도 균등화하지 않는다.
HMI가 "펌프 2가 lead"라고 표시할 때는 하드코딩된 라벨이 아니라 LeadPumpNo를 읽어야 한다. 운전자가 왜 펌프 1이 아니라 펌프 3이 기동했는지 물으면, 그 답은 로직을 노려보며 재구성하는 것이 아니라 이 태그들에서 보여야 한다.
"available"과 "running"을 분리하라
대부분의 순환 버그는 모호한 available 정의로 거슬러 올라간다. 펌프는 진짜로 준비되었을 때만 역할 자격이 있어야 한다.
- Local이나 Hand가 아니라 Auto/Remote 모드일 것.
- Active trip이나 lockout이 없을 것.
- 통신 품질 양호 (명령할 수 없는 펌프는 standby가 아니다).
- 모터에 기동 간 냉각이 필요하다면, 정지 후 rest 타이머 안에 있지 않을 것. 이 타이머 값은 로직 취향이 아니라 모터 등급에서 나온다. IEC 60034-1은 duty type을 S1(연속)부터 S10까지 정의하는데, S1로 주문한 모터는 잦은 기동을 전제로 한 등급이 아니다. NEMA MG 1은 유도전동기의 기동 횟수를 냉간 상태에서 연속 2회, 열간 상태에서 1회로 잡고 그 뒤 냉각을 요구한다. 출력·극수별 최소 간격 표까지 쓸 거면 명판과 제조사 자료에서 직접 확인해라 — 여기 일반값을 적어도 그 모터에는 안 맞는다. 내가 쓰는 출발점은 minimum-rest 300초, minimum-run 120초이고, 모터 자료가 더 긴 값을 요구하면 그쪽이 이긴다.
Pump[n].Available을 이 조건들로부터 하나의 derived tag로 만들고, 순환 결정에는 그 태그만 사용하라. 순환 로직이 한 곳에서는 raw fault 비트를, 다른 곳에서는 mode 비트를 확인하면 둘은 결국 서로 어긋나고, 펌프는 어떤 화면으로도 설명되지 않는 어중간한 상태에 빠진다.
관련된 함정: fault가 났다가 해제된 펌프가 주기 도중에 조용히 lead로 복귀해서는 안 된다. 복구된 펌프가 다음 standby로 재진입할지(보통 이 선택), 운전자 확인을 기다릴지 결정하라.
순환 트리거를 의도적으로 고르라
흔한 트리거는 세 가지이고, 생각 없이 섞으면 마모 불균형이 생긴다.
- 정지할 때마다. 수요가 떨어지고 lead 펌프가 정지할 때마다 lead가 순환한다. 단순하지만, 연속 운전하는 세트는 절대 순환하지 않는다.
- 누적 운전 시간 기준. Lead의 운전 시간이 lag보다 임계값(예: 24 또는 100시간)만큼 넘을 때 순환한다. 연속 듀티에 좋지만, 운전 중 순환 경우를 명시적으로 처리해야 한다.
- 고정 스케줄. 실제 마모와 무관하게 매주 순환한다. 정비 계획에는 예측 가능하지만 실제 마모를 무시한다.
운전 시간 균등화가 가장 흔한 목표이므로, 보통 패턴은 이렇다. 운전 시간을 비교하고, 차이가 임계값을 넘으면 RotationPending을 세운 뒤, 실제 역할 교체는 안전한 시점을 기다린다. 임계값을 넘는 순간 바로 순환하지 마라.
부하 중 순환은 make-before-break 없이 하지 마라
가장 손상이 큰 순환 버그는 교체 중 헤더를 떨어뜨리는 것이다. 로직이 현재 lead를 정지시킨 뒤 새 lead를 기동하면, 아무것도 펌핑하지 않는 간극이 생긴다. 한 현장에서 이 간극은 6초였다. 헤더가 4.2 bar에서 2.9 bar까지 내려갔고, 후단 RO skid의 저압 트립 설정이 3.0 bar였다. 순환 한 번에 공정 하나가 섰다. 트립 설정값과 헤더 압력을 나란히 적어보기 전까지는 이 간극이 안전한지 아무도 모른다.
안전한 두 가지 패턴:
- 수요가 0일 때만 순환. 세트가 자연스럽게 운전 펌프 0대(저수요)로 갈 때까지
RotationPending을 유지하다가, 모두 정지한 상태에서 역할을 재배정한다. 가장 단순하고 안전하다. - Make-before-break. 들어오는 lead를 먼저 기동하고, run feedback과 유량/압력이 형성됐는지 확인한 뒤에 나가는 lead를 정지한다. 잠시 두 대를 돌릴 수 있는 유압 용량과, 정지 전 확실한 run-proving이 필요하다. Run-prove 타이머는 기동 방식에 맞춘다. DOL starter면 5초, soft starter가 ramp를 타면 15초쯤이 내 출발점이다.
Make-before-break에는 값이 붙는다. 두 대가 같은 헤더에 병렬로 붙어 있는 동안 각 펌프의 운전점은 BEP에서 밀려난다. ANSI/HI 9.6.3은 rotodynamic pump의 preferred operating region을 BEP 유량의 70~120%로 두는데, 시스템 곡선이 평평하면 병렬 2대는 각각 그 구간 왼쪽으로 들어간다. 겹침이 10초면 대개 무해하다. 그 10초가 운전자 확인을 기다리다 10분이 되면 다른 얘기다.
어느 쪽을 고르든 문서화하라. 순환 중 두 펌프가 10초간 함께 도는 것을 보는 운전자는 이것이 fault가 아니라 진행 중인 make-before-break 교체임을 HMI에서 확인할 수 있어야 한다.
Standby 기동은 빠르고 독립적이어야 한다
Standby의 존재 이유는 failover다. 그 기동 조건은 방금 실패한 바로 그 로직에 의존해서는 안 된다. 다음 중 하나로 standby 기동을 트리거하라.
- Lead(또는 lag)가 기동 타이머 안에 running을 증명하지 못함.
- 운전 중인 duty 펌프가 예기치 않게 run feedback을 잃음.
- Lead가 running이라고 보고하는데도 압력이 계속 떨어지는 등, 공정 변수가 정상 lead/lag 밴드를 벗어난 standby-demand 설정값을 넘음.
마지막 조건은 펌프가 running이라고 말하지만 실제로는 유체를 옮기지 않는 고약한 경우를 잡는다. 커플링 파손, 토출 밸브 닫힘, deadhead 펌프 같은 경우다. 레벨이나 압력이 반응하지 않는 것이 종종 유일한 정직한 신호다.
Standby가 정상 변동 중에 들락날락 chattering 하지 않도록, standby의 demand 설정값을 lead/lag 제어 밴드 바깥에 명확히 두어라.
Standby 기동은 event가 아니라 alarm이다. 정상 운전에서는 일어나지 않아야 하고, 일어났으면 누가 뭔가 해야 한다. ISA-18.2(국제판은 IEC 62682)의 rationalization 단계가 요구하는 게 이것이다 — alarm마다 설정값, 우선순위, 운전자 대응, 미조치 시 결과를 문서로 붙이는 것. 'Standby 기동'에 운전자 대응을 적으려면 왜 기동했는지가 화면에 있어야 한다. 반대로 예정된 순환이 정상 완료된 건 alarm이 아니라 event log다. 이 둘을 같은 우선순위로 올리는 현장이 많은데, 그러면 EEMUA 191이 제시하는 정상 운전 평균 10분에 1건이라는 alarm 부하 목표부터 깨진다.
펌프가 싸우지 않도록 설정값을 계단식으로
여러 duty 펌프로 레벨이나 압력을 제어할 때는 각 단계마다 자기 start/stop 지점을 주고 단계 사이에 deadband를 둬라.
| 단계 | Start | Stop |
|---|---|---|
| Lead | 40% | 60% |
| Lag | 30% | 55% |
| Standby | 20% | 50% |
Lag는 lead가 밴드를 유지하지 못할 때(레벨이 계속 30%까지 떨어질 때)만 기동한다. 겹치거나 너무 좁은 설정값은 펌프가 서로에 대해 start/stop 하게 만든다. Start 시도 제한이나 anti-cycle 타이머를 추가하기 전에 deadband를 먼저 넓혀라. 대부분의 "펌프 hunting" 신고는 로직 결함이 아니라 그냥 설정값이 너무 가까운 것이다.
설정값이 맞더라도 순간적 수요 스파이크가 모터를 급속 사이클링 시키지 못하도록, 펌프마다 최소 운전(minimum-run) 및 최소 휴지(minimum-rest) 타이머를 함께 두어라.
전체 상태를 HMI에서 읽을 수 있게 하라
운전자는 순환 로직을 볼 수 있을 때만 신뢰한다. 펌프 그룹 faceplate에 최소한 다음을 표시하라.
- 각 펌프의 현재 역할(Lead / Lag / Standby / Unavailable), 역할 태그로 구동.
- 펌프별 운전 시간과 순환 임계값, 듀티 분배가 보이도록.
RotationPending과 그 이유("운전 시간 차 26h > 24h, 저수요 대기 중").- 펌프가 unavailable인 이유(모드, fault, 통신, rest 타이머) — 빨간 상자 하나가 아니라 이유 문자열 하나로.
- 권한으로 게이트되고 로그로 남는 수동 "지금 순환" 및 "펌프 N을 lead로 강제" 제어.
Standby가 왜 기동하지 않았는지 알아내려고 운전자가 제어 엔지니어에게 전화해야 한다면, 실패한 것은 운전자가 아니라 화면이다.
시운전 체크리스트
인계 전에, 종이 위가 아니라 실제로 펌프를 돌려가며 각 경우를 증명하라.
- 운전 시간 균등화: 차이를 강제로 만들고 순환이 요청되어 안전한 시점에 완료되는지 확인.
- 부하 중 순환이 의도한 make-before-break 또는 수요-0 패턴을 쓰며 헤더 저하가 없는지.
- Standby가 lead fail-to-prove, 예기치 않은 run feedback 상실, standby-demand 설정값에서 기동하는지.
- Deadhead 펌프 경우: 펌프가 "running"이라고 보고하는데 공정 변수가 계속 흐를 때도 standby를 투입하는지.
- Faulted 펌프가 깔끔히 빠지고, fault 해제 후 lead가 아니라 standby로 재진입하는지.
- 펌프 통신 상실 시 unavailable로 표시되어 역할 배정에서 제외되는지.
- 최소 운전/최소 휴지 타이머가 수요 스파이크 중 급속 사이클링을 막는지.
- 모든 역할, 운전 시간, 대기 중 순환, unavailable 이유가 PLC를 열지 않고도 HMI에서 보이는지.
순환 로직은 데모에서는 잘 돌다가 여섯 달 뒤 실제 failover 때 모두를 놀라게 한다. 그럴 때 해결책은 거의 항상 더 영리한 로직이 아니다 — available 정의가 너무 느슨했거나, 아무도 수요로 게이트하지 않아 순환이 부하 중에 터진 것이다. 이 둘만 제대로 잡으면 나머지 설비는 알아서 얌전해진다.