Серийное сообщение получено частично - PullRequest
0 голосов
/ 29 апреля 2019

Я пытаюсь получить последовательное сообщение от устройства, похоже, что сигнал readyRead () активируется после 1, 2 или более символов, появившихся в последовательном буфере.

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{

ui->setupUi(this);

timerTx = new QTimer(this);
timerTx->setInterval(100);

timer.start();
serialRx = new QSerialPort(this);

serialRx->setPortName("COM5"); 
serialRx->setBaudRate(QSerialPort::Baud9600);
serialRx->setParity(QSerialPort::NoParity);
serialRx->setDataBits(QSerialPort::Data8);
serialRx->setStopBits(QSerialPort::OneStop);
serialRx->setFlowControl(QSerialPort::NoFlowControl);

serialTx = new QSerialPort(this);

serialTx->setPortName("COM3"); 
serialTx->setBaudRate(QSerialPort::Baud9600);
serialTx->setParity(QSerialPort::NoParity);
serialTx->setDataBits(QSerialPort::Data8);
serialTx->setStopBits(QSerialPort::OneStop);
serialTx->setFlowControl(QSerialPort::NoFlowControl);

connect(serialRx, SIGNAL(readyRead()), this, SLOT(serialReceive()));
connect(timerTx, SIGNAL(timeout()), this, SLOT(serialSend()));
connect(ui->pushButton, SIGNAL(clicked()), timerTx, SLOT(start()));

}

void MainWindow::serialReceive()
{
QByteArray baRx, num, numOfMs;

qint64 time_ms;
baRx = serialRx -> readAll();

qDebug() << baRx;

time_ms = timer.elapsed();

counterRecDev++;
num = QByteArray::number(counterRecDev);
numOfMs = QByteArray::number(time_ms);

ui->receiveWindow->insertPlainText(num + "\t" + baRx + " \t " + numOfMs + 
"\n" );
ui->receiveWindow -> moveCursor(QTextCursor::End);
}

Я отправляю сообщение "@ Test $" через последовательный порт, но получаю следующее: "@" «Т» "стандартное восточное время" "%" Другое время: "@" «Т» «эс» «Т» "%"

Подскажите пожалуйста, как это решить? Может быть, проблема в том, что я использую сигнал readyRead ()?

С наилучшими пожеланиями.

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

Я столкнулся с проблемами при получении сообщений QSerialPort по множественным сигналам readyRead.Наличие накопительного буфера может помочь вам, но вам понадобится либо начальный, либо конечный идентификатор.

0 голосов
/ 29 апреля 2019

Использование readyRead () - это нормально, но вы должны проверить в своем коде, что все ожидаемые данные получены, перед их обработкой.Обычно это делается с помощью символов запуска и остановки в сообщениях и проверки того, что полученные данные содержат оба перед обработкой (похоже, вы уже используете для этого "@" и "$). И так как чтение из QSerialPort очистит его буфер,Вам также нужно будет буферизовать полученные данные в своем коде, пока он не будет готов к обработке. Вы можете сделать что-то вроде этого:

QByteArray rxBuffer;
void MainWindow::serialReceive()
{
   rxBuffer.append(serialRx -> readAll());
   while(rxBuffer.contains("@") && rxBuffer.contains("$")) {
      QByteArray message;

      // Discard any data preceding message start character
      rxBuffer = rxBuffer.right(rxBuffer.length() - rxBuffer.indexOf("@"));

      // Take first complete message from the buffer
      message = rxBuffer.left(rxBuffer.indexOf("$") + 1);

      // Remove extracted message from buffer
      rxBuffer = rxBuffer.right(rxBuffer.length() - rxBuffer.indexOf("$") - 1);

      // Your code here

   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...