0. 순서

더보기

Step 1. GUI + LED 제어 맛보기

  • 버튼 1개
  • 포트·보드레이트 코드에 고정
  • GUI → 시리얼 → 아두이노 → 로그 흐름 경험 중심

 

👉 Step 2. 포트 선택 추가

  • 포트 개념 이해
  • 포트 선택 콤보박스 추가하여 어떤 장치와 통신하는가 개념 학습
  • Step 2는 기능 확장이 아니라, 통신 대상 선택이라는 개념을 추가하는 단계입니다.

 

Step 3. 문자열 송신/수신 추가

  • 자유 문자열 전송 입력창 추가
  • TX / RX 개념 명확화
  • LED 제어 + Echo 응답 확인

 

Step 4. QTimer 수신 처리 추가

  • 주기적 수신 처리 구조 도입
  • GUI 멈춤 현상 체험
  • “왜 비동기가 필요한가” 문제 제기

 

Step 5. QThread 비동기 수신 추가

  • RX 전용 스레드 분리
  • Signal / Slot 구조 학습
  • 안정적인 GUI + 실시간 수신 구현

 

1. 목표

더보기

목표

  • 이 단계의 목표는 여러 장치 중, 내가 통신할 대상을 선택하는 것입니다.
  • Step 1에서 “연결은 이미 되어 있다” 였다면,
    Step 2에서는 “이제 내가 직접 고른다” 로 한 단계 확장합니다.

 

학습을 마치면 할 수 있는 것

  • PC에 연결된 시리얼 장치 목록을 확인할 수 있다.
  • 콤보박스에서 통신할 포트 하나를 선택할 수 있다.
  • 선택한 포트가 아두이노 장치임을 인식할 수 있다.
  • GUI → 선택된 포트 → 아두이노 → 응답 흐름을 이해한다.

 

2. 아두이노 스케치 구현 

: 교재 P.110 ~ 143

더보기
Step 1. 동일

 

3. PySide6 앱 2단계 구현

└─ 3.1 전체 소스 코드

더보기
# Step 2: 포트 선택 추가
# 목적: "어떤 장치와 통신하는가"를 사용자가 선택

import sys
import serial
from serial.tools import list_ports   # [추가]

from PySide6.QtWidgets import (
    QApplication, QMainWindow, QPushButton,
    QTextEdit, QVBoxLayout, QWidget,
    QComboBox, QLabel                  # [추가]
)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Serial LED Test - Step 2")
        self.resize(360, 320)

        self.ser = None                # [변경] 처음에는 연결하지 않음
        self.led_on = False

        # --- [추가] 포트 선택 UI ---
        self.combo_port = QComboBox()
        self.load_ports()

        # --- 기존 UI ---
        self.btn_led = QPushButton("LED OFF")
        self.log = QTextEdit()
        self.log.setReadOnly(True)

        # --- Layout ---
        layout = QVBoxLayout()
        layout.addWidget(QLabel("Port"))      # [추가]
        layout.addWidget(self.combo_port)     # [추가]
        layout.addWidget(self.btn_led)
        layout.addWidget(self.log)

        central = QWidget()
        central.setLayout(layout)
        self.setCentralWidget(central)

        self.btn_led.clicked.connect(self.toggle_led)

    # --- [추가] 포트 목록 로드 ---
    def load_ports(self):
        ports = list_ports.comports()
        for p in ports:
            self.combo_port.addItem(p.device)

    def toggle_led(self):
        # --- [추가] 버튼 클릭 시 최초 1회 연결 ---
        if self.ser is None:
            port = self.combo_port.currentText()
            if not port:
                self.log.append("No port selected")
                return
            self.ser = serial.Serial(port, 9600, timeout=1)
            self.log.append(f"Connected to {port}")

        self.led_on = not self.led_on
        msg = "1" if self.led_on else "0"
        self.ser.write((msg + "\n").encode())
        self.log.append(f"TX: {msg}")

        line = self.ser.readline().decode().strip()
        if line:
            self.log.append(f"RX: {line}")

        self.btn_led.setText("LED ON" if self.led_on else "LED OFF")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec())

└─ 3.2 전체 동작 흐름

더보기
[ 포트 선택 ] # 추가
        ↓
[ LED 버튼 클릭 ]
        ↓
[ 선택된 포트로 "1" 또는 "0" 전송 (TX) ] # 확장 개선
        ↓
[ Arduino LED ON / OFF ]
        ↓
[ 상태 메시지 수신 (RX) ]
        ↓
[ 로그 창에 표시 ]

 

└─ 3.3 포트 목록 가져오기

더보기

동작

PC → 시리얼 장치 목록 조회 → 콤보박스에 표시
  • PC에 연결된 시리얼 장치를 조회
  • 실행 시 또는 버튼 클릭 시 목록 갱신

 

소스코드 

from serial.tools import list_ports
def load_ports(self):
    ports = list_ports.comports()
    for p in ports:
        self.combo_port.addItem(p.device)

└─ 3.4 포트 선택 콤보박스

더보기

동작

선택된 포트 = 내가 통신할 대상
  • 사용자는 콤보박스에서 하나의 포트 선택
  • 문자열이 아니라 실제 포트 값을 사용

 

소스코드

self.combo_port = QComboBox()
layout.addWidget(QLabel("Port"))
layout.addWidget(self.combo_port)

└─ 3.5 선택된 포트로 시리얼 연결

더보기
serial.Serial(선택된_포트, 9600)
  • 변경 포인트는 딱 이 한 줄입니다.


4. 테스트

더보기

정상 동작 확인

  • 콤보박스에 하나 이상의 포트가 보인다.
  • 아두이노가 연결된 포트를 선택할 수 있다.
  • 버튼 클릭 시 LED가 정상적으로 켜졌다/꺼진다.
  • 로그 창에 아래와 같은 형태가 출력된다.
TX: 1
RX: LED:ON

TX: 0
RX: LED:OFF