Название: QSerialPort принимает пакет два раза
Отправлено: vorotislav от Февраль 05, 2015, 09:23
Доброго времени суток. Есть класс, в котором объект класса QSerialPort. Его сигнал readyRead(), связан с моим слотом. Слот сначала говорит, что минимальный размер пакета должен быть 15 байт, затем делает первичный разбор пакета на наличие синхробайта. (Если синхробайт первый в пакете - все отлично. Но проверяем каждый последующий байт. Если опять синхробайт - значит уже другой пакет.) Ниже сам код. void SPort::slotReadPort() { QByteArray arrayFromPort, arrayRecieve; arrayFromPort.clear(); arrayRecieve.clear(); quint64 buf = _port.bytesAvailable(); quint64 minBuf = 15; QString packet;
if (buf < minBuf) return; else { arrayFromPort = _port.read(buf); packet = arrayFromPort.toHex();
for (int i = 0; i < arrayFromPort.size(); i++) { switch (arrayFromPort.at(i)) { case 00: { // синхробайт if (i == 0) { arrayRecieve.append(arrayFromPort.at(i)); break; } else { if (i < (minBuf - 1)) { for (int z = 2; z < packet.size(); z += 3) packet.insert(z, ' '); // для ведения лога удобнее читать по байтам, вот и делю emit signalMessageOutPort("<< " + _port.portName() + " -- пришел битый пакет: " + packet); //не большой лог в главном окне программы emit signalMessageToLog("<< " + _port.portName() + " -- пришел битый пакет: " + packet); // основной лог arrayRecieve.clear(); arrayFromPort.clear(); packet.clear(); goto stop; // выход полностью из слота break; } else { QString msg = arrayRecieve.toHex(); for (int z = 2; z < msg.size(); z += 3) msg.insert(z, ' '); emit signalMessageToLog("<< " + _port.portName() + " -- " + msg); emit signalArrayOutPort(arrayRecieve); arrayFromPort.clear(); arrayRecieve.clear(); goto stop; break; } break; } } default:{ arrayRecieve.append(arrayFromPort.at(i)); break; } } } if (arrayRecieve.size() >= minBuf) { QString msg = arrayRecieve.toHex(); for (int z = 2; z < msg.size(); z += 3) msg.insert(z, ' '); emit signalMessageToLog("<< " + _port.portName() + " -- " + msg); // основной лог emit signalArrayOutPort(arrayRecieve); // передача пакета для дальнейшего разбора arrayFromPort.clear(); arrayRecieve.clear(); _port.clear(QSerialPort::Input); return; } } stop: arrayFromPort.clear(); arrayRecieve.clear(); _port.clear(QSerialPort::Input); }
Беда в том, что иногда пакеты приходят дважды. Помогите решить проблему. Отправляются точно по одному пакету (смотрю через qDebug()). Заранее благодарен
Название: Re: QSerialPort принимает пакет два раза
Отправлено: vorotislav от Февраль 05, 2015, 09:29
В основном логе вот такая картина:
05.02.2015 11:26:29 | << COM7 -- 00 22 11 f0 bb dd f0 f0 f0 11 f0 44 ee 0f f0 05.02.2015 11:26:29 | << COM3 -- 00 22 11 f0 f0 ee f0 f0 f0 11 f0 c3 22 11 0f 05.02.2015 11:26:29 | << COM5 -- 00 22 77 f0 77 dd f0 f0 f0 11 f0 88 ee c3 f0 // вот эти две строки 05.02.2015 11:26:29 | << COM5 -- 00 22 77 f0 77 dd f0 f0 f0 11 f0 88 ee c3 f0 05.02.2015 11:26:29 | << COM7 -- 00 22 f0 f0 77 dd f0 f0 f0 11 f0 3c bb 77 3c
Возможно ли такое, что сигнал readyRead испускается дважды, если да, то как "обнулить" сигнал?
Название: Re: QSerialPort принимает пакет два раза
Отправлено: Bepec от Февраль 05, 2015, 10:53
Ответ - врядли. Сериалпорт работает стабильно и без таких выкидонов. Значит ищите ответ в своём коде.
Название: Re: QSerialPort принимает пакет два раза
Отправлено: kuzulis от Февраль 05, 2015, 13:49
Для проверки достаточно запихнуть qDebug() в слот: C++ (Qt) Foo::slotReadyRead() { QByteArray data = port->readAll(); qDebug() << data; // тут нужно преобразовать в toHex }
|