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
Forum Updated to NodeBB v4.3 + New Features

Serial Data "reading" disorder

Scheduled Pinned Locked Moved General and Desktop
arduinoseriesbuffer
16 Posts 3 Posters 6.6k 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.
  • F Offline
    F Offline
    ftsm
    wrote on 23 Nov 2015, 23:31 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
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 23 Nov 2015, 23:42 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 24 Nov 2015, 20:35
      1
      • M Offline
        M Offline
        mrjj
        Lifetime Qt Champion
        wrote on 24 Nov 2015, 10:15 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 24 Nov 2015, 20:44
        1
        • S SGaist
          23 Nov 2015, 23:42

          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 24 Nov 2015, 20:35 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
          • M mrjj
            24 Nov 2015, 10:15

            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 24 Nov 2015, 20:44 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 ...

            M 1 Reply Last reply 24 Nov 2015, 20:52
            0
            • F ftsm
              24 Nov 2015, 20:44

              @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 ...

              M Offline
              M Offline
              mrjj
              Lifetime Qt Champion
              wrote on 24 Nov 2015, 20:52 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 24 Nov 2015, 21:49
              1
              • M mrjj
                24 Nov 2015, 20:52

                @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 24 Nov 2015, 21:49 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

                M 1 Reply Last reply 24 Nov 2015, 21:52
                0
                • F ftsm
                  24 Nov 2015, 21:49

                  @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

                  M Offline
                  M Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on 24 Nov 2015, 21:52 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 24 Nov 2015, 22:03
                  1
                  • M mrjj
                    24 Nov 2015, 21:52

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

                    F Offline
                    F Offline
                    ftsm
                    wrote on 24 Nov 2015, 22:03 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
                    • S Offline
                      S Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 24 Nov 2015, 22:07 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 24 Nov 2015, 22:12
                      1
                      • S SGaist
                        24 Nov 2015, 22:07

                        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 24 Nov 2015, 22:12 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 ?

                        M 1 Reply Last reply 24 Nov 2015, 22:18
                        0
                        • S Offline
                          S Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on 24 Nov 2015, 22:15 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 25 Nov 2015, 00:17
                          1
                          • F ftsm
                            24 Nov 2015, 22:12

                            @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 ?

                            M Offline
                            M Offline
                            mrjj
                            Lifetime Qt Champion
                            wrote on 24 Nov 2015, 22:18 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
                            • S SGaist
                              24 Nov 2015, 22:15

                              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 25 Nov 2015, 00:17 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 25 Nov 2015, 00:25 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

                                M 1 Reply Last reply 25 Nov 2015, 05:13
                                0
                                • F ftsm
                                  25 Nov 2015, 00:25

                                  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

                                  M Offline
                                  M Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on 25 Nov 2015, 05:13 last edited by
                                  #16

                                  @ftsm
                                  Congratulations with the baby ;)

                                  1 Reply Last reply
                                  0

                                  8/16

                                  24 Nov 2015, 21:52

                                  • Login

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