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. Canbus. Cant received frame after write frame
Forum Updated to NodeBB v4.3 + New Features

Canbus. Cant received frame after write frame

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 2 Posters 711 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.
  • E Offline
    E Offline
    Eugene5_11
    wrote on last edited by
    #1

    Hello everybody! I need your help. I cant received frame after write frame;

    pseudocode:
    writeFrame(myFrame); // I will write new frame to can, after..
    auto answerFrame = getFrame(int id); // but, the frame does not have time to arrive before this code is executed

    Who-How to get the frame, without QCanBusDevice::framesReceived signal

    C 1 Reply Last reply
    0
    • E Eugene5_11

      Hello everybody! I need your help. I cant received frame after write frame;

      pseudocode:
      writeFrame(myFrame); // I will write new frame to can, after..
      auto answerFrame = getFrame(int id); // but, the frame does not have time to arrive before this code is executed

      Who-How to get the frame, without QCanBusDevice::framesReceived signal

      C Offline
      C Offline
      ChrisW67
      wrote on last edited by
      #2

      @Eugene5_11 Welcome to the forum.

      If you must use synchronous methods then you need to look at:

      • QCanBusDevice::waitForFramesReceived()
      • QCanBusDevice::waitForFramesWritten()
      E 1 Reply Last reply
      1
      • C ChrisW67

        @Eugene5_11 Welcome to the forum.

        If you must use synchronous methods then you need to look at:

        • QCanBusDevice::waitForFramesReceived()
        • QCanBusDevice::waitForFramesWritten()
        E Offline
        E Offline
        Eugene5_11
        wrote on last edited by
        #3

        @ChrisW67 Hello! waitForFramesReceived() dont work, but I get more frames from others frameID, so this function working is not correctly

        C 1 Reply Last reply
        0
        • E Eugene5_11

          @ChrisW67 Hello! waitForFramesReceived() dont work, but I get more frames from others frameID, so this function working is not correctly

          C Offline
          C Offline
          ChrisW67
          wrote on last edited by
          #4

          @Eugene5_11 Post your actual code and explain what "don't work" is supposed to mean.

          E 1 Reply Last reply
          0
          • C ChrisW67

            @Eugene5_11 Post your actual code and explain what "don't work" is supposed to mean.

            E Offline
            E Offline
            Eugene5_11
            wrote on last edited by Eugene5_11
            #5

            @ChrisW67
            can_test.h

            #pragma once
            #include <qcanbusdeviceinfo.h>
            #include <qmessagebox.h>
            #include <qcanbus.h>
            #include <qobject.h>
            #include <qthread.h>
            #include <qdebug.h>
            
            #include <Windows.h>
            
            enum class CanStatus
            {
            	connected,
            	connecting,
            	unconnected
            };
            
            class CanTest : public QObject
            {
            	Q_OBJECT
            
            private:
            	QCanBusDevice* m_device;
            	CanStatus canStatus = CanStatus::unconnected;
            	QVector<QCanBusFrame> framescash;
            
            public:
                CanTest();
               ~CanTest();
            	
                CanStatus getCanStatus();
                QCanBusFrame readData();
            
                void writeData(QCanBusFrame frame);
            
            signals:
                void sig_changeCanState();
            
            public slots:
                void changeCanState();
                void framesReceived();
            };
            

            can_test.cpp

            #include "can.h"
            
            CanTest::CanTest()
            {
                QString error_str;
                m_device = QCanBus::instance()
                    ->createDevice(QStringLiteral("passthrucan"), QStringLiteral("SM2 USB"), &error_str);
            
                if (!m_device)
                {
                    QMessageBox::critical(nullptr, "Error", "Error, " + error_str);
                    return;
                }
            
                if (!m_device->connectDevice())
                {
                    QMessageBox::critical(nullptr, "Error", "Error, " + error_str);
                    return;
                }
            
                connect(m_device, &QCanBusDevice::framesReceived, this, &CanTest::framesReceived);
                connect(m_device, &QCanBusDevice::stateChanged, this, &CanTest::changeCanState);
            }
                
            
            QCanBusFrame CanTest::readData()
            {
                if (framescash.size() > 0)
                {
                    return framescash.at(0);
                }
                return QCanBusFrame(1, 0x0);
            }
            
            void CanTest::framesReceived()
            {
               QVector<QCanBusFrame> frames = m_device->readAllFrames();
               for (const auto& _t : frames)
               {
                   if (_t.frameId() == 0x7CE)
                   {
                       framescash.append(_t);
                       qDebug() << "Frame from QCanBusDevice::framesReceived(): " << _t.toString();
                   }
               }
            }
            
            void CanTest::writeData(QCanBusFrame frame)
            {
                if (!m_device)
                    return;
            
                m_device->writeFrame(frame);
            }
            
            CanStatus CanTest::getCanStatus()
            {
                return canStatus;
            }
            
            void CanTest::changeCanState()
            {
                switch (m_device->state())
                {
                case QCanBusDevice::ConnectedState:
                    canStatus = CanStatus::connected;
                    break;
            
                case QCanBusDevice::ConnectingState:
                    canStatus = CanStatus::connecting;
                    break;
            
                case QCanBusDevice::UnconnectedState:
                    canStatus = CanStatus::unconnected;
                    break;
                }
                qDebug() << "can status: " << m_device->state();
                emit sig_changeCanState();
            }
            
            CanTest::~CanTest()
            {
                if (!m_device)
                    return;
            
                if (m_device->state() ==
                    QCanBusDevice::ConnectedState)
                {
                    m_device->disconnectDevice();
                }
            
                delete m_device;
            }
            

            widgetclass:

            ....

            void QtWidgetsClass::sendMsg()
            {
            	//for (int i = 0; i < 100; i++)
            	{
            		can->writeData(newFrame); 
            		
                            // here I need got a frame
            		auto answerFrame = can->readData();
            		qDebug() << "Frame before writeFrame function(): " << answerFrame.toString();
            	}
            }
            
            

            2.png

            C 1 Reply Last reply
            0
            • E Eugene5_11

              @ChrisW67
              can_test.h

              #pragma once
              #include <qcanbusdeviceinfo.h>
              #include <qmessagebox.h>
              #include <qcanbus.h>
              #include <qobject.h>
              #include <qthread.h>
              #include <qdebug.h>
              
              #include <Windows.h>
              
              enum class CanStatus
              {
              	connected,
              	connecting,
              	unconnected
              };
              
              class CanTest : public QObject
              {
              	Q_OBJECT
              
              private:
              	QCanBusDevice* m_device;
              	CanStatus canStatus = CanStatus::unconnected;
              	QVector<QCanBusFrame> framescash;
              
              public:
                  CanTest();
                 ~CanTest();
              	
                  CanStatus getCanStatus();
                  QCanBusFrame readData();
              
                  void writeData(QCanBusFrame frame);
              
              signals:
                  void sig_changeCanState();
              
              public slots:
                  void changeCanState();
                  void framesReceived();
              };
              

              can_test.cpp

              #include "can.h"
              
              CanTest::CanTest()
              {
                  QString error_str;
                  m_device = QCanBus::instance()
                      ->createDevice(QStringLiteral("passthrucan"), QStringLiteral("SM2 USB"), &error_str);
              
                  if (!m_device)
                  {
                      QMessageBox::critical(nullptr, "Error", "Error, " + error_str);
                      return;
                  }
              
                  if (!m_device->connectDevice())
                  {
                      QMessageBox::critical(nullptr, "Error", "Error, " + error_str);
                      return;
                  }
              
                  connect(m_device, &QCanBusDevice::framesReceived, this, &CanTest::framesReceived);
                  connect(m_device, &QCanBusDevice::stateChanged, this, &CanTest::changeCanState);
              }
                  
              
              QCanBusFrame CanTest::readData()
              {
                  if (framescash.size() > 0)
                  {
                      return framescash.at(0);
                  }
                  return QCanBusFrame(1, 0x0);
              }
              
              void CanTest::framesReceived()
              {
                 QVector<QCanBusFrame> frames = m_device->readAllFrames();
                 for (const auto& _t : frames)
                 {
                     if (_t.frameId() == 0x7CE)
                     {
                         framescash.append(_t);
                         qDebug() << "Frame from QCanBusDevice::framesReceived(): " << _t.toString();
                     }
                 }
              }
              
              void CanTest::writeData(QCanBusFrame frame)
              {
                  if (!m_device)
                      return;
              
                  m_device->writeFrame(frame);
              }
              
              CanStatus CanTest::getCanStatus()
              {
                  return canStatus;
              }
              
              void CanTest::changeCanState()
              {
                  switch (m_device->state())
                  {
                  case QCanBusDevice::ConnectedState:
                      canStatus = CanStatus::connected;
                      break;
              
                  case QCanBusDevice::ConnectingState:
                      canStatus = CanStatus::connecting;
                      break;
              
                  case QCanBusDevice::UnconnectedState:
                      canStatus = CanStatus::unconnected;
                      break;
                  }
                  qDebug() << "can status: " << m_device->state();
                  emit sig_changeCanState();
              }
              
              CanTest::~CanTest()
              {
                  if (!m_device)
                      return;
              
                  if (m_device->state() ==
                      QCanBusDevice::ConnectedState)
                  {
                      m_device->disconnectDevice();
                  }
              
                  delete m_device;
              }
              

              widgetclass:

              ....

              void QtWidgetsClass::sendMsg()
              {
              	//for (int i = 0; i < 100; i++)
              	{
              		can->writeData(newFrame); 
              		
                              // here I need got a frame
              		auto answerFrame = can->readData();
              		qDebug() << "Frame before writeFrame function(): " << answerFrame.toString();
              	}
              }
              
              

              2.png

              C Offline
              C Offline
              ChrisW67
              wrote on last edited by
              #6

              @Eugene5_11 You claim that waitForFramesReceived() "dont work" but your code does not use the function.

              You first need to decide if your code is supposed to operate synchronously (i.e use the wait* functions) or asynchronously (i.e. using signals to determine when stuff is received). Your current code is asynchronous but is expecting synchronous behaviour.

              can->writeData(newFrame); 
              
              // ^^^ This frame will not be written until the Qt event loop is reached
              // ^^^ Responses will not be received until the Qt event loop is reached
              // vvv so here it has not been sent and a response cannot have been received.
              
              // here I need got a frame
              auto answerFrame = can->readData();
              
              // ^^^ this returns something regardless of whether there is  anything in your QVector cache
              
              E 2 Replies Last reply
              1
              • C ChrisW67

                @Eugene5_11 You claim that waitForFramesReceived() "dont work" but your code does not use the function.

                You first need to decide if your code is supposed to operate synchronously (i.e use the wait* functions) or asynchronously (i.e. using signals to determine when stuff is received). Your current code is asynchronous but is expecting synchronous behaviour.

                can->writeData(newFrame); 
                
                // ^^^ This frame will not be written until the Qt event loop is reached
                // ^^^ Responses will not be received until the Qt event loop is reached
                // vvv so here it has not been sent and a response cannot have been received.
                
                // here I need got a frame
                auto answerFrame = can->readData();
                
                // ^^^ this returns something regardless of whether there is  anything in your QVector cache
                
                E Offline
                E Offline
                Eugene5_11
                wrote on last edited by Eugene5_11
                #7

                @ChrisW67 waitForFramesReceived() wait any frame , how to correctly use wait functions, if I got a lot of frames, I need get only one frameID?

                1 Reply Last reply
                0
                • C ChrisW67

                  @Eugene5_11 You claim that waitForFramesReceived() "dont work" but your code does not use the function.

                  You first need to decide if your code is supposed to operate synchronously (i.e use the wait* functions) or asynchronously (i.e. using signals to determine when stuff is received). Your current code is asynchronous but is expecting synchronous behaviour.

                  can->writeData(newFrame); 
                  
                  // ^^^ This frame will not be written until the Qt event loop is reached
                  // ^^^ Responses will not be received until the Qt event loop is reached
                  // vvv so here it has not been sent and a response cannot have been received.
                  
                  // here I need got a frame
                  auto answerFrame = can->readData();
                  
                  // ^^^ this returns something regardless of whether there is  anything in your QVector cache
                  
                  E Offline
                  E Offline
                  Eugene5_11
                  wrote on last edited by
                  #8

                  @ChrisW67 I do

                  QCanBusFrame CanTest::readData(int id)
                  {
                      /*if (framescash.size() > 0)
                      {
                          return framescash.at(0);
                      }
                      return QCanBusFrame(1, 0x0);*/
                  
                      while (m_device->waitForFramesReceived(1000))
                      {
                          QVector<QCanBusFrame> frames = m_device->readAllFrames();
                          for (const auto& _t : frames)
                          {
                              if (_t.frameId() == 0x7CE)
                              {
                                  return _t;
                              }
                          }
                  
                      }
                  }
                  
                  

                  This is work! But, I think that not correctly

                  C 1 Reply Last reply
                  0
                  • E Eugene5_11

                    @ChrisW67 I do

                    QCanBusFrame CanTest::readData(int id)
                    {
                        /*if (framescash.size() > 0)
                        {
                            return framescash.at(0);
                        }
                        return QCanBusFrame(1, 0x0);*/
                    
                        while (m_device->waitForFramesReceived(1000))
                        {
                            QVector<QCanBusFrame> frames = m_device->readAllFrames();
                            for (const auto& _t : frames)
                            {
                                if (_t.frameId() == 0x7CE)
                                {
                                    return _t;
                                }
                            }
                    
                        }
                    }
                    
                    

                    This is work! But, I think that not correctly

                    C Offline
                    C Offline
                    ChrisW67
                    wrote on last edited by
                    #9

                    @Eugene5_11 We do not know your entire requirement but this is the general flow using standard Qt async processing:

                    • Sending
                      • Clear the response queue
                      • Send a request frame
                      • Return to the Qt event loop
                    • Receiving
                      • Receive all CAN frames (You have no control over this).
                        • Queue any frame with frameID 0x7CE.
                        • Discard any other frame
                      • If queue not empty then signal response received. The slot attached to this signal should process the queue.
                      • Return to Qt event loop

                    If you are only interested in the first 0x7CE received after sending the request frame, then the queue could be a single QCanBusFrame.

                    For more complex flows a simple state machine could be implemented.

                    E 1 Reply Last reply
                    1
                    • C ChrisW67

                      @Eugene5_11 We do not know your entire requirement but this is the general flow using standard Qt async processing:

                      • Sending
                        • Clear the response queue
                        • Send a request frame
                        • Return to the Qt event loop
                      • Receiving
                        • Receive all CAN frames (You have no control over this).
                          • Queue any frame with frameID 0x7CE.
                          • Discard any other frame
                        • If queue not empty then signal response received. The slot attached to this signal should process the queue.
                        • Return to Qt event loop

                      If you are only interested in the first 0x7CE received after sending the request frame, then the queue could be a single QCanBusFrame.

                      For more complex flows a simple state machine could be implemented.

                      E Offline
                      E Offline
                      Eugene5_11
                      wrote on last edited by
                      #10

                      @ChrisW67 Thank you for help friend, You've guided me to the right thoughts.

                      1 Reply Last reply
                      0
                      • E Eugene5_11 has marked this topic as solved on

                      • Login

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