Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSerialPort sets DTR to high upon closing port; won't emit readyReady when DTR is otherwise held high.
Forum Updated to NodeBB v4.3 + New Features

QSerialPort sets DTR to high upon closing port; won't emit readyReady when DTR is otherwise held high.

Scheduled Pinned Locked Moved General and Desktop
qserialportwindows
13 Posts 3 Posters 7.7k Views 1 Watching
  • 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.
  • bweirB Offline
    bweirB Offline
    bweir
    wrote on last edited by bweir
    #4

    Wow! This is perfect! That was exactly what I needed and my loader works now!!

    But this leads to a more troubling issue now.

    I felt so dumb thinking that I somehow overlooked this property though, as I had read through the QSerialPort docs up one side and down the other trying to figure this out, but now it makes sense why I didn't find it.

    http://doc.qt.io/qt-5/qserialport-obsolete.html#settingsRestoredOnClose-prop =(

    What's the deal? How can they mark this as obsolete and relegate it to some back corner of the documentation when it's the only way my application can possibly work?

    Now I have a much larger worry that my loader is going to stop working and there will be no way to fix it if I ever upgrade to the latest version of Qt 7! Is there any path to knock on developer's doors and say "PLEASE KEEP THIS FEATURE FOREVER DON'T DEPRECATE PLEASE PLEASE PLEASE"?

    Thanks for your help. :)

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

      What's the deal?
      How can they mark this as obsolete and relegate it to some back corner of the documentation when it's the only way my application can possibly work?

      Yes, in future it will be deprecated (for Qt6, I guess). Instead, QSerialPort never won't restore settings when closing. Also when opening, QSerialPort will drop the state to some initial (e.g. when DTR/RTS is in low, always).

      PS: So, for your case it will be irrelevant.

      1 Reply Last reply
      0
      • bweirB Offline
        bweirB Offline
        bweir
        wrote on last edited by
        #6

        Let me give you a little more background on why this is an issue.

        Here is a screen capture of the entire download protocol. The DTR line in this configuration is tied to a circuit that pulses the hardware reset when a DTR transition is received. This reset marks the beginning of the download process.

        As you can see, there is only one reset at the beginning, and at the end, the microcontroller starts running the program that was just downloaded. One of the compelling features of the Propeller microcontroller is the ability to download code to the device's RAM and run it directly, speeding up testing considerably.

        Naturally, if code is loaded into RAM and the board is reset, this code is lost, but this is exactly the situation that the auto-restore is creating, because it's forcing an extra reset after code download is complete.

        The problem I am having is that the library can't guarantee what the serial port settings were prior to using QSerialPort. So on my Linux machine, my code runs fine, because it sets DTR to high, then to low, and when the program closes, DTR is low by default so everything is great.

        But on Windows, DTR defaults to high, so when my command-line application finishes downloading code with DTR set to false, and closes the serial port, QSerialPort puts DTR back to high, which transitions DTR sending another reset, defeating the purpose of downloading to RAM.

        I know what you're thinking; just go from low to high on Windows. Well, two problems:

        • This is the other issue I reported that having DTR set high seems to result in readyRead() not ever being triggered. Any thoughts?
        • I also now have platform-specific behavior when the whole reason to use Qt is to avoid that.

        This download protocol has been around for nearly ten years, and there is another similar protocol that has been around for almost twenty. The number of boards that rely on this DTR behavior likely number in the hundreds of thousands at this point, so I can't change the protocol.

        I am working on a new download manager to support these boards, and I was very thrilled to see that Qt had its own serial library. There are not a lot of C++ serial libraries out there, let alone good ones, and QSerialPort is a breath of fresh air and very well done.

        However, if the library won't guarantee that the DTR behavior is well-defined, it breaks one of the core features of the application I'm using it for. By well-defined, I mean not resetting the serial port to whatever arbitrary values it had before I opened the port.

        I understand that what I am using serial for is not the most likely use case. However, removing it limits what I will be able to accomplish with this library.

        So why is this feature being removed with nothing to replace it? I added that one line, settingsRestoredOnClose(false), to my constructor, and now my application works flawlessly on Windows, and I can keep on developing my application.

        What am I supposed to do if this is removed?

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

          What am I supposed to do if this is removed?

          Nothing. As I wrote above, this is in planns (for Qt6) that QSerialPort will be always initialize DTR/RTS to an default initial state (e.g. to low) when opening, and no not restore nothing when closing. In this case, after closing you got a same state as after opening (with no DTR triggering back). So, this "deprecating" just should to simplify behavior in future (when we knows and can relies on initial state after opening).

          bweirB 1 Reply Last reply
          0
          • K kuzulis

            What am I supposed to do if this is removed?

            Nothing. As I wrote above, this is in planns (for Qt6) that QSerialPort will be always initialize DTR/RTS to an default initial state (e.g. to low) when opening, and no not restore nothing when closing. In this case, after closing you got a same state as after opening (with no DTR triggering back). So, this "deprecating" just should to simplify behavior in future (when we knows and can relies on initial state after opening).

            bweirB Offline
            bweirB Offline
            bweir
            wrote on last edited by
            #8

            It's the not initial state that matters in this case, but the final state. Is there a way to determine what the initial conditions were so that my code can account for it and use the reset in a way that won't cause a transition?

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JasonDorie
              wrote on last edited by
              #9

              I'm running into this exact issue. I have an application connecting to an external programmable chip via the serial port. When the Qt application terminates it resets the device. I wasn't having this problem in C#.

              Would it be possible to have a setting on the port object to not touch DTR at all? I've tried everything mentioned here and mine is resetting on app exit regardless of any settings I apply.

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

                use QSerialPort::settingsRestoredOnClose(false)

                1 Reply Last reply
                1
                • J Offline
                  J Offline
                  JasonDorie
                  wrote on last edited by
                  #11

                  I tried that - has no effect. I'm enumerating all serial ports, looking for a connected external device. When I open the port, I do this:

                  foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
                  {
                      if( info.portName() == QString("COM3") ) continue;
                      if( info.portName() == QString("COM4") ) continue;
                  
                  	if( quit ) return;
                  
                      serial->close();  // close any previously open port
                      serial->setPortName(info.portName());
                      serial->setBaudRate( QSerialPort::Baud115200 );
                  	serial->setFlowControl( QSerialPort::NoFlowControl );
                  	serial->setParity( QSerialPort::NoParity );
                  	serial->setStopBits( QSerialPort::OneStop );
                  	serial->setReadBufferSize(8192);
                  	serial->setSettingsRestoredOnClose(false);
                  
                  	if( !serial->open(QIODevice::ReadWrite) || !serial->isOpen() ) {
                          continue;
                      }
                      serial->setDataTerminalReady(true);  // tried high, low, and neither
                  

                  I have tried setting DTR after opening the port (tried setting both high and low, and not at all) and that has no effect either. Any suggestions? Every time I connect to this board it resets. I don't have this issue on Mac, and I wasn't having it with C# either.

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    JasonDorie
                    wrote on last edited by
                    #12

                    I found this, possibly relevant?

                    https://forum.qt.io/topic/37086/dtr-resets-when-changing-baud-rate-of-qserialport-object-on-windows-systems

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      JasonDorie
                      wrote on last edited by
                      #13

                      I looked at the Qt source for the serial port, and it's relatively simple, so it was pretty clear the issue wasn't there. I did more digging and found that the reset signal is inverted on the device I'm using (maybe it normally is - I'm not sure). In any case, me setting the DTR line true was causing the reset. I had tried setting it false as well, but it's possible I did that without having the "restoreOnClose" setting cleared.

                      Regardless, thank you for pointing me in the right direction.

                      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