프로그램&회로

python - pc - pyserial

엠칩 2024. 11. 20. 09:39
반응형

pip install pyserial 명령을 통해 모듈을 설치해야 한다.
자세한 자료는 pyserial · PyPI 참고바람..
python도 최신 버전으로 업그레이드 해야 한다. 이전버전에서는 에러가 나는 경우가 많음...

import serial
import serial.tools.list_ports
 
class DataReceiver(QThread):
    data_received = pyqtSignal(list)
 
    def __init__(self, uart=None):
        super().__init__()
        self.uart = uart
 
   
    def run(self):
        while True:
            if self.uart and self.uart.is_open and self.uart.inWaiting() > 0:
                try:
                    tdata = self.uart.readline().strip()

                except serial.SerialException as e:
                    print(f"SerialException: {e}")
                    self.WarningWindow(f"{e}")
                    break
이런 식으로 구성된다...

그다음.. uart설정 및 포트지정하고 값을 읽고 써야 한다.
 
class GraphWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("TwoS-tech Data Logger  "+VERSION)
        self.setGeometry(100, 100, 1000, 800)  # Adjusted width to accommodate controls
        #self.setFixedSize(QSize(500, 300))     # full screen size
       
        # Initialize UART
        self.uart = None
        self.data_receiver = None
 
        # Add open/close button
        self.button_layout = QHBoxLayout()
        self.toggle_button = QPushButton("Open", self.control_widget)
        self.toggle_button.setFixedWidth(70)  # Set fixed width for buttons
        self.toggle_button.clicked.connect(self.toggle_port)
        self.button_layout.addWidget(self.toggle_button)

        # Add a button to exit the application
        self.exit_button = QPushButton("Exit", self.control_widget)
        self.exit_button.setFixedWidth(70)  # Set fixed width for buttons
        self.exit_button.clicked.connect(self.close)
       
        self.button_layout.addWidget(self.exit_button)
        self.control_layout.addLayout(self.button_layout)

        # Add port and baudrate selection
        self.port_layout = QHBoxLayout()
        self.port_label = QPushButton("Refresh", self.control_widget)
        self.port_label.clicked.connect(self.refresh_comports)
        self.port_combo = QComboBox(self.control_widget)

        # Scan for available COM ports and add them to the combo box
        available_ports = [port.device for port in serial.tools.list_ports.comports()]
        self.port_combo.addItems(available_ports)

        self.port_combo.setCurrentText("COM4")  # Set default value to COM4 if available
        self.port_layout.addWidget(self.port_label)
        self.port_layout.addWidget(self.port_combo)
        self.control_layout.addLayout(self.port_layout)

        self.baudrate_layout = QHBoxLayout()
        self.baudrate_label = QLabel(" Baudrate :", self.control_widget)
        self.baudrate_combo = QComboBox(self.control_widget)
        self.baudrate_combo.addItems(["9600", "19200", "28800", "38400", "57600", "115200"])
        self.baudrate_combo.setCurrentText("19200")  # Set default value to 19200
        self.baudrate_layout.addWidget(self.baudrate_label)
        self.baudrate_layout.addWidget(self.baudrate_combo)
        self.control_layout.addLayout(self.baudrate_layout)
 
        # Timer to update the plot
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_plot)
        self.timer.start(50)  # Update every 1 ms
 
    def toggle_port(self):
        if self.uart and self.uart.is_open:
            self.close_port()
        else:
            self.open_port()
 
    def open_port(self):
        port = self.port_combo.currentText()
        baudrate = int(self.baudrate_combo.currentText())
        try:
            self.uart = serial.Serial(port=port, baudrate=baudrate)
            self.data_receiver = DataReceiver(self.uart)
            self.data_receiver.data_received.connect(self.buffer_data)
            self.data_receiver.invalid_data_received.connect(self.show_invalid_data)
            self.data_receiver.start()
            self.toggle_button.setText("Close")
            self.data_receiver.save_to_file_enabled = self.temp_save_to_file_enabled
        except serial.SerialException as e:
            self.WarningWindow(f"{e}")
           
    def close_port(self):
        if self.uart and self.uart.is_open:
            self.data_receiver.terminate()
            self.uart.close()
            self.toggle_button.setText("Open")

    def buffer_data(self, data):
        self.data_buffer.append(data)
        if len(self.data_buffer) > 100:
            self.data_buffer.pop(0)
           
    def send_data(self):
        if self.uart and self.uart.is_open:
            data = self.send_text.toPlainText()
            self.cmd_display.append("T> "+data)
            if self.append_checkbox.isChecked():
                data += "\n\r"
            self.uart.write(data.encode())
 
 
    def update_plot(self):
        if self.uart and self.uart.is_open and self.data_buffer:
            data = self.data_buffer.pop(0)
            data_parts = list(data)
       ...
 
활성화 되어 있는 com port를 찾아서 콤보 박스에 할당해주고, 
baudrate 설정해서 open하면 된다.
기타 stopbit, parity bit등 거의 사용 안하기 때문에 무시했다.
 
timer에 설정된 시간마다 update_plot를 호출하여 수신 데이타를 확인하여 처리하는 루틴 구성하면되고,
전송할때는 send_data를 호출하여 사용한다.

일련의 과정들은 Copilot을 이용하여 코딩하였다.
 
반응형

'프로그램&회로' 카테고리의 다른 글

touchGFX  (0) 2024.12.10
역률  (0) 2024.11.14
Relay 허용전류와 cos φ  (0) 2024.11.14
IAR Embeded workbench break point활용법  (0) 2024.10.28
VS code 확장프로그램 - 일련번호 입력하기  (0) 2024.10.16