Как правильно передать данные из COM порта

95
28 июня 2019, 06:00

В COM порт поступают данные вида 0,0,999,000000110: , получив строку ее надо привести к виду 0,0,999,0,0,0,0,0,0,1,1,0... чтоб в последующем я смог в QML файле обратиться к любому из них, что я собственно и реализовал:

void SerialPort::onReadData()
{
    if(arduino->bytesAvailable()>0){
      QByteArray data = arduino->readAll();
      QString value = QString(data).trimmed(); 
      QStringList sl = value.split(",");
      QString qqq;
      std::vector<QString> fullData;
      fullData.reserve(sl.size() + 12);
      for(int i = 0; i < sl.size()-1; i++)
          fullData.push_back(sl[i]);
      QString lastItem = sl[sl.size()-1];
      lastItem.chop(2);
      for(int i = 0; i < lastItem.size(); i++)
         fullData.push_back(QString(lastItem[i])); 
      for(int i = 0; i <fullData.size(); i++)
         qqq+= fullData[i]+',';
      set_serial_data(qqq);
      //qDebug()<< qqq ;
    }
}

и сам вывод

 SerialPort
    {
        id: cppClass
    }
    Text
    { 
        text: cppClass.serial_data[5] 
    }
    Text
    { 
        text: cppClass.serial_data[2] 
    }

Проблема в том, что данные в этой ячейке к которой я обращаюсь скачет(меняется). Посмотрев Debug , увидел что есть моменты где считает до 4 числа и начинает счет заново с 0. Получается, что данные не успевают отобразиться как уже переписываются. Еще постоянно выскакивает ошибка unable to assign [undefined] to QString Как сделать так, чтоб я получил массив своих чисел 0,0,999,0,0,0,0,0,0,1,1,0 - потом считал их, через определенный промежуток времени опять, получил - считал... ?

Answer 1

запись идет одна статического размера 12 значений такого вида, 0,0,999,000000110:

Ожидать, что readAll() будет возвращать одну целую запись не следует, для такого медленного интерфейса как последовательный порт сигнал readyRead(), вероятней всего будет прилетать на каждый байт. Так что данные необходимо накапливать по мере получения, после получения целой записи просматривать полностью. Типовое чтение будет выглядеть примерно следующим образом (не отлажено):

class SerialPort {
//...
private:
  QByteArray dataBuffer;
}
//...
void SerialPort::onReadData () {
  QByteArray dataRecv = arduino->readAll ();
  int sepPos = dataRecv.indexOf (':');
  int dataBufSz = dataBuffer.size ();
  dataBuffer.append (dataRecv);
  if (sepPos!=-1) {
    int recStart = 0;
    sepPos += dataBufSz;
    do {
      processSingleRecord (dataBuffer.mid (recStart, sepPos - recStart));
      recStart = sepPos + 1;
      sepPos = dataBuffer.indexOf (':', recStart);
    } while (sepPos!=-1);
    dataBuffer = dataBuffer.mid (recStart);
  }
}
void SerialPort::processSingleRecord (QByteArray data) {
  // ... разбор полученной записи и связанные действия
}

По поводу вопроса: возможны и другие ошибки.

READ ALSO
Ошибка в с++ программа

Ошибка в с++ программа

Найти сумму под и над главной диагональю ПРИМЕР 1 2 3 4 5 6 7 8 9 над ней будет 2+3+6=11 - правильно, а под 4+7+8=19 , а выдает 15 (7+8) Вот код:`

120
Как использовать Qt в C++ без QtCreator?

Как использовать Qt в C++ без QtCreator?

Как я могу использовать Qt без QtCreator?

96
Специализация шаблонной функции для std::string

Специализация шаблонной функции для std::string

Есть шаблонная функция, принимающая аргумент произвольного типаХочется сделать специализацию этой функции для строк, но при этом строку...

112
Логические операторы c++

Логические операторы c++

Начал учить с++, на теме логических операторов после пары минут экспериментов наткнулся на то, что есть некоторые нелогичные моменты у логических...

111