1주차 : OpenPLC · Node-RED · FUXA로 Modbus 기반 아키텍처 기초 다지기

OpenPLC, Node-RED, FUXA가 각각 어떤 역할을 하며 Modbus/TCP로 어떻게 연결되는지 한눈에 보이는 개념도 예시입니다.

1주차 : OpenPLC · Node-RED · FUXA로 Modbus 기반 아키텍처 기초 다지기

한눈에 보는 요약

1주차의 목표는 “누가 서버이고, 누가 클라이언트인지”를 명확히 이해하고, Modbus 주소(코일·레지스터)와 포트, 폴링 주기 같은 기본 값을 내 환경 기준으로 고정하는 것입니다.

OpenPLC는 Modbus/TCP 서버(포트 5020) 역할을 하고, Node-RED와 FUXA는 이 서버에 접속하는 클라이언트로 동작합니다. 따라서 IP·포트·Unit ID(슬레이브 ID)·주소 오프셋을 정확히 맞추는 것이 핵심입니다.

1회차에서는 OpenPLC / Node-RED / FUXA의 역할과 포트를 확인하고 아키텍처를 그림으로 정리하고, 2회차에서는 Modbus Coil/DI/IR/HR, Function code를 실제 Read 노드로 실습합니다.

3회차에서는 주소 체계(0-based vs 1-based)를 이해하고 OpenPLC 변수 1~2개를 만들어 FUXA와 Node-RED에서 같은 값이 보이도록 교차 검증하며, 마지막으로 “내 환경 기준 주소 규칙 표”를 만들어 이후 주차의 기준점을 확보합니다.

목차


핵심 포인트

  • OpenPLC는 Modbus/TCP 서버(포트 5020)로서 데이터를 “제공”하고, Node-RED와 FUXA는 이 서버에 접속해 읽고 쓰는 클라이언트입니다.
  • Modbus는 Coil, Discrete Input, Input Register, Holding Register 네 가지 데이터 영역을 가지며, 각 영역마다 사용 가능한 Function code가 다릅니다.
  • 주소 체계는 도구마다 0-based(첫 주소를 0으로 보는 방식)와 1-based(첫 주소를 1로 보는 방식)가 섞여 있어, 이를 명확히 정리하지 않으면 값이 한 칸씩 밀려 보이는 문제가 자주 발생합니다.
  • 1주차 안에 “내 환경 기준 주소 규칙 표”를 만들어두면, 이후 HMI 화면을 늘리거나 로직을 복잡하게 만들 때도 헷갈리지 않고 확장할 수 있습니다.
  • 폴링 주기와 타임아웃 설정은 통신 안정성에 직접 영향을 주므로, 초반에 적절한 값(예: 500~1000ms, 타임아웃 2~5초)을 정해놓고 테스트하는 것이 좋습니다.

상세 설명

1. 1주차 전체 목표와 회차별 구성

1주차의 가장 큰 목표는 “도구 이름을 외우는 것”이 아니라, 데이터가 어떤 경로를 통해 움직이는지 머릿속에 그림을 그릴 수 있게 되는 것입니다. 이를 위해 총 3회차로 나누어 학습합니다.

각 회차의 목표와 실습, 산출물은 아래와 같습니다.

회차 핵심 주제 필수 실습 산출물 / 체크
1회차 아키텍처 이해: OpenPLC / Node-RED / FUXA 역할 분리 서버/클라이언트 구분, 포트·주소(1880/8080/1881/5020) 확인 시스템 구성도 1장, 점검 체크리스트
2회차 Modbus 기본: Coil/DI/IR/HR, Function code 개념 Node-RED Modbus Read로 코일·레지스터 읽기 (주기·타임아웃 변경) 읽기 성공 화면 캡처 + Debug 로그 스크린샷
3회차 주소 체계(0-based vs 1-based) & 태그-주소 매핑 OpenPLC 변수 1~2개 생성 후, FUXA·Node-RED에서 값 교차 검증 “내 환경 기준” 주소 규칙 표(자체 기준표)

이 구조를 머릿속에 두고 나머지 내용을 읽으면, 각 개념이 어느 회차에서 어떻게 쓰이는지 자연스럽게 연결됩니다.

