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. Signal receiving problem from Arduino to Qt graphics view
Forum Updated to NodeBB v4.3 + New Features

Signal receiving problem from Arduino to Qt graphics view

Scheduled Pinned Locked Moved Unsolved General and Desktop
18 Posts 4 Posters 4.6k Views 1 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.
  • jazzycamelJ jazzycamel

    @Macive-Xiong

    Ok, I don't know why your program isn't working or why its hanging. The following is a fully working example that I've tested with an Arduino Uno running your code connected to my MacBook Pro running the following (compiled with Qt5.6):

    Forum2.pro

    QT       += core gui serialport
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = Forum2
    TEMPLATE = app
    
    
    SOURCES += main.cpp\
            mainwindow.cpp
    
    HEADERS  += mainwindow.h
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    class QSerialPort;
    class QGraphicsScene;
    class QGraphicsView;
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    public slots:
        void updateP();
    
    private:
        QGraphicsScene *scene;
        QGraphicsView *view;
        QSerialPort *arduino;
        bool open;
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include <QRegularExpression>
    #include <QTextStream>
    #include <QDebug>
    #include <QtSerialPort>
    #include <QGraphicsScene>
    #include <QGraphicsView>
    
    #include "mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent), open(false)
    {
        this->resize(1024,768);
    
        scene=new QGraphicsScene(this);
        scene->setSceneRect(0,0,1024,768);
        view=new QGraphicsView(scene, this);
        setCentralWidget(view);
    
        arduino=new QSerialPort("/dev/ttys002");
        arduino->setBaudRate(QSerialPort::Baud9600);
        connect(arduino, SIGNAL(readyRead()), this, SLOT(updateP()));
        if(!arduino->open(QSerialPort::ReadOnly)){
            qDebug() << "Failed to open serial port!";
            return;
        }
        open=true;
    }
    
    MainWindow::~MainWindow(){}
    
    void MainWindow::updateP(){
        if(!open) return;
    
        QTextStream stream(arduino);
        QString line;
        while(stream.readLineInto(&line)){
            QRegularExpression re("x = ([0-9]{2,3})");
            QRegularExpressionMatch match=re.match(line);
            if(!match.hasMatch()) continue;
            QString matched=match.captured(1);
            bool ok;
            int x=matched.toInt(&ok);
            if(!ok) continue;
    
            QBrush redBrush(Qt::red);
            QPen blackPen(Qt::black, 1.);
            scene->addEllipse(x, 768/2., 20, 20, blackPen, redBrush);
        }
    }
    

    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    You will need to change the name of the serial/COM port being passed to QSerialPort in line 20 of mainwindow.cpp.

    I hope this gets you up and running :)

    Macive XiongM Offline
    Macive XiongM Offline
    Macive Xiong
    wrote on last edited by
    #9

    Hi @jazzycamel ,

    Your every answer is really helpful. Thank you so much for this. I copied the exactly the same code you provide and change the serial port.
    My graphicsView seems like

    Can you take a screen shot on your graphicsView screen for me? And any suggestion?? I think the graphicsView should be the line which is connected by the ellipses from x = 94 to x = 512. Thank you so much.

    jazzycamelJ 1 Reply Last reply
    0
    • Macive XiongM Macive Xiong

      Hi @jazzycamel ,

      Your every answer is really helpful. Thank you so much for this. I copied the exactly the same code you provide and change the serial port.
      My graphicsView seems like

      Can you take a screen shot on your graphicsView screen for me? And any suggestion?? I think the graphicsView should be the line which is connected by the ellipses from x = 94 to x = 512. Thank you so much.

      jazzycamelJ Offline
      jazzycamelJ Offline
      jazzycamel
      wrote on last edited by
      #10

      @Macive-Xiong

      Probably a timing issue. Try putting a longer delay between the Serial.println() in the Arduino code and see if it improves. Mine looks like the following:

      Output Screenshot

      For the avoidance of doubt:

      1. All my code samples (C++ or Python) are tested before posting
      2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
      Macive XiongM 1 Reply Last reply
      0
      • jazzycamelJ jazzycamel

        @Macive-Xiong

        Probably a timing issue. Try putting a longer delay between the Serial.println() in the Arduino code and see if it improves. Mine looks like the following:

        Output Screenshot

        Macive XiongM Offline
        Macive XiongM Offline
        Macive Xiong
        wrote on last edited by Macive Xiong
        #11

        Hi @jazzycamel

        I tried to extend my delay time but it didn't work. And I thought it's about the data rate problem. So I changed the Serial.begin from 9600 to 115200. And it works fine. Even my original code is fine:)

        0_1472656321946_2016-08-31 (5).png

        But here are some questions, why there are so many red ellipse running in the same time? Despite I set it as "for" loop. But is the second ellipse supposed to be set after first ellipse run to the end??

        And about the code you provided:

        QRegularExpression re("x = ([0-9]{2,3})");
        

        the class information says is a pattern, but why [0-9]{2,3}?

        Thank you so much for your help:)

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #12

          The fact that it's not a continuing series of data is probably due to the fact that you read half lines that are skipped by if(!match.hasMatch()) continue;. This is the problem with readAll I was talking about.

          try replacing

          if(!match.hasMatch()) continue;
          

          with

          if(!match.hasMatch()){
          qDebug() << "Row Skipped";
          continue;
          }
          

          and see how many get skipped

          QRegularExpression uses perl regular expression. there are whole books written on this sintax, a quick reference can be found here http://www.regular-expressions.info/refquick.html

          "x = ([0-9]{2,3})" means "x = " followed by 2 or 3 digits, the parethesis are used to capture part of the text that is then retrieved by match.captured(1);

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          2
          • jazzycamelJ Offline
            jazzycamelJ Offline
            jazzycamel
            wrote on last edited by
            #13

            @Macive-Xiong

            There are so many red ellipses because you draw a new one for each value of x rather than moving the original one. Try adding the ellipse once in the MainWindow constructor and then calling ellipse->setPos(x,10); in MainWindow::updateP().

            As @VRonin points out (and as I've said in my posts), this is a very basic, idealised example of how to read and process data from an asynchronous stream. You should probably add available data to a buffer each time readyRead() is emitted and then process it such that partially received data is not lost/thrown away.

            Below is a slightly more complex version of above (still not complete!) and here is a video of it working (I'm sending a Sine function from the Arduino):

            mainwindow.h

            #ifndef MAINWINDOW_H
            #define MAINWINDOW_H
            
            #include <QMainWindow>
            
            class QSerialPort;
            class QGraphicsScene;
            class QGraphicsView;
            class QGraphicsEllipseItem;
            
            class MainWindow : public QMainWindow
            {
                Q_OBJECT
            
            public:
                MainWindow(QWidget *parent = 0);
                ~MainWindow();
            
            public slots:
                void updateP();
            
            private:
                QGraphicsScene *scene;
                QGraphicsView *view;
                QGraphicsEllipseItem *ellipse;
                QSerialPort *arduino;
                bool open;
            };
            
            #endif // MAINWINDOW_H
            

            mainwindow.cpp

            #include <QRegularExpression>
            #include <QTextStream>
            #include <QDebug>
            #include <QtSerialPort>
            #include <QGraphicsScene>
            #include <QGraphicsView>
            #include <QGraphicsEllipseItem>
            
            #include "mainwindow.h"
            
            MainWindow::MainWindow(QWidget *parent)
                : QMainWindow(parent), open(false)
            {
                this->resize(1024,768);
            
                scene=new QGraphicsScene(this);
                scene->setSceneRect(0,0,1024,768);
                view=new QGraphicsView(scene, this);
                setCentralWidget(view);
            
                arduino=new QSerialPort("/dev/ttys005");
                arduino->setBaudRate(QSerialPort::Baud9600);
                connect(arduino, SIGNAL(readyRead()), this, SLOT(updateP()));
                if(!arduino->open(QSerialPort::ReadOnly)){
                    qDebug() << "Failed to open serial port!";
                    return;
                }
                open=true;
            
                QBrush redBrush(Qt::red);
                QPen blackPen(Qt::black, 1.);
                ellipse=scene->addEllipse(0, 768/2., 20, 20, blackPen, redBrush);
            }
            
            MainWindow::~MainWindow(){}
            
            void MainWindow::updateP(){
                if(!open) return;
            
                QTextStream stream(arduino);
                QString line;
                while(stream.readLineInto(&line)){
                    QRegularExpression re("x = ([0-9]{2,3})");
                    QRegularExpressionMatchIterator i=re.globalMatch(line);
                    while(i.hasNext()){
                        QRegularExpressionMatch match=i.next();
                        if(!match.hasMatch()){
                            qDebug() << "No match!";
                            continue;
                        }
                        QString matched=match.captured(1);
                        bool ok=false;
                        int x=matched.toInt(&ok);
                        if(!ok){
                            qDebug() << "Could not convert \"" << matched <<"\" to an integer!";
                            continue;
                        }
                        ellipse->setPos(x,0.);
                    }
                }
            }
            

            For the avoidance of doubt:

            1. All my code samples (C++ or Python) are tested before posting
            2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
            Macive XiongM 1 Reply Last reply
            2
            • jazzycamelJ jazzycamel

              @Macive-Xiong

              There are so many red ellipses because you draw a new one for each value of x rather than moving the original one. Try adding the ellipse once in the MainWindow constructor and then calling ellipse->setPos(x,10); in MainWindow::updateP().

              As @VRonin points out (and as I've said in my posts), this is a very basic, idealised example of how to read and process data from an asynchronous stream. You should probably add available data to a buffer each time readyRead() is emitted and then process it such that partially received data is not lost/thrown away.

              Below is a slightly more complex version of above (still not complete!) and here is a video of it working (I'm sending a Sine function from the Arduino):

              mainwindow.h

              #ifndef MAINWINDOW_H
              #define MAINWINDOW_H
              
              #include <QMainWindow>
              
              class QSerialPort;
              class QGraphicsScene;
              class QGraphicsView;
              class QGraphicsEllipseItem;
              
              class MainWindow : public QMainWindow
              {
                  Q_OBJECT
              
              public:
                  MainWindow(QWidget *parent = 0);
                  ~MainWindow();
              
              public slots:
                  void updateP();
              
              private:
                  QGraphicsScene *scene;
                  QGraphicsView *view;
                  QGraphicsEllipseItem *ellipse;
                  QSerialPort *arduino;
                  bool open;
              };
              
              #endif // MAINWINDOW_H
              

              mainwindow.cpp

              #include <QRegularExpression>
              #include <QTextStream>
              #include <QDebug>
              #include <QtSerialPort>
              #include <QGraphicsScene>
              #include <QGraphicsView>
              #include <QGraphicsEllipseItem>
              
              #include "mainwindow.h"
              
              MainWindow::MainWindow(QWidget *parent)
                  : QMainWindow(parent), open(false)
              {
                  this->resize(1024,768);
              
                  scene=new QGraphicsScene(this);
                  scene->setSceneRect(0,0,1024,768);
                  view=new QGraphicsView(scene, this);
                  setCentralWidget(view);
              
                  arduino=new QSerialPort("/dev/ttys005");
                  arduino->setBaudRate(QSerialPort::Baud9600);
                  connect(arduino, SIGNAL(readyRead()), this, SLOT(updateP()));
                  if(!arduino->open(QSerialPort::ReadOnly)){
                      qDebug() << "Failed to open serial port!";
                      return;
                  }
                  open=true;
              
                  QBrush redBrush(Qt::red);
                  QPen blackPen(Qt::black, 1.);
                  ellipse=scene->addEllipse(0, 768/2., 20, 20, blackPen, redBrush);
              }
              
              MainWindow::~MainWindow(){}
              
              void MainWindow::updateP(){
                  if(!open) return;
              
                  QTextStream stream(arduino);
                  QString line;
                  while(stream.readLineInto(&line)){
                      QRegularExpression re("x = ([0-9]{2,3})");
                      QRegularExpressionMatchIterator i=re.globalMatch(line);
                      while(i.hasNext()){
                          QRegularExpressionMatch match=i.next();
                          if(!match.hasMatch()){
                              qDebug() << "No match!";
                              continue;
                          }
                          QString matched=match.captured(1);
                          bool ok=false;
                          int x=matched.toInt(&ok);
                          if(!ok){
                              qDebug() << "Could not convert \"" << matched <<"\" to an integer!";
                              continue;
                          }
                          ellipse->setPos(x,0.);
                      }
                  }
              }
              
              Macive XiongM Offline
              Macive XiongM Offline
              Macive Xiong
              wrote on last edited by Macive Xiong
              #14

              @jazzycamel and @VRonin

              Thank you guys so much for your help. Your answer is extremely helpful for novice:)

              I am wondering if I could control both X and Y in the same time, my Arduino code is :

              
              
              void setup() {
                Serial.begin(115200);
              
              }
              
              void loop() { 
              
              int x1 = 10;
              int y1 = 15;
              int y = y1;
              
              while (y<=100)
                 {
                   
                   for ( int x = x1; x <= 100; x++) {
                     delay(100);
                     Serial.print("x = ");
                     Serial.println(x);
                   }
              
                   y += 10;
                   Serial.print("y = ");
                   Serial.println(y);
              
                   for (int x = 100; x >= x1; x--) {
                     delay(100);
                     Serial.print("x = ");
                     Serial.println(x);
                   }
              
                   y += 10;
              
                   Serial.print("y = ");
                   Serial.println(y);
                 }
              
              }
              

              The graphicsView is supposed to be like

              How can I change the code? I think the readAll should be replaced by read x and y data separately, and the QRegularExpression also need to include y.

              const QByteArray data = arduino->readAll();
                      QTextStream stream(data);
                      QString line;
                      while(stream.readLineInto(&line)){
                          QRegularExpression re("x = ([0-9]{2,3})");
                          QRegularExpressionMatch match=re.match(line);
                          if(!match.hasMatch()){
                              qDebug()<<"ROW Skipped";
                              continue;
                          }
                          QString matched=match.captured(1);
                          bool ok;
                          int x=matched.toInt(&ok);
                          int y=matched.toInt(&ok);
                          if(!ok) continue;
              
              //set scene
                      QBrush redBrush(Qt::red);
                      QPen blackpen(Qt::black);
                      blackpen.setWidth(1);
              
              
                      ellipse = scene->addEllipse(x, y, 10, 10, blackpen, redBrush);
              
              

              I've tried this code and it will update x for x and y since I read all signal. Is there any suggestion? Thank you so much:)

              1 Reply Last reply
              0
              • jazzycamelJ Offline
                jazzycamelJ Offline
                jazzycamel
                wrote on last edited by
                #15

                @Macive-Xiong

                Very doable, you just need to extend the regular expression to capture the letter before the = as well as the value that follows, like so:

                QRegularExpression re("([x,y]) = ([0-9]{2,3})");
                

                See the example code below and this video of the output.

                mainwindow.h

                #ifndef MAINWINDOW_H
                #define MAINWINDOW_H
                
                #include <QMainWindow>
                
                class QSerialPort;
                class QGraphicsScene;
                class QGraphicsView;
                class QGraphicsEllipseItem;
                
                class MainWindow : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    MainWindow(QWidget *parent = 0);
                    ~MainWindow();
                
                public slots:
                    void updateP();
                
                private:
                    QGraphicsScene *scene;
                    QGraphicsView *view;
                    QGraphicsEllipseItem *ellipse;
                    QSerialPort *arduino;
                    bool open;
                    int x,y;
                };
                
                #endif // MAINWINDOW_H
                

                mainwindow.cpp

                #include <QRegularExpression>
                #include <QTextStream>
                #include <QDebug>
                #include <QtSerialPort>
                #include <QGraphicsScene>
                #include <QGraphicsView>
                #include <QGraphicsEllipseItem>
                
                #include "mainwindow.h"
                
                MainWindow::MainWindow(QWidget *parent)
                    : QMainWindow(parent), open(false), x(0), y(0)
                {
                    this->resize(1024,768);
                
                    scene=new QGraphicsScene(this);
                    scene->setSceneRect(0,0,1024,768);
                    view=new QGraphicsView(scene, this);
                    setCentralWidget(view);
                
                    arduino=new QSerialPort("/dev/ttys003");
                    arduino->setBaudRate(QSerialPort::Baud9600);
                    connect(arduino, SIGNAL(readyRead()), this, SLOT(updateP()));
                    if(!arduino->open(QSerialPort::ReadOnly)){
                        qDebug() << "Failed to open serial port!";
                        return;
                    }
                    open=true;
                
                    QBrush redBrush(Qt::red);
                    QPen blackPen(Qt::black, 1.);
                    ellipse=scene->addEllipse(0, 0, 20, 20, blackPen, redBrush);
                }
                
                MainWindow::~MainWindow(){}
                
                void MainWindow::updateP(){
                    if(!open) return;
                
                    QTextStream stream(arduino);
                    QString line;
                    while(stream.readLineInto(&line)){
                        QRegularExpression re("([x,y]) = ([0-9]{2,3})");
                        QRegularExpressionMatchIterator i=re.globalMatch(line);
                        while(i.hasNext()){
                            QRegularExpressionMatch match=i.next();
                            if(!match.hasMatch()){
                                qDebug() << "No match!";
                                continue;
                            }
                            QString xory=match.captured(1);
                            QString matched=match.captured(2);
                
                            bool ok=false;
                            if(xory=="x") x=matched.toInt(&ok);
                            else if(xory=="y") y=matched.toInt(&ok);
                            else continue;
                            if(!ok){
                                qDebug() << "Could not convert \"" << matched <<"\" to an integer!";
                                continue;
                            }
                            ellipse->setPos(x,y);
                        }
                    }
                }
                

                For the avoidance of doubt:

                1. All my code samples (C++ or Python) are tested before posting
                2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
                Macive XiongM 1 Reply Last reply
                2
                • jazzycamelJ jazzycamel

                  @Macive-Xiong

                  Very doable, you just need to extend the regular expression to capture the letter before the = as well as the value that follows, like so:

                  QRegularExpression re("([x,y]) = ([0-9]{2,3})");
                  

                  See the example code below and this video of the output.

                  mainwindow.h

                  #ifndef MAINWINDOW_H
                  #define MAINWINDOW_H
                  
                  #include <QMainWindow>
                  
                  class QSerialPort;
                  class QGraphicsScene;
                  class QGraphicsView;
                  class QGraphicsEllipseItem;
                  
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                  
                  public:
                      MainWindow(QWidget *parent = 0);
                      ~MainWindow();
                  
                  public slots:
                      void updateP();
                  
                  private:
                      QGraphicsScene *scene;
                      QGraphicsView *view;
                      QGraphicsEllipseItem *ellipse;
                      QSerialPort *arduino;
                      bool open;
                      int x,y;
                  };
                  
                  #endif // MAINWINDOW_H
                  

                  mainwindow.cpp

                  #include <QRegularExpression>
                  #include <QTextStream>
                  #include <QDebug>
                  #include <QtSerialPort>
                  #include <QGraphicsScene>
                  #include <QGraphicsView>
                  #include <QGraphicsEllipseItem>
                  
                  #include "mainwindow.h"
                  
                  MainWindow::MainWindow(QWidget *parent)
                      : QMainWindow(parent), open(false), x(0), y(0)
                  {
                      this->resize(1024,768);
                  
                      scene=new QGraphicsScene(this);
                      scene->setSceneRect(0,0,1024,768);
                      view=new QGraphicsView(scene, this);
                      setCentralWidget(view);
                  
                      arduino=new QSerialPort("/dev/ttys003");
                      arduino->setBaudRate(QSerialPort::Baud9600);
                      connect(arduino, SIGNAL(readyRead()), this, SLOT(updateP()));
                      if(!arduino->open(QSerialPort::ReadOnly)){
                          qDebug() << "Failed to open serial port!";
                          return;
                      }
                      open=true;
                  
                      QBrush redBrush(Qt::red);
                      QPen blackPen(Qt::black, 1.);
                      ellipse=scene->addEllipse(0, 0, 20, 20, blackPen, redBrush);
                  }
                  
                  MainWindow::~MainWindow(){}
                  
                  void MainWindow::updateP(){
                      if(!open) return;
                  
                      QTextStream stream(arduino);
                      QString line;
                      while(stream.readLineInto(&line)){
                          QRegularExpression re("([x,y]) = ([0-9]{2,3})");
                          QRegularExpressionMatchIterator i=re.globalMatch(line);
                          while(i.hasNext()){
                              QRegularExpressionMatch match=i.next();
                              if(!match.hasMatch()){
                                  qDebug() << "No match!";
                                  continue;
                              }
                              QString xory=match.captured(1);
                              QString matched=match.captured(2);
                  
                              bool ok=false;
                              if(xory=="x") x=matched.toInt(&ok);
                              else if(xory=="y") y=matched.toInt(&ok);
                              else continue;
                              if(!ok){
                                  qDebug() << "Could not convert \"" << matched <<"\" to an integer!";
                                  continue;
                              }
                              ellipse->setPos(x,y);
                          }
                      }
                  }
                  
                  Macive XiongM Offline
                  Macive XiongM Offline
                  Macive Xiong
                  wrote on last edited by Macive Xiong
                  #16

                  Hi @jazzycamel ,

                  Thanks for your answer, these are all really helpful.
                  I have tried the code your provide on the potentialmeter signal received, it doesn't work, you have any suggestion??

                  My code:
                  mainwindow.h

                  #ifndef MAINWINDOW_H
                  #define MAINWINDOW_H
                  
                  #include <QMainWindow>
                  #include <QGraphicsEllipseItem>
                  
                  class QSerialPort;
                  class QGraphicsScene;
                  class QGraphicsView;
                  
                  
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                  
                  public:
                      MainWindow(QWidget *parent = 0);
                      ~MainWindow();
                  
                  public slots:
                      void updateP();
                      void readSerial();
                  
                  private:
                      QGraphicsScene *scene;
                      QGraphicsView *view;
                      QSerialPort *arduino;
                      QGraphicsEllipseItem *ellipse;
                      bool open;
                  };
                  
                  #endif // MAINWINDOW_H
                  
                  

                  mainwindow.cpp

                  #include <QRegularExpression>
                  #include <QTextStream>
                  #include <QDebug>
                  #include <QtSerialPort>
                  #include <QGraphicsScene>
                  #include <QGraphicsView>
                  #include <QGraphicsEllipseItem>
                  
                  #include "mainwindow.h"
                  
                  MainWindow::MainWindow(QWidget *parent)
                      : QMainWindow(parent), open(false)
                  {
                      this->resize(1024,768);
                  
                      scene=new QGraphicsScene(this);
                      scene->setSceneRect(0,0,1024,768);
                      view=new QGraphicsView(scene, this);
                      setCentralWidget(view);
                  
                      arduino=new QSerialPort("COM5");
                      arduino->setBaudRate(QSerialPort::Baud115200);
                      connect(arduino, SIGNAL(readyRead()), this, SLOT(updateP()));
                      if(!arduino->open(QSerialPort::ReadWrite)){
                          qDebug() << "Failed to open serial port!";
                          return;
                      }
                      open=true;
                  
                  }
                  
                  MainWindow::~MainWindow(){}
                  
                  void MainWindow::updateP(){
                      if(!open) return;
                  
                      QTextStream stream(arduino);
                      QString line;
                      while(stream.readLineInto(&line)){
                          QRegularExpression re("x = ([0-9]{2,3})");
                          QRegularExpressionMatch match=re.match(line);
                          if(!match.hasMatch()) continue;
                          QString matched=match.captured(1);
                          bool ok;
                          float x=matched.toFloat(&ok);
                          if(!ok) continue;
                  
                          QBrush redBrush(Qt::red);
                          QPen blackPen(Qt::black, 1.);
                          scene->addEllipse(x, 300, 20, 20, blackPen, redBrush);
                  }
                  }
                  void MainWindow::readSerial()
                  {
                      this->updateP();
                  }
                  

                  But this code is perfectly working on for loop"x from 0 to 512".

                  My Arduino code for potentialmeter signal:

                  void setup() {:
                    Serial.begin(115200);
                  }
                  void loop() {
                    float x = analogRead (A0);
                    Serial.println(x);
                    delay(5);      
                  }
                  

                  And here is an extra question, how can I write the code only for receiving the value I want to? For example, I have different variable in Arduino x1, x2, y1, y2. But I only want to get the signal of x1 and y1, how can I modify the code?

                  Thank you so much:)

                  1 Reply Last reply
                  0
                  • jazzycamelJ Offline
                    jazzycamelJ Offline
                    jazzycamel
                    wrote on last edited by
                    #17

                    @Macive-Xiong

                    You've changed your Arduino code. You used to print x = 96 for example, but now you are only printing 96. The regular expression expects the first format. Also, the regular expression works for values 10 - 999, the range of analogRead() is 0-1023. If you want to use the current (value only) format for the full range of analogRead() then I suggest you change the regular expressions as follows:

                    QRegularExpression re("([0-9]{1,4})");
                    

                    And then, after converting the matched string to an integer, check if its in the desired range:

                    bool ok=false;
                    int x=matched.toInt(&ok);
                    if(!ok){
                        qDebug() << "Could not convert \"" << matched <<"\" to an integer!";
                        continue;
                    }
                    if(x<0 || x>1023){
                        qDebug() << "Value of x (" << x << ") out of range!";
                        continue;
                    }
                    

                    For the avoidance of doubt:

                    1. All my code samples (C++ or Python) are tested before posting
                    2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
                    Macive XiongM 1 Reply Last reply
                    0
                    • jazzycamelJ jazzycamel

                      @Macive-Xiong

                      You've changed your Arduino code. You used to print x = 96 for example, but now you are only printing 96. The regular expression expects the first format. Also, the regular expression works for values 10 - 999, the range of analogRead() is 0-1023. If you want to use the current (value only) format for the full range of analogRead() then I suggest you change the regular expressions as follows:

                      QRegularExpression re("([0-9]{1,4})");
                      

                      And then, after converting the matched string to an integer, check if its in the desired range:

                      bool ok=false;
                      int x=matched.toInt(&ok);
                      if(!ok){
                          qDebug() << "Could not convert \"" << matched <<"\" to an integer!";
                          continue;
                      }
                      if(x<0 || x>1023){
                          qDebug() << "Value of x (" << x << ") out of range!";
                          continue;
                      }
                      
                      Macive XiongM Offline
                      Macive XiongM Offline
                      Macive Xiong
                      wrote on last edited by Macive Xiong
                      #18

                      @jazzycamel

                      Thank you so much for your help, it totally works!
                      Here are few question:

                      1.What if I would like to send the decimal numbers to Qt and do some calculation, what should I modify the codes?
                      Say, I would like to send x & y from 1.34 to 4.96 to Qt. I change the code like:

                      void MainWindow::updateP(){
                          if(!open) return;
                      
                          QTextStream stream(arduino);
                          QString line;
                          while(stream.readLineInto(&line)){
                              QRegularExpression re("([x,y]) = ([0-9]{-1,4})");
                              QRegularExpressionMatchIterator i=re.globalMatch(line);
                              while(i.hasNext()){
                                  QRegularExpressionMatch match=i.next();
                                  if(!match.hasMatch()){
                                      qDebug() << "No match!";
                                      continue;
                                  }
                                  QString xory=match.captured(1);
                                  QString matched=match.captured(2);
                      
                                  bool ok=false;
                                  if(xory=="x") x=matched.toFloat(&ok);
                                  else if(xory=="y") y=matched.toFloat(&ok);
                                  else continue;
                                  if(!ok){
                                      qDebug() << "Could not convert \"" << matched <<"\" to an integer!";
                                      continue;
                                  }
                                  QBrush redBrush(Qt::red);
                                  QPen blackPen(Qt::black, 1.);
                                  scene->addEllipse(x*102, y*102, 10, 10, blackPen, redBrush);
                              }
                          }
                      }
                      
                      
                      
                      1. my graphicsView still set weird ellipse on a unset position:
                        Like this
                        The ellipses on the left side, I didn't set the position on that but there are still some ellipses, I already set my BaudRate to 115200 and it's the best I could get so far...

                      And this

                      The ellipses on the top side of the graphics view is not set, I don't know why there are so many signals to set the ellipses. Please give me some suggestion here.

                      1. If I want to close Arduino reading by click a button, what kind of command should I add in my button_clicked?
                      void MainWindow::on_Reset_btn_clicked()
                      {
                      
                      }
                      

                      Any suggestion?
                      Thank you so much!!:)

                      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