PDA

View Full Version : Serial Port Reading problem



sfabel
13th February 2010, 01:18
Hi people,

using Qt4 plus qextserialport 1.1, I am trying to do couple of things. In the Constructor of my "Motor" class, which is to be controlled using the serial port, I have these two lines pertaining to the serial port. The port settings are correct, and I am also opening the correct device.



port = new QextSerialPort( portFile, portsettings );
connect(port, SIGNAL(readyRead()),this,SLOT(onReceive()));


This is my onReceive():



void Motor::onReceive()
{
QMutexLocker locker(&m);
if(port->canReadLine()) {

// ("data" is a QByteArray)
// this doesn't work: data = port->readLine(); although QIODevice has it?
char tmp[RX_BUF_SIZE];
qint64 len = port->readLine(tmp, RX_BUF_SIZE);
data.fromRawData(tmp,len);

quint8 fault = 0;

// do something with the data before
// clearing the buffer

data.clear();

rxcnt++;
}
}


What I want is that it reads the output of the serial controller board for the motor until it hits '\n' and then interprets the results. I noticed there are a variety of methods available to read data from the port, this seemed (intuitively) to be the most straight-forward, but I might be totally off the mark.

Any help would be greatly appreciated.

Thanks,
Stephan

Lesiok
13th February 2010, 10:18
First change this historical version of qextserial to this version (http://code.google.com/p/qextserialport/).

sfabel
13th February 2010, 10:41
This project currently has no downloads. (http://code.google.com/p/qextserialport/downloads/list)

snappy
16th February 2010, 22:33
I agree. No Downloads. Do we have to get the source and build it?

snappy
16th February 2010, 22:52
I agree. No Downloads. Do we have to get the source and build it?

So I got a clone of the project. Using TortoiseHG for Windows.

kuzulis
17th February 2010, 05:21
snappy, if you have the operating system Linux or Windows XP - you can use another library QSerialDevice http://fireforge.net/snapshots.php?group_id=199

sfabel
17th February 2010, 20:22
Version changed. I downloaded the latest devel version using hg.

canReadLine() always returns false. The above code has not changed.

What could be the trouble?

norobro
17th February 2010, 22:36
Maybe this is your problem. From the canReadLine() docs:
Note that unbuffered devices, which have no way of determining what can be read, always return false.

I communicate with an unbuffered device and if I were using your onReceive() function it would look something like this:


void Motor::onReceive()
{
QMutexLocker locker(&m);
while(port->bytesAvailable()< RX_BUF_SIZE) {} //wait for data

char tmp[RX_BUF_SIZE];
qint64 len = port->read(tmp, RX_BUF_SIZE); //use read instead of readline
data.fromRawData(tmp,len);

quint8 fault = 0;

// do something with the data before
// clearing the buffer

data.clear();

rxcnt++;
}
}

sfabel
18th February 2010, 00:47
My problem is that I need to read until I hit a '\n', then interpret the output as a whole. This is why I (conveniently) thought I could just use readLine(). But I guess I did not understand the "Unbuffered" part of the serial port... :)

I suppose the problem is that the readyRead() signal is emitted every time something new arrives, correct? So I need to keep track of what has been read before, until I hit a '\n' and then interpret the whole thing until then.

Stephan

norobro
18th February 2010, 02:15
My device, a weather station, only sends data when it receives a request, so I don't use readyRead(). I write to the port requesting a certain record (the main records used are 100, 267 & 439 bytes), immediately call my "read" function and wait for data. The record length (equivalent to your RX_BUF_SIZE) is passed into the read function where it waits for that number of bytes to be available(while loop), reads the record and calls the appropriate function to process the record.

My device sends data as a fixed length record with no end of line terminator so I can't use readLine(). You should try it since your device is sending "\n".

If readLine() doesn't work and your lines are all the same length you should be able to use bytesAvailable() to wait for "line length" no. of bytes and then read "line length" no. of Bytes.

I hope this makes some sense.

By the way, I'm using qextserialport 1.1 with no problems.

kuzulis
18th February 2010, 05:37
"mouse cried, stung, but continued to chew on a cactus!" :) (C)
PS: folklore

Lesiok
18th February 2010, 06:41
My problem is that I need to read until I hit a '\n', then interpret the output as a whole. This is why I (conveniently) thought I could just use readLine(). But I guess I did not understand the "Unbuffered" part of the serial port... :)
.....
Stephan

You must read data byte by byte and complete one record in buffer until You read a '\n' character.

norobro
18th February 2010, 14:59
From the qextserialport docs:

qint64 QIODevice::readLine ( char * data, qint64 maxSize )
. . .
. . .
Data is read until either of the following conditions are met:

* The first '\n' character is read.
* maxSize - 1 bytes are read.
* The end of the device data is detected.
. . .
. . .
This function calls readLineData(), which is implemented using repeated calls to getChar(). . . .

So iif bytesAvailable() is equal to record size it looks like readLine() should work.

@kuzulis - I'm in Texas. We are used to being stung by the ubiquitous prickly pear cactus. I'm downloading as I type.