2. OpenPLC / Node-RED / FUXA 역할과 포트 정리

먼저 “누가 서버이고, 누가 클라이언트인가”를 명확히 구분해야 합니다. Modbus/TCP에서 서버는 포트를 열어두고 요청을 기다리는 쪽이고, 클라이언트는 그 포트로 접속해 데이터를 읽거나 쓰는 쪽입니다.

  • OpenPLC
    • 역할: Modbus/TCP 서버 (PLC 역할)
    • 주요 포트 예시:
      • 웹 관리 화면: 8080 (프로그램 업로드, 매핑 설정 등)
      • Modbus/TCP 서버: 5020 (클라이언트가 접속하는 포트)
    • 설명: 실제 PLC 대신 PC에서 동작하는 가상 PLC로, Ladder/ST 코드 실행과 I/O 맵핑을 담당합니다.
  • Node-RED
    • 역할: Modbus 클라이언트 + 데이터 허브(오케스트레이션)
    • 주요 포트 예시:
      • 에디터(UI): 1880
    • 설명: Modbus 노드를 사용하여 OpenPLC에 주기적으로 접속해 Coil/레지스터를 읽고 쓰며, 다른 시스템(HTTP, MQTT 등)과 연계할 때도 중심 역할을 합니다.
  • FUXA
    • 역할: 웹 기반 HMI/SCADA 클라이언트
    • 주요 포트 예시:
      • 에디터/런타임: 1881 (설치 환경에 따라 다를 수 있음)
    • 설명: 브라우저에서 동작하는 HMI 도구로, 태그(변수)를 Modbus 주소에 매핑해 계기판, 버튼, 알람 화면 등을 구성합니다.

1회차에서는 위 세 도구를 각각 사각형 블록으로 그리고, IP·포트·프로토콜(Modbus/TCP)을 화살표와 함께 표시한 “시스템 구성도 1장”을 직접 만드시는 것을 권장드립니다. 이 그림 하나만 제대로 그려도 이후 디버깅이 훨씬 쉬워집니다.

3. Modbus 기본: Coil/DI/IR/HR와 Function code

2회차의 핵심은 Modbus 데이터 모델을 “어디에 무엇을 저장할지” 관점에서 이해하는 것입니다. Modbus에는 대표적으로 다음 네 가지 영역이 있습니다.

영역 이름 약어 번호 대역 (관례) 읽기/쓰기 대표 Function code 주요 용도
Coil CO 0xxxx R/W 01(Read), 05/15(Write) 디지털 출력(릴레이, 램프, 모터 On/Off 등)
Discrete Input DI 1xxxx Read only 02(Read) 디지털 입력(센서 접점, 스위치 상태)
Input Register IR 3xxxx Read only 04(Read) 아날로그 입력(온도, 압력, 유량 등 측정값)
Holding Register HR 4xxxx R/W 03(Read), 06/16(Write) 설정값, 아날로그 출력, 파라미터 저장

실습에서는 Node-RED의 Modbus Read 노드를 사용해 Coil과 Holding Register를 각각 읽어보고, 주기(poll rate)와 타임아웃을 바꿔보면서 통신이 어떻게 달라지는지 경험해 보는 것이 좋습니다. 이때 Debug 노드를 연결해 실제로 읽힌 값이 어떻게 보이는지 캡처해 두면, 이후 문제 발생 시 비교 기준으로 활용할 수 있습니다.

4. 주소 체계(0-based vs 1-based)와 태그 매핑

3회차에서 가장 중요한 키워드는 바로 “주소 체계 통일”입니다. 같은 Modbus 서버(OpenPLC)에 접속하더라도, 도구마다 주소를 0부터 보느냐 1부터 보느냐가 달라질 수 있습니다.

  • 0-based: 첫 번째 Coil을 0으로 보고, 두 번째를 1로 보는 방식
  • 1-based: 첫 번째 Coil을 1로, 두 번째를 2로 보는 방식

예를 들어, 어떤 도구에서는 Holding Register 주소를 “40001”처럼 1-based로 표기하고, 다른 도구에서는 같은 위치를 “0번 HR”로 입력하게 되어 있을 수 있습니다. 이 차이를 이해하지 못하면 값이 한 칸씩 밀려서 보이는 현상이 발생합니다.

