Retake control of serial port after using QProcess
-
Hi,
I'm writing a qt linux application to exchange files between two computers using zmodem protocol via Serial port and PSTN network. I'm using serial->write and waitforbytewritten functions to write data to serial port and readyRead() signal to read data from serial port. I open the serial port using the readwrite mode and i establish connection between the two computers.connect(serial, SIGNAL(readyRead()), SLOT(handleReadyRead())); connect(ui->chat,SIGNAL(returnPressed()),this,SLOT(chat()));//chat is a QLineEdit void MainWindow::chat(){ QString str1= ui->chat->text(); char* str2 = qstringToCharEtoile(str1);//function to convert qstring to char* quint16 byteWritten=serial->write(str2); serial->waitForBytesWritten(-1); qDebug()<<byteWritten<<":"<<str2; } void MainWindow::handleReadyRead() { char data[300]; serial->readLine(data,300); this->outputerror->putData(data);//outputerror is a plainTextEdit if(strlen(data)>3){ for(int i=3;i<strlen(data);i++) if(data[i-3]=='r'&&data[i-2]=='z'&&data[i-1]=='r'&&dataSerial[i]=='z'){ receiveFile();//if we receive rzrz via serialport we start the zmodem receiving process } } }
Everything works fine. I can read and write data between the two computers. After that, I use QProcess to send a file using zmodem protocol.
connect(ui->sendFile, SIGNAL(clicked()), this, SLOT(sendFile())); void MainWindow::sendFile() { serial->write("rzrz");//write rzrz to start receiving file in the other side serial->waitForBytesWritten(-1); m_sz = new QProcess(this); QStringList listProcessArgs; listProcessArgs.append("-c"); QString device = ui->ports->currentText(); QString tmp = "sz --zmodem --resume --binary " + filename + " <" + device + " >" + device; listProcessArgs.append(tmp); m_sz->setReadChannel(QProcess::StandardOutput); m_sz->setProcessChannelMode(QProcess::MergedChannels); m_sz->start("sh", listProcessArgs); if (!m_sz->waitForStarted()) { QMessageBox::information(this, tr("Comm error"), tr("Could not start sz")); delete m_sz; //openDevice(); return; } m_progress = new QProgressDialog(tr("Sending file via %1 ...").arg("ZMODEM"), tr("Cancel"), 0, 100, this); m_progress->setMinimumDuration(100); m_progress->setValue(0); int i=0; while (m_rz->state() == QProcess::Running) { m_rprogress->setValue(i); i++; if(i==100)i=0; millisleep(10L); } m_sz->waitForFinished(); m_sz->closeReadChannel(QProcess::StandardOutput); m_sz->closeReadChannel(QProcess::StandardError); m_sz->closeWriteChannel(); if (m_sz != nullptr) m_sz->terminate(); if (m_progress != nullptr) m_progress->close(); delete m_sz; m_sz=nullptr; delete m_progress; m_progress=nullptr; } void MainWindow::receiveFile() { m_rz = new QProcess(this); QStringList listProcessArgs; listProcessArgs.append("-c"); QString device = ui->ports->currentText();//the name of the serialport QString tmp = "rz --zmodem --resume --binary --overwrite --o-sync >" + device + " <" + device ; listProcessArgs.append(tmp); m_rz->setReadChannel(QProcess::StandardOutput); m_rz->setProcessChannelMode(QProcess::MergedChannels); m_rz->start("sh", listProcessArgs); if (!m_rz->waitForStarted()) { QMessageBox::information(this, tr("Comm error"), tr("Could not start sz")); delete m_rz; return; } m_rprogress = new QProgressDialog(tr("Receiving file via %1 ...").arg("ZMODEM"), tr("Cancel"), 0, 100, this); m_rprogress->setMinimumDuration(100); m_rprogress->setValue(0); int i=0; while (m_rz->state() == QProcess::Running) { m_rprogress->setValue(i); i++; if(i==100)i=0; millisleep(10L); } m_rz->waitForFinished(); m_rz->closeReadChannel(QProcess::StandardOutput); m_rz->closeReadChannel(QProcess::StandardError); m_rz->closeWriteChannel(); if (m_rz != nullptr) m_rz->terminate(); if (m_rprogress != nullptr) m_rprogress->close(); delete m_rz; m_rz=nullptr; delete m_rprogress; m_rprogress=nullptr; }
I can transmit a file between the two computer. After that I can't write anything to the serial port, when I use the chat to send data nothing received by the other side.
Do you have any idea why I can't send any data?
Thanks,
madababi -
Hi and welcome
Since you are using zmodem to transfer file, have you tried
to close comport and reopen in main app to make sure
its no longer expecting zmodem control chars ? -
Hi,
Thanks for the reply,
If i close and reopen the comport everything work fine. But the problem is that I will loose the connection established between the two computers and I must start a new session.
I'm searching a way to retake control of the serial port without loosing connection. -
Hi,
Thanks for the reply,
If i close and reopen the comport everything work fine. But the problem is that I will loose the connection established between the two computers and I must start a new session.
I'm searching a way to retake control of the serial port without loosing connection.Ok I understand.
Have you checked that QProcess with sz is 100% terminated ?
Its not because sz is still running?Would it be possible to disable zmodem with sz ?
-
I use QProcess waitForFinished() function to ensure that it terminate. I checked process running using the command
ps -aux
but sz dosn't exist.
the weired thing is that this problem occurs only in the sending (sz) side. in the receiving side (rz) I can send data and read it in the sending side using the chat function. -
Hmm
sound it sounds terminated.
Have you tested if running manually in shell also
blocks the comport after? -
Yes, it block the comport, I only can send data from the receiving side.
It's for that reason that i think that my qt application loose the control over the serial port.