Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 30, 2019 10:59:30

banzayy
Зарегистрирован: 2019-04-30
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 и com port

подскажите, как получить список доступных COM портов?
Делаю так

from PyQt5.QtSerialPort import QSerialPort, QSerialPortInfo
ports = self.my_ports.availablePorts()
В ports ссылки на объекты
как преобразовать ports в читаемые названия портов?

только недавно занялся python, поэтому вопрос может быть и глупый. Названия нужны, чтоб отобразить их в comboBox, где будет выбор порта. Графическую часть сделал, всё без глюков. Для новичка даже очень ничего так получилось.

Отредактировано banzayy (Апрель 30, 2019 11:11:52)

Офлайн

#2 Апрель 30, 2019 12:14:40

banzayy
Зарегистрирован: 2019-04-30
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 и com port

получилось..

self.my_ports = QSerialPortInfo()
ports = self.my_ports.availablePorts()
for port in ports:
pid = port.productIdentifier()
vid = port.vendorIdentifier()
port_name = port.portName()

Офлайн

#3 Апрель 30, 2019 20:25:28

banzayy
Зарегистрирован: 2019-04-30
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 и com port

ещё один вопрос. При приёме данных с COM порта получаю строку b'\xaa\xb0\x00\xcd\x00\x00\x00'. Как преобразовать её в hex побайтно??

Офлайн

#4 Апрель 30, 2019 21:40:41

vic57
Зарегистрирован: 2015-07-07
Сообщения: 903
Репутация: +  126  -
Профиль   Отправить e-mail  

PyQT5 и com port

 >>>  s = b'\xaa\xb0\x00\xcd\x00\x00\x00'
>>> s.hex()
'aab000cd000000'
>>> 

Офлайн

#5 Май 1, 2019 10:29:33

banzayy
Зарегистрирован: 2019-04-30
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 и com port

спс, я просто неправильно hex применял. новичок просто

Офлайн

#6 Май 1, 2019 18:52:18

banzayy
Зарегистрирован: 2019-04-30
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 и com port

созрел ещё один вопрос.
после выбора СОМ порта запускается поток, в котором в бесконечном цикле идёт приём данных.
По нажатию кнопки передаются данные в com порт и, если пришёл ответ, данные возвращаются из потока.
Но так как ответ может и не прийти, например, отключен подключённый девайс или что-то с кабелем, нужен таймаут. Для этого я сделал ещё один поток, который запускается при начале передачи данных и настроил его, например на 2 секунды.
Т.е. если данные не пришли то через 2 секунды приходит сигнал, что типа связи нет. Если данные пришли раньше, то поток останавливается и ошибка не приходит.
Я не могу понять как остановить поток в PyQT5??

Отредактировано banzayy (Май 1, 2019 18:54:33)

Офлайн

#7 Май 1, 2019 21:54:02

vic57
Зарегистрирован: 2015-07-07
Сообщения: 903
Репутация: +  126  -
Профиль   Отправить e-mail  

PyQT5 и com port

код покажите

Офлайн

#8 Май 2, 2019 08:50:07

banzayy
Зарегистрирован: 2019-04-30
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 и com port

это 2 потока. Первый это таймаут, второй - приём передача данных

 class TimeOutThreadClass(QThread):
    time_out_signal = pyqtSignal(bytes)
    def __init__(self, parent=None):
        super(TimeOutThreadClass, self).__init__(parent)
    def run(self):
        self.sleep(2)
        time_error = [0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1]
        self.time_out_signal.emit(bytes(time_error))
class SerialThreadClass(QThread):
    rx_signal = pyqtSignal(bytes)
    avaliable_comport_list = ['']
    def __init__(self, port, parent=None):
        super(SerialThreadClass, self).__init__(parent)
        # open the serial port
        self.serport = QSerialPort()
        self.serport.setBaudRate(14400)
        self.serport.setPortName(port)
        self.serport.open(QIODevice.ReadWrite)
    def select_port(self):
        self.my_ports = QSerialPortInfo()
        ports = self.my_ports.availablePorts()
        for port in ports:
            port_name = port.portName()
            SerialThreadClass.avaliable_comport_list.append(port_name)
        print(SerialThreadClass.avaliable_comport_list)
        return SerialThreadClass.avaliable_comport_list
    def run(self):
        while True:
            rx_data = self.serport.readLine()
            if len(rx_data) > 0:
                self.rx_signal.emit(bytes(rx_data))
            self.msleep(5)
    def senddata(self, data):
        tx_data = bytes(data)
        self.serport.write(tx_data)

после выбора нужного порта запускаем

[code python]
def list_comport(self):
port = self.comboBox.currentText()
self.my_thread = SerialThreadClass(port)
self.time_out_thread = TimeOutThreadClass()
if self.my_thread.serport.isOpen() is True:
self.textBrowser.append('порт {} открыт'.format(str(port)))
self.my_thread.rx_signal.connect(self.on_change, QtCore.Qt.QueuedConnection)
self.time_out_thread.time_out_signal.connect(self.on_change, QtCore.Qt.QueuedConnection)
self.my_thread.start()
[/code]

по нажатию кнопки;
     def btn_init(self):
        my_list = [0xAA, 0xB0, 0x00, 0xCD, 0x00, 0x00, 0x00]
        self.my_thread.senddata(my_list)
        self.time_out_thread.start()

после приёма данных проверяем на ошибки
     def check_error_rx(self, data):
        if len(data) != 7:
            text_error = 'ошибка передачи данных'
           [b] self.time_out_thread.terminate()[/b]
            return text_error
        if data[6] == 0xE1:
            text_error = 'нет связи или устройство не отвечает'
            return text_error
        text_error = 'Ok'
        return text_error
и вот этом методе пытаюсь остановить поток. Вроде как по документации не желательно использовать terminate. Должно останавливать, но нет.

Код немного кусками, извините. просто я сначала пробую работу в маленьких программах, а затем, когда уже разобрался, переношу в своё приложение. Можно было бы использовать TIMEOUT из QSerialPort(), но не пойму как настроить. Ошибка по таймауту есть, а в настройках порта его настройки нет. Можно конечно попробовать PYSERIAL, но т.к. делаю в PyQt5, хочется обойтись штатными средствами

Отредактировано banzayy (Май 2, 2019 08:51:17)

Офлайн

#9 Май 2, 2019 08:54:28

banzayy
Зарегистрирован: 2019-04-30
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 и com port

если какие то баги в оформлении кода или что-то можно сделать красивее, подсказывайте. Это реально первые шаги в Python. Хочу немного сам поднатаскаться и пойти на курсы поучиться…Для себя

Офлайн

#10 Май 2, 2019 10:43:57

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQT5 и com port

banzayy
Но так как ответ может и не прийти, например, отключен подключённый девайс или что-то с кабелем, нужен таймаут. Для этого я сделал ещё один поток,

banzayy имхо вы подходите не с той стороны, не плодите потоки сверх необходимого, а читайте документацию:
https://doc.qt.io/qt-5/qserialport.html
там есть такая штука waitForReadyRead. Я лично не пользовался QSerialPort-ом, но судя по документации, использовать нужно както так:

 ....
serial = QSerialPort()
....
if serial.waitForReadyRead(timeout):
    res =serial.readLine()
   
и никаких дополнительных потоков нафик не нужно..



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Май 2, 2019 10:51:01)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version