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. Need explanation QSerialPort vs Pyserial
Forum Updated to NodeBB v4.3 + New Features

Need explanation QSerialPort vs Pyserial

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 3 Posters 4.0k Views 2 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.
  • M Offline
    M Offline
    moscowbob
    wrote on last edited by
    #1

    I'm trying to reset an Arduino Leonardo into boot loader mode by opening and closing the usb serial with a baudrate of 1200. This does not seem to work with Qt. When I tried this with PySerial, just opening and closing the port it works. I also tested with stty and that also works.

    Does anybody have any ideas why QSerialPort does not work ?

    void Programmer::resetAvr()
    {
        m_port.setBaudRate(QSerialPort::Baud1200);
        m_port.setDataBits(QSerialPort::Data8);
        m_port.setParity(QSerialPort::NoParity);
        m_port.setStopBits(QSerialPort::OneStop);
        m_port.setFlowControl(QSerialPort::NoFlowControl);
        m_port.setPortName(m_portName);
    
        if(m_port.open(QIODevice::ReadWrite) == true)
        {
            m_port.close();
        }
    }
    
    #!/usr/bin/env python
    
    import serial, sys
    
    serialPort = sys.argv[1]
    print serialPort
    
    ser = serial.Serial(
        port=serialPort,
        baudrate=1200,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        bytesize=serial.EIGHTBITS
    )
    ser.isOpen()
    ser.close()             # close port
    
    stty -F /dev/ttyACM0 1200 cs8 -cstopb -parenb
    
    aha_1980A 1 Reply Last reply
    0
    • M Offline
      M Offline
      moscowbob
      wrote on last edited by
      #10

      Well after spending many hours digging through usb protocol documentation I have finally got to a point where I can say the problem is with QSerialPort. Since I cannot upload files I will try and explain.

      PySerial and linux stty both exhibit the same behavior when viewed in wireshark usb capture:

      1. Host send command 0x22 with value 0x03 to enable RTS and DTR
      2. Host send comand 0x20 with 7 bytes data to configure BAUD, DATABITS, PARITY and STOPBITS
        1200, 8, n, 1
      3. Host send command 0x22 with value 0x00 to disable RTS/DTR

      Now the device resets and goes into boot mode.

      QSerialPort behaves as follows - Open/Close :

      1. Host send command 0x22 with value 0x03 to enable RTS and DTR
      2. Host send command 0x20 with 7 bytes data to configure BAUD, DATABITS, PARITY and STOPBITS
        (all these configurations are sent)
        400000, 8, n, 1
        9600, 8, n, 1
        1200, 8, n, 1
        115200, 8, n, 1
      3. Host send command 0x22 with value 0x00 to disable RTS and DTR
      #include <QCoreApplication>
      #include <QDebug>
      #include <QSerialPort>
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
          QSerialPort mPort;
      
          mPort.setBaudRate(QSerialPort::Baud1200);
          mPort.setDataBits(QSerialPort::Data8);
          mPort.setStopBits(QSerialPort::OneStop);
          mPort.setParity(QSerialPort::NoParity);
          mPort.setPortName("/dev/ttyACM0");
      
          qDebug() << "Open Port";
          mPort.open(QIODevice::ReadWrite);
          if(mPort.isOpen())
          {
              qDebug() << "Close Port";
              mPort.close();
          }
      
          exit(0);
      //    return a.exec();
      }
      

      Anybody ??

      1 Reply Last reply
      0
      • M moscowbob

        I'm trying to reset an Arduino Leonardo into boot loader mode by opening and closing the usb serial with a baudrate of 1200. This does not seem to work with Qt. When I tried this with PySerial, just opening and closing the port it works. I also tested with stty and that also works.

        Does anybody have any ideas why QSerialPort does not work ?

        void Programmer::resetAvr()
        {
            m_port.setBaudRate(QSerialPort::Baud1200);
            m_port.setDataBits(QSerialPort::Data8);
            m_port.setParity(QSerialPort::NoParity);
            m_port.setStopBits(QSerialPort::OneStop);
            m_port.setFlowControl(QSerialPort::NoFlowControl);
            m_port.setPortName(m_portName);
        
            if(m_port.open(QIODevice::ReadWrite) == true)
            {
                m_port.close();
            }
        }
        
        #!/usr/bin/env python
        
        import serial, sys
        
        serialPort = sys.argv[1]
        print serialPort
        
        ser = serial.Serial(
            port=serialPort,
            baudrate=1200,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            bytesize=serial.EIGHTBITS
        )
        ser.isOpen()
        ser.close()             # close port
        
        stty -F /dev/ttyACM0 1200 cs8 -cstopb -parenb
        
        aha_1980A Offline
        aha_1980A Offline
        aha_1980
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi @moscowbob,

        just opening and closing a serial port without sending data will not change anything for the other side (independent of the baud rate).

        So there is most likely a control line (RTS, CTS, RTR) involved that actually does the reset? Do you have a description how the reset is supposed to work?

        And if it is working like this, there can be indeed a difference between pyserial and QSerialPort.

        Qt has to stay free or it will die.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          moscowbob
          wrote on last edited by
          #3

          @aha_1980 , thanks for response.
          The connection is a USB CDC connection, the AT32U4 chip has an embedded usb that is configured as a virtual comport. So there are no control lines connected. As I understand, when the host opens the port, it will configure the device endpoint and it is there where the 1200 baud is used to reset the device into bootloader mode.

          I have captured the usb conversation between the host pc and device for all 3 methods and the QSerialPort conversation looks completely different - unfortunately my knowledge is very limited when it comes to this, so if you want, I can post the three Wireshark capure files for viewing.

          aha_1980A 1 Reply Last reply
          0
          • M moscowbob

            @aha_1980 , thanks for response.
            The connection is a USB CDC connection, the AT32U4 chip has an embedded usb that is configured as a virtual comport. So there are no control lines connected. As I understand, when the host opens the port, it will configure the device endpoint and it is there where the 1200 baud is used to reset the device into bootloader mode.

            I have captured the usb conversation between the host pc and device for all 3 methods and the QSerialPort conversation looks completely different - unfortunately my knowledge is very limited when it comes to this, so if you want, I can post the three Wireshark capure files for viewing.

            aha_1980A Offline
            aha_1980A Offline
            aha_1980
            Lifetime Qt Champion
            wrote on last edited by
            #4

            Hi @moscowbob,

            yeah, you can post them, but I have to admit that my knowledge is also limited here :)

            But maybe someone else can help you here...

            Qt has to stay free or it will die.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              moscowbob
              wrote on last edited by
              #5

              What is the accepted method for the forum when posting files - I do not have privilege to upload here ?

              Thanks

              mrjjM 1 Reply Last reply
              0
              • M moscowbob

                What is the accepted method for the forum when posting files - I do not have privilege to upload here ?

                Thanks

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @moscowbob
                Hi
                It only wants
                alt text
                What type are you trying ?

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  moscowbob
                  wrote on last edited by
                  #7

                  Thanks @mrjj ,
                  The capture files I have are wireshark .pcapng or a zip file containing all 3 captures.

                  mrjjM 1 Reply Last reply
                  0
                  • M moscowbob

                    Thanks @mrjj ,
                    The capture files I have are wireshark .pcapng or a zip file containing all 3 captures.

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #8

                    Not sure it will accept those.

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      moscowbob
                      wrote on last edited by
                      #9

                      No there is something else wrong, I just tried to upload a simple text file with .c extension and I just get the same message

                      " ERROR
                      You do not have enough privileges for this action."

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

                        Well after spending many hours digging through usb protocol documentation I have finally got to a point where I can say the problem is with QSerialPort. Since I cannot upload files I will try and explain.

                        PySerial and linux stty both exhibit the same behavior when viewed in wireshark usb capture:

                        1. Host send command 0x22 with value 0x03 to enable RTS and DTR
                        2. Host send comand 0x20 with 7 bytes data to configure BAUD, DATABITS, PARITY and STOPBITS
                          1200, 8, n, 1
                        3. Host send command 0x22 with value 0x00 to disable RTS/DTR

                        Now the device resets and goes into boot mode.

                        QSerialPort behaves as follows - Open/Close :

                        1. Host send command 0x22 with value 0x03 to enable RTS and DTR
                        2. Host send command 0x20 with 7 bytes data to configure BAUD, DATABITS, PARITY and STOPBITS
                          (all these configurations are sent)
                          400000, 8, n, 1
                          9600, 8, n, 1
                          1200, 8, n, 1
                          115200, 8, n, 1
                        3. Host send command 0x22 with value 0x00 to disable RTS and DTR
                        #include <QCoreApplication>
                        #include <QDebug>
                        #include <QSerialPort>
                        
                        int main(int argc, char *argv[])
                        {
                            QCoreApplication a(argc, argv);
                            QSerialPort mPort;
                        
                            mPort.setBaudRate(QSerialPort::Baud1200);
                            mPort.setDataBits(QSerialPort::Data8);
                            mPort.setStopBits(QSerialPort::OneStop);
                            mPort.setParity(QSerialPort::NoParity);
                            mPort.setPortName("/dev/ttyACM0");
                        
                            qDebug() << "Open Port";
                            mPort.open(QIODevice::ReadWrite);
                            if(mPort.isOpen())
                            {
                                qDebug() << "Close Port";
                                mPort.close();
                            }
                        
                            exit(0);
                        //    return a.exec();
                        }
                        

                        Anybody ??

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          moscowbob
                          wrote on last edited by
                          #11

                          Well, finally a breakthrough !

                          It turn out that the deprecated function

                          mPort.setSettingsRestoredOnClose(false);
                          

                          Does the trick.

                          Although the Arduino now does reset, since QSerialPort does not send the restored values before closing the port, it still sends a garbage packet before setting the 1200 baud. I have not figured that one out yet, and I am now getting tired.

                          So I will mark this as solved but will raise another post to query the strange behavior when QSerialPort opens.

                          aha_1980A 1 Reply Last reply
                          2
                          • M moscowbob

                            Well, finally a breakthrough !

                            It turn out that the deprecated function

                            mPort.setSettingsRestoredOnClose(false);
                            

                            Does the trick.

                            Although the Arduino now does reset, since QSerialPort does not send the restored values before closing the port, it still sends a garbage packet before setting the 1200 baud. I have not figured that one out yet, and I am now getting tired.

                            So I will mark this as solved but will raise another post to query the strange behavior when QSerialPort opens.

                            aha_1980A Offline
                            aha_1980A Offline
                            aha_1980
                            Lifetime Qt Champion
                            wrote on last edited by
                            #12

                            @moscowbob

                            Please report this at bugreports.qt.io (and provide a link to the bug here).

                            You will have better possibilities to discuss the behavior with the developers there and you should also be able to attach the Wireshark logs.

                            Thanks.

                            Qt has to stay free or it will die.

                            1 Reply Last reply
                            1

                            • Login

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