LS PLC 통신 실습 – Python으로 XGT FEnet & Modbus TCP 연결하기 (코드 포함)

LS PLC 통신 실습 – Python으로 XGT FEnet & Modbus TCP 연결하기 (코드 포함)

A

AutoHano

2026년 2월 16일

PLC 데이터를 엑셀에 손으로 옮기고 있다면, 이 글이 그 작업을 끝내줄 수 있습니다.

저도 예전에 현장에서 매일 아침 PLC 화면 보면서 수기로 데이터 옮겼습니다. "이걸 자동으로 못 하나?" 싶어서 Python으로 직접 연결해봤는데, 생각보다 간단했습니다. 한번 만들어 놓으니까 매일 30분씩 아끼더라고요.

개념이 궁금하시면 이전 글을 먼저 보세요.

→ LS PLC 통신 방법 비교 – Modbus TCP vs XGT 전용 프로토콜

여기서는 실제 코드를 다룹니다.

  • XGT FEnet — Python 기본 라이브러리만으로 연결 (socket, struct)

  • Modbus TCP — pymodbus 라이브러리 사용
  • 둘 다 실제 PLC에 연결해서 테스트 완료한 코드입니다.

    이 글에서 다루는 내용

  • 준비물 — PLC, PC, 네트워크 세팅

  • XGT FEnet 실습 — socket만으로 PLC 읽기/쓰기 (라이브러리 불필요)

  • Modbus TCP 실습 — pymodbus로 PLC 읽기/쓰기

  • 코드 비교 — 같은 데이터를 XGT vs Modbus로 읽을 때

  • 32비트 값 변환 — DWORD, FLOAT 처리

  • 트러블슈팅 — PLC 통신 연결 안 될 때 체크리스트

  • FAQ — 자주 묻는 질문 8가지
  • LS Electric XGK PLC – 이더넷 통신으로 Python에서 데이터 읽기


    준비물

    항목XGT FEnetModbus TCP
    PLCLS XGK/XGB/XGI + FEnet 모듈 (또는 내장 이더넷)LS XGK/XGB + Modbus 서버 설정
    PCPython 3.8 이상Python 3.8 이상 + pymodbus
    네트워크같은 서브넷 (이더넷 케이블)같은 서브넷 (이더넷 케이블)
    PLC 포트2004502

    공통 확인사항:

  • PLC IP 주소를 알고 있어야 합니다 (XG5000에서 확인)

  • PC와 PLC가 같은 네트워크에 있어야 합니다

  • 방화벽에서 해당 포트가 열려 있어야 합니다

  • Part 1: XGT FEnet – Python으로 PLC 데이터 읽기

    XGT FEnet이 좋은 이유 (다시 한번)

    별도 라이브러리 설치가 필요 없습니다. 개인적으로 이게 XGT FEnet의 가장 큰 장점이라고 생각합니다. 현장 PC에 뭔가 설치하는 게 쉬운 일이 아니거든요.

    Python 기본 socketstruct만 있으면 됩니다.

    PLC 쪽에서도 아무 설정 안 해도 됩니다. FEnet 모듈만 꽂혀 있으면 바로 통신 가능합니다.

    LS Electric XBL-EMTA FEnet 이더넷 통신 모듈

    위 사진이 FEnet 통신 모듈(XBL-EMTA)입니다. PLC 베이스에 장착하면 이더넷 통신이 가능해집니다.

    XGT FEnet 프로토콜 구조

    XGT FEnet은 TCP 소켓 위에 자체 프로토콜을 사용합니다.

    모든 패킷은 20바이트 헤더 + 응용 데이터로 구성됩니다.

    ┌──────────────────────────────────────────┐
    │ 헤더 (20 bytes) │
    ├──────────────────────────────────────────┤
    │ Company ID : "LSIS-XGT" (8 bytes) │
    │ Reserved : 0x0000 (2 bytes) │
    │ PLC Info : 0x0033 (2 bytes) │
    │ CPU Info : 0xA0 = XGK (1 byte) │
    │ Source : 0x33 = PC (1 byte) │
    │ Invoke ID : 순번 (2 bytes) │
    │ Data Length : 데이터 길이 (2 bytes) │
    │ Slot / Base : 0x00 (2 bytes) │
    ├──────────────────────────────────────────┤
    │ 응용 데이터 (N bytes) │
    ├──────────────────────────────────────────┤
    │ Command : 0x0054=읽기 (2 bytes) │
    │ Data Type : 0x0000 (2 bytes) │
    │ Reserved : 0x0000 (2 bytes) │
    │ Block Count : 블록 수 (2 bytes) │
    │ Var Name Len : 이름 길이 (2 bytes) │
    │ Var Name : "%MW100" 등 (N bytes) │
    │ Data Count : 읽을 개수 (2 bytes) │
    └──────────────────────────────────────────┘

    핵심은 Var Name 부분입니다. "%MW100"처럼 PLC 메모리 주소를 문자열 그대로 보냅니다.

    Modbus처럼 레지스터 번호를 쓰는 게 아니라, PLC 메모리 이름을 직접 보내는 겁니다.

    XGT FEnet Python 읽기 코드

    아래 함수 하나면 PLC에서 데이터를 읽을 수 있습니다.

    코드가 길어 보이지만, 핵심은 헤더 조립 → 전송 → 응답 파싱 세 단계입니다.

    import socket
    import struct


    def read_xgt(host: str, port: int, address: str, count: int = 1) -> list:
    """XGT FEnet으로 PLC 메모리 읽기

    Args:
    host: PLC IP 주소 (예: '192.168.0.10')
    port: 포트 번호 (기본 2004)
    address: PLC 메모리 주소 (예: '%MW100')
    count: 읽을 워드 수

    Returns:
    읽은 값 리스트
    """
    # 1) TCP 소켓 연결
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(3.0)
    sock.connect((host, port))

    # 2) 변수 이름을 ASCII 바이트로 변환
    var_name = address.encode('ascii')

    # 3) 응용 데이터 조립
    app_data = struct.pack('<H', 0x0054) # 명령: 읽기
    app_data += struct.pack('<H', 0x0000) # 데이터 타입: 개별
    app_data += struct.pack('<H', 0x0000) # Reserved
    app_data += struct.pack('<H', 1) # 블록 수: 1
    app_data += struct.pack('<H', len(var_name)) # 변수 이름 길이
    app_data += var_name # 변수 이름 ("%MW100")
    app_data += struct.pack('<H', count) # 읽을 개수

    # 4) 20바이트 헤더 조립
    header = b'LSIS-XGT' # Company ID (8 bytes)
    header += struct.pack('<H', 0x0000) # Reserved
    header += struct.pack('<H', 0x0033) # PLC Info
    header += struct.pack('<B', 0xA0) # CPU Info (XGK)
    header += struct.pack('<B', 0x33) # Source (PC)
    header += struct.pack('<H', 1) # Invoke ID
    header += struct.pack('<H', len(app_data)) # Data Length
    header += struct.pack('<B', 0x00) # Slot
    header += struct.pack('<B', 0x00) # Base

    # 5) 전송
    sock.sendall(header + app_data)

    # 6) 응답 수신 — 헤더 20바이트 먼저
    resp_header = b''
    while len(resp_header) < 20:
    resp_header += sock.recv(20 - len(resp_header))

    # 응답 데이터 길이 추출
    data_len = struct.unpack('<H', resp_header[16:18])[0]

    # 응답 데이터 수신
    resp_data = b''
    while len(resp_data) < data_len:
    resp_data += sock.recv(data_len - len(resp_data))

    # 7) 에러 체크
    error = struct.unpack('<H', resp_data[6:8])[0]
    if error != 0:
    sock.close()
    raise RuntimeError(f"PLC 에러: 0x{error:04X}")

    # 8) 데이터 파싱
    values = []
    offset = 10 # 응답 헤더(8) + block_count(2)
    data_count = struct.unpack('<H', resp_data[offset:offset + 2])[0]
    offset += 2

    for i in range(count):
    val = struct.unpack('<H', resp_data[offset:offset + 2])[0]
    values.append(val)
    offset += 2

    sock.close()
    return values

    위 코드에서 가장 중요한 부분은 3번(응용 데이터 조립)입니다. "%MW100" 같은 PLC 주소를 ASCII 문자열로 직접 보냅니다.

    주소만 바꾸면 어떤 메모리든 읽을 수 있습니다.

    XGT FEnet 읽기 사용 예시

    # %MW100부터 5개 워드 읽기
    values = read_xgt('192.168.0.10', 2004, '%MW100', count=5)
    print(f"MW100~104: {values}")

    출력 예: MW100~104: [1234, 0, 5678, 100, 0]

    비트나 다른 메모리 영역도 주소만 바꾸면 됩니다.

    # 비트 읽기 (ON/OFF)
    bits = read_xgt('192.168.0.10', 2004, '%MX100', count=1)
    print(f"MX100: {'ON' if bits[0] else 'OFF'}")

    D 영역 읽기


    d_values = read_xgt('192.168.0.10', 2004, '%DW0', count=3)
    print(f"DW0~2: {d_values}")

    XGT FEnet Python 쓰기 코드

    읽기와 거의 같습니다. 명령 코드만 다릅니다.

  • 읽기: 0x0054

  • 쓰기: 0x0058
  • 나머지 구조는 동일하고, 쓰기에는 데이터 값이 추가됩니다.

    def write_xgt(host: str, port: int, address: str, values: list) -> bool:
    """XGT FEnet으로 PLC 메모리 쓰기"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(3.0)
    sock.connect((host, port))

    var_name = address.encode('ascii')

    # 응용 데이터 — 명령이 0x0058 (쓰기)
    app_data = struct.pack('<H', 0x0058) # 명령: 쓰기
    app_data += struct.pack('<H', 0x0000)
    app_data += struct.pack('<H', 0x0000)
    app_data += struct.pack('<H', 1)
    app_data += struct.pack('<H', len(var_name))
    app_data += var_name
    app_data += struct.pack('<H', len(values))

    # 데이터 추가
    for val in values:
    app_data += struct.pack('<H', val & 0xFFFF)

    # 헤더
    header = b'LSIS-XGT'
    header += struct.pack('<H', 0x0000)
    header += struct.pack('<H', 0x0033)
    header += struct.pack('<B', 0xA0)
    header += struct.pack('<B', 0x33)
    header += struct.pack('<H', 1)
    header += struct.pack('<H', len(app_data))
    header += struct.pack('<B', 0x00)
    header += struct.pack('<B', 0x00)

    sock.sendall(header + app_data)

    # 응답 확인
    resp_header = b''
    while len(resp_header) < 20:
    resp_header += sock.recv(20 - len(resp_header))
    data_len = struct.unpack('<H', resp_header[16:18])[0]
    resp_data = b''
    while len(resp_data) < data_len:
    resp_data += sock.recv(data_len - len(resp_data))

    error = struct.unpack('<H', resp_data[6:8])[0]
    sock.close()

    if error != 0:
    raise RuntimeError(f"PLC 쓰기 에러: 0x{error:04X}")

    return True

    쓰기 사용법도 간단합니다.

    # %MW200에 값 1234 쓰기
    write_xgt('192.168.0.10', 2004, '%MW200', [1234])

    %MW300부터 3개 워드에 값 쓰기


    write_xgt('192.168.0.10', 2004, '%MW300', [100, 200, 300])

    XGT CPU 타입별 설정

    PLC 시리즈에 따라 헤더의 CPU Info 바이트가 다릅니다.

    PLC 시리즈CPU Info 값비고
    XGK0xA0기본값 (변경 불필요)
    XGB0xA4코드에서 0xA0 → 0xA4 변경
    XGI0xA8코드에서 0xA0 → 0xA8 변경

    XGB를 쓰신다면, 코드에서 0xA00xA4로 바꾸면 됩니다.

    헤더 조립 부분에서 CPU Info 한 줄만 수정하면 됩니다.


    Part 2: Modbus TCP – Python으로 PLC 데이터 읽기

    Modbus TCP는 1979년에 만들어진 산업 표준 프로토콜입니다. LS뿐만 아니라 지멘스, 미쓰비시, AB 등 거의 모든 PLC가 지원합니다.

    Modbus TCP 통신 구조 – Master(PC)와 Slave(PLC) 네트워크

    위 그림처럼 Modbus TCP는 Master(PC) → Slave(PLC) 구조입니다. PC에서 요청을 보내면 PLC가 데이터를 응답합니다. XGT FEnet과 방향은 같지만, 주소 방식이 다릅니다.

  • XGT: "%MW100" (이름으로 접근)

  • Modbus: 100 (번호로 접근, 매핑 필요)
  • Modbus TCP 사전 준비 (PLC 쪽)

    XGT와 가장 큰 차이입니다.

    Modbus TCP를 쓰려면 PLC 쪽에서 먼저 설정해야 합니다.

  • XG5000에서 Modbus 서버 활성화

  • 매핑 테이블 작성 — 어떤 PLC 메모리를 몇 번 레지스터에 넣을지 지정

  • PLC에 다운로드
  • 이 과정은 XG5000(PLC 프로그래밍 소프트웨어)에서 해야 하고, PLC 프로그래머가 해야 합니다.

    XGT FEnet은 이런 과정이 전혀 필요 없었다는 점과 비교해보세요.

    pymodbus 설치

    pip install pymodbus

    Modbus TCP Python 읽기 코드

    Modbus는 pymodbus 라이브러리를 쓰면 코드가 간단합니다.

    라이브러리가 프로토콜 처리를 전부 해주기 때문에, XGT처럼 헤더를 직접 조립할 필요가 없습니다.

    from pymodbus.client import ModbusTcpClient


    def read_modbus(host: str, port: int, address: int,
    count: int = 1, slave_id: int = 1) -> list:
    """Modbus TCP로 홀딩 레지스터 읽기 (FC03)

    Args:
    host: PLC IP 주소
    port: 포트 번호 (기본 502)
    address: 시작 레지스터 번호
    count: 읽을 레지스터 수
    slave_id: Slave ID (기본 1)

    Returns:
    읽은 값 리스트
    """
    client = ModbusTcpClient(host=host, port=port, timeout=3)
    client.connect()

    result = client.read_holding_registers(
    address=address,
    count=count,
    slave=slave_id
    )

    client.close()

    if result.isError():
    raise RuntimeError(f"Modbus 에러: {result}")

    return result.registers

    코드가 짧은 이유는 pymodbus가 패킷 조립·파싱을 전부 처리하기 때문입니다.

    Modbus TCP 읽기 사용 예시

    # 레지스터 100번부터 5개 읽기
    values = read_modbus('192.168.0.10', 502, address=100, count=5)
    print(f"레지스터 100~104: {values}")

    여기서 "레지스터 100번"은 PLC 쪽 매핑 테이블에서 정한 번호입니다. PLC 프로그래머가 %MW100을 레지스터 100번에 넣었다면, 위 코드로 읽을 수 있습니다.

    # Slave ID가 2인 장비에서 읽기
    values = read_modbus('192.168.0.10', 502, address=0, count=10, slave_id=2)

    Modbus TCP Python 쓰기 코드

    def write_modbus(host: str, port: int, address: int,
    values: list, slave_id: int = 1) -> bool:
    """Modbus TCP로 레지스터 쓰기 (FC16)"""
    client = ModbusTcpClient(host=host, port=port, timeout=3)
    client.connect()

    result = client.write_registers(
    address=address,
    values=values,
    slave=slave_id
    )

    client.close()

    if result.isError():
    raise RuntimeError(f"Modbus 쓰기 에러: {result}")

    return True

    쓰기도 마찬가지로 매핑된 레지스터 번호를 사용합니다.

    # 레지스터 200번에 1234 쓰기
    write_modbus('192.168.0.10', 502, address=200, values=[1234])

    레지스터 300번부터 3개에 값 쓰기


    write_modbus('192.168.0.10', 502, address=300, values=[100, 200, 300])

    Modbus TCP Function Code 정리

    Modbus에는 용도별로 여러 명령(Function Code)이 있습니다. 가장 많이 쓰는 건 FC03(레지스터 읽기)입니다.

    # FC01: 코일 읽기 (비트 단위, ON/OFF)
    result = client.read_coils(address=0, count=8, slave=1)

    FC02: 디스크리트 입력 읽기 (비트, 읽기 전용)


    result = client.read_discrete_inputs(address=0, count=8, slave=1)

    FC03: 홀딩 레지스터 읽기 (워드 단위) ← 가장 많이 사용


    result = client.read_holding_registers(address=100, count=5, slave=1)

    FC04: 입력 레지스터 읽기 (워드, 읽기 전용)


    result = client.read_input_registers(address=100, count=5, slave=1)

    FC05: 코일 1개 쓰기


    client.write_coil(address=0, value=True, slave=1)

    FC06: 레지스터 1개 쓰기


    client.write_register(address=200, value=1234, slave=1)

    FC16: 레지스터 여러 개 쓰기


    client.write_registers(address=300, values=[100, 200, 300], slave=1)

    실무에서는 FC03(읽기)과 FC16(여러 개 쓰기)을 가장 많이 씁니다.


    XGT vs Modbus – 같은 데이터를 읽을 때 코드 비교

    %MW100에서 5개 워드를 읽는 코드를 비교합니다.

    XGT FEnet 코드

    values = read_xgt('192.168.0.10', 2004, '%MW100', count=5)

  • 라이브러리 설치 불필요

  • PLC 메모리 주소를 직접 지정

  • PLC 쪽 설정 불필요
  • Modbus TCP 코드

    values = read_modbus('192.168.0.10', 502, address=100, count=5)

  • pymodbus 설치 필요

  • 레지스터 번호로 지정 (PLC 쪽 매핑 필요)

  • PLC 쪽에서 %MW100 → 레지스터 100 매핑을 해놔야 함
  • 코드 길이만 보면 Modbus가 간단해 보이지만, PLC 쪽 설정(매핑)까지 포함하면 XGT가 전체적으로 더 간단합니다.


    Python에서 32비트 값 읽기 (온도, 실수 등)

    PLC 레지스터는 16비트(워드) 단위입니다.

    32비트 정수(DWORD)나 실수(FLOAT)를 읽으려면 워드 2개를 합쳐야 합니다.

    아래 변환 함수를 쓰면 됩니다.

    import struct


    def words_to_dword(w1: int, w2: int, signed: bool = False) -> int:
    """워드 2개 → 32비트 정수"""
    raw = struct.pack('<HH', w1, w2)
    fmt = '<i' if signed else '<I'
    return struct.unpack(fmt, raw)[0]


    def words_to_float(w1: int, w2: int) -> float:
    """워드 2개 → 32비트 실수 (소수점)"""
    raw = struct.pack('<HH', w1, w2)
    return struct.unpack('<f', raw)[0]

    실제 사용 예시입니다. XGT와 Modbus 모두 동일하게 적용됩니다.

    # XGT로 32비트 정수 읽기 (%MW100~101 두 워드 사용)
    words = read_xgt('192.168.0.10', 2004, '%MW100', count=2)
    dword_value = words_to_dword(words[0], words[1])
    print(f"32비트 정수: {dword_value}")

    온도 같은 실수값 읽기 (%MW200~201)


    words = read_xgt('192.168.0.10', 2004, '%MW200', count=2)
    temp = words_to_float(words[0], words[1])
    print(f"온도: {temp:.1f}°C")


    PLC 통신 연결 안 될 때 체크리스트

    LS Electric XBC PLC – 이더넷 포트와 통신 연결 단자

    PLC 통신이 안 되는 원인의 80%는 물리 연결이나 네트워크 설정 문제입니다. 코드를 의심하기 전에, 아래 순서대로 확인하세요.

    1단계: 물리 연결 확인

  • [ ] 이더넷 케이블이 꽂혀 있는가?

  • [ ] PLC의 이더넷 LED가 깜빡이는가?

  • [ ] PC에서 PLC IP로 ping이 가는가?
  • ping 192.168.0.10

    ping이 안 가면 케이블이나 IP 설정 문제입니다. 코드를 볼 필요 없습니다.

    2단계: 네트워크 서브넷 확인

  • [ ] PC와 PLC가 같은 서브넷에 있는가?

  • [ ] 예: PC 192.168.0.100 / PLC 192.168.0.10 → OK

  • [ ] 예: PC 192.168.1.100 / PLC 192.168.0.10 → NG (서브넷 다름)
  • 서브넷이 다르면 공유기나 라우터 설정을 확인해야 합니다.

    3단계: 포트 및 방화벽 확인

  • [ ] XGT FEnet → 2004 포트

  • [ ] Modbus TCP → 502 포트

  • [ ] 방화벽에서 해당 포트가 열려 있는가?
  • # Windows에서 포트 연결 테스트
    Test-NetConnection -ComputerName 192.168.0.10 -Port 2004

    포트 테스트에서 실패하면 방화벽 문제일 가능성이 높습니다.

    4단계: PLC 설정 확인 (Modbus만 해당)

  • [ ] XG5000에서 Modbus 서버가 활성화되어 있는가?

  • [ ] 매핑 테이블이 작성되어 있는가?

  • [ ] PLC에 다운로드(전송)했는가?
  • XGT FEnet은 이 단계가 필요 없습니다. FEnet 모듈만 있으면 됩니다.


    자주 묻는 질문 – LS PLC Python 통신

    pymodbus 말고 다른 Modbus 라이브러리는?

    pyModbusTCP도 있습니다. 더 가볍지만 기능이 적습니다.

    pip install pyModbusTCP

    from pyModbusTCP.client import ModbusClient

    client = ModbusClient(host='192.168.0.10', port=502, auto_open=True)
    values = client.read_holding_registers(100, 5)

    어떤 라이브러리를 쓰든 PLC 쪽 매핑 설정은 동일하게 필요합니다.

    XGT FEnet Python 라이브러리가 있나?

    공식 라이브러리는 없습니다.

    하지만 위 코드처럼 socket + struct만으로 충분합니다. 프로토콜 자체가 단순하기 때문입니다.

    프로덕션에서 쓸 때는 연결 유지, 재연결, 멀티스레딩 처리를 추가하면 됩니다.

    PLC 주소를 여러 개 한 번에 읽을 수 있나?

    XGT FEnet — Block Count를 늘려서 여러 주소를 한 프레임에 읽을 수 있습니다.

    Modbus TCP — 연속된 레지스터는 count를 늘려서 한 번에 읽고, 띄엄띄엄이면 여러 번 요청해야 합니다.

    여러 PLC에 동시에 접속할 수 있나?

    가능합니다. PLC마다 별도 소켓 연결을 만들면 됩니다.

    # PLC 2대에서 동시에 읽기
    values_1 = read_xgt('192.168.0.10', 2004, '%MW100', count=5)
    values_2 = read_xgt('192.168.0.11', 2004, '%MW100', count=5)

    대수가 많으면 threading이나 asyncio로 병렬 처리하는 게 효율적입니다.

    Python 말고 다른 언어(C#, Java 등)로도 되나?

    네. XGT FEnet은 TCP 소켓만 있으면 되니까 어떤 언어든 가능합니다.

    Modbus TCP도 대부분 언어에 라이브러리가 있습니다.

  • C#: NModbus4, EasyModbus

  • Java: j2mod, Modbus4J

  • Node.js: modbus-serial
  • 모니터링 polling 주기는 어느 정도가 적당한가?

    일반적으로 100ms ~ 1초 사이입니다.

    용도권장 주기
    화면 표시용 (HMI)500ms ~ 1초
    데이터 로깅1초 ~ 5초
    알람 감시100ms ~ 500ms

    너무 빠르면 PLC에 부하가 걸리고, 너무 느리면 값 변화를 놓칩니다. 현장 상황에 맞게 조절하세요.

    PLC 데이터를 DB에 저장하려면?

    읽은 값을 SQLite(로컬)나 PostgreSQL(서버)에 넣으면 됩니다.

    import sqlite3, time

    conn = sqlite3.connect('plc_log.db')
    conn.execute('CREATE TABLE IF NOT EXISTS log (ts TEXT, mw100 INT, mw101 INT)')

    while True:
    values = read_xgt('192.168.0.10', 2004, '%MW100', count=2)
    conn.execute('INSERT INTO log VALUES (?, ?, ?)',
    (time.strftime('%Y-%m-%d %H:%M:%S'), values[0], values[1]))
    conn.commit()
    time.sleep(1)

    이렇게 하면 시간별 데이터를 엑셀이나 대시보드로 분석할 수 있습니다.


    다음 단계 – PLC 모니터링 만들기

    위 코드를 기반으로 1초마다 PLC 값을 읽는 간단한 모니터링을 만들 수 있습니다.

    import time

    while True:
    try:
    values = read_xgt('192.168.0.10', 2004, '%MW100', count=5)
    print(f"[{time.strftime('%H:%M:%S')}] MW100~104: {values}")
    except Exception as e:
    print(f"통신 에러: {e}")
    time.sleep(1)

    이것만으로도 실시간 값 확인용 도구가 됩니다. 여기서 더 확장하면:

  • CSV 저장csv.writer로 값을 파일에 기록 → 나중에 엑셀로 분석

  • 알람 — 값이 임계치를 넘으면 알림 (이메일, 텔레그램 등)

  • 웹 대시보드 — Flask나 FastAPI로 브라우저에서 모니터링

  • HMI 화면 — PyQt로 터치 모니터링 화면 구현
  • LS PLC 현장이라면 XGT FEnet으로 시작하는 걸 추천합니다.

    PLC 쪽 설정이 필요 없어서, 코드만 짜면 바로 통신됩니다.


    이 코드를 현장 산업용 PC에서 돌리려면, 어떤 PC를 쓸지도 중요합니다. 사이즈별 가격과 스펙을 비교해 봤습니다.

    >
    → 10인치 산업용 터치PC 가격비교 2026