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. Serial Port Communication with Arduino

Serial Port Communication with Arduino

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 1.8k 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.
  • W Offline
    W Offline
    Will_Craig
    wrote on 22 Oct 2019, 01:00 last edited by
    #1

    Hi all,
    I'm building a multi-sensory device using an Arduino uno and i want to output the sensor values to the qt ui, the only thing i'm struggling with is interpreting the data read from the Arduino, you'll see in the code for readsearial() the first section before QStringList bufferSplit works, i am reading data and it is correct in terms of value however it is splitting the data up in the wrong place. I also need for this process to work to write the buffer split data to the variables in the inputData array however this code is never being executed and i don't know why, help would be greatly appreciated. Thank you in advance.

    Read Serial function in main.cpp

    void MainWindow::readSerial()
    {
        qDebug() << "Reading serial port data...";
        QByteArray data = arduino->readAll();
        qDebug() << data; //displaying all input data to the debug consol
        //serialBuffer = serialBuffer + QString::fromStdString(serialData.toStdString());
        qDebug() << "Serial Buffer Value: " << data << "\n";
        QStringList bufferSplit = serialBuffer.split(",");
    
        if(bufferSplit.length() < 3){
            // no parsed value yet so continue accumulating bytes from serial in the buffer.
            serialData = arduino->readAll();
            serialBuffer = serialBuffer + QString::fromStdString(serialData.toStdString());
            serialData.clear();
        }else{
            // the second element of buffer_split is parsed correctly, update the temperature value on temp_lcdNumber
            serialBuffer = "";
            qDebug() << &bufferSplit << "\n";
            inputData.temperatureArray[1] = bufferSplit[0].toFloat();
            inputData.phArray[1] = bufferSplit[1].toFloat();
            inputData.moistureArray[1] = bufferSplit[2].toFloat();
            qDebug() << "Temperature: " << &inputData.temperatureArray[1] << "\n";
            MainWindow::sensorUpdate(inputData.temperatureArray[1], inputData.phArray[1], inputData.moistureArray[1]);
        }
    
        data.clear();
    }
    

    Header function cause thats where most of the variables are declared:

    private slots:
        void on_Device_1_clicked(); //Takes user to Device_1 page
    
        void on_Device_2_clicked(); //Takes user to Device_2 page
    
        void on_actionHOMEPAGE_triggered(); //Takes user to Homepage (from toolbar menu)
    
        void on_actionDEVICE_1_triggered(); //Takes user to Device_1 page (from toolbar menu)
    
        void openSerial(); //Opens serial port connection
    
        void readSerial(); //Reads serial port connection
    
        void DatUpdate(); //Updates the displayed homepage data
    
        void sensorUpdate(QString tempSensorReading, QString moistureSensorReading, QString PHSensorReading); //Updates the displayed sensor values
    
        void errorAlert(QString errorMsg); //Opens a dialog box which displays an error message
    
    private:
        Ui::MainWindow *ui;
    
        QSerialPort *arduino;
        static const quint16 arduinoUnoVendorId = 9025;
        static const quint16 arduinoUnoProductId = 67;
        QString arduinoPortName;
        QByteArray serialData;
        QString serialBuffer;
        QString parsedData;
        int updateType;
        double temperatureValue;
    };
    

    The values will be diffrent because i can't open serial port coms to view on arduino and qt at the same time but here are some examples of the ouputs from both
    arduino output:
    23.11.21,0,15.92,10.35,0,23.24,11.19,0,23.24,10.12,0,
    qt output:

    Reading serial port data...
    "1.20"
    Serial Buffer Value:  "1.20" 
    
    Reading serial port data...
    ",0,"
    Serial Buffer Value:  ",0," 
    
    Reading serial port data...
    "2"
    Serial Buffer Value:  "2" 
    
    Reading serial port data...
    "3.24"
    Serial Buffer Value:  "3.24" 
    
    Reading serial port data...
    ",10."
    Serial Buffer Value:  ",10." 
    
    Reading serial port data...
    "14,0"
    Serial Buffer Value:  "14,0" 
    
    Reading serial port data...
    ","
    Serial Buffer Value:  "," 
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 22 Oct 2019, 20:18 last edited by
      #2

      Hi,

      What is usually done is to have frames with a start and end char (or sequence of char) so that you can easily identify when you got one frame of data and then process it accordingly.

      You then cumulate the data received on dataRead and check if there's at least a frame available. If not, do nothing and start again next time you receive data.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      W 1 Reply Last reply 23 Oct 2019, 00:11
      1
      • S SGaist
        22 Oct 2019, 20:18

        Hi,

        What is usually done is to have frames with a start and end char (or sequence of char) so that you can easily identify when you got one frame of data and then process it accordingly.

        You then cumulate the data received on dataRead and check if there's at least a frame available. If not, do nothing and start again next time you receive data.

        W Offline
        W Offline
        Will_Craig
        wrote on 23 Oct 2019, 00:11 last edited by Will_Craig
        #3

        @SGaist that makes a lot of sense, i was going down a similar path or at least i thought i was by having the Arduino output commas after every data chunk however as you can see that didn't work well, could you give me an example of implementing it? Would you be using QByteArray functions or something else? Thank you

        A 1 Reply Last reply 23 Oct 2019, 06:13
        0
        • W Will_Craig
          23 Oct 2019, 00:11

          @SGaist that makes a lot of sense, i was going down a similar path or at least i thought i was by having the Arduino output commas after every data chunk however as you can see that didn't work well, could you give me an example of implementing it? Would you be using QByteArray functions or something else? Thank you

          A Offline
          A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on 23 Oct 2019, 06:13 last edited by
          #4

          Hi @Will_Craig,

          I assume your data looks like that: 123,456,789\n

          then your slot would look like that (untested, not even compiled):

          MyClass::serialDataReady()
          {
            while (m_serial->canReadLine()) {
              const QByteArray data = m_serial->readLine();
              const QStringList list = QString(data).split(',');
              if (list.size() != 3) {
                // corrupted data, discard it
               continue;
              }
          
              // data seems valid, handle it
              qDebug() << list;
            }
          }
          
          Regards

          Qt has to stay free or it will die.

          1 Reply Last reply
          3
          • W Offline
            W Offline
            Will_Craig
            wrote on 24 Oct 2019, 01:39 last edited by
            #5

            Yeah it comes in 3's but with no newline, the serial port kept reading the newline character so i am only displaying the " , " not a new line on Arduino output.

            The way the Arduino is outputting the data is float temperature, int ph, int moisture, and then it repeats in line.

            I've changed the code a bit and I'm starting to get clearer readings but now it is reading floats weird which is throwing everything else out of place. i may try running the code and see what it picks up if the output of the singular float variable is an int, because if its a problem with the decimal i will just work with an int the precision is not too much of an issue here.

            That if statement that broke it into a 3variable package was not needed that i can see from the output of new code it was wasted lines i think i was overthinking it.

            UPDATED CODE:

            void MainWindow::readSerial()
            {
                QByteArray data = arduino->readAll();
                serialBuffer = data;
                data.truncate(3);
                    QStringList bufferSplit = serialBuffer.split(", ");
                    if(counter == 0) {
                        inputData.temperatureArray[1] = bufferSplit[0];
                        qDebug() << "TEMPERATURE: " << bufferSplit[0] << "\n";
                    } else if(counter == 1) {
                        inputData.phArray[1] = bufferSplit[0];
                        qDebug() << "PH: " << bufferSplit[0] << "\n";
                    } else if(counter == 2) {
                        inputData.moistureArray[1] = bufferSplit[0];
                        qDebug() << "MOISTURE: " << bufferSplit[0] << "\n";
                    }
                    MainWindow::sensorUpdate(inputData.temperatureArray[1], inputData.phArray[1], inputData.moistureArray[1]);
                    counter++;
                    if(counter == 3)
                    {
                        counter = 0;
                    }
                data.clear();
            }
            

            Thanks everyone for the help so far.

            A 1 Reply Last reply 24 Oct 2019, 04:50
            0
            • W Will_Craig
              24 Oct 2019, 01:39

              Yeah it comes in 3's but with no newline, the serial port kept reading the newline character so i am only displaying the " , " not a new line on Arduino output.

              The way the Arduino is outputting the data is float temperature, int ph, int moisture, and then it repeats in line.

              I've changed the code a bit and I'm starting to get clearer readings but now it is reading floats weird which is throwing everything else out of place. i may try running the code and see what it picks up if the output of the singular float variable is an int, because if its a problem with the decimal i will just work with an int the precision is not too much of an issue here.

              That if statement that broke it into a 3variable package was not needed that i can see from the output of new code it was wasted lines i think i was overthinking it.

              UPDATED CODE:

              void MainWindow::readSerial()
              {
                  QByteArray data = arduino->readAll();
                  serialBuffer = data;
                  data.truncate(3);
                      QStringList bufferSplit = serialBuffer.split(", ");
                      if(counter == 0) {
                          inputData.temperatureArray[1] = bufferSplit[0];
                          qDebug() << "TEMPERATURE: " << bufferSplit[0] << "\n";
                      } else if(counter == 1) {
                          inputData.phArray[1] = bufferSplit[0];
                          qDebug() << "PH: " << bufferSplit[0] << "\n";
                      } else if(counter == 2) {
                          inputData.moistureArray[1] = bufferSplit[0];
                          qDebug() << "MOISTURE: " << bufferSplit[0] << "\n";
                      }
                      MainWindow::sensorUpdate(inputData.temperatureArray[1], inputData.phArray[1], inputData.moistureArray[1]);
                      counter++;
                      if(counter == 3)
                      {
                          counter = 0;
                      }
                  data.clear();
              }
              

              Thanks everyone for the help so far.

              A Offline
              A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on 24 Oct 2019, 04:50 last edited by aha_1980
              #6

              @Will_Craig your protocol should really have a start/end of line marker, as it makes parsing so much easier.

              It may be impossible to understand the data if you only have int or float strings with comma between.

              Regards

              Qt has to stay free or it will die.

              1 Reply Last reply
              0

              5/6

              24 Oct 2019, 01:39

              • Login

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