파이썬 시리얼 통신 - pyserial

STM32F429 개발보드에서 시리얼로 출력되는 json 결과를 이용하여 J1939 데이터를 파싱하여 출력하는 간단한 모니터링 앱을 만들기 위해 파이썬으로 시리얼 통신 방법을 구글링 한 결과, pyserial 모듈을 사용하면 간단히 시리얼 통신을 할 수 있어 pip로 pyserial 모듈을 설치하도록 한다.

$ sudo pip3 install pyserial

시스템 전체에 설치하고 싶지 않다면 가상환경을 만들어서 프로젝트 디렉토리에 설치하는 것도 가능하다. pyserial 모듈을 사용하여 시리얼 통신하는 방법은 인터넷에 많은 자료가 있기에 자세한 설명은 생략하기로 하고, STM32 개발보드에서 발생한 문제를 수정한 것들을 정리한 것이다.

위 앱은 일정주기로 사용자가 원하는 J1939 메시지를 PCAN_XXX 커맨드를 UART 사용하여 STM32F429 개발보드에 커맨드를 전달하면 개발보드는 CAN으로 전송된 J1939 메시지를 받아 각 항목 별로 파싱하여 json으로 변환하여 시리얼로 출력한 결과를 파이썬에서 읽어 J1939 메시지를 모니터링하는 프로그램이다.

 

STM32F429 개발보드의 UART RX/TX 버퍼 크기는 작은 편이며, CPU 성능도 높지 않은 편이기 때문에 시리얼통신 과정에서 데이터 손실이 발생한 것을 줄이고자 몇 가지 트릭으로 손실을 회피하였다.

 

UART RX

STM32F429의 UART RX 버퍼가 작기 때문에 아래 코드와 같이 일정 sleep없이 지속적으로 RX 버퍼를 읽도록 한다. 만약 RX 버퍼의 데이터가 없다면 null이 리턴되기 때문에 이것은 스킵하도록 하였다.

    def run(self):
        buf   = list()
        null  = bytes(0x00)
        while self.__is_run:
            c = self.__serial.read()
            if c == null: continue

            buf.append(c.decode("utf-8"))
            if buf[len(buf)-2] == '\r' and buf[len(buf)-1] == '\n':
                s = "".join(buf)
                if s.find("PCAN_") < 0:
                    # print("RECV({}) :: {}".format(len(s), s))
                    self.__queue.put(s)
                buf.clear()

PCAN_XXX는 사용자가 요청한 UART 커맨드가 개발보드에서 에코되어 출력되기 때문에 스킵처리한 것이다. 만약 UART RX 스레드에서 일정주기로 sleep을 줄 경우, 데이터 손실이 발생하는 문제가 발생한다.

 

UART TX

UART 커맨드는 json과 다르게 문자열 길이가 짧기 때문에 문제가 없을 것이라고 생각하고, 한번에 커맨드 메시지를 개발보드에 보냈는데, 커맨드 길이와 상관없이 개발보드 상태에 따라 UART 커맨드도 손실이 발생하여 아래와 같이 하나의 문자를 보낼 때마다 50ms 간격으로 전달하도록 수정하였다.

    def tx_message(self, message):
        # self.__serial.write((message+"\r").encode())
        for c in message:
            self.__serial.write(c.encode())
            time.sleep(0.005)
        self.__serial.write(b'\r')

원래 주석 처리된 코드로 처리했는데, PCAN_XXX와 같이 짧은 UART 커맨드 메시지도 손실이 발생하여 위와 같이 변경하여 데이터 손실되는 회피하도록 하였다.

 

전체 코드는 아래 GitHub 저장소에서 J1939 디렉토리에 있는 코드를 참고하도록 한다.

 

highgon2/PythonTest

Python Test code. Contribute to highgon2/PythonTest development by creating an account on GitHub.

github.com

파이썬에서 CAN 통신 모듈이 있는 것 같은데, 나중에 시간날 때는 이런 시리얼 방식이 아닌 직접 CAN 데이터를 모니터링하는 방법을 찾아야겠다.