Вопрос:
Я пытаюсь прочитать данные, отправленные через разъем устройства через usb. Сначала я прочитал данные с помощью этой команды
- sudo stty -F/dev/ttyUSB0 1200 sane parenb evenp cs7 -crtscts
- cat/dev/ttyUSB0
И данные подобны этому
TGPHI_s -0,24 = MESURES2 BT 4 SUP36 A PTCOUR2 HPH /
Теперь я хочу прочитать данные через программу Qt5.3
QSerialPort serial; serial.setPortName(«ttyUSB0»); if(!serial.setBaudRate(QSerialPort::Baud1200 , QSerialPort::Input)) qDebug() << serial.errorString(); if(!serial.setDataBits(QSerialPort::Data7)) qDebug() << serial.errorString(); if(!serial.setParity(QSerialPort::EvenParity)) qDebug() << serial.errorString(); if(!serial.setFlowControl(QSerialPort::HardwareControl)) qDebug() << serial.errorString(); if(!serial.setStopBits(QSerialPort::OneStop)) qDebug() << serial.errorString(); if(!serial.open(QIODevice::ReadOnly)) qDebug() << serial.errorString(); qDebug() << serial.bytesAvailable(); while(true) { if (serial.isOpen()) { qDebug() << «Serial port is open…»; QByteArray datas = serial.readAll(); if (datas.size() == 0) { qDebug() << «Arrived data: 0»; } else { for (int i = 0; i < datas.size(); i++){ if (datas.at(i)) { qDebug() << datas[i]; } } } } else { qDebug() << «OPEN ERROR: » << serial.errorString(); } } return 0;
и ответ ->
«/dev/ttyUSB0» 0 Serial port is open… Arrived data: 0 Serial port is open… Arrived data: 0
Таким образом, моя программа не улавливает данные… Мои вопросы:
- Я что-то пропустил в настройке QSerialPort?
- Если нет, почему нет отображения данных через qDebug()
РЕДАКТИРОВАТЬ
Благодаря майку я могу окончательно прочитать это устройство USB! вот мой последний код
QSerialPort serial; serial.setPortName(«ttyUSB0»); if(!serial.setBaudRate(QSerialPort::Baud1200)) qDebug() << serial.errorString(); if(!serial.setDataBits(QSerialPort::Data7)) qDebug() << serial.errorString(); if(!serial.setParity(QSerialPort::EvenParity)) qDebug() << serial.errorString(); if(!serial.setFlowControl(QSerialPort::HardwareControl)) qDebug() << serial.errorString(); if(!serial.setStopBits(QSerialPort::OneStop)) qDebug() << serial.errorString(); if(!serial.open(QIODevice::ReadOnly)) qDebug() << serial.errorString(); QObject::connect(&serial, &QSerialPort::readyRead, [&] { //this is called when readyRead() is emitted //qDebug() << «New data available: » << serial.bytesAvailable(); qDebug() << «New data available: » << serial.bytesAvailable(); QByteArray datas = serial.readAll(); qDebug() << datas; }); QObject::connect(&serial, static_cast<void(QSerialPort::*)(QSerialPort::SerialPortError)> (&QSerialPort::error), [&](QSerialPort::SerialPortError error) { //this is called when a serial communication error occurs qDebug() << «An error occured: » << error; return qApp->quit(); }); if(!serial.open(QIODevice::ReadOnly)) qDebug() << serial.errorString(); return qApp->exec(); Лучший ответ:
Большинство функций ввода-вывода в Qt являются асинхронными. Это означает, что readAll() не readAll() получения данных. Вместо этого он возвращает доступные в настоящее время данные (данные, которые могут быть считаны с устройства без ожидания). В настоящее время вы просто вызываете readAll в бесконечном цикле (это делает поток, тратить все свое время в этом цикле, не может получить новые данные, которые, возможно, прибыли…)
Вам нужно позвонить readAll только тогда, когда вы знаете, что появились новые данные. Это можно выполнить двумя способами:
-
Неблокирующий асинхронный путь:
Используйте сигнал readyRead() чтобы получать уведомления, когда новые данные доступны на устройстве, а не циклически. Вот как вы должны делать большинство вещей в Qt, чтобы иметь возможность действовать на нескольких событиях, которые могут появиться в любое время. Ваш код можно переписать следующим образом:
#include <QtSerialPort> int main(int argc, char* argv[]){ QCoreApplication a(argc, argv); QSerialPort serial; serial.setPortName(«ttyUSB0»); if(!serial.setBaudRate(QSerialPort::Baud1200)) qDebug() << serial.errorString(); if(!serial.setDataBits(QSerialPort::Data7)) qDebug() << serial.errorString(); if(!serial.setParity(QSerialPort::EvenParity)) qDebug() << serial.errorString(); if(!serial.setFlowControl(QSerialPort::HardwareControl)) qDebug() << serial.errorString(); if(!serial.setStopBits(QSerialPort::OneStop)) qDebug() << serial.errorString(); if(!serial.open(QIODevice::ReadOnly)) qDebug() << serial.errorString(); QObject::connect(&serial, &QSerialPort::readyRead, [&] { //this is called when readyRead() is emitted qDebug() << «New data available: » << serial.bytesAvailable(); QByteArray datas = serial.readAll(); qDebug() << datas; }); QObject::connect(&serial, static_cast<void(QSerialPort::*)(QSerialPort::SerialPortError)> (&QSerialPort::error), [&](QSerialPort::SerialPortError error) { //this is called when a serial communication error occurs qDebug() << «An error occured: » << error; a.quit(); }); return a.exec(); // ^^^^^^^^ //very important: starts the Qt main event loop //this makes all asynchronous stuff possible }
-
Блокировка синхронного пути:
Используйте waitForReadyRead() чтобы заблокировать поток до тех пор, пока новые данные не waitForReadyRead() на последовательный порт. Это делает вызывающий поток неспособным ничего делать, пока на этот последовательный порт не появятся новые данные. Если этот поток был потоком GUI, это заставит приложение не отвечать на запросы в течение этого периода времени. Используйте этот подход только тогда, когда вы уверены, что это то, что вы хотите. Ваш код можно переписать следующим образом:
#include <QtSerialPort> int main(int argc, char* argv[]){ QCoreApplication a(argc, argv); QSerialPort serial; serial.setPortName(«ttyUSB0»); if(!serial.setBaudRate(QSerialPort::Baud1200)) qDebug() << serial.errorString(); if(!serial.setDataBits(QSerialPort::Data7)) qDebug() << serial.errorString(); if(!serial.setParity(QSerialPort::EvenParity)) qDebug() << serial.errorString(); if(!serial.setFlowControl(QSerialPort::HardwareControl)) qDebug() << serial.errorString(); if(!serial.setStopBits(QSerialPort::OneStop)) qDebug() << serial.errorString(); if(!serial.open(QIODevice::ReadOnly)) qDebug() << serial.errorString(); qDebug() << serial.bytesAvailable(); while(serial.isOpen()) { if(!serial.waitForReadyRead(-1)) //block until new data arrives qDebug() << «error: » << serial.errorString(); else{ qDebug() << «New data available: » << serial.bytesAvailable(); QByteArray datas = serial.readAll(); qDebug() << datas; } } return 0; }