따라서 3회차에서는 다음 순서를 추천합니다.

  1. OpenPLC에서 간단한 변수 1~2개를 생성합니다. (예: Start 버튼, 온도 값 등)
  2. 각 변수를 Coil 또는 Holding Register 등 Modbus 주소에 맵핑합니다.
  3. Node-RED에서 해당 주소를 읽는 Modbus Read 노드를 만들고, 값이 정상적으로 읽히는지 확인합니다.
  4. FUXA에서도 동일한 주소에 태그를 연결하고, 화면에서 같은 값이 보이는지 교차 검증합니다.

이 과정을 거친 뒤, “내 환경 기준 주소 규칙 표”를 만들어두면 좋습니다. 아래 예시 표처럼, 앞으로 쓸 태그와 주소 규칙을 한눈에 볼 수 있도록 정리해 두십시오.

도구·주소 규칙 표 예시

아래는 1주차 마지막에 정리해 두기 좋은 “내 환경 기준 주소 규칙 표” 예시입니다. 실제 프로젝트에서는 본인 환경에 맞게 내용을 수정해 사용하시면 됩니다.

태그 이름 용도 설명 데이터 영역 OpenPLC 기준 주소 주소 체계 Node-RED 입력값 FUXA 입력값 비고
BTN_START 설비 시작 버튼 상태 Coil 0번 Coil 0-based 주소 0, FC=01 주소 0, FC=01 디지털 입력, Read only
SET_TEMP 설정 온도 값(°C) Holding Register 10번 HR 0-based 주소 10, FC=03/16 주소 10, FC=03/16 스케일링 (x10) 적용

이 표를 프로젝트 초기에 잘 만들어 두면, 팀원 간 의사소통이 쉬워지고 “여기 주소가 몇 번이었지?” 같은 질문을 크게 줄일 수 있습니다.

5. 자주 막히는 포인트와 점검 체크리스트

1주차에 가장 많이 막히는 지점은 다음 세 가지입니다.

  • 주소 오프셋: 0-based와 1-based 혼동으로 값이 한 칸 밀려 보임
  • Unit ID(슬레이브 ID): 서버 측(OpenPLC)과 클라이언트(Node-RED/FUXA)의 설정 값 불일치
  • 폴링 주기/타임아웃: 지나치게 짧거나 긴 설정으로 인한 통신 실패, 지연

1회차에 만들 점검 체크리스트에는 적어도 아래 항목들이 들어가면 좋습니다.

  • OpenPLC Modbus 서버 IP와 포트(5020)가 명확히 기록되어 있는가?
  • Node-RED Modbus 노드와 FUXA 태그 설정에 동일한 IP·포트·Unit ID가 입력되어 있는가?
  • 주소 체계(0-based/1-based)를 도구별로 어떻게 볼지 문서화했는가?
  • 폴링 주기와 타임아웃을 합리적인 값(예: 500~1000ms, 타임아웃 2~5초)으로 맞추었는가?

