PDA

View Full Version : Frustrating problem with QextSerialPort write()



kachofool
27th November 2009, 00:16
Hey all,

I'm trying to write to a serial device using QextSerialPort. Here are some things I should note:

*I can read from the device, but cannot write to it.
*I can read and write from the device using a serial communication tool (cutecom)
*Using a loopback serial cable, I can see that write is working

Based on this info, I know it seems like the problem is device related, and for what its worth, it seems to have a really flaky serial I/F. However, I've been able to use it with normal linux serial drivers, and I can communicate with the device with cutecom (a linux gui app that r/w to serial ports -- handy for testing) no problem. This leads me to believe I'm doing something wrong with QextSerialPort that I don't understand. I made a simple program similar to the "events" example included with the source.

I'd really appreciate any advice!

-KF



// System Includes
#include "main.h"

// RS232 Helper Thread
RS232Thread::RS232Thread(QextSerialPort* port, QObject* parent)
:QThread(parent)
{ serialPort = port; }

RS232Thread::~RS232Thread()
{}

void RS232Thread::run()
{
// constantly get user input
std::string inpSt;

std::cerr << "Send MVP a command string: " << std::endl;

while (inpSt.compare("quit") != 0)
{
std::getline(std::cin, inpSt);
std::cerr << serialPort->write(inpSt.c_str());
std::cerr << "Sent command: " << inpSt << std::endl;
}

serialPort->close();
}


// RS232 Signal Handler
RS232SignalHandler::RS232SignalHandler(QextSerialP ort* port, RS232Thread* thread, QObject* parent):
QObject(parent)
{ serialPort = port;
sTime = thread->startTime; }

RS232SignalHandler::~RS232SignalHandler()
{}

void RS232SignalHandler::RS232ReceivedData()
{

char data[512];
int numBytesRead = serialPort->read(data, 512);

std::cerr << "DATA READ IN: " << std::endl;

// print out what we read in as chars
for (int i=0; i < numBytesRead; i++)
{ std::cerr << data[i]; }
std::cerr << std::endl;

// print out what we read in as ints
for (int i=0; i < numBytesRead; i++)
{ std::cerr << int(data[i]); }
std::cerr << std::endl;
}


// Start Main
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

// set up serial port
QextSerialPort *port = new QextSerialPort("/dev/ttyUSB0", QextSerialPort::EventDriven);
port->setBaudRate(BAUD9600);
port->setFlowControl(FLOW_OFF);
port->setParity(PAR_NONE);
port->setDataBits(DATA_8);
port->setStopBits(STOP_1);

// setup helper thread
RS232Thread* hThread = new RS232Thread(port);
a.connect(hThread, SIGNAL(finished()), &a, SLOT(quit()));
hThread->start();

// setup data received signal handler
RS232SignalHandler* handler = new RS232SignalHandler(port, hThread);
handler->connect(port, SIGNAL(readyRead()), handler, SLOT(RS232ReceivedData()));

// event loop
return a.exec();
}

kuzulis
27th November 2009, 05:36
You will QSerialDevice:
http://qt-apps.org/content/show.php/QSerialDevice?content=112039

Look there examples:
/examples/writer
/examples/reader
/examples/sreader

For SVN to visit the site: fireforge.net
But sometimes this site does not work. ((
So write to me at mail and I'll send you the latest from SVN.
Address mail to the source code QSerialDevice.

PS: better to take from SVN, because QSerialDevice 0.1.0 version has more bugs.

Best regards,
Denis

calhal
27th November 2009, 13:44
kuzulis: I hate when people use forums this way. Did kachofool ask for any alternatives or for helping with a specific problem? If you want to advertise your library maybe start new thread in a proper subforum with info about it. If you really have to do it here, maybe first try to answer for the question, or point that the code has bug or is incomplete and then propose an alternative.

wysota
27th November 2009, 13:50
Unless something changed recently, QExtSerialPort doesn't emit readyRead(). You need to periodically check if there is anything to read with a timer. I don't know if that's related to your problem, in theory problems with reading should not stop you from writing (unless some buffer gets full which might happen here).

calhal
27th November 2009, 13:59
while (inpSt.compare("quit") != 0)
{
std::getline(std::cin, inpSt);
std::cerr << serialPort->write(inpSt.c_str());
std::cerr << "Sent command: " << inpSt << std::endl;
}

What do you get from this on stderr?
And am I missing something or you're not opening the port in your code?
The rest as wysota wrote ;)

kachofool
27th November 2009, 14:37
Thanks to all for the replies.

@wysota
Emit seems to be working. I downloaded the latest source from the project website and read under their 'issues' section that event based I/O had been implemented (in POSIX at least, and I'm on linux).

@calhan
For some odd reason (maybe copy/paste) the line of code for opening the port isn't in my original post. The line is actually



// open serial port
port->open(QIODevice::ReadWrite);


And it's right after I set up the port parameters, before I launch the helper threads.

The output of stderr is the expected number of characters I write. An example of a command string I'm outputting to the device is "1 RN".
The return value of the write command is 4.

EDIT:
The issue was with the command string I was sending to the device. The string needed to be terminated with *both* newline and carriage return characters... everything seems okay now. Thanks!

EDIT (EDIT):
@kuzulis: I've tried your library and it works as well (since the error was on my part). Thank you for providing the community with a Qt serial i/o library, however I want to agree with what calhan said in that you've advertised your library often (already in another thread of mine!) without really replying to the question.