콘텐츠로 이동

PLC (Modbus TCP)~

AoT는 Modbus TCP로 PLC, 릴레이 보드, 게이트웨이, 계량기와 통신합니다. 읽기는 Modbus TCP (PLC) 입력으로, 제어는 On/Off: Modbus TCP Coil (PLC) 출력으로 합니다. 둘 다 기본 내장이라 따로 설치할 것이 없습니다.

Modbus에는 인증도 암호화도 없습니다

네트워크로 장치에 닿을 수 있는 사람은 누구나 모든 레지스터를 읽고 쓸 수 있습니다. PLC는 반드시 격리망(VLAN 또는 방화벽 allow-list)에 두고, 인터넷에 노출하지 마십시오.

시작하기 전에~

벤더 문서에서 레지스터 맵을 확보하십시오. 다루려는 값마다 다음이 필요합니다.

  • 어느 테이블에 있는지 — coil, discrete input, holding register, input register
  • 주소
  • 16비트를 넘는 값이라면 데이터 타입과 워드 순서

첫 연결에서 거의 모두가 걸리는 두 가지가 있습니다.

  • 주소 기준. 벤더 문서는 1부터 세는 주소를 쓰는 경우가 많습니다(40001이 holding register 0, 00001이 coil 0). AoT는 실제 통신에 쓰이는 0부터 세는 주소를 씁니다.
  • 워드 순서. 32비트 값에서 상위 워드를 먼저 두는 벤더와 하위 워드를 먼저 두는 벤더가 갈립니다. 주소는 맞는데 값이 엉뚱하면 대부분 이것입니다 — 워드 순서 옵션을 반대로 바꿔 다시 읽어 보십시오.

값 읽기~

Modbus TCP (PLC) 입력을 추가하고 다음을 설정합니다.

옵션 설명
호스트 / 포트 장치 주소. 502가 표준 포트입니다
Unit ID 장치를 직접 지정할 때는 보통 1, 시리얼 게이트웨이 뒤에 있으면 그 슬레이브 주소
타임아웃 / 재시도 느린 장치가 아니면 1.0초·1회 그대로 두십시오. 타이밍 참조
주기 폴링 간격(초). 1~5초로 시작해 PLC 부하를 보며 조정하십시오

측정 개수를 읽을 레지스터 수만큼 지정한 뒤, 채널마다 다음을 설정합니다.

채널 옵션 설명
레지스터 종류 Coil과 Discrete Input은 비트, Holding·Input Register는 16비트 워드입니다
레지스터 주소 해당 테이블 안에서 0부터 세는 주소
데이터 타입 코일·접점은 Bit, 레지스터는 int16/uint16/int32/uint32/float32
워드 순서 32비트 타입에만 해당. 값이 이상하면 반대로 바꿔 보십시오
배율 원본 값에 곱합니다. 0.1 단위로 보고하는 장치라면 0.1

비트는 1.0/0.0으로 저장되므로 다른 측정값과 똑같이 그래프로 보고 함수에서 쓸 수 있습니다.

읽기에 실패하면 그 채널에는 아무 값도 저장하지 않습니다. 그 침묵이 곧 장치가 두절됐다는 신호이며, 임시값을 채워 넣으면 오히려 두절을 가리게 됩니다. 채널 하나가 실패해도 나머지 채널은 계속 읽습니다.

코일 제어~

On/Off: Modbus TCP Coil (PLC) 출력을 추가합니다. 호스트·포트·Unit ID·타임아웃·재시도의 의미는 입력과 같습니다. 채널 수를 제어할 코일 개수만큼 지정하고 저장하면 코일당 한 행이 생기며, 각 행에는 코일 주소만 넣으면 됩니다.

AoT는 명령을 보낼 때마다 코일에 쓴 뒤 곧바로 다시 읽습니다. 그 재조회가 곧 확인입니다.

  • 재조회 값이 명령과 같으면, 채널 상태는 추정이 아니라 장치가 확인해 준 값이 됩니다.
  • 값이 다르면 명령을 실패로 알립니다. 보통 PLC 프로그램이 그 코일을 직접 제어하고 있거나, 주소가 틀린 경우입니다.
  • 장치에 닿지 못하면 명령이 실패하고 채널은 직전 상태를 유지합니다 — PLC가 받아들인 적 없는 상태가 화면에 뜨는 일은 없습니다.

재조회는 레지스터를 확인할 뿐, 릴레이를 확인하지는 않습니다

코일을 다시 읽는 것은 PLC가 값을 받아들였다는 증명입니다. 릴레이가 실제로 움직였는지, 배선이 멀쩡한지는 증명하지 못합니다. 그것까지 확인하려면 피드백 접점을 배선해 별도 입력으로 읽고 비교해야 합니다.

시작 상태종료 상태는 다른 출력과 동일하게 동작합니다. PLC에서는 시작 상태를 "아무것도 안 함"으로 두는 편이 대개 맞습니다 — 그러면 AoT가 코일을 읽어 PLC가 이미 가진 상태를 그대로 받아들이고, 덮어쓰지 않습니다.

데몬이 막 시작된 직후에는 채널이 잠시 "확인 불가"로 보입니다. AoT가 백그라운드에서 실제 상태를 읽는 동안이며, 읽지 못한 코일을 꺼져 있다고 단정하지 않기 위한 의도된 동작입니다.

연결 공유~

같은 호스트와 포트를 가리키는 입력과 출력은 자동으로 하나의 TCP 연결을 공유하고, 그 위의 요청은 순서대로 처리됩니다. 따로 설정할 것은 없으며, 덕분에 PLC 한 대에 여러 입력·출력을 붙여도 대부분의 장치가 걸어 둔 동시 연결 수 제한에 걸리지 않습니다.

알아 둘 점은 하나입니다. 타임아웃과 재시도는 장치 등록 항목별이 아니라 연결별입니다. 같은 호스트·포트를 공유하는 것들 중 가장 먼저 활성화된 쪽의 설정이 적용됩니다.

통신 상태~

PLC가 응답하지 않으면 별도 설정 없이 그대로 드러납니다.

  • 출력은 링크가 끊기는 즉시 그 PLC의 모든 채널이 오류로 표시됩니다. 명령을 보내지 않고 있어도 마찬가지입니다. 다만 프레임 하나 유실로는 부족하며, 연속 2회 실패해야 두절로 확정합니다.
  • 입력은 측정값의 신선도로 판정합니다. 폴링 주기가 여러 번 지나도록 새 측정이 없으면 통신 불가로 표시됩니다.

데몬은 장치가 통신 오류 상태로 바뀌거나 거기서 회복될 때 관리자 이메일도 보냅니다. 알림 문서를 참조하십시오.

타이밍~

요청 1회는 최대 타임아웃 × (재시도 + 1), 연결은 최대 타임아웃만큼 걸립니다. 기본값(1.0초, 재시도 1회)이면 PLC에 닿지 못하는 명령이 약 3초 만에 포기합니다.

재시도를 올리면 응답 없는 장치가 붙잡는 시간이 그만큼 배로 늘어납니다. 제어 명령은 동기로 실행되므로, 재시도를 한 번 더 짜내는 것보다 이 곱이 데몬의 명령 처리 예산 안에 넉넉히 들어오게 두는 편이 중요합니다. 정말로 느린 장치라면 재시도가 아니라 타임아웃을 올리십시오.

문제 해결~

증상 유력한 원인
값이 크게 틀렸는데 일정하게 나옴 워드 순서, 또는 그 레지스터에 맞지 않는 데이터 타입
값이 10배·100배 어긋남 배율 미설정
읽기는 되는데 쓰기에서 불일치 오류 PLC 프로그램이 그 코일을 제어 중이거나, 코일 주소가 틀림
전부 타임아웃, 연결 자체가 안 됨 호스트·포트가 틀렸거나 방화벽이 연결을 버리는 중
연결은 되는데 모든 요청이 실패 Unit ID가 틀림
주소가 전부 하나씩 어긋남 벤더 문서가 1부터 세는 기준 — 1을 빼십시오

입력·출력의 디버그 로깅을 켜면 각 요청과 결과가 로그에 남습니다.