따라하기: 1주차 실습 단계별 가이드

  1. 환경 확인 및 포트 점검 (1회차)
    OpenPLC, Node-RED, FUXA가 모두 실행되어 있는지 확인합니다. 브라우저에서 각각 :8080, :1880, :1881 포트로 접속해 관리 화면이 열리는지 테스트합니다. 이때 IP와 포트 번호를 메모해 두고, “시스템 구성도 1장”에 기입합니다.
  2. 서버/클라이언트 역할 구분해서 그리기 (1회차)
    OpenPLC를 가운데에 두고, 왼쪽에 Node-RED, 오른쪽에 FUXA를 그립니다. OpenPLC에는 “Modbus/TCP Server (5020)”이라고 적고, Node-RED와 FUXA에는 “Modbus Client”라고 적은 뒤, 화살표로 데이터 흐름을 표시합니다. 이 그림이 1주차의 핵심 산출물입니다.
  3. Node-RED에서 첫 Modbus Read 실습 (2회차)
    Node-RED 에디터(1880)에 접속해 Modbus Read 노드를 플로우에 배치하고, OpenPLC IP와 5020 포트를 설정합니다. Coil 또는 Holding Register 중 하나를 선택해 주기(예: 1000ms)와 타임아웃(예: 2000ms)을 설정하고, Debug 노드를 연결해 실제로 값이 들어오는지 확인합니다. 성공 화면을 캡처해 두십시오.
  4. Modbus 데이터 영역별 Read 테스트 (2회차)
    Coil, DI, IR, HR 각 영역에서 하나씩 주소를 골라 Read 테스트를 해 봅니다. 모든 영역을 한 번씩 경험해 보면, Function code 차이를 감각적으로 이해할 수 있습니다. 각 테스트 결과를 간단한 표나 노트로 정리해 두면 좋습니다.
  5. OpenPLC 변수 생성 및 매핑 (3회차)
    OpenPLC 웹 화면(8080)에서 간단한 변수 예를 들어 BTN_START(BOOL), SET_TEMP(INT) 등을 생성하고, 각각 Coil과 Holding Register에 매핑합니다. 매핑된 주소(예: Coil 0, HR 10)를 명확히 기록합니다.
  6. Node-RED와 FUXA에서 값 교차 검증 (3회차)
    Node-RED의 Modbus Read 노드와 FUXA의 태그 설정에 동일한 주소를 입력한 뒤, OpenPLC 프로그램에서 변수를 On/Off 하거나 값을 변경해 봅니다. 두 도구에서 동시에 같은 값이 보이는지 확인하고, 만약 다르다면 주소 오프셋이나 Unit ID를 우선 의심해 봅니다.
  7. “내 환경 기준 주소 규칙 표” 작성 (3회차)
    위 실습에서 사용한 태그들을 중심으로, 앞서 제시한 형식에 맞춰 나만의 주소 규칙 표를 만듭니다. 이 표에는 태그 이름, 용도, 영역, 주소, 0/1-based 기준, Node-RED/FUXA 입력 방법 등이 포함되어야 합니다. 이 표가 이후 모든 HMI·로직 개발의 기준 문서가 됩니다.

코드 예시: Node-RED Modbus Read 설정 샘플

[
  {
    "id": "modbus-read-coil0",
    "type": "modbus-read",
    "z": "flow1",
    "name": "Read Coil 0",
    "dataType": "Coil",
    "adr": "0",
    "quantity": "1",
    "rate": "1000",
    "server": "modbus-server-openplc",
    "x": 300,
    "y": 120,
    "wires": [["debug-coil0"]]
  },
  {
    "id": "modbus-server-openplc",
    "type": "modbus-client",
    "z": "",
    "name": "OpenPLC Server",
    "clienttype": "tcp",
    "tcpHost": "192.168.0.10",
    "tcpPort": "5020",
    "unit_id": 1,
    "reconnectOnTimeout": true,
    "timeout": 2000
  }
]

위 JSON 예시는 Node-RED에서 Modbus Read 노드를 사용해 OpenPLC(192.168.0.10:5020)의 Coil 주소 0을 1초마다 읽는 설정 구조를 단순화해 표현한 것입니다. 실제 프로젝트에서는 자신의 IP와 포트, Unit ID에 맞게 값을 수정하셔야 합니다. 특히 adr 필드(여기서는 0)가 0-based인지 1-based인지, 그리고 unit_id 값이 OpenPLC 측 설정과 일치하는지 반드시 확인해야 통신 오류를 줄일 수 있습니다.


추가로 생각해볼 점

  • 1주차에 만든 시스템 구성도와 주소 규칙 표는 버전 관리를 고려해 Git 등으로 함께 관리하면, 여러 사람이 협업할 때 큰 도움이 됩니다.
  • IP 주소가 DHCP로 할당되는 환경이라면, OpenPLC/Node-RED/FUXA가 설치된 장비는 가급적 고정 IP를 사용하도록 네트워크 담당자와 미리 협의하는 것이 좋습니다.
  • 이후 주차에서 MQTT, 데이터베이스, 클라우드 연계를 추가할 계획이라면, Node-RED를 “데이터 허브”로 두고 인터페이스를 어떻게 나눌지 미리 구상해 두면 설계 변경 비용을 줄일 수 있습니다.
Reactions

댓글 쓰기

0 댓글