글 / Modbus·OPC UA

Pymodbus 레지스터 읽기와 쓰기

ModbusTcpClient로 레지스터를 읽고 쓰며, 예외 응답은 isError로, 무응답은 ModbusException으로 확인한다.

작성일 · 읽는 시간 2분 · Pymodbus 3.13 기준

연결

ModbusTcpClient는 요청을 전송하고 응답을 수신할 때까지 대기하는 동기 방식 클라이언트이다. 호스트만 지정하면 포트 502, 응답 대기 3초, 재시도 3회가 기본값이다. connect()는 연결 여부를 True/False로 반환한다.

읽기와 쓰기 예제

pythonclient.py
from pymodbus import ModbusException
from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient("192.0.2.10")
if not client.connect():
    raise SystemExit("연결 실패")

try:
    # 주소 0부터 holding register 2개를 읽는다
    rr = client.read_holding_registers(0, count=2, device_id=1)
    if rr.isError():
        print("예외 응답:", rr.exception_code)
    else:
        print(rr.registers)

    # 주소 10에 값 1을 쓴다
    wr = client.write_register(10, 1, device_id=1)
    if wr.isError():
        print("예외 응답:", wr.exception_code)
except ModbusException as exc:
    # 응답이 오지 않는 등 통신이 실패한 경우다
    print("통신 오류:", exc)
finally:
    client.close()

ModbusTcpClient 연결, 읽기, 쓰기, 닫기 호출의 순서

인자

  • address: 0부터 세는 프로토콜 주소이다. 설명서의 40001은 0이다.
  • count: 읽을 레지스터 개수이다. 기본값은 1이다.
  • device_id: 장비 번호(unit identifier)이다. 기본값은 1이다.

count와 device_id는 count=2처럼 키워드 인자로만 전달할 수 있다.

참고

device_id는 3.10에서 변경된 이름이다. 그 이전의 3.x에서는 같은 인자를 slave라는 이름으로 사용한다.

실패 유형

장비가 예외 응답을 전송하면 Python 예외는 발생하지 않는다. 반환된 응답의 isError()가 True이고 exception_code에 장비가 전송한 코드가 저장된다. 존재하지 않는 주소를 읽은 경우가 여기에 해당한다.

응답이 전혀 수신되지 않으면 ModbusException이 발생한다. 통신선이 분리되었거나 장비의 전원이 차단된 경우이다.

예외 응답과 무응답의 확인 방식 차이