Python을 사용하여 RS485 명령을 전송하는 방법

D

Daniel Zhang

Jul 12, 2026에 마지막으로 업데이트 됨

Python은 널리 사용되는 프로그래밍 언어입니다. Python을 통해 Modbus 명령을 전송하면 모터 동작을 편리하게 제어할 수 있습니다. 아래는 Python을 사용하여 Modbus 명령을 전송하는 간단한 코드 예제입니다. Modbus 명령은 A6 서보 모터 RS485 운전 지침 문서의 섹션 2.3 "5000 펄스 절대 위치 이동(기본 설정: 10000 펄스/회전, C00.02=10000)"에서 발췌한 것입니다. 이 코드는 StepperOnline의 A6-RS 시리즈 서보 드라이브에 적용되며, 모터를 절대 위치 모드에서 5000 펄스만큼 운전하도록 제어합니다.

Python 코드는 다음과 같습니다:

import serial
import time
import binascii
from crcmod import crcmod

# 시리얼 포트 설정 - 실제 장치에 맞게 수정하세요
PORT = 'COM3'  # 시리얼 포트 (Windows: 'COM3', Linux: '/dev/ttyUSB0')
BAUDRATE = 9600  # 보율 (일반적인 값: 9600, 19200, 38400, 57600, 115200)
PARITY = serial.PARITY_NONE
STOPBITS = serial.STOPBITS_ONE
BYTESIZE = serial.EIGHTBITS
TIMEOUT = 0.5  # 읽기 타임아웃 (초)

# Modbus CRC16 함수 생성
modbus_crc = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)

# 명령 정의 (CRC 제외)
commands_without_crc = [
    "010600000000",  # 드라이브 제어 모드를 위치 모드로 설정 C00.00=0
    "010611010000",  # 위치 프로파일 명령을 절대 위치 결정으로 설정 C11.01=0
    "010603000002",  # 위치 명령 소스를 스텝 증분으로 설정 C03.00=2
    "0106030D0001",  # 운전 속도를 1 rpm으로 설정 C03.0D=1
    "0106030C1388",  # 이동량을 5000 펄스로 설정 C03.0C=5000
    "010604000022",  # DI1을 위치 스텝 증분 활성화로 설정 C04.00=34 (0x22)
    "010604110001",  # 모터 활성화 및 운전 시작 C04.11=1
    "010604010001",  # DI1 활성화 트리거 C04.01=1
    "010604110000",  # 비상 정지 명령, 모터 비활성화 C04.11=0
    "010604010000"   # DI1 비활성화 C04.01=0
]

# 명령 설명
descriptions = [
    "드라이브 제어 모드를 위치 모드로 설정 (C00.00=0)",
    "위치 프로파일을 절대 위치 결정으로 설정 (C11.01=0)",
    "위치 명령 소스를 스텝 증분으로 설정 (C03.00=2)",
    "운전 속도를 1 rpm으로 설정 (C03.0D=1)",
    "이동량을 5000 펄스로 설정 (C03.0C=5000)",
    "DI1을 위치 스텝 증분 활성화로 설정 (C04.00=34)",
    "모터 활성화 및 운전 시작 (C04.11=1)",
    "DI1 활성화 트리거 (C04.01=1)",
    "비상 정지 명령, 모터 비활성화 (C04.11=0)",
    "DI1 비활성화 (C04.01=0)"
]

def calculate_crc(hex_str):
    """16진수 문자열에 대한 Modbus CRC16을 계산합니다"""
    data = binascii.unhexlify(hex_str)
    crc = modbus_crc(data)
    # CRC를 리틀 엔디안 형식(하위 바이트 우선)으로 반환
    return bytes([crc & 0xFF, (crc >> 8) & 0xFF])

def format_hex(data):
    """바이트 데이터를 16진수 문자열로 포맷합니다"""
    return ' '.join([f"{b:02X}" for b in data])

def send_modbus_command(ser, hex_cmd, description):
    """단일 Modbus 명령을 전송하고 응답을 처리합니다"""
    try:
        # CRC를 계산하여 명령에 추가
        crc_bytes = calculate_crc(hex_cmd)
        full_cmd = binascii.unhexlify(hex_cmd) + crc_bytes

        # 명령 전송
        ser.write(full_cmd)
        print(f"\n명령 전송: {description}")
        print(f"데이터: {format_hex(full_cmd)}")

        # 장치 처리 대기
        time.sleep(0.3)

        # 응답 읽기 (Modbus RTU 응답은 일반적으로 8바이트)
        response = ser.read(8)

        if response:
            print(f"장치 응답: {format_hex(response)}")
            return True
        else:
            print("오류: 응답을 받지 못했습니다!")
            return False

    except Exception as e:
        print(f"명령 전송 오류: {str(e)}")
        return False

def main():
    # 시리얼 연결 생성
    try:
        ser = serial.Serial(
            port=PORT,
            baudrate=BAUDRATE,
            parity=PARITY,
            stopbits=STOPBITS,
            bytesize=BYTESIZE,
            timeout=TIMEOUT
        )
        print(f"시리얼 포트 연결 성공: {ser.name}\n")
    except serial.SerialException as e:
        print(f"시리얼 포트 열기 실패: {str(e)}")
        return
    except Exception as e:
        print(f"오류가 발생했습니다: {str(e)}")
        return

    # 모든 명령 전송
    for i, (cmd, desc) in enumerate(zip(commands_without_crc, descriptions), 1):
        print(f"명령 실행 {i}/{len(commands_without_crc)}")
        success = send_modbus_command(ser, cmd, desc)

        if not success:
            print("명령 실행 실패, 프로그램 종료")
            break

        # 주요 명령에는 더 긴 지연 적용
        if "활성화" in desc or "트리거" in desc or "비상" in desc:
            time.sleep(1.0)  # 동작 관련 명령에 더 긴 지연
        else:
            time.sleep(0.5)  # 설정 명령에 표준 지연

    # 시리얼 포트 닫기
    ser.close()
    print("\n모든 명령 처리 완료, 시리얼 포트 닫힘")

if __name__ == "__main__":
    main()

참고 사항:

a. 이 코드는 Modbus 명령에 대한 CRC 검증을 수행하기 위해 crcmod 라이브러리에 의존합니다. 코드를 실행하기 전에 필요한 라이브러리를 설치해야 합니다:

pip install pyserial crcmod

b. 장치의 실제 구성에 따라 올바른 COM 포트(PORT)와 보율(BAUDRATE)을 설정하세요. 장치의 응답 시간에 따라 지연 매개변수(time.sleep)를 조정하세요.

c. 이 예제의 Modbus 명령은 StepperOnline의 A6-RS 시리즈 서보 드라이브에만 적용됩니다. StepperOnline의 DSY-RS 시리즈 서보 드라이브, T6 시리즈 서보 드라이브 또는 RS 시리즈 스테핑 드라이브 등 다른 드라이브를 사용하는 경우, 해당 드라이브의 매뉴얼에 따라 Modbus 명령을 수정하세요.