Задать вопрос
@Kopcheniy

Микроконтроллер отправляет через UART-USB преобразователь строки в виртуальный COM порт. Почему они отображаются кусками?

Микроконтроллер отправляет через UART-USB преобразователь данные в виртуальный COM порт.
Микроконтроллер отправляет строки вида
uint8_t str[] = "Command received\0";
HAL_UART_Transmit(&huart1, str, 16, 30);

Приложение на PyQt 5 читает строки так:
rx_data = self.serial.readLine()
#rx_data1 = self.serial.readAll()
rx_str = str(rx_data, 'utf-8')# Переводим массив байт в строку
#Помещаем строку в поле для вывода текста
self.plainTextEditLog.appendPlainText(rx_str)


Проблема в том, что строки читаются кусками (частями). Причём части время от времени меняются. Пример вывода в текстовое поле:
C
ommand recei
ved
E
nab
led
C
ommand r
eceived
C
ommand
received

Возможно, нужно добавить символы конца строки \r\n (или какие?), если используется readLine()?
Пробовал читать документацию (например, эту), искал примеры. Но пока до конца не понял разницу между readLine() и readAll().

Кто знает, подскажите пожалуйста.
  • Вопрос задан
  • 98 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 2
NeiroNx
@NeiroNx
Программист
Они отображаются по мере приема данных и опроса буфера приема(аппаратного).
Само собой опрос буфера приема не синхронизирован с отправкой данных.
Он опрашивается настолько часто что там только всегда куски передачи.
Принимайте в свой буфер, накапливайте и обрабатывайте по приему символа конца строки("\r\n").
Ответ написан
@Kopcheniy Автор вопроса
Объявляем в конструкторе окна строку — свой буфер.
#Буфер для накапливания строк из ком порта.
        self.serialStrbuffer = ""

Накапливаем её до прихода символа конца строки, потом разделяем строку на этом символе и помещаем в список. Затем, если конечный элемент списка – пустая строка, то выводим все элементы списка кроме последнего в своё текстовое поле.
def onRead(self):
        rx_data = self.serial.readAll()#Считываем куски строк из буфера
        rx_str = str(rx_data, 'utf-8')# Переводим массив байт в строку
        #Соединяем куски в цельные строки в нашем буфере. Разделитель "", т е без разделителя. 
        self.serialStrbuffer = "".join([self.serialStrbuffer, rx_str])
        #print(self.serialStrbuffer)

        # Разделяем строки на подстроки на символе конца строки
        tempList = self.serialStrbuffer.split("\r\n")
        #print(tempList)

        #Как только приходит кусок строки, содержащий символ конца строки \r\n,
        # в списке становится на одну строку больше. Значит в первом элементе списка целая строка.
        #Иногда прилетает сразу 2 целых строки. Поэтому сделаем цикл. Последний элемент списка 
        # содержит символ конца строки.
        length = len(tempList)
        if length>1 and tempList[length-1] == '':# Если строка не одна и последняя пустая
            
            #for string in tempList:
                #self.plainTextEditLog.appendPlainText(string)
            #Выводим все строки из списка, кроме последней.
            for i in range(0,length-1,1):
                self.plainTextEditLog.appendPlainText(tempList[i])

            self.serialStrbuffer = ""#очищаем буфер
            #  очищаем список, (он и так очистится, т к очистили буфер)


Ф-я print выводит в терминал такое
65a93da3a9a36813257037.png
Все строки, присылаемые микроконтроллером заканчиваем символом конца строки "\r\n".

Возможны и иные варианты решения, но это работает.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы