PDA

View Full Version : Qextserial on debian linux and readyRead slot



zamek42
13th December 2013, 10:19
Hi All,
I would like to use Qextserial in debian linux with readyRead signal. There is no error on init, but it cannot send signal.
Here is my settings:



mSerialPort = new QextSerialPort("/dev/ttyUSB0", QextSerialPort::EventDriven);
mSerialPort->setBaudRate(BAUD921600);
mSerialPort->setDataBits(DATA_8);
mSerialPort->setStopBits(STOP_1);
mSerialPort->setParity(PAR_NONE);
mSerialPort->setFlowControl(FLOW_OFF);
mSerialPort->setQueryMode(QextSerialPort::EventDriven);
mSerialPort->setRts(true);
mSerialPort->setDtr(true);

QObject::connect(mSerialPort, SIGNAL(readyRead()), this, SLOT(dataAvailable()));
mSerialPort->open(QIODevice::ReadWrite);
if (!mSerialPort->isOpen())
log_exception(PacketDriverException, "cannot open %s", "/dev/ttyUSB0");


I read a post here

http://www.qtcentre.org/threads/15622-QExtSerialPort-with-readyRead()

from 2008, it said I can' t use signal in linux :(
Is it true?
How can I set to use signals?

thx a lot
Zamek

^NyAw^
13th December 2013, 10:28
Hi,

This is a deprecated library. Use QtSerialPort instead that is developed by Qt team. It is a part of Qt 5 and also can be used on Qt 4 as a module.

zamek42
14th December 2013, 10:35
Hi,

This is a deprecated library. Use QtSerialPort instead that is developed by Qt team. It is a part of Qt 5 and also can be used on Qt 4 as a module.

Thx for your response. I changed to QtSerialPort, but unfortunately it doesn't works:(
QExtSerial can read but didn't send signal, QtSerial doesn't read in polling mode:(

There is hardware which sends 80bytes of frames with 921600 8N1 no flow.
Here is the code which I tried:


mSerialPort.setPortName("/dev/ttyUSB0");
mSerialPort.open(QIODevice::ReadWrite);

if (!mSerialPort.isOpen())
log_exception(PacketDriverException, "cannot open %s", "/dev/ttyUSB0");

if (! (mSerialPort.setBaudRate(921600, QSerialPort::AllDirections) &&
mSerialPort.setDataBits(QSerialPort::Data8) &&
mSerialPort.setStopBits(QSerialPort::OneStop) &&
mSerialPort.setParity(QSerialPort::NoParity) &&
mSerialPort.setFlowControl(QSerialPort::NoFlowCont rol)))
log_exception(PacketDriverException, "cannot set params of %s", "/dev/ttyUSB0");

mSerialPort.clearError();
mSerialPort.flush();
mSerialPort.clear(QSerialPort::AllDirections);

QObject::connect(&mSerialPort, SIGNAL(readyRead()), this, SLOT(dataAvailable()));
QObject::connect(&mSerialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(error()));
QByteArray b = mSerialPort.readAll();
std::cout<<b.size()<<std::endl;



There is no error and data comings to port. Size of b is 0.
What did I do wrong?

thx
Zamek

kuzulis
14th December 2013, 17:21
YourClass::dataAvailable()
{
QByteArray b = mSerialPort.readAll();
std::cout<<b.size()<<std::endl;
}

zamek42
14th December 2013, 18:43
Hi,





YourClass::dataAvailable()
{
QByteArray b = mSerialPort.readAll();
std::cout<<b.size()<<std::endl;
}



Yes my dataAvailable is:


void PacketDriver::dataAvailable()
{
if (mSerialPort.isReadable())
readChar(mSerialPort.readAll());
}

void PacketDriver::error()
{
QString err=mSerialPort.errorString();
qDebug()<<err;
mSerialPort.clearError();
}


but I use readAll at end of open, because there is no signal. After I open the port and there are incoming data I have to read something with readAll.
I started this with QExtSerial, which can read after open, but it cannot send signals. QtSerial cannot read after open and cannot send signal:(
The hardware continuously send 80 bytes of frames at every 5 ms. Cutecom and gtkterm can read it.

kuzulis
14th December 2013, 20:59
So, the readyRead() signal does not emitted never? Can you test it with use the Terminal example from the QtSerialPort?

zamek42
15th December 2013, 09:12
So, the readyRead() signal does not emitted never? Can you test it with use the Terminal example from the QtSerialPort?

Hi Kuzulis,

creaderasync example works well. And I try to modify it, because it passing QSerialPort as a pointer in constructor, but I need to instantiate QSerialport in my constructor.
There is the problem, because when I try to instantiate in constructor it doesn't works, but no error!

Here is my test version:



#include "serialportreader.h"

#include <QCoreApplication>
#include <iostream>

QT_USE_NAMESPACE

#ifdef TEST
SerialPortReader::SerialPortReader(QObject *parent)
#else
SerialPortReader::SerialPortReader(QSerialPort *serialPort, QObject *parent)
#endif
: QObject(parent)
#ifndef TEST
, m_serialPort(serialPort)
#endif
, m_standardOutput(stdout)
{
#ifdef TEST
m_serialPort = new QSerialPort();

if (!m_serialPort->open(QIODevice::ReadWrite))
return;

if (!m_serialPort->setBaudRate(921600))
return;

if (!m_serialPort->setDataBits(QSerialPort::Data8))
return;

if (!m_serialPort->setParity(QSerialPort::NoParity))
return;

if (!m_serialPort->setStopBits(QSerialPort::OneStop))
return;

if (!m_serialPort->setFlowControl(QSerialPort::NoFlowControl))
return;
#endif
connect(m_serialPort, SIGNAL(readyRead()), SLOT(handleReadyRead()));
connect(m_serialPort, SIGNAL(error(QSerialPort::SerialPortError)), SLOT(handleError(QSerialPort::SerialPortError)));
}

SerialPortReader::~SerialPortReader()
{
}

void SerialPortReader::handleReadyRead()
{
m_readData = m_serialPort->readAll();
std::cout<<"read, size:"<<m_readData.length()<<std::endl;

if (!m_timer.isActive())
m_timer.start(5000);
}

void SerialPortReader::handleTimeout()
{
if (m_readData.isEmpty()) {
m_standardOutput << QObject::tr("No data was currently available for reading from port %1").arg(m_serialPort->portName()) << endl;
} else {
m_standardOutput << QObject::tr("Data successfully received from port %1").arg(m_serialPort->portName()) << endl;
m_standardOutput << m_readData << endl;
}

QCoreApplication::quit();
}

void SerialPortReader::handleError(QSerialPort::SerialP ortError serialPortError)
{
if (serialPortError == QSerialPort::ReadError) {
m_standardOutput << QObject::tr("An I/O error occurred while reading the data from port %1, error: %2").arg(m_serialPort->portName()).arg(m_serialPort->errorString()) << endl;
QCoreApplication::exit(1);
}
}



So, how can I instantiate QSerialport at constructor?

thx
Zamek

zamek42
15th December 2013, 13:21
Some advance:

Is it true I need to use connect before I open the port? In terminal example does this.
I tried to this, and in open I get an error: "No such file or direcory". I tried /dev/ttyUSB0 and ttyUSB0 too.



PacketDriver::PacketDriver(const QString& cfgPrefix)
: mFifo(cfgPrefix)
{
mSerialPort = new QSerialPort(this);

connect(mSerialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(error()));
connect(mSerialPort, SIGNAL(readyRead()), this, SLOT(onReadyRead()));

mSerialPort->setPortName("/dev/ttyUSB0");

if (!mSerialPort->open(QIODevice::ReadWrite))
log_exception(PacketDriverException, "cannot open /dev/ttyUSB0");

if (!mSerialPort->setBaudRate(921600))
log_exception(PacketDriverException, "cannot set baud 921600");

if (!mSerialPort->setDataBits(QSerialPort::Data8))
log_exception(PacketDriverException, "cannot set databits 8");

if (!mSerialPort->setParity(QSerialPort::NoParity))
log_exception(PacketDriverException, "cannot set noparity");

if (!mSerialPort->setStopBits(QSerialPort::OneStop))
log_exception(PacketDriverException, "cannot set one stopbits");

if (!mSerialPort->setFlowControl(QSerialPort::NoFlowControl))
log_exception(PacketDriverException, "cannot set noflow");
}

void PacketDriver::error()
{
QString err=mSerialPort->errorString();
std::cout<<"Error:"<<err.toStdString()<<std::endl;
}

void PacketDriver::onReadyRead()
{
std::cout<<"dataAvailable";
if (mSerialPort->bytesAvailable()) {
QByteArray bytes = mSerialPort->readAll();
std::cout<<", bytes:"<<bytes.length()<<std::endl;
readChar(bytes);
}
}



Could I debug into QtSerial?

thx
Zamek

kuzulis
15th December 2013, 13:23
Seems, you missed setup a port name, like:




SerialPortReader::SerialPortReader(...)
{
...

m_serialPort = new QSerialPort();

m_serialPort->setPortName("/dev/ttyUSB0"); // << :)

if (!m_serialPort->open(QIODevice::ReadWrite))
return;
...
}


UPD:


Is it true I need to use connect before I open the port? In terminal example does this.

Yes, you can... Has no difference do it before or after than open(). But if you do QObject::connect() after open(), don't forget after close() to call QObject::disconnect().


I tried to this, and in open I get an error: "No such file or direcory". I tried /dev/ttyUSB0 and ttyUSB0 too.

It because maybe really a port is not present.


Could I debug into QtSerial?

Yes, of course.

zamek42
15th December 2013, 17:09
hi,


Seems, you missed setup a port name, like:

Yes thx, it was a little mistake, I already found it...



It because maybe really a port is not present.


No, the port continuously works, cutecom, gtkterm and qtserialport example terminal can use it and works well. There is a hw, which always sends 80 bytes of frames at every 5 ms.
I used to check with lsof /dev/ttyUSB0 to opened locks. I am the member of dialout groups.

What do I need to set for debugging into source of qtserialport?
When I debug my program, I see the address of serialport, but I can't see the variables and I cannot step into a function.

thx
Zamek

kuzulis
15th December 2013, 19:33
What do I need to set for debugging into source of qtserialport?

Build *.so library as "debug" target... Or directly connect the sources via "serialport-lib.pri" file (imho, *.pri - it is preffered and simple to do gebugging).

zamek42
18th December 2013, 18:32
Hi Kuzulis,

I found the problem. I wrote this test inside an infinite loop, so the main thread couldn't runs and there was no emitted event on received char.
It was good lesson for me: the main thread cannot blocked!

Many thx to you

Zamek