Qserialdevice 2.0 waitForBytesWritten halfduplex question
I have a question, writing a Qt GUI and I have the RTS line connected to a RS-485 driver transmit/receive control signal. I am sending out x number of bytes, I use the setRts(1) to make it go high (start of transmisson) and setRts(0) when I finish (as direction control). Does the waitForBytesWritten method work? I want it to wait until all the bytes have been transmitted out of the serial port, so I can setRts low. I see that sometimes the RTS signal is going low before all the bytes have been transferred. Any one have any ideas?
Do I have to set it up in unbuffered mode?
Here is a snippet of my code. Thanks in advance.
Code:
void TraceDialog::procSendButtonClick()
{
data.append(ui->lineEdit->text());
m_port->setRts(1);
if (data.size() > 0) {
m_port->write(data);
printTrace(data, false);
ui
->lbError
->setText
(QString::number(m_port
->error
()));
}
// Add in sleep timer
while(m_port->waitForBytesWritten(15)); // Time out for 15 ms
m_port->setRts(0);
}
Re: Qserialdevice 2.0 waitForBytesWritten halfduplex question
To be honest, this method waitForBytesWritten() has not been tested.
>Do I have to set it up in unbuffered mode?
Try it.
Re: Qserialdevice 2.0 waitForBytesWritten halfduplex question
Hi Kuzulis,
I see your the expert in qserialdevice. I added a delay (depends on bytes sent and baud rate) to change the RTS signal. Seems to work.
I have another question I want to receive back a variable string of bytes. The first byte contains the amount (max is 255) is there a way to read one byte and then read x bytes depending on the first byte? In the code below I see the first byte with a msgsize of 15, but I don't see the 15 bytes of data. I know they are coming over because I can see them on the logic analzer. Do you know what is wrong?
Thanks
void TraceDialog::procReadyRead()
{
while(m_port->bytesAvailable() < 1) {} //wait for datacount
char msgsize[1];
// Read the first byte to determine amount of bytes
qint64 datacnt = m_port->read(msgsize, 1);
char datamsg[32];
while(m_port->bytesAvailable() == 15) {} //wait for datacount
qint64 data2cnt = m_port->read(datamsg, 15);
//QByteArray data = m_port->readAlll();
//printTrace(data, true);
ui->lbError->setText(QString::number(m_port->error()));
}
Re: Qserialdevice 2.0 waitForBytesWritten halfduplex question
Do not use call waiting with a "while", because of this, you're slow/freeze Qt event loop.
Use signals and slots.
To find out about the possibility of reading the first 15 bytes, for example, can after first emitted signal readyRead(), make to run QTimer, with wait timeout limit. Thus, after each emitting readyRead() to check the number of bytes available for reading bytesAVailable(), and if it is >= 15 then reset QTimer and read the data; if <15 then do nothing (wait for the next readyRead()). If worked signal from QTimer, then the limit has expired timeout - then do something.
Ie this approach the analysis and reading the input data will be executed asynchronously, as if with a delay in phase relative to their real receive.
So it must be done!
Re: Qserialdevice 2.0 waitForBytesWritten halfduplex question
Thanks for your help, this works without the timer. Going to add in a timeout if I don't get the message in (baud_rate*numbytes) time to reset msgsize back to zero. I will never use while loops in a slot.
void MainWidget::procSerialDataReceive()
{
if (this->initTraceWidget() && this->serial && this->serial->isOpen()) {
if ((msgsize == 0) && (serial->bytesAvailable() >= 1))
{
QByteArray msg_size = this->serial->read(1);
msgsize = msg_size[0];
}
if ((msgsize != 0) && (this->serial->bytesAvailable() >= msgsize))
{
QByteArray data = this->serial->read(msgsize);
msgsize = 0;
this->traceWidget->printTrace(data, true);
}
}
}