Название: Проблема с QSerialDevice
Отправлено: Backloz от Август 01, 2013, 11:10
Доброго всем времени суток. Недавно возникла необходимость передавать и читать данные от устройства через com порт. в программе реализован QTimer по сигналу от которого происходит вызов следующего кода void MainWindow::onDataGetTaimer() { short ADCDATA; int i=0; QByteArray Data,DATA1; DATA1.clear(); Data+=(char)0x00; ComDevice->write(Data); ComDevice->waitForBytesWritten(1); while(DATA1.size()<1) { if(ComDevice->waitForReadyRead(1)) { DATA1+=ComDevice->read(1); } i++; if(i>1000) { MessageBox1->setIcon(QMessageBox::Critical); MessageBox1->setText("Data get error"); MessageBox1->setDefaultButton(QMessageBox::Ok); MessageBox1->show(); } } i=0; DATA1.clear(); Data.clear(); Data+=(char)0x83; Data+=(char)0x03; ComDevice->write(Data); ComDevice->waitForBytesWritten(1); while(DATA1.size()<3) { if(ComDevice->waitForReadyRead(1)) { DATA1+=ComDevice->readAll(); } i++; if(i>1000) { MessageBox1->setIcon(QMessageBox::Critical); MessageBox1->setText("Data get error"); MessageBox1->setDefaultButton(QMessageBox::Ok); MessageBox1->show(); }
} GetByte(SILow,ADCDATA)=DATA1[1]; GetByte(SIHigh,ADCDATA)=DATA1[2]; DATA1.clear(); Data.clear(); }
Для настройки порта создал удобный удобный виджет. Далее приведу код данного виджета; основная инициализация происходит в ComInitDialog::OnOkButtonPress(). ComInitDialog::ComInitDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ComInitDialog) { ui->setupUi(this); //Настраиваю интерфейс ui->BRComboBox->setEditable(true); //Соединяю сигналы и слоты connect(ui->OkButton,SIGNAL(clicked()),this,SLOT(OnOkButtonPress())); connect(ui->CancelButton,SIGNAL(clicked()),this,SLOT(OnCancelButtonPress())); //ui->comboBox->setFrame(QFrame::HLine|QFrame::Raised); //ComDevice->setBaudRate() ComDevice=NULL; } ComInitDialog::~ComInitDialog() { delete ui; } //Задаёт порт который необходимо настроить void ComInitDialog::SetDevice(AbstractSerial *Device) { ComDevice=Device; //Device->setReadBufferSize(500); //ui->BRComboBox->clear(); //ui->BRComboBox->addItems(ComDevice->listBaudRate()); ui->DataComboBox->clear(); ui->DataComboBox->addItems(ComDevice->listDataBits()); ui->DataComboBox->removeItem(0); ui->ParityComboBox->clear(); ui->ParityComboBox->addItems(ComDevice->listParity()); ui->ParityComboBox->removeItem(0); ui->StopBitComboBox->clear(); ui->StopBitComboBox->addItems(ComDevice->listStopBits()); ui->StopBitComboBox->removeItem(0); ui->FlowControlComboBox->clear(); ui->FlowControlComboBox->addItems(ComDevice->listFlowControl()); ui->FlowControlComboBox->removeItem(0); } //Задаёт порт который необходимо настроить и вызывает окно настройки порта void ComInitDialog::InitDevice(AbstractSerial *Device) { ComDevice=Device; show(); } //Обработка нажатия на кнопку OK void ComInitDialog::OnOkButtonPress() { bool ok=true; if(ComDevice==NULL) { MessageBox1.setIcon(QMessageBox::Critical); MessageBox1.setText("ComDevice is null!!!"); MessageBox1.setDefaultButton(QMessageBox::Ok); MessageBox1.show(); return; } //Освобождаю порт если уже был занят if(ComDevice->isOpen()){ComDevice->close();} //Пытаюсь захватить выбранный порт ComDevice->setDeviceName(ui->PortComboBox->currentText()); //Открываю порт для чтения и записи if(!ComDevice->open(AbstractSerial::ReadWrite)) { MessageBox1.setIcon(QMessageBox::Critical); MessageBox1.setText("Can't open port!!!"); MessageBox1.setDefaultButton(QMessageBox::Ok); MessageBox1.show(); return; } if(!ComDevice->setBaudRate(ui->BRComboBox->currentText().toInt(&ok,10))) { ComDevice->listBaudRate(); ComDevice->close(); MessageBox1.setIcon(QMessageBox::Critical); MessageBox1.setText("baud rate set error!!!"); MessageBox1.setDefaultButton(QMessageBox::Ok); MessageBox1.show(); return; } if(!ComDevice->setDataBits(ui->DataComboBox->currentText())) { ComDevice->close(); MessageBox1.setIcon(QMessageBox::Critical); MessageBox1.setText("DataBits set error!!!"); MessageBox1.setDefaultButton(QMessageBox::Ok); MessageBox1.show(); return; }
if(!ComDevice->setParity(ui->ParityComboBox->currentText())) { ComDevice->close(); MessageBox1.setIcon(QMessageBox::Critical); MessageBox1.setText("Parity set error!!!"); MessageBox1.setDefaultButton(QMessageBox::Ok); MessageBox1.show(); return; } //FlowControlComboBox if(!ComDevice->setFlowControl(ui->FlowControlComboBox->currentText())) { ComDevice->close(); MessageBox1.setIcon(QMessageBox::Critical); MessageBox1.setText("FlowControl set error!!!"); MessageBox1.setDefaultButton(QMessageBox::Ok); MessageBox1.show(); return; } ComDevice->setReadBufferSize(10000); ComDevice->setTotalReadConstantTimeout(1000); ComDevice->setCharIntervalTimeout(1000); close(); } //Обработка нажатия на кнопку Cancel void ComInitDialog::OnCancelButtonPress() { close(); }
ну и приведу код основной инициализации главного окна. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); MessageBox1=new QMessageBox(); MessageBox1->setParent(this); MessageBox1->hide(); ComDevice = new AbstractSerial(); ComDevice->setParent(this); //ComDevice->setCharIntervalTimeout(5000); DockPlot = new QwtDockPlot(); DockPlot->setParent(this); addDockWidget(Qt::TopDockWidgetArea,DockPlot,Qt::Vertical); Curve1 = new QwtPlotCurve("ISENS5"); Curve2 = new QwtPlotCurve("ISENS2"); Curve3 = new QwtPlotCurve("ISENS7"); Curve1->setRenderHint(QwtPlotItem::RenderAntialiased); Curve1->setPen(QPen(Qt::red)); Curve2->setRenderHint(QwtPlotItem::RenderAntialiased); Curve2->setPen(QPen(Qt::blue)); Curve3->setRenderHint(QwtPlotItem::RenderAntialiased); Curve3->setPen(QPen(Qt::yellow)); Curve1Data = new QVector<QPointF>(); Curve2Data = new QVector<QPointF>(); Curve3Data = new QVector<QPointF>(); Dialog1 = new ComInitDialog(); Dialog1->SetDevice(ComDevice); //Dialog1->setParent(this); Dialog1->InitDevice(ComDevice); DataGetTaimer = new QTimer(this);
X=0; connect(DockPlot,SIGNAL(SendToTransClicked()),this,SLOT(DockPlotSendToTransClicked())); connect(DockPlot,SIGNAL(TransOFFClicked()),this,SLOT(DockPlotTransOFFClicked())); connect(DockPlot,SIGNAL(StartClicked()),this,SLOT(DockPlotStartClicked())); connect(DockPlot,SIGNAL(StopClicked()),this,SLOT(onStopPress())); connect(DataGetTaimer,SIGNAL(timeout()),this,SLOT(onDataGetTaimer())); Curve1->attach(DockPlot->GetPlot()); Curve2->attach(DockPlot->GetPlot()); Curve3->attach(DockPlot->GetPlot()); }
вобщемто всё работает данные передаются и принимаются однако через какоето время комп уходит в перезагрузку. Так и не могу понять в чём дело. Подскажите пожалуйста.
Название: Re: Проблема с QSerialDevice
Отправлено: kuzulis от Август 01, 2013, 13:49
1. Используй QtSerialPort (http://qt-project.org/wiki/QtSerialPort_Russian)
Оно уже есть в Qt5.1 по умолчанию. Также легко собирается и юзается для Qt4.8.x. (см. Wiki, ссылку на которую я привел).
QtSerialPort - это потомок QSerialDevice, поэтому особых проблем со сменой API быть не должно. :) QSerialDevice - уже давно больше не поддерживается и я даже отвечать на вопросы связанные с ним не буду. Точка!
2. Не используй блокирующее чтение/запись с waitForXXX(). Используй асинхронный I/O с сигналами readyRead(), bytesWritten() и т.п.
|