Symbol은 초록인데 shaft는 멈춰 있다
Overview 화면의 pump symbol이 초록색이다. 운전자는 방금 기동했다고 한다. MCC에 내려가 보면 starter contactor가 열려 있다. 전류도 없고 축도 안 돈다. HMI는 버튼을 누른 순간 start command bit만 보고 초록으로 바뀌었다. 설비가 아니라 클릭을 보여준 것이다.
이건 시운전에서 가장 자주 잡는 command 확인 결함이고, 원인은 하나다. 운전자가 무엇을 요청했는지로 symbol을 칠하고, 설비가 무엇을 증명했는지로 칠하지 않은 것. 클릭은 요청일 뿐이다. PLC, drive, actuator, vendor controller에서 feedback이 돌아오기 전까지는 아무것도 완료가 아니다.
명령마다 전체 경로를 그리고, 지금 화면이 실제로 어느 링크를 보여주는지 정직하게 확인한다.
- 운전자가 HMI control을 누른다.
- HMI가 command bit, command word, setpoint를 쓴다.
- PLC가 mode, permissive, interlock으로 accept 또는 reject한다.
- Field device가 움직이거나 상태를 바꾼다.
- Feedback이 명령 결과를 증명한다.
- HMI가 success, timeout, reject reason, uncertain을 보여준다.
Symbol이 2단계에서 바뀐다면, 3~5단계가 실패할 때마다 거짓말하는 화면을 만든 것이다. ISA-101(ANSI/ISA-101.01)의 state 표시 지침도 같은 말을 한다. 그래픽은 실제 공정 상태를 나타내야 하며, command state와 feedback state는 같은 것이 아니다.
Symbol은 feedback으로 몰아라
Running은 running feedback에서 온다. Open은 open limit switch나 actuator position에서 온다. 2초 전에 누군가 Open을 눌렀다는 사실에서 오는 게 아니다. Recipe-load-complete는 화면 타이머가 아니라 controller의 sequence state에서 온다.
중요한 것은 command state와 feedback state를 따로 보여준다. 이 습관 하나가 야간 운전자에게 "PLC가 내 명령을 아예 못 받았다"와 "PLC는 받았는데 valve가 안 움직였다"를 구분하게 해 준다. 원인도 조치도 완전히 다른 두 문제다.
Device class별로 잡는 tag 묶음:
| 장치 | Command tag | Feedback tag | Diagnostic tag |
|---|---|---|---|
| Motor | Start, stop, reset | Running, stopped, faulted | Local mode, overload, permissive missing |
| Valve | Open, close | Opened, closed, traveling | Travel timeout, air pressure low, manual override |
| Drive | Run, stop, speed setpoint | Running, actual speed, fault | Not ready, interlock, speed reference source |
| Package skid | Start seq, stop seq | Sequence state, complete, aborted | Step number, reject code, active hold |
| Robot / tool | Remote command, recipe select | Busy, ready, selected recipe | Host mode, alarm code, command reject |
Valve 행에 Opened와 Closed feedback이 둘 다 있는 것을 보라. "not open"인 valve와 "closed"인 valve는 다르다. Open limit만 배선하고 closed를 그 부재로 추정하면, 이동 중인 valve와 고장 난 limit switch와 진짜 닫힌 valve가 화면에서 전부 같아 보인다.
Momentary와 maintained — 하나로 정하고 edge는 PLC가 소유하게
Momentary command는 pulse이고, maintained command는 다른 상태가 바뀔 때까지 true로 남는다. 한 faceplate 안에 둘을 섞으면 아무도 재현 못 하는 결함이 나온다.
내 기준은 이렇다. One-shot 생성은 PLC가 소유한다. HMI가 깨끗한 pulse를 그린다고 믿는 대신 controller 안에서 command bit에 R_TRIG(IEC 61131-3)를 건다. HMI scan과 network update 주기(보통 250 ms~1초)가 짧은 pulse를 삼켜 버리면 운전자는 자기 press가 사라진 걸 영영 모른다. 느린 설비는 명시적 request/acknowledge handshake를 쓰고, request는 임의의 화면 delay 뒤가 아니라 PLC가 accept할 때 clear한다.
전형적인 maintained-command 함정이 있다. Start bit가 motor 기동 후에도 true로 남는다. 나중에 fault가 trip하고, 운전자가 reset하고, permissive가 돌아오면 — 오래된 command가 아직 latch돼 있어서 motor가 혼자 다시 시작된다. 아무도 버튼을 안 눌렀다. Trip 후 latch된 command가 다시 실행돼도 되는지 PLC에서 정하고, 그 결정을 문서화하고, HMI가 그 상태를 절대 숨기지 못하게 한다.
Timeout은 template 기본값이 아니라 실제 행정으로 잡아라
Timeout은 faceplate library가 아니라 장치에 속한다. 작은 solenoid는 1초도 안 돼 위치를 증명한다. 24인치 pneumatic damper는 20~40초 stroke가 필요할 수 있다. Pump는 motor feedback이 true가 된 뒤에도 토출 압력을 만들 시간이 필요하다. 그래서 "running" timeout과 "pressure reached" timeout은 서로 다른 시계다.
Template이 그렇게 나왔다는 이유로 모든 object에 같은 10초 timeout을 붙이지 마라. Device class별 parameter로 관리한다. Command마다 못 박을 것: 기대 feedback 조건, 정상 응답 시간, 허용 최대 시간, timeout 시 나올 message, 운전자 retry 허용 여부, 시계가 만료됐을 때 PLC가 safe state를 강제해야 하는지. Travel timeout은 보통 alarm으로 올릴 값이다. 조용한 status bit가 아니라, 다른 alarm처럼 ISA-18.2 rationalization 아래에서 priority와 운전자 응답 문구를 붙여 다룬다.
"Command failed"는 진단이 아니다
Command는 네 가지로 실패한다. HMI write가 도달하지 못함, PLC가 거부함, device가 안 움직임, feedback이 bad quality. 넷을 "command failed" 하나로 뭉치면 모두의 시간이 낭비된다. 실제 이유를 보여줘라.
- Remote/automatic mode 아님
- 필요한 permissive 없음
- Interlock 또는 trip active
- 이미 요청한 상태에 있음
- Command source가 local panel / MCC / vendor controller / MES
- Communication quality bad
- Safety system reset 안 됨
- 다른 sequence가 장치 점유 중
"valve not remote"는 운전자를 몇 초 만에 움직이게 하고, "open failed"는 전화벨을 울린다. PLC의 active reject bit를 faceplate에 바로 띄워라. 새벽 2시에 문제를 보는 사람이 이유를 알려고 PLC에 online으로 붙을 일은 없어야 한다.
Setpoint write는 display 변경이 아니다
Setpoint write는 제어 동작이고, start command와 같은 엄격함을 받아야 한다. Write가 commit되기 전에:
- HMI scale과 PLC scale이 맞다 (틀리면 50%가 5000이 된다)
- 입력창과 표시값 둘 다 unit이 보인다
- Write 전에 min, max, decimal precision을 client에서 제한한다
- Controller에서 읽어 온 값이 보낸 값과 맞다
- Controller가 값을 reject할 수 있고 이유를 말한다
- 필요한 경우 audit log에 old value, new value, operator, timestamp, station이 남는다
Read-back은 생각보다 중요하다. 150을 자기 한계 100으로 clamp하고 아무 말 없는 PLC는 운전자가 loop가 150이라고 믿게 만든다. Recipe나 batch 값은 command ID나 transaction number를 붙여서, 진짜 새 command와 화면 refresh, 늦게 온 acknowledgement를 구분한다.
Quality가 bad이면 추측하지 말고 그렇게 말하라
Feedback quality가 bad이면 HMI는 아무것도 정직하게 확인할 수 없다. Command-write quality가 bad이면 요청이 controller에 도달했는지조차 모른다. 두 경우 모두 정의된 동작이 필요하고, OPC UA가 이미 어휘를 준다. StatusCode는 Good, Uncertain, Bad이며, stale feedback은 편안한 초록색 "stopped"가 아니라 Uncertain으로 칠해야 한다.
대부분 설비에서 내가 잡는 기준:
- Control-path quality가 bad이면 start, open, mode command를 막는다.
- Write path가 독립적으로 정상임이 확인되면 stop 또는 safe command는 허용한다. 통신 잠깐 끊겼다고 모든 버튼을 잠그는 게 오히려 덜 안전할 수 있다.
- Stale feedback은 uncertain으로 보이고, 정상 stopped/closed로는 절대 안 보인다.
- Stroke 중 feedback이 bad가 됐다는 이유만으로 timeout을 조용히 clear하지 않는다.
- 통신 실패는 device movement 실패와 별도로 기록한다.
핵심은 만능 규칙이 아니라, 실제로 시험한 명시적 규칙이다.
시운전: 일부러 깨뜨려라
가능하면 실제 feedback으로 시험한다. Simulation은 logic 확인에는 좋지만, 배선 오류와 실제 설비에서만 나오는 actuator 특성을 숨긴다.
- 한 번 눌러서 PLC가 정확히 request 하나만 보는지 확인한다. 연속 write 폭주가 아니라.
- Symbol이 실제 feedback 변경 후에만 바뀌는지 확인한다.
- Permissive를 하나 빼고 reject reason 문구를 확인한다.
- Feedback을 bad quality로 만들고 표시 상태를 본다.
- Actuator를 막고(또는 움직임 없음을 만들고) timeout 동작을 끝까지 확인한다.
- Local mode로 바꾸고 remote command가 막히거나 명확히 reject되는지 본다.
- Command pending 중에 HMI client와 alarm server를 restart한다.
- 끝나고 audit log와 event record를 읽는다.
Sequence는 abort, pause, reset, retry를 시험한다. 거의 모든 command 결함은 happy path 밖에 산다. 그런데 대부분의 factory acceptance test는 바로 그 happy path에 시간을 쓴다.
좋은 command faceplate는 운전자가 묻기 전에 세 가지에 답한다. 무엇을 요청했는지, 설비가 실제로 무엇을 증명했는지, 따라오지 않았다면 왜인지. Command contract, class별 timeout 값, feedback 정의, reject-code list를 HMI 표준 옆에 둔다. 이게 바로 아무도 당신에게 전화하기 전에 멈춘 valve를 움직이게 하는 문서다.