ModScan과 Python을 이용한 Modbus 통신 데이터 시뮬레이션
IoT나 산업 자동화 시스템을 개발하다 보면 Modbus 프로토콜을 이용해 데이터를 주고 받는 환경이 자주 등장합니다. 실제 장비가 없거나 테스트 환경 구축이 어려울 때 ModScan이라는 시뮬레이터를 활용하면 매우 유용합니다.
이번 글에서는 ModScan으로 Modbus 데이터를 생성하고, Python 코드로 해당 데이터를 읽어오는 방법을 정리해보겠습니다.
Modbus 통신 구조
이번 실습은 Modbus TCP 기반으로 구성하였습니다.
ModScan (Modbus Slave Server 역할)
↓
Python (Modbus Client 역할)
- ModScan: 데이터 생성 (서버)
- Python: 데이터 읽기 (클라이언트)
ModScan 설정 방법
2025.03.08 - [Computer Science/CS 지식] - [Modbus] Modscan & Modsim 으로 TCP 통신하기
[Modbus] Modscan & Modsim 으로 TCP 통신하기
Modscan과 Modsim은 Modbus 프로토콜을 사용하는 장치와 통신을 테스트하고 시뮬레이션하는 도구입니다. 이들은 산업 자동화, SCADA 시스템, PLC(Programmable Logic Controller) 및 기타 Modbus 기반 장치의 진단과
rnasterofmysea.tistory.com
해당 링크에 자세한 내용을 참고해주세요!
Pymodbus
Python에서는 pymodbus 라이브러리를 이용해 Modbus 프로토콜을 쉽게 처리할 수 있습니다.
다운로드~~
pip install pymodbus
pymodbus 주요 메서드 정리 (TCP, RTU 공통)
읽기 메서드 (Read)
메서드 | 읽는 대상 | 레지스터 번호 | 예시 |
read_coils | Coil (디지털 출력) | 00001 ~ | client.read_coils(address=0, count=5, unit=1) |
read_discrete_inputs | Discrete Input (디지털 입력) | 10001 ~ | client.read_discrete_inputs(address=0, count=5, unit=1) |
read_holding_registers | Holding Register (데이터 저장 공간, 읽기/쓰기 가능) | 40001 ~ | client.read_holding_registers(address=0, count=5, unit=1) |
read_input_registers | Input Register (데이터 저장 공간, 읽기 전용) | 30001 ~ | client.read_input_registers(address=0, count=5, unit=1) |
이번 포스트에서는 데이터를 파이썬으로 읽어오는 것이기 때문에 Read 메서드를 사용할 예정입니다.
쓰기 메서드 (Write)
메서드 | 대상 | 레지스터 번호 | 예시 |
write_coil | Coil (디지털 출력) | 00001 ~ | client.write_coil(address=0, value=True, unit=1) |
write_register | Holding Register (단일 값 쓰기) | 40001 ~ | client.write_register(address=0, value=123, unit=1) |
write_registers | Holding Register (여러 값 쓰기) | 40001 ~ | client.write_registers(address=0, values=[10, 20, 30], unit=1) |
레지스터 구분 요약
Coil | 00001 ~ | 디지털 출력 (ON/OFF) | read_coils / write_coil |
Discrete Input | 10001 ~ | 디지털 입력 (읽기 전용) | read_discrete_inputs |
Input Register | 30001 ~ | 아날로그 입력 데이터 | read_input_registers |
Holding Register | 40001 ~ | 읽기/쓰기 가능 데이터 저장소 | read_holding_registers / write_register(s) |
핵심 파라미터 설명
(pymodbus read_holding_registers 함수 기준)
result = client.read_holding_registers(address=0, count=10, unit=1)
파라미터 | 설명 | 예시 | 비고 |
address | 시작 주소 | 0 | Modbus 레지스터 주소 (0부터 시작) |
count | 읽을 레지스터 개수 | 10 | 몇 개를 읽을지 결정 |
unit | Slave ID | 1 | ModScan에서 설정한 Slave ID |
1. address
- Modbus 레지스터 번호는 보통 이렇게 표기합니다.
Modbus 레지스터 번호 | pymodbus address |
40001 | 0 |
40002 | 1 |
40003 | 2 |
... | ... |
→ 즉, ModScan에서 40001 번 레지스터 = pymodbus 에서는 address=0 입니다.
2. count
- 몇 개의 레지스터 값을 읽을 건지 지정합니다.
count=10
- 의미:
40001 ~ 40010 까지 10개의 값을 읽겠다는 의미입니다.
3. unit
- Modbus 장비 구분 ID입니다.
unit=1
- ModScan 실행 시 설정한 Slave ID 값과 일치시켜야 합니다.
- 예를 들어 ModScan 설정이 이렇게 되어 있다면:→ Python 코드에서도 unit=1 로 설정해야 통신됩니다.
파이썬 코드
from pymodbus.client.sync import ModbusTcpClient
MODSCAN_HOST = '192.168.0.100' # ModScan 실행 PC IP
MODSCAN_PORT = 502 # ModScan Port
client = ModbusTcpClient(MODSCAN_HOST, port=MODSCAN_PORT)
if client.connect():
print("Modbus TCP 연결 성공")
# Holding Register 40001번부터 10개 값 읽기
result = client.read_holding_registers(address=0, count=10, unit=1)
if result.isError():
print("데이터 읽기 실패")
else:
print("읽은 데이터:", result.registers)
client.close()
else:
print("Modbus TCP 연결 실패")
Modscan 실행
Connection - Remote Modbus TCP Server - IP 와 Port 번호 입력
빨간 박스 부분에서 출력 방식을 결정할수 있습니다.
(Binary, Demical, Integer, Hex 등등)
'Computer Science > CS 지식' 카테고리의 다른 글
교류 전력과 역률(Power Factor) (0) | 2025.03.10 |
---|---|
[Modbus] Modscan & Modsim 으로 TCP 통신하기 (0) | 2025.03.09 |
모드버스(Modebus) 프로토콜 (feat. RTU, TCP/IP, Function Code) (0) | 2025.03.07 |
LoRa (Long Range)와 LoRaWAN(Long Range Wide Area Network) (1) | 2025.03.05 |
시리얼 통신(Serial Communication) (0) | 2025.03.05 |