RS232c Serial 통신 관련 질문이 있습니다.

23.12.14 18:48 작성 조회수 274

1

안녕하세요

연구실에서 자체적으로 실험기기와 컴퓨터랑 통신을 진행하는 중인데, 하나가 해결이 안 되어서 너무 답답해서 고수님들께 자문을 구하려고 합니다.

 

Rs232 rtu 모드를 지원한다고 한 OS-20 overhead stirrer과 통신을 진행 중 입니다. 이 친구의 통신 규격과 방식은 아래 그림 3개와 같습니다.

 

2023-12-14_17-23-19.png2023-12-14_17-23-25.png2023-12-14_17-23-30.png이중 stirrer control 부분을 제가 참조해서 저 command를 hex 방식으로 입력하였는데 도무지 안되는 겁니다. 그런데 웃긴게 이 회사에서 지원하는 공식 통신프로그램을 사용하면 작동이 잘 되더군요.

 

Instruction overview에서 나온 규칙은 다음과 같습니다.

Command 구조는 Prefix Instruction_code Data_frame Checksum로 되어 있고

입력의 prefix는 0xfe로 시작하며 responce는 0xfd로 시작합니다.

모든 바이트 사이에는 50ms delay가 존재해야하며 Dataframe은 큰 수 자리부터 전송합니다.

ex) 1000rpm을 data frame에 입력하려고 할 시 Hex값이 03E8이니까 앞에 두 자리를 0x03에 해당하고 뒤에 두 자리를 0xE8로 해당시킵니다.

Null은 0x00입니다.

Checksum 방식은 0xfe,0xfd인 prefix를 제외하고 나머지를 전부 더한 값으로 0xnn 이런식으로 표현됩니다. 신기하게도 16진수의 2자리를 넘어가도 뒤에 2 자리만 붙이면 된다고 하더군요.

ex) 0xfe 0xb1 0x03 0xe8 0x00 checksum인데 0xfe를 제외하고 다 더하면 019c이지만 0x9c만 입력하면 되는 형식입니다.

 

그래서 이 규칙대로 코드를 짜서 통신을 해 보았는데, 아무리 해도 안되어서 너무 답답합니다.

 

심지어 제가 잘못했는지 확인하려고 시리얼 통신 sniffer을 사용하여서 공식 프로그램에서는 어떻게 통신이 되나 뜯어보았습니다. 결과는 아래 사진과 같습니다.

2023-12-14_17-30-58.png

제가 python으로 작성한 코드는 아래와 같습니다.


import serial
import time

ser = serial.Serial(
    port='COM7',  # Update with your actual port
    baudrate=9600,
    parity=serial.PARITY_NONE,  # No parity
    stopbits=serial.STOPBITS_ONE,  # 1 stop bit
    bytesize=serial.EIGHTBITS  # 8 data bits
)


def send_hex_string(hex_string):
    # Convert the hex string to bytes
    byte_data = bytes.fromhex(hex_string)

    # Send the bytes over the serial port
    ser.write(byte_data)

def send_hex_string_with_delay(hex_string, delay_ms=50):
    for i in range(0, len(hex_string), 2):
        # Extract each pair of characters and convert to bytes
        hex_pair = hex_string[i:i + 2]
        byte_data = bytes.fromhex(hex_pair)

        # Send the bytes over the serial port
        ser.write(byte_data)

        # Wait for the specified delay
        time.sleep(delay_ms / 1000.0)


command = 'feb103e8009c'
send_hex_string_with_delay(command)

ser.close()

또한 파이썬에서의 결과를 시리얼 전송으로 보면 다음과 같습니다.

2023-12-14_18-46-00.png입력은 제대로 되는데 기기에는 반응이 제대로 나오지 않네요...

 

제가 잘못하고 빠뜨린 점이 있을까요?

 

읽어주셔서 정말 감사드립니다.

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.12.15

안녕하세요, 인프런 AI 인턴입니다.

질문 주신 내용에 따르면 RS232C 시리얼 통신을 이용해서 실험기기와 컴퓨터 간 통신을 시도하고 계신 상황인데 특정 명령이 제대로 동작하지 않는 문제를 겪고 계시군요. 제시된 이미지와 설명에 따르면 커맨드 구조는 Prefix, Instruction_code, Data_frame, 그리고 Checksum으로 구성되어 있고, 각 바이트 사이에는 최소 50ms의 딜레이가 필요하며, 데이터는 높은 자리수부터 전송해야 한다고 합니다.

파이썬 코드와 제시된 시리얼 통신 로그를 근거로 든다면, 체크섬을 계산할 때 발생할 수 있는 문제나 통신 설정, 또는 하드웨어 연결 문제 등을 확인해 봐야 할 것 같습니다.

여러 가능성 중 하나로 체크섬 계산 방식에 주의를 기울여야 할 것 같습니다. 체크섬은 Prefix를 제외한 명령의 모든 바이트를 더한 후, 16진수의 마지막 두 자리만을 사용해야 합니다. 파이썬 코드에서 command = 'feb103e8009c' 부분에서 체크섬을 ‘9c’로 설정하셨는데, 이 값이 실제로 Prefix를 제외한 나머지 바이트들의 합에 해당하는 값인지 다시 한번 확인해 보시는 것이 중요합니다.

또 하나의 중요한 사항은 ‘COM7’ 포트 설정과 기기 설정이 정확히 일치하는지 확인하는 것입니다. Baud rate, parity, stop bits 및 data bits가 기기 매뉴얼과 일치하는지 점검해야 합니다.

이 외에도 시리얼 통신에서 수시로 발생하는 물리적 연결 문제, 소프트웨어 설정의 오류, 실제 통신을 방해하는 다른 하드웨어적인 이슈 등을 고려해야 할 수도 있습니다. 이러한 문제를 해결하기 위해서는 다음과 같은 방식으로 문제를 접근해보실 것을 권장합니다:

  1. 원시 데이터 전송과 정상 동작하는 공식 프로그램 사이의 통신 패턴을 비교하여 차이점을 찾아보세요.
  2. 파이썬 코드에서 직렬 포트 설정(특히 시간 지연)을 정확히 기기의 요구 사항과 일치시키세요.
  3. 실제 기기에서 사용하는 체크섬 계산 방식을 잘 이해하고, 코드에 올바르게 구현되었는지 확인하세요.

위의 조언이 해결에 도움이 되셨으면 좋겠습니다. 추가적으로 Spring과 관련된 더 많은 정보는 Spring의 참조 문서를 확인하시면 도움이 될 수 있습니다. 예를 들어, Spring Data JDBC의 문서 링크는 여기 있습니다: https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#get-started:help

문제 해결을 위해 행운을 빕니다!