Qt Forum

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

    Solved QtSerialport blockingslave Example with Mainwindow class .

    General and Desktop
    3
    6
    149
    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.
    • M
      Marco Flad last edited by

      i am using the blocking example to communicate with micro controller with Mainwindow class instead of dialog to send and receive data any time from micro-controller without block receiving data from GUI
      so i redesign but this error is appear ,

      ASSERT failure in QMutexLocker: "QMutex pointer is misaligned", file C:\Qt\5.13.1\mingw73_64\include\QtCore/qmutex.h, line 202
      20:28:09: The program has unexpectedly finished.
      

      //mainwindow.h
      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H
      
      #include "slavethread.h"
      #include <QMainWindow>
      
      QT_BEGIN_NAMESPACE
      namespace Ui { class MainWindow; }
      QT_END_NAMESPACE
      
      class MainWindow : public QMainWindow
      {
          Q_OBJECT
      
      public:
          MainWindow(QWidget *parent = nullptr);
          ~MainWindow();
      private:
          Ui::MainWindow *ui;
          SlaveThread *m_thread ;
      };
      #endif // MAINWINDOW_H
      
      

      //slavethread.h
      #ifndef SLAVETHREAD_H
      #define SLAVETHREAD_H
      
      #include <QMutex>
      #include <QThread>
      #include <QWaitCondition>
      
      class SlaveThread : public QThread
      {
          Q_OBJECT
      public:
          explicit SlaveThread(QObject *parent = nullptr);
          ~SlaveThread();
          void startSlave(const QString &portName, int waitTimeout, const QString &response);
      signals:
          void request(const QString &s);
          void error(const QString &s);
          void timeout(const QString &s);
      
      private:
          void run() override;
      
          QString m_portName;
          QString m_response;
          int m_waitTimeout = 0;
          QMutex m_mutex;
          bool m_quit = false;
      };
      
      #endif // SLAVETHREAD_H
      
      

      //mainwindow.cpp
      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
          , ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
          m_thread->startSlave("COM15",10000,"HI");
      }
      
      MainWindow::~MainWindow()
      {
          delete ui;
      }
      
      

      //slavethread.cpp
      #include "slavethread.h"
      #include <QSerialPort>
      #include <QTime>
      #include <QDebug>
      
      SlaveThread::SlaveThread(QObject *parent) :
          QThread(parent)
      {
      
      }
      
      SlaveThread::~SlaveThread()
      {
          m_mutex.lock();
          m_quit = true;
          m_mutex.unlock();
          QThread::wait();
      }
      
      void SlaveThread::startSlave(const QString &portName, int waitTimeout, const QString &response)
      {
      
          const QMutexLocker locker(&m_mutex);
          m_portName = portName;
          m_waitTimeout = waitTimeout;
          m_response = response;
      
          if (!QThread::isRunning())
              QThread::start();
      }
      
      void SlaveThread::run()
      {
          bool currentPortNameChanged = false;
      
          m_mutex.lock();
      
          QString currentPortName;
          if (currentPortName != m_portName) {
              currentPortName = m_portName;
              currentPortNameChanged = true;
          }
      
          int currentWaitTimeout = m_waitTimeout;
          QString currentRespone = m_response;
          m_mutex.unlock();
      
          QSerialPort serial;
      
          while (!m_quit) {
      
              if (currentPortNameChanged) {
                  serial.close();
                  serial.setPortName(currentPortName);
      
                  if (!serial.open(QIODevice::ReadWrite)) {
                      emit error(tr("Can't open %1, error code %2")
                                 .arg(m_portName).arg(serial.error()));
                      return;
                  }
              }
      
              if (serial.waitForReadyRead(currentWaitTimeout)) {
      
                  // read request
                  QByteArray requestData = serial.readAll();
                  while (serial.waitForReadyRead(10))
                      requestData += serial.readAll();
      
                  // write response
                  const QByteArray responseData = currentRespone.toUtf8();
                  serial.write(responseData);
                  if (serial.waitForBytesWritten(m_waitTimeout)) {
                      const QString request = QString::fromUtf8(requestData);
                      emit this->request(request);
      
                  } else {
                      emit timeout(tr("Wait write response timeout %1")
                                   .arg(QTime::currentTime().toString()));
                  }
      
                  qDebug() << "Data :" <<  requestData;
                 qDebug() << "Sent :" <<  responseData;
      
              } else {
                  emit timeout(tr("Wait read request timeout %1")
                               .arg(QTime::currentTime().toString()));
              }
      
              m_mutex.lock();
              if (currentPortName != m_portName) {
                  currentPortName = m_portName;
                  currentPortNameChanged = true;
              } else {
                  currentPortNameChanged = false;
              }
              currentWaitTimeout = m_waitTimeout;
              currentRespone = m_response;
              m_mutex.unlock();
          }
      //! [13]
      }
      
      aha_1980 1 Reply Last reply Reply Quote 0
      • K
        kuzulis Qt Champions 2020 last edited by

        Don't use Qt 5.13.1, it has bugs.

        aha_1980 1 Reply Last reply Reply Quote 2
        • aha_1980
          aha_1980 Lifetime Qt Champion @Marco Flad last edited by

          @Marco-Flad Threading is an advanced topic.

          Your problem can be solved with non-blocking serial communication, please use it and proper signal+slot handling.

          Regards

          Qt has to stay free or it will die.

          M 1 Reply Last reply Reply Quote 0
          • M
            Marco Flad @aha_1980 last edited by

            @aha_1980
            the signal and slots dosnt work with readyread() dosn't triggered if data available on serial its only triggered when i send data from qt to the connected device"and this data is old data " i tried with no solution the issue is her if you can have a look please ,

            https://forum.qt.io/topic/110038/qt-serial-port-not-receive-data-until-send-data-to-mc/5

            1 Reply Last reply Reply Quote 0
            • K
              kuzulis Qt Champions 2020 last edited by

              Don't use Qt 5.13.1, it has bugs.

              aha_1980 1 Reply Last reply Reply Quote 2
              • aha_1980
                aha_1980 Lifetime Qt Champion @kuzulis last edited by

                Hi @kuzulis,

                Are those bugs fixed in 5.14.0 for sure?

                Regards

                Qt has to stay free or it will die.

                1 Reply Last reply Reply Quote 1
                • K
                  kuzulis Qt Champions 2020 last edited by

                  I'm think, yes.

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