Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. 3rd Party Software
  4. Problem with QtSerialPort on Windows
QtWS25 Last Chance

Problem with QtSerialPort on Windows

Scheduled Pinned Locked Moved 3rd Party Software
10 Posts 3 Posters 10.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    ms_airo
    wrote on last edited by
    #1

    Hello all!

    I'm trying to develop a simple command line program to write to a device connected through USB-Serial adapter. Using the example application from "here":http://qt-project.org/wiki/QtSerialPort (scroll down to "Simple Example" that lists connected serial devices), it shows the device. But whenever I normally open a connection to the device, it gives error "void __thiscall QSerialPortPrivate::detectDefaultSettings(void): Unexpected flow
    control settings" on open, and nothing goes through to the device even if I alter the flow control, parity and other settings afterwards. It doesn't give any other error or warning while the port is open, nor is there any errors set for the port.

    The code I'm trying to execute is as follows:
    @
    // QByteArr bytearr is introduced and filled with data before this snippet in the program code
    QSerialPort serial;
    serial.setPortName("COM11");
    if (serial.open(QIODevice::ReadWrite)) {
    bool success = serial.setBaudRate(QSerialPort::Baud9600) &
    serial.setStopBits(QSerialPort::OneStop) &
    serial.setDataBits(QSerialPort::Data8) &
    serial.setParity(QSerialPort::NoParity) &
    serial.setFlowControl(QSerialPort::NoFlowControl);
    qDebug() << "Connected to usb device " << serial.portName() << " " << (success ? "OK" : "FAIL");

        serial.write(bytearr);
        serial.waitForBytesWritten(-1);
        serial.close();
    }
    

    @
    The serial port name in use has been confirmed with the example application. The device I'm trying to write to accepts commands as bytes, and it does not send any response back at all.

    The weird thing is, I can get the program shown above to work by running another application, that opens the same port, and continuously (in while(true) loop) reads all data from the port and writes it to command line, and then manually closing the program. Although this test program for reading gives the same error about flow control settings, after running the test program the other program for writing works for as long as the usb cable is connected. Running the test program also removes the flow control setting error message from appearing in either of the programs.

    This is the test program, that should read everything from the port (it doesn't work like it should, but it resolves the issue):
    @#include <QtCore/QCoreApplication>
    #include <QtCore/QDebug>

    #include <QtSerialPort/QSerialPort>
    #include <QtSerialPort/QSerialPortInfo>

    QT_USE_NAMESPACE

    int main(int argc, char *argv[])
    {

        QSerialPort serial;
        serial.setPortName("COM11");
        if (serial.open(QIODevice::ReadWrite)) {
            bool success = serial.setBaudRate(QSerialPort::Baud9600) &
            serial.setStopBits(QSerialPort::OneStop) &
            serial.setDataBits(QSerialPort::Data8) &
            serial.setParity(QSerialPort::NoParity) &
            serial.setFlowControl(QSerialPort::NoFlowControl);
            qDebug() << "Connected to usb device: " << (success ? "OK" : "FAIL");
    
            while(true) {
              if(serial.waitForReadyRead(-1)) {
                QByteArray out = serial.readAll();
                for(int i=0; i< out.length(); i++) {
                    qDebug() << (int) out[i];
                }
              }
            }
            serial.close();
    
            qDebug() << "Connection closed.";
        }
    qDebug() << "Program exiting.";
    return 0;
    

    }@

    Although my question/problem should be obvious by now, this way for this to work isn't very optimal. Is there something I'm doing wrong in the writing application / something that I'm not taking into account, or is this a bug in Windows 8 environment? The program code has been proven to work as it is in Ubuntu Linux environment, and it kinda works in windows environment as well, but only after running the reader program. Calling the readAll function for 1M times in a for-loop doesn't work to simulate the effect of running the reader program, nor does opening the serial port without closing it first before trying to write.

    I am running Qt 5.2 32-bit, my compiler is MSVC2012 and my os is Windows 8 64-bit, although this has been confirmed to happen on 64-bit Windows 7. 32-bit Windows has not been tested.

    Any help is greatly appreciated!

    1 Reply Last reply
    0
    • K Offline
      K Offline
      kuzulis
      Qt Champions 2020
      wrote on last edited by
      #2

      [quote]
      “void __thiscall QSerialPortPrivate::detectDefaultSettings(void): Unexpected flow control settings”
      [/quote]

      It is normal, don't pay attention.

      It is wrong in your case (though it will work):
      [code]
      ...
      serial.write(bytearr);
      serial.flush();
      serial.close();
      ...
      [/code]

      should be:
      [code]
      ...
      serial.write(bytearr);
      serial.waitForBytesWritten();
      serial.close();
      ...
      [/code]

      Next, it is wrong in your case:
      [code]
      ...
      while(true) {
      QByteArray out = serial.readAll();
      for(int i=0; i< out.length(); i++) {
      qDebug() << (int) out[i];
      }
      }
      serial.close();
      ...
      [/code]

      Should be:
      [code]
      ...
      while(true) {
      if (serial.waitForReadyRead()) {
      QByteArray out = serial.readAll();
      for(int i=0; i< out.length(); i++) {
      qDebug() << (int) out[i];
      }
      }
      }
      serial.close();
      ...
      [/code]

      So, please look an examples of QtSerialPort and read Qt documentation.

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jmimi
        wrote on last edited by
        #3

        kuzulis! did not you mention that async approach is the best for serial communication in qt already?

        1 Reply Last reply
        0
        • K Offline
          K Offline
          kuzulis
          Qt Champions 2020
          wrote on last edited by
          #4

          yes. it is. but in your case it is synch approach.

          1 Reply Last reply
          0
          • J Offline
            J Offline
            jmimi
            wrote on last edited by
            #5

            kuzulis, I'm not questioner :). I saw your helpful comments in forum.

            1 Reply Last reply
            0
            • K Offline
              K Offline
              kuzulis
              Qt Champions 2020
              wrote on last edited by
              #6

              Ahh.. Sorry.. :)

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jmimi
                wrote on last edited by
                #7

                Never mind, your comments always are helpful.

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  ms_airo
                  wrote on last edited by
                  #8

                  Thank you for your replies. Although I'm sure these are things to be taken into account, they are not the thing in this case. The latter program is provided only because running it makes the first program for writing work. Whether it actually reads anything or not is not the issue, and making the change you suggested would probably break the reader program even further, as the device will not send anything to the program at all, thus it will never actually reach the readAll part.

                  As for the change in writer program, waitForBytesWritten has already been tried and it did not change anything in how the program worked (or didn't). Your suggested fix also contains a problem, as waitForBytesWritten expects integer parameter for wait timeout in msecs.

                  Although you mention that the error/warning message can be ignored, results show otherwise as it will not appear when the program works as it should (after running reader program once). But I also understand it is not the cause of my problems, only an effect of something else not working. And that "something else" is what I need help with most likely.

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    kuzulis
                    Qt Champions 2020
                    wrote on last edited by
                    #9

                    @ms_airo,

                    I already say to you that it is necessary to change in your code when using the synchronous approach (because your code demonstrated sync approach).

                    But I recommend to use asynchronous approach with use of signals/slots.

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      ms_airo
                      wrote on last edited by
                      #10

                      @kuzulls

                      And I already said, what you suggested didn't fix the problem. :) I also tried the fix you gave for the reader program, and it actually did start working, and it also still works so that it makes the writer program work afterwards until usb cable is removed. But it doesn't solve the problem I need help with. The writer program (first piece of code) has to work without the reader program (second piece of code).

                      Inspired from the fixes, I also attempted having one waitForReadRead call with long timeout before trying to write there, but this didn't solve the problem which is, the device does not receive (or does not receive correctly) what I'm trying to send there unless I run the second piece of code first.

                      As for it being sync'd or async'd, it doesn't matter at this point. Purpose of this program / project at this stage is to get the connection to device to work for writing, it's okay if the program has to wait for the connection. Also it's worthwhile to mention (like I mentioned in OP) that this works in other environments than windows flawlessly, even with the "flawed" code I have now fixed (without seeing any changes in results really).

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved