Pythonでシリアル通信(RS-232C)を行う方法を説明する。
基本的な使用方法
1. ライブラリ
serialというライブラリを使用する。
import serial
from serial.tools import list_ports
2. COMポートの検出
comports()でPCに搭載されているCOMポートを検出しリストで返ってくる。
self.ports = list_ports.comports()
例)PCにCOMポート1、3、5が搭載されていた場合
self.portsに[1, 3, 5]というリストが代入される。
3. COMポートを設定
- 使いたいポート番号を指定する。
- serial.Seiralのインスタンスを設定する。
- ボーレート、パリティ、バイトサイズ、ストップビット、タイムアウトを必要な値に設定する。
一例を示す。
self.use_port = str(COMポート番号)
self.ser = serial.Serial(self.use_port)
self.ser.baudrate = 115200
self.ser.parity = serial.PARITY_NONE
self.ser.bytesize = serial.EIGHTBITS
self.ser.stopbits = serial.STOPBITS_ONE
self.ser.timeout = 1 #sec
4. 送信
送りたい文字列をwrite()に記述する。
self.ser.write(bytes(送りたい文字列, 'UTF-8'))
例1)「cd /mnt」を送信して改行(正規表現で「\n」)したい場合や、Ctrl + C( 正規表現で「\x03」)でブレークし改行(正規表現で「\n」)したい場合は以下のようになる。
self.ser.write(bytes('cd /mnt\n', 'UTF-8'))
self.ser.write(bytes('\x03\n', 'UTF-8'))
5. 受信
readline()で受信する。
recv_data = self.ser.readline()
6. COMポートを切断
close()でCOMポートを切断する。
self.ser.close()
具体例
このようなアプリを作成する。
- COMポートを検出する。
- 検出したCOMポートをコンボボックスに表示する。
- connectボタンをクリックすると接続する。
- データを送信する。
- データを受信する。
- 切断する。
メインの動作はこんな感じに実装してみる。
def main(self):
self.set_serial_port()
self.send_serial_data('うんこ出た?')
if self.read_serial_data() == '出たよ':
print('良かったね')
else:
print('残念だったね')
self.close_serial_ports()
コード全文
- serialをimportする。
- COMポートを検出する。
- 検出したCOMポートをコンボボックスに追加する。
- COMポートを設定する。
- データを送信する。
- データを受信する。
- COMポートを切断する。
#!/usr/bin/env python3
import os
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton,\
QComboBox, QGridLayout
from PyQt6 import QtGui ,QtCore
import serial # 1
from serial.tools import list_ports # 1
class GuiWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.set_variables()
self.build_ui()
self.connect_signal_slot()
def set_variables(self):
self.combobox = QComboBox()
self.button = QPushButton('connect')
self.detect_serial_ports() # 2
for i in range(len(self.ports)): # 3
self.combobox.addItem(str(self.ports[i]).split(' ')[0])
def build_ui(self):
self.grid = QGridLayout()
self.grid.addWidget(self.combobox, 0, 0)
self.grid.addWidget(self.button, 0, 1)
self.setLayout(self.grid)
def connect_signal_slot(self):
self.button.clicked.connect(self.main)
def main(self):
self.set_serial_port() # 4
self.send_serial_data('うんこ出た?') # 5
if self.read_serial_data() == '出たよ': # 6
print('良かったね')
else:
print('残念だったね')
self.close_serial_ports() # 7
# serial
def detect_serial_ports(self): # 2
self.ports = list_ports.comports()
def set_serial_port(self): # 4
self.use_port = str(self.combobox.currentText())
self.ser = serial.Serial(self.use_port)
self.ser.baudrate = 115200
self.ser.parity = serial.PARITY_NONE
self.ser.bytesize = serial.EIGHTBITS
self.ser.stopbits = serial.STOPBITS_ONE
self.ser.timeout = 1 #sec
def send_serial_data(self, cmd): # 5
data = cmd + "\n"
self.ser.write(bytes(data, 'UTF-8'))
def read_serial_data(self): # 6
recv_data = self.ser.readline()
recv_data = recv_data.decode('utf-8').split('<0x1b>')
recv_data = [s.replace('\r\n', '') for s in recv_data]
return recv_data
def close_serial_ports(self): # 7
self.ser.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = GuiWindow()
window.move(0,0)
window.show()
sys.exit(app.exec())
まとめ
Pythonでシリアル通信(RS-232C)を行う方法を説明した。
コメント