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 Data "reading" disorder
QtWS25 Last Chance

Serial Data "reading" disorder

Scheduled Pinned Locked Moved General and Desktop
arduinoseriesbuffer
16 Posts 3 Posters 6.5k 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.
  • F Offline
    F Offline
    ftsm
    wrote on last edited by
    #1

    Hi everyone !

    It's my first program on Qt, so please be understanding ... (for my english too)
    

    It have an arduino uno card, and some potentiometers on it. I made a small Dialog window just to see if I can receive everything by serial buffer. I managed to receive and see all the informations (basicaly 6 numbers with 1 or 4 digits each).
    In order to separate them (they arrived like "12359542288752145"), I put a letter betwen each value with arduino, so datas arrive like "A1235AB954BC2288CD75DE2145E".
    Then i make some sections with the right letter and got the separate datas like i need.

    But the problem is I never receive data the same way, it could be either:
    "A1235AB954BC2288CD75DE2145E"
    or
    "A12"
    or even
    ""

    Do you know how to fiw that ? Here is a part of my (poor) code:

    #include "dialog.h"
    #include "ui_dialog.h"
    #include <QSerialPort>
    #include <QSerialPortInfo>
    #include <string>
    #include <QDebug>
    #include <QMessageBox>
    #include <QTime>

    Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
    {
    ui->setupUi(this);
    ui->InclinoD_lcdNumber->display("----");
    ui->InclinoG_lcdNumber->display("----");
    ui->Godet_lcdNumber->display("----");
    ui->Balancier_lcdNumber->display("----");
    ui->Fleche_lcdNumber->display("----");
    ui->Tourelle_lcdNumber->display("----");

    arduino = new QSerialPort(this);
    serialBuffer = "";
    
    bool arduino_is_available = false;
    QString arduino_uno_port_name;
    
    foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()){
        if(serialPortInfo.hasProductIdentifier() && serialPortInfo.hasVendorIdentifier()){
            if((serialPortInfo.productIdentifier() == arduino_uno_product_id)
                    && (serialPortInfo.vendorIdentifier() == arduino_uno_vendor_id)){
                arduino_is_available = true; 
                arduino_uno_port_name = serialPortInfo.portName();
            }
        }
    }
    
    if(arduino_is_available){
        qDebug() << "Found the arduino port...\n";
        arduino->setPortName(arduino_uno_port_name);
        arduino->open(QSerialPort::ReadOnly);
        arduino->setBaudRate(QSerialPort::Baud9600);
        arduino->setDataBits(QSerialPort::Data8);
        arduino->setFlowControl(QSerialPort::NoFlowControl);
        arduino->setParity(QSerialPort::NoParity);
        arduino->setStopBits(QSerialPort::OneStop);
        QObject::connect(arduino, SIGNAL(readyRead()), this, SLOT(readSerial()));
    }else{
        qDebug() << "Couldn't find the correct port for the arduino.\n";
        QMessageBox::information(this, "Serial Port Error", "Couldn't open serial port to arduino.");
    }
    

    }

    Dialog::~Dialog()
    {
    if(arduino->isOpen()){
    arduino->close(); // Close the serial port if it's open.
    }
    delete ui;
    }

    void Dialog::readSerial()
    {

        QStringList buffer_split;
    
        serialData = arduino->readAll();
        serialBuffer = QString::fromStdString(serialData.toStdString());
    
        parsed_data = serialBuffer.section("D", 1,1); 
        buffer_split.insert(0,parsed_data);
        parsed_data = serialBuffer.section("G", 1,1); 
        buffer_split.insert(1,parsed_data);
        parsed_data = serialBuffer.section("o", 1,1); 
        buffer_split.insert(2,parsed_data);
        parsed_data = serialBuffer.section("B", 1,1); 
        buffer_split.insert(3,parsed_data);
        parsed_data = serialBuffer.section("F", 1,1); 
        buffer_split.insert(4,parsed_data);
        parsed_data = serialBuffer.section("T", 1,1); 
        buffer_split.insert(5,parsed_data);
    
        qDebug() << buffer_split << "\n";
    
        serialData.clear();
        serialBuffer = "";
    
    
        Dialog::updateInclinoD(buffer_split[0]);
        Dialog::updateInclinoG(buffer_split[1]);
        Dialog::updateGodet(buffer_split[2]);
        Dialog::updateBalancier(buffer_split[3]);
        Dialog::updateFleche(buffer_split[4]);
        Dialog::updateTourelle(buffer_split[5]);
    

    // And after come my functions ...

    Thank you all !

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      The usual way to handle incoming data is to store them in a buffer until there's enough of them to form a complete package and only then parse the packet.

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

      F 1 Reply Last reply
      1
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by mrjj
        #3

        Hi
        Data most often comes in pieces so as @SGaist says, you must keep reading
        like
        m_readData.append( m_serialPort->readAll());
        until you got whole "line" of data
        you can check
        if (m_readData.size() >= EXPECTED_BYTES)
        Parse()
        or have kind of stop marker in the data.

        Other note. you could maybe use same separator between numbers, like | and then
        just say
        serialBuffer = QString::fromStdString(serialData.toStdString());
        QStringList list = serialBuffer .split ( "|" );
        then you have list of each number.
        list[0] being the first.

        Just a though. might not suit your needs.

        F 1 Reply Last reply
        1
        • SGaistS SGaist

          Hi and welcome to devnet,

          The usual way to handle incoming data is to store them in a buffer until there's enough of them to form a complete package and only then parse the packet.

          F Offline
          F Offline
          ftsm
          wrote on last edited by
          #4

          @SGaist Thank you or your answer. Yes i suppose that's what I have to do, but I don't really know how. I tried with "waitForReadyRead()" but he doesn't work, my code just stop and crash on it, despite what I read I don't really know how to use it properly.

          1 Reply Last reply
          0
          • mrjjM mrjj

            Hi
            Data most often comes in pieces so as @SGaist says, you must keep reading
            like
            m_readData.append( m_serialPort->readAll());
            until you got whole "line" of data
            you can check
            if (m_readData.size() >= EXPECTED_BYTES)
            Parse()
            or have kind of stop marker in the data.

            Other note. you could maybe use same separator between numbers, like | and then
            just say
            serialBuffer = QString::fromStdString(serialData.toStdString());
            QStringList list = serialBuffer .split ( "|" );
            then you have list of each number.
            list[0] being the first.

            Just a though. might not suit your needs.

            F Offline
            F Offline
            ftsm
            wrote on last edited by
            #5

            @mrjj Thank you.
            I used differents letters as separator because i wanted to reconize each data. Indeed I can just use one separator but it means that I have to gather all the data in the good order.
            ".append" seams like a good way but my problem is that I can't know the size of my expected bytes. Each potentiometer can send 1 to 4 digits. I assume there are already solutions for that, but I don't know what ...

            mrjjM 1 Reply Last reply
            0
            • F ftsm

              @mrjj Thank you.
              I used differents letters as separator because i wanted to reconize each data. Indeed I can just use one separator but it means that I have to gather all the data in the good order.
              ".append" seams like a good way but my problem is that I can't know the size of my expected bytes. Each potentiometer can send 1 to 4 digits. I assume there are already solutions for that, but I don't know what ...

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

              @ftsm
              Ah ok, yes if they can come out of order then same separator is not a option.

              -Each potentiometer can send 1 to 4 digits
              so maybe there comes 1 byte or maybe 4 ?

              F 1 Reply Last reply
              1
              • mrjjM mrjj

                @ftsm
                Ah ok, yes if they can come out of order then same separator is not a option.

                -Each potentiometer can send 1 to 4 digits
                so maybe there comes 1 byte or maybe 4 ?

                F Offline
                F Offline
                ftsm
                wrote on last edited by
                #7

                @mrjj Indeed. And so if I try ".append" I will have a huge disorder in datas ...
                I'm still trying to figure out a way to get everything in order but nothing work fine yet

                mrjjM 1 Reply Last reply
                0
                • F ftsm

                  @mrjj Indeed. And so if I try ".append" I will have a huge disorder in datas ...
                  I'm still trying to figure out a way to get everything in order but nothing work fine yet

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

                  @ftsm
                  but how does the potentiometer send its data ?
                  you have no control over the format?

                  F 1 Reply Last reply
                  1
                  • mrjjM mrjj

                    @ftsm
                    but how does the potentiometer send its data ?
                    you have no control over the format?

                    F Offline
                    F Offline
                    ftsm
                    wrote on last edited by
                    #9

                    @mrjj The potentiometer send its data via Arduino. I can write how I want to send it. First I tried with "," to separate, but I could'nt reconize wich data was what. So I tried with a specific letter before and after each potentiometer value. In this case it is really hard for me to extract the potentiometer value from the line (from serial) because I only know the "split" technic

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Mix both techniques: an ID to know what kind of data you have and the "special" char to know where to split.

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

                      F 1 Reply Last reply
                      1
                      • SGaistS SGaist

                        Mix both techniques: an ID to know what kind of data you have and the "special" char to know where to split.

                        F Offline
                        F Offline
                        ftsm
                        wrote on last edited by
                        #11

                        @SGaist Yes I think that is my best move, that's what I'm currently trying to do.
                        But I have a last problem: how can I try the existence of a string from QstringList ? For example I need to know if after spliting "buffer_split[1]" exist ?

                        mrjjM 1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          You can use a while loop and take the first element at each iteration so no need for a particular check.

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

                          F 1 Reply Last reply
                          1
                          • F ftsm

                            @SGaist Yes I think that is my best move, that's what I'm currently trying to do.
                            But I have a last problem: how can I try the existence of a string from QstringList ? For example I need to know if after spliting "buffer_split[1]" exist ?

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

                            @ftsm
                            also QstringList has a size() that tells the number of elements. (strings)
                            That also gives hints to valid index.

                            1 Reply Last reply
                            1
                            • SGaistS SGaist

                              You can use a while loop and take the first element at each iteration so no need for a particular check.

                              F Offline
                              F Offline
                              ftsm
                              wrote on last edited by
                              #14

                              @SGaist @mrjj Thank you for that, I managed to split correctly and find the right data.
                              But I am still able to do that only on debug mode, when I try to run the program it's like i'm going too fast and my "->ReadAll()" don't gather enought data. (I saw that with some qDebug()).
                              So I go back to my first problem, if I use a while loop with "append" I will mix the data.
                              Can't I use "waitForReadyRead()" ?

                              1 Reply Last reply
                              0
                              • F Offline
                                F Offline
                                ftsm
                                wrote on last edited by
                                #15

                                OH MY GOD that was the solution since the begining !! It's 1:30am and it's perfectly working !!

                                THank you guys I love you so much !!

                                YAAaaaaaayyy my first beautiful program on Qt and it rules !! THANK YOU

                                mrjjM 1 Reply Last reply
                                0
                                • F ftsm

                                  OH MY GOD that was the solution since the begining !! It's 1:30am and it's perfectly working !!

                                  THank you guys I love you so much !!

                                  YAAaaaaaayyy my first beautiful program on Qt and it rules !! THANK YOU

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

                                  @ftsm
                                  Congratulations with the baby ;)

                                  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