Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Solved read data from serial port

    General and Desktop
    4
    29
    3043
    Loading More Posts
    • 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.
    • mrjj
      mrjj Lifetime Qt Champion @isan last edited by

      @isan
      ok so it must be on the fly.

      Then you need to use 2 buffers as not to parse already received data over and over.
      so in pseudo code

      Read char from serial
      tempbuffer += char
      if char is \n then
      split tempbuffer
      emit value
      clear tempbuffer

      //i assume u want to store all ?
      Mainbuffer +=char

      I 1 Reply Last reply Reply Quote 1
      • I
        isan @mrjj last edited by isan

        @mrjj so the code is like:

        void MyThread::run()
        {
        
            qDebug("Thread id inside run %d",(int)QThread::currentThreadId());
        
            int fd ,x;
            
              
            if ((fd = serialOpen ("/dev/ttyACM0",230400)) < 0)
            {
                fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
            }
        
            while (serialDataAvail(fd)>-2)
            {
                 //-------value format is int -------//
                value=serialGetchar (fd) ;
             //--------vs format is QString------//
                 vs.push_back(value);
            //--------tempbuffer format is QString------//
           tempbuffer .append( vs);
           if (vs=="\n")
          //-------- values format is QStringList------//
             values = tempbuffer.split(",");
              x= values[0].toInt();
         msleep(1); 
               emit signalValueUpdated(x);
               tempbuffer.clear();
          
            }
            serialClose(fd); 
        }
        

        is it true?

        mrjj 1 Reply Last reply Reply Quote 0
        • mrjj
          mrjj Lifetime Qt Champion @isan last edited by mrjj

          @isan
          Hi
          Almost, you need to clear tempbuffer as soon as you have used it.
          And u need to check last read char (value) being the \n

          void MyThread::run() {
          
            qDebug("Thread id inside run %d", (int)QThread::currentThreadId());
          
            int fd, x=0;
          
          
            if ((fd = serialOpen ("/dev/ttyACM0", 230400)) < 0) {
              fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
            }
          
            while (serialDataAvail(fd) > -2) {
              value = serialGetchar (fd) ;
              vs.push_back(value);
              tempbuffer += value;
              if (value == '\n') {
                values = tempbuffer.split(",");
                x = values[0].toInt();
                tempbuffer.clear();
              }
              msleep(1);
              emit signalValueUpdated(x);
              
          
            }
            serialClose(fd);
          }
          
          JonB 1 Reply Last reply Reply Quote 1
          • JonB
            JonB @mrjj last edited by JonB

            @mrjj , @isan
            This code looks wrong. It doesn't help that we don't see the declarations of vs or tempbuffer. Comment:

            //--------tempbuffer format is QStringList------//

            No, it isn't, because later you go tempbuffer.split(",");. So it's probably a QString.

            Then: you read 1 char, you append it to vs. Then you append vs to tempbuffer. If value is not \n, you pick up the next char, append that to vs (now 2 chars long), append that to tempBuffer (now 3 chars long)...

            Hmm, vs must be a single char, not a QString like the comment says it is? Who knows....

            Separate issue:

            while (serialDataAvail(fd)>-2)
            

            Nope. serialDataAvail(fd) returns -1 on error. The code accepts that as a legal. It also should therefore never exit the while loop. Further, if 0 bytes are available code goes into the value=serialGetchar (fd) call. After 10 seconds of no data that will return -1. At which point accepts that as the legal char received. Finally, if error opening device in the first place, the code writes a message and then continues into the loop, which makes no sense.

            All this code really needs correcting....

            Finally, have a think about the fact that sometimes you are using Qt & C++ functions, sometimes you are doing lowest-level C library calls. Do you really need to mix them?

            mrjj 1 Reply Last reply Reply Quote 2
            • mrjj
              mrjj Lifetime Qt Champion @JonB last edited by mrjj

              +@JonB
              Thx, yes value should be added to tempbuffer.
              Then i can learn not to edit code in forum directly :)
              So something like this + all than @JonB said

              while (serialDataAvail(fd) > -2) { // fix condition! 
                  value = serialGetchar (fd) ;// read char
                  vs.push_back(value); // store in ful buffer
                  tempbuffer += value; // add to tempbuffer
                  if (value == '\n') { // if we just read \n
                    values = tempbuffer.split(","); // split on , to QStringList
                    x = values[0].toInt(); // take first index and convert to int
                    tempbuffer.clear(); // clear it for next 
                  }
              ......
              
              I 1 Reply Last reply Reply Quote 1
              • J.Hilk
                J.Hilk Moderators last edited by

                I‘ve been following this thread for a while now, and you guy‘s doing a great job :-)

                Just one thing that‘s been buging me from the beginning.

                The call off split on the string. It‘s used for nothing but temporary storage to than turn the first entry into an INT.

                I would highly recommand to at least use splitref.

                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

                Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                mrjj 1 Reply Last reply Reply Quote 3
                • I
                  isan @mrjj last edited by isan

                  @mrjj Thanks for keep helping to solve my problem
                  It's work!

                  mrjj 1 Reply Last reply Reply Quote 2
                  • mrjj
                    mrjj Lifetime Qt Champion @isan last edited by

                    @isan
                    Super :) \O/

                    1 Reply Last reply Reply Quote 0
                    • mrjj
                      mrjj Lifetime Qt Champion @J.Hilk last edited by

                      @J.Hilk
                      Yes i agree. but in this case we wanted to split very small sample so
                      i decided not to introduce new classes. (QVector/QStringRef)
                      as to focus on getting it running. But yes, much better to use normally as the speed gain is huge for large dataset. (more than i did imagine)

                      1 Reply Last reply Reply Quote 1
                      • First post
                        Last post