Results 1 to 4 of 4

Thread: QtSerialPort - reading fails after random times.

  1. #1
    Join Date
    Apr 2013
    Location
    N/A
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default QtSerialPort - reading fails after random times.

    As a follow up to the thread I posted about SerialPortInfo returning 0 ports available:
    http://www.qtcentre.org/threads/5432...orts-available

    I have made a code that uses master example (I also did blocking master which I was told should not be the approach right now since implementation is not yet ready).

    I also did a suggestion that in readyRead() wait until all data is available and then process it and/or append the data to some buffer as it comes since readyRead is emited even 1 charachter is received out of N that could come.

    My observation is that again after some random amount of time, reading simply stalls and timeout occurs.

    I am sending 30 charachters so that would be about 270 bits. At 9600 bps this transfer would take 28 msec and at 57600 bps it would take about 4.7 msec. I have tested both speeds - same behavior.

    My device does not constantly stream data - a character (any) needs to be send and then only device sends a single line terminated with \n\r

    I have put qDebug() statements when I am sending and receiving and when timeout occurs and following happens:

    There is only one readyRead() signal being emitted and my slot is being called.
    Inside the slot I am checking if data can be read with canReadLine() and then reading it with readAll() or readLine() - either works in my case.

    At random times timeout occurs and at that point readyRead() seems never to be transmitted and readResponse() was never called. bytesAvailable() call returns 0 in qDebug() from timeout handler which is strange.

    I did a quick "fix" by closing and opening the serial port in timeout slot. Then code works again until next time reading fails - it may happen immediately or after some random time and random amount of successful reads.

    I have tested my device using Terminal program and also using Python PySerial library and it works fine by reading for several hours (overnight)

    .inf file for driver is available at my initial thread.

    Below is the new code:

    Qt Code:
    1. DataFeeder2::DataFeeder2(QString useComPort, QObject *parent, int nSleepTime) :
    2. QObject(parent), sleepTime(nSleepTime), comPort(useComPort), waitingForReply(false)
    3. {
    4.  
    5. QSettings settings;
    6. //sleepTime = settings.value("Interval", QVariant(nSleepTime)).toInt()*60*1000; // in msec
    7. sleepTime = 1000; // DEBUG only
    8.  
    9. serial.setPortName(comPort);
    10. timer.setInterval(sleepTime);
    11. errorTimer.setSingleShot(true);
    12.  
    13. connect(&serial, SIGNAL(readyRead()),
    14. this, SLOT(readResponse()));
    15. connect(&timer, SIGNAL(timeout()),
    16. this, SLOT(acquireData()));
    17. connect(&errorTimer, SIGNAL(timeout()),
    18. this, SLOT(processTimeout()));
    19. }
    20.  
    21. DataFeeder2::~DataFeeder2()
    22. {
    23. if(serial.isOpen())
    24. {
    25. serial.close();
    26. }
    27. }
    28.  
    29. bool DataFeeder2::start()
    30. {
    31. bool retval = true;
    32.  
    33. serial.setPortName(comPort);
    34.  
    35. qDebug() << "Trying to open " << comPort;
    36. if (!serial.open(QIODevice::ReadWrite)) {
    37. qDebug() << QString("Can't open %1, error code %2").arg(comPort).arg(serial.error());
    38. retval = false;
    39. }
    40.  
    41. if (!serial.setBaudRate(QSerialPort::Baud57600)) {
    42. qDebug() << QString("Can't set baud rate 9600 baud to port %1, error code %2").arg(comPort).arg(serial.error());
    43. retval = false;
    44. }
    45.  
    46. if (!serial.setDataBits(QSerialPort::Data8)) {
    47. qDebug() << QString("Can't set 8 data bits to port %1, error code %2").arg(comPort).arg(serial.error());
    48. retval = false;
    49. }
    50.  
    51. if (!serial.setParity(QSerialPort::NoParity)) {
    52. qDebug() << QString("Can't set no patity to port %1, error code %2").arg(comPort).arg(serial.error());
    53. retval = false;
    54. }
    55.  
    56. if (!serial.setStopBits(QSerialPort::OneStop)) {
    57. qDebug() << QString("Can't set 1 stop bit to port %1, error code %2").arg(comPort).arg(serial.error());
    58. retval = false;
    59. }
    60.  
    61. if (!serial.setFlowControl(QSerialPort::NoFlowControl)) {
    62. qDebug() << QString("Can't set no flow control to port %1, error code %2").arg(comPort).arg(serial.error());
    63. retval = false;
    64. }
    65.  
    66.  
    67. qDebug() << comPort << " opened.";
    68.  
    69.  
    70. waitingForReply = false;
    71.  
    72. timer.start();
    73.  
    74.  
    75. return retval;
    76.  
    77. }
    78.  
    79. void DataFeeder2::stop()
    80. {
    81. timer.stop();
    82. errorTimer.stop();
    83. serial.close();
    84.  
    85. qDebug() << "DataFeeder2 stopped.";
    86. }
    87.  
    88. void DataFeeder2::setSleepTime(int nSleepTime)
    89. {
    90. if(sleepTime != nSleepTime)
    91. {
    92. sleepTime = nSleepTime;
    93. timer.setInterval(sleepTime);
    94. emit sleepTimeChanged(sleepTime);
    95. }
    96. }
    97.  
    98. void DataFeeder2::processTimeout()
    99. {
    100. qDebug() << "Timeout waiting to read serial port " << comPort << " - " << QDateTime::currentDateTimeUtc().time().toString();
    101. qDebug() << "Error code: " << serial.error() << " String: " << serial.errorString();
    102. qDebug() << "Bytes avail: " << serial.bytesAvailable();
    103. emit feederError(QString("<font color=\"#ff0000\">ERROR(%1)</font>").arg(serial.error()));
    104.  
    105. // DEBUG only
    106. stop();
    107. start();
    108. // END DEBUG only
    109. }
    110.  
    111. void DataFeeder2::acquireData()
    112. {
    113. if(!waitingForReply)
    114. {
    115. serial.write(QString("d").toLocal8Bit());
    116. errorTimer.start(4000);
    117. waitingForReply = true;
    118. qDebug() << "Sent at: " << QDateTime::currentDateTimeUtc().time().toString();
    119. }
    120. }
    121.  
    122. void DataFeeder2::readResponse()
    123. {
    124. qDebug() << "In ReadResponse()" << QDateTime::currentDateTimeUtc().time().toString();
    125. if(serial.canReadLine())
    126. //if(serial.bytesAvailable()>10)
    127. {
    128. errorTimer.stop();
    129.  
    130.  
    131.  
    132. responseData = serial.readAll();
    133. //responseData = serial.readLine();
    134. QString data;
    135. data = data.fromLatin1(responseData).trimmed();
    136. qDebug() << "Got:$" << data << "$";
    137.  
    138.  
    139. waitingForReply = false;
    140. }
    141.  
    142. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - reading fails after random times.

    Please provide the minimum source project which reproduces a problem. I will try it to build and to test.

    Also show data string/array which you send and you expect for reception.

  3. #3
    Join Date
    Apr 2013
    Location
    N/A
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - reading fails after random times.

    Quote Originally Posted by kuzulis View Post
    Please provide the minimum source project which reproduces a problem. I will try it to build and to test.

    Also show data string/array which you send and you expect for reception.

    Here is the code:

    ToTestSerial.zip

    And here are the strings and code from the device firmware source code:


    Got:$ "DAT:2067,6502,8,19,0,25,102,0" $
    MainWindow::handleDataItem() - Time: QDateTime("Fri May 3 19:24:43 2013") "DAT:2067,6502,8,19,0,25,102,0"
    Sent at: "19:24:44"
    In ReadResponse() "19:24:44"
    Got:$ "DAT:2066,6503,8,18,0,25,103,0" $
    MainWindow::handleDataItem() - Time: QDateTime("Fri May 3 19:24:44 2013") "DAT:2066,6503,8,18,0,25,103,0"
    Sent at: "19:24:45"
    Timeout waiting to read serial port "COM3" - "19:24:49"
    Error code: 9 String: "Unknown error"
    Bytes avail: 0
    Feeder Error: "<font color="#ff0000">ERROR(9)</font>"


    Code from device:

    Qt Code:
    1. snprintf((char *)buff, MAX_BUFF, "DAT:%d,%d,%d,%d,%d,%d,%d,%d\n\r", humi_val, temp_val, humiMsb, humiLsb, humiError, tMsb,tLsb,tError);
    2. len = strlen((const char*)buff);
    3. UsbdCdc_SendData(buff, len);
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Apr 2013
    Location
    N/A
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - reading fails after random times.

    An update:

    Device uses NXP LPC11U35 MCU which has on-board USB CDC stack implementation.

    I have tested the same code from Qt on Linux (Ubuntu 12.04) with Qt 5.0 and new 5.1 - and data is being read correctly from the device all the time.

    Still even when compling with Qt 5.1 on Windows 7 64-bit, after some time ERROR 9 appears - some time perhaps 1K transfer max.
    However, on Windows C# or Python application works perfectly.

    I guess QtSerialPort is broken on Windows still.

Similar Threads

  1. QtSerialPort dependency on Perl
    By cstr in forum Installation and Deployment
    Replies: 1
    Last Post: 17th April 2013, 08:27
  2. Replies: 6
    Last Post: 17th December 2012, 11:53
  3. cannot build qtserialport
    By banlinhtienphong in forum Qt Programming
    Replies: 1
    Last Post: 16th December 2011, 05:56
  4. Replies: 11
    Last Post: 1st December 2010, 11:28
  5. Replies: 1
    Last Post: 7th April 2010, 16:26

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.