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. Sending a data to Arduino through serial port using Qt
Forum Updated to NodeBB v4.3 + New Features

Sending a data to Arduino through serial port using Qt

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 5 Posters 28.4k Views 3 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.
  • brotifyB Offline
    brotifyB Offline
    brotify
    wrote on last edited by
    #1

    Hi all, I want to send and receive data between arduino and computer through serial port. I programmed my Arduino such that when I send the character "a", it responds by sending a string "12334ı485" (just an example). It works when I use Arduino IDE serial monitor. However I need to send and receive data in a Qt project. I wrote this code but it does not work and what I get is this: http://i.hizliresim.com/VaLGWV.png

    Here is my code

    #include <iostream>
    #include <QSerialPort>
    #include <QSerialPortInfo>
    #include <QDebug>
    #include <windows.h>
    
    QSerialPort serial;
    using namespace std;
    int main()
    {
    
       serial.setPortName("COM18");
       serial.setBaudRate(QSerialPort::Baud9600);
       serial.setDataBits(QSerialPort::Data8);
       serial.setParity(QSerialPort::NoParity);
       serial.setStopBits(QSerialPort::OneStop);
       serial.setFlowControl(QSerialPort::NoFlowControl);
       serial.open(QIODevice::ReadWrite);
       QByteArray data="a";
       serial.write(data);
       while(!serial.isOpen()) serial.open(QIODevice::ReadWrite);
    while(1){
        serial.write(data);
           Sleep(1500);
               QByteArray ba;
               ba=serial.readAll();
    
               qDebug()<<ba;
    
    }
    }
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      You should take a look at the QtSerialPort examples. You'll find there several possible implementations depending on your application needs.

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

      brotifyB 1 Reply Last reply
      1
      • M Offline
        M Offline
        michelson
        wrote on last edited by michelson
        #3

        First while has ";" after it so probably you should fix it.

        while(!serial.isOpen()) serial.open(QIODevice::ReadWrite);

        I usually use readyRead singal or I use waitForBytesWritten and waitForReadReady combination.

        1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          You should take a look at the QtSerialPort examples. You'll find there several possible implementations depending on your application needs.

          brotifyB Offline
          brotifyB Offline
          brotify
          wrote on last edited by
          #4

          @SGaist They seems to me rather complicated and poorly explained.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            asanka424
            wrote on last edited by
            #5

            Hi, I would sugget you to read about how Qt event system works. All Qt IODevice derived classes work asynchronously. You need to use QApplication in order to host its object system. After that you need to change your code so that its not blocking io thread of QSerialPort.

            brotifyB 1 Reply Last reply
            0
            • A asanka424

              Hi, I would sugget you to read about how Qt event system works. All Qt IODevice derived classes work asynchronously. You need to use QApplication in order to host its object system. After that you need to change your code so that its not blocking io thread of QSerialPort.

              brotifyB Offline
              brotifyB Offline
              brotify
              wrote on last edited by
              #6

              @asanka424 Thanks I have solved the problem but this time I have another problem. When I connect the arduino with the usb cable my code works perfectly, but I when I use bluetooth module it does not work correctly. To show what the problem is I will share secreenshot of output with usb cable and bluetooth module.
              With USB cable: http://i.hizliresim.com/MpWPPQ.png
              With bluetooth: http://i.hizliresim.com/Va6gAr.png

              As you can see when working with bluetooth it sometimes get the data wrong.
              Why does it happen?

              My code is here:

              #include <QCoreApplication>
              #include <iostream>
              #include <QSerialPort>
              #include <QDebug>
              #include <Windows.h>
              using namespace std;
              QSerialPort serial;
              int main(int argc, char *argv[])
              {
                  QCoreApplication a(argc, argv);
                  serial.setPortName("COM21");
                  serial.open(QIODevice::ReadWrite);
                     serial.setBaudRate(QSerialPort::Baud115200);
                     serial.setDataBits(QSerialPort::Data8);
                     serial.setParity(QSerialPort::NoParity);
                     serial.setStopBits(QSerialPort::OneStop);
                     serial.setFlowControl(QSerialPort::NoFlowControl);
                      while(!serial.isOpen()) serial.open(QIODevice::ReadWrite);
                   
                     if (serial.isOpen() && serial.isWritable())
                     {
                     qDebug() << "Serial is open";
              
                     QByteArray output;
                     QByteArray input;
              
                       while(true)
                       {
                       output = "a";
                       serial.write(output);
                      serial.flush();
              
                       serial.waitForBytesWritten(1000);
                       serial.waitForReadyRead(1000);
              
                       input = serial.readAll();
                       qDebug()<<input;
              
                       }
                     }
                  return a.exec();
              }
              
              
              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                The data you receive is not wrong it's just that you don't receive it at the same pace with both devices e.g. the underlying buffer are handled differently. But all in all the data is the same.

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

                brotifyB 1 Reply Last reply
                0
                • SGaistS SGaist

                  The data you receive is not wrong it's just that you don't receive it at the same pace with both devices e.g. the underlying buffer are handled differently. But all in all the data is the same.

                  brotifyB Offline
                  brotifyB Offline
                  brotify
                  wrote on last edited by
                  #8

                  @SGaist How can I modify my code so that I get the same output?

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    michelson
                    wrote on last edited by
                    #9

                    IMO 2 options:

                    • QSerialPort::readData() - make your program read data of given length
                      http://doc.qt.io/qt-5/qserialport.html#readData
                    • QSerialPort::bytesAvailable() - check if there is expected number of bytes available
                      http://doc.qt.io/qt-5/qserialport.html#bytesAvailable
                    brotifyB 1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      asanka424
                      wrote on last edited by
                      #10

                      If you know the amount of bytes in a message, don't read it until you have more or same available to read. When you read, only read that number of bytes.

                      1 Reply Last reply
                      0
                      • M michelson

                        IMO 2 options:

                        • QSerialPort::readData() - make your program read data of given length
                          http://doc.qt.io/qt-5/qserialport.html#readData
                        • QSerialPort::bytesAvailable() - check if there is expected number of bytes available
                          http://doc.qt.io/qt-5/qserialport.html#bytesAvailable
                        brotifyB Offline
                        brotifyB Offline
                        brotify
                        wrote on last edited by
                        #11

                        @michelson That works, thanks. I want to share final version of the code

                        #include <QCoreApplication>
                        #include <iostream>
                        #include <QSerialPort>
                        #include <QDebug>
                        #include <Windows.h>
                        #include <QElapsedTimer>
                        using namespace std;
                        QSerialPort serial;
                        QElapsedTimer timer;
                        int main(int argc, char *argv[])
                        {
                            QCoreApplication a(argc, argv);
                            serial.setPortName("COM21");
                            serial.open(QIODevice::ReadWrite);
                               serial.setBaudRate(QSerialPort::Baud115200);
                               serial.setDataBits(QSerialPort::Data8);
                               serial.setParity(QSerialPort::NoParity);
                               serial.setStopBits(QSerialPort::OneStop);
                               serial.setFlowControl(QSerialPort::NoFlowControl);
                                while(!serial.isOpen()) serial.open(QIODevice::ReadWrite);
                        
                               if (serial.isOpen() && serial.isWritable())
                               {
                               qDebug() << "Serial is open";
                        
                               QByteArray output;
                               QByteArray input;
                        
                                 while(true)
                                 {
                                 output = "a";
                                 serial.write(output);
                                serial.flush();
                                timer.start();
                               // Sleep(80);
                                qDebug() << timer.elapsed();
                                 serial.waitForBytesWritten(100);
                                 serial.waitForReadyRead(100);
                                if(serial.bytesAvailable()>=18)
                                 input = serial.read(18);
                                qDebug()<<input;
                        
                                 }
                               }
                            return a.exec();
                        }
                        
                        
                        sankarapandiyanS 1 Reply Last reply
                        1
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          That while on isOpen is just plain wrong. You already opened the serial port and if for any reason if fails to open you'r going to get stuck in that loop.

                          Do the check on the first open and act accordingly.

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

                          brotifyB 1 Reply Last reply
                          2
                          • SGaistS SGaist

                            That while on isOpen is just plain wrong. You already opened the serial port and if for any reason if fails to open you'r going to get stuck in that loop.

                            Do the check on the first open and act accordingly.

                            brotifyB Offline
                            brotifyB Offline
                            brotify
                            wrote on last edited by
                            #13

                            @SGaist
                            I add this option because sometimes the computer cannot connect to the bluetooth module, therefore if it cannot connect the first time I want my program to try connecting bluetooth module again, but anyway I exluded this option, since I am using GUI in my project.

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

                              Then add a "Try Again" button to your GUI. It will be cleaner.

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

                              1 Reply Last reply
                              1
                              • brotifyB brotify

                                @michelson That works, thanks. I want to share final version of the code

                                #include <QCoreApplication>
                                #include <iostream>
                                #include <QSerialPort>
                                #include <QDebug>
                                #include <Windows.h>
                                #include <QElapsedTimer>
                                using namespace std;
                                QSerialPort serial;
                                QElapsedTimer timer;
                                int main(int argc, char *argv[])
                                {
                                    QCoreApplication a(argc, argv);
                                    serial.setPortName("COM21");
                                    serial.open(QIODevice::ReadWrite);
                                       serial.setBaudRate(QSerialPort::Baud115200);
                                       serial.setDataBits(QSerialPort::Data8);
                                       serial.setParity(QSerialPort::NoParity);
                                       serial.setStopBits(QSerialPort::OneStop);
                                       serial.setFlowControl(QSerialPort::NoFlowControl);
                                        while(!serial.isOpen()) serial.open(QIODevice::ReadWrite);
                                
                                       if (serial.isOpen() && serial.isWritable())
                                       {
                                       qDebug() << "Serial is open";
                                
                                       QByteArray output;
                                       QByteArray input;
                                
                                         while(true)
                                         {
                                         output = "a";
                                         serial.write(output);
                                        serial.flush();
                                        timer.start();
                                       // Sleep(80);
                                        qDebug() << timer.elapsed();
                                         serial.waitForBytesWritten(100);
                                         serial.waitForReadyRead(100);
                                        if(serial.bytesAvailable()>=18)
                                         input = serial.read(18);
                                        qDebug()<<input;
                                
                                         }
                                       }
                                    return a.exec();
                                }
                                
                                
                                sankarapandiyanS Offline
                                sankarapandiyanS Offline
                                sankarapandiyan
                                wrote on last edited by
                                #15

                                @brotify could you show me the IDE code

                                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