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. readyRead() signal behavior
Forum Updated to NodeBB v4.3 + New Features

readyRead() signal behavior

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 928 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.
  • E Offline
    E Offline
    epicQt
    wrote on last edited by
    #1

    I am using the connect() method with the QIODevice::readyRead() signal to read data coming from an ESP32 with Arduino code. Does readyRead() emits a signal every time a new character is received or when the end of line (null) character is received?

    Alternatively, since the ESP32 is basically echoing what it receives from Qt, does QSerialPort->write("hello") sends the string with a null character after each character sent? eg h\0 e\0 l\0 l\0 o\0

    My code and output is below:

    void Dialog::on_connect_clicked() // a slot for a button
    {
        if(esp_available){
            esp->setPortName(espPortName);
            esp->setBaudRate(9600);
            esp->setDataBits(QSerialPort::Data8);
            esp->setParity(QSerialPort::NoParity);
            esp->setStopBits(QSerialPort::OneStop);
            esp->setFlowControl(QSerialPort::NoFlowControl);
    
            connect(esp, SIGNAL(readyRead()), this, SLOT(onDataReady()));
    
            esp->open(QSerialPort::ReadWrite);
            esp->clear();
        } 
    }
    
    void Dialog::on_startStream_clicked()
    {
        if(esp->isOpen()){
            esp->write("hello");
        }
    }
    
    void Dialog::onDataReady()
    {
        QByteArray ba;
        if(esp->canReadLine()){
            ba = esp->readLine();
            qDebug() << ba;
        }
    }
    

    The data from the ESP32 using Arduino code is below and should send "hello\n" to via USB:

    bool packet_recevived = false;
    const int max_packet_size = 10;
    char incoming_packet[max_packet_size];
    int parse_packet();
    
    void setup() { Serial.begin(9600); }
    
    void loop() {
        if (Serial.available() > 0 && packet_recevived == false) {
            parse_packet();
        }
    }
    
    int parse_packet() {
        int in_size = Serial.available();
        for (int i = 0; i <= in_size; i++) {
            incoming_packet[i] = Serial.read();
        }
        Serial.println(incoming_packet); // should print "hello\n"
        packet_recevived = false;
        return 0;
    }
    

    The output I'm getting from qDebug() is:

    "h\xFF\r\n"
    "e\xFF\r\n"
    "l\xFF\r\n"
    "l\xFF\r\n"
    "o\xFF\r\n"
    
    eyllanescE 1 Reply Last reply
    0
    • E epicQt

      @eyllanesc said in readyRead() signal behavior:

      @epicQt change i <= in_size to i < in_size. You are reading out of the serial port buffer, for example let's say that available() returns 5 so you must iterate from 0 to 4 but you are iterating from 0 to 5. And the bytes out of the buffer can have any value.

      @eyllanesc The took care of the \xFF characters but the output is still coming out as one character at a time as opposed to the entire line. Here is the output:

      "h"
      "e"
      "l"
      "l"
      "o"
      
      eyllanescE Offline
      eyllanescE Offline
      eyllanesc
      wrote on last edited by eyllanesc
      #6

      @epicQt The "problem" is that you are assuming something that is not guaranteed. You think that communication is per packet ("hello") but in serial communication it is from byte to byte, therefore 5 blocks travel through the wire (one for each letter) and each time it receives a block it indicates that there is data available. A possible solution is to use a delimiter, for example "\n" then you send esp->write("hello\n");, and in the esp2 code accumulate the bytes until you receive the "\n" and then you just send the response. By example use readStringUntil()

      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

      E 1 Reply Last reply
      2
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @epicQt said in readyRead() signal behavior:

        does QSerialPort->write("hello") sends the string with a null character after each character sent?

        Why should this be done?

        Does readyRead() emits a signal every time a new character is received or when the end of line (null) character is received?

        It is fired when data is available. It can fire after each character or whatever it wants.

        "hello\n"

        You send "hello" so why do you expect to receive "hello\n" ?

        First you should output the in_size and then every single character which is returned from Serial.read(). Don't know what Serial.println(incoming_packet) is doing with the data though.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        E 1 Reply Last reply
        0
        • Christian EhrlicherC Christian Ehrlicher

          @epicQt said in readyRead() signal behavior:

          does QSerialPort->write("hello") sends the string with a null character after each character sent?

          Why should this be done?

          Does readyRead() emits a signal every time a new character is received or when the end of line (null) character is received?

          It is fired when data is available. It can fire after each character or whatever it wants.

          "hello\n"

          You send "hello" so why do you expect to receive "hello\n" ?

          First you should output the in_size and then every single character which is returned from Serial.read(). Don't know what Serial.println(incoming_packet) is doing with the data though.

          E Offline
          E Offline
          epicQt
          wrote on last edited by
          #3

          @Christian-Ehrlicher said in readyRead() signal behavior:

          It is fired when data is available. It can fire after each character or whatever it wants.

          "hello\n"

          You send "hello" so why do you expect to receive "hello\n" ?

          First you should output the in_size and then every single character which is returned from Serial.read(). Don't know what Serial.println(incoming_packet) is doing with the data though.

          I'm expecting "hello\n" because as far as I know Arduino's Serial.println("hello") will attach an termination character. I don't really care what it attaches, I would like to receive the entire string in one line as opposed to individual characters followed by a termination character (which is what is happening now).

          The variable in_size is sending a 1 for every character in "hello". This is what I get in the
          qDebug() output. I'm also not sure why the \xFF characters are appearing:

          "1 h\xFF"
          "1 e\xFF"
          "1 l\xFF"
          "1 l\xFF"
          "1 o\xFF"
          
          1 Reply Last reply
          0
          • E epicQt

            I am using the connect() method with the QIODevice::readyRead() signal to read data coming from an ESP32 with Arduino code. Does readyRead() emits a signal every time a new character is received or when the end of line (null) character is received?

            Alternatively, since the ESP32 is basically echoing what it receives from Qt, does QSerialPort->write("hello") sends the string with a null character after each character sent? eg h\0 e\0 l\0 l\0 o\0

            My code and output is below:

            void Dialog::on_connect_clicked() // a slot for a button
            {
                if(esp_available){
                    esp->setPortName(espPortName);
                    esp->setBaudRate(9600);
                    esp->setDataBits(QSerialPort::Data8);
                    esp->setParity(QSerialPort::NoParity);
                    esp->setStopBits(QSerialPort::OneStop);
                    esp->setFlowControl(QSerialPort::NoFlowControl);
            
                    connect(esp, SIGNAL(readyRead()), this, SLOT(onDataReady()));
            
                    esp->open(QSerialPort::ReadWrite);
                    esp->clear();
                } 
            }
            
            void Dialog::on_startStream_clicked()
            {
                if(esp->isOpen()){
                    esp->write("hello");
                }
            }
            
            void Dialog::onDataReady()
            {
                QByteArray ba;
                if(esp->canReadLine()){
                    ba = esp->readLine();
                    qDebug() << ba;
                }
            }
            

            The data from the ESP32 using Arduino code is below and should send "hello\n" to via USB:

            bool packet_recevived = false;
            const int max_packet_size = 10;
            char incoming_packet[max_packet_size];
            int parse_packet();
            
            void setup() { Serial.begin(9600); }
            
            void loop() {
                if (Serial.available() > 0 && packet_recevived == false) {
                    parse_packet();
                }
            }
            
            int parse_packet() {
                int in_size = Serial.available();
                for (int i = 0; i <= in_size; i++) {
                    incoming_packet[i] = Serial.read();
                }
                Serial.println(incoming_packet); // should print "hello\n"
                packet_recevived = false;
                return 0;
            }
            

            The output I'm getting from qDebug() is:

            "h\xFF\r\n"
            "e\xFF\r\n"
            "l\xFF\r\n"
            "l\xFF\r\n"
            "o\xFF\r\n"
            
            eyllanescE Offline
            eyllanescE Offline
            eyllanesc
            wrote on last edited by eyllanesc
            #4

            @epicQt change i <= in_size to i < in_size. You are reading out of the serial port buffer, for example let's say that available() returns 5 so you must iterate from 0 to 4 but you are iterating from 0 to 5. And the bytes out of the buffer can have any value.

            If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

            E 1 Reply Last reply
            0
            • eyllanescE eyllanesc

              @epicQt change i <= in_size to i < in_size. You are reading out of the serial port buffer, for example let's say that available() returns 5 so you must iterate from 0 to 4 but you are iterating from 0 to 5. And the bytes out of the buffer can have any value.

              E Offline
              E Offline
              epicQt
              wrote on last edited by
              #5

              @eyllanesc said in readyRead() signal behavior:

              @epicQt change i <= in_size to i < in_size. You are reading out of the serial port buffer, for example let's say that available() returns 5 so you must iterate from 0 to 4 but you are iterating from 0 to 5. And the bytes out of the buffer can have any value.

              @eyllanesc The took care of the \xFF characters but the output is still coming out as one character at a time as opposed to the entire line. Here is the output:

              "h"
              "e"
              "l"
              "l"
              "o"
              
              eyllanescE 1 Reply Last reply
              0
              • E epicQt

                @eyllanesc said in readyRead() signal behavior:

                @epicQt change i <= in_size to i < in_size. You are reading out of the serial port buffer, for example let's say that available() returns 5 so you must iterate from 0 to 4 but you are iterating from 0 to 5. And the bytes out of the buffer can have any value.

                @eyllanesc The took care of the \xFF characters but the output is still coming out as one character at a time as opposed to the entire line. Here is the output:

                "h"
                "e"
                "l"
                "l"
                "o"
                
                eyllanescE Offline
                eyllanescE Offline
                eyllanesc
                wrote on last edited by eyllanesc
                #6

                @epicQt The "problem" is that you are assuming something that is not guaranteed. You think that communication is per packet ("hello") but in serial communication it is from byte to byte, therefore 5 blocks travel through the wire (one for each letter) and each time it receives a block it indicates that there is data available. A possible solution is to use a delimiter, for example "\n" then you send esp->write("hello\n");, and in the esp2 code accumulate the bytes until you receive the "\n" and then you just send the response. By example use readStringUntil()

                If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                E 1 Reply Last reply
                2
                • eyllanescE eyllanesc

                  @epicQt The "problem" is that you are assuming something that is not guaranteed. You think that communication is per packet ("hello") but in serial communication it is from byte to byte, therefore 5 blocks travel through the wire (one for each letter) and each time it receives a block it indicates that there is data available. A possible solution is to use a delimiter, for example "\n" then you send esp->write("hello\n");, and in the esp2 code accumulate the bytes until you receive the "\n" and then you just send the response. By example use readStringUntil()

                  E Offline
                  E Offline
                  epicQt
                  wrote on last edited by
                  #7

                  @eyllanesc the problem was my Arduino. I simplified it just to test and based on your suggestion and now it is working properly even at 500K baud:

                  Arduino code:

                  char buffer[16];
                  void process();
                  
                  void setup() { Serial.begin(500000); }
                  
                  void loop() { process(); }
                  
                  void process() {
                      while (Serial.available() > 1) {
                          Serial.readBytesUntil('\n', buffer, 16);
                          Serial.println(buffer);
                      }
                  }
                  
                  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