Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QUdpSocket multicast receiver timeout detection?
QtWS25 Last Chance

QUdpSocket multicast receiver timeout detection?

Scheduled Pinned Locked Moved Solved Mobile and Embedded
8 Posts 3 Posters 2.0k Views
  • 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.
  • S Offline
    S Offline
    samy03
    wrote on last edited by
    #1

    I am using multicast receiver example. How can I add a timer where if I loose the multicast signal and don't get any multicast signal in a specific time, then it will set a gpio to high?
    This is what I tried but it does not work the way its supposed to.

    if (udpSocket->hasPendingDatagrams() != 1)
    {
    QTimer::singleShot(5000, this, SLOT(nomsg()));
    }
    
    
    void MainWindow::nomsg()
    {
    ::gpio_set_value(this->GREEN_LED_PIN, HIGH);
    }
    
    

    I receive 1 udp signal every second, so this program just keeps toggling the gpio to high and low.
    I just want to turn my gpio high if I don't get any multicast message in 5 seconds.

    Any help will be greatly appreciated.

    JonBJ Pablo J. RoginaP 2 Replies Last reply
    0
    • S samy03

      I am using multicast receiver example. How can I add a timer where if I loose the multicast signal and don't get any multicast signal in a specific time, then it will set a gpio to high?
      This is what I tried but it does not work the way its supposed to.

      if (udpSocket->hasPendingDatagrams() != 1)
      {
      QTimer::singleShot(5000, this, SLOT(nomsg()));
      }
      
      
      void MainWindow::nomsg()
      {
      ::gpio_set_value(this->GREEN_LED_PIN, HIGH);
      }
      
      

      I receive 1 udp signal every second, so this program just keeps toggling the gpio to high and low.
      I just want to turn my gpio high if I don't get any multicast message in 5 seconds.

      Any help will be greatly appreciated.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @samy03
      You need to be reading the datagrams that do arrive, e.g. via QUdpSocket::receiveDatagram().

      How about:

      1. Create function to set GREEN (nomsg()).
      2. Create function to set off QTimer::singleShot(5000, this, SLOT(nomsg()));.
      3. Set off that function initially.
      4. In readyRead slot whenever a datagram received, read it (receiveDatagram()) and then cancel existing 5 second timer and call function to restart a new one.

      ?

      Alternatively, if http://doc.qt.io/qt-5/qabstractsocket.html#waitForReadyRead works for your UDP (and note it's not reliable if you are Windows anyway), you might architect using http://doc.qt.io/qt-5/qabstractsocket.html#waitForReadyRead specifying your 5,000ms, but you'll probably end up with using earlier methof.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        samy03
        wrote on last edited by
        #3

        @samy03 said in QUdpSocket multicast receiver timeout detection?:

        @JonB I tried both methods but none of them are working.
        With the first method, as soon as I start receiving multicast message, my program shutdown.

        With waitForReadyRead, nothing was happening, even though its on Linux.

        JonBJ 1 Reply Last reply
        0
        • S samy03

          @samy03 said in QUdpSocket multicast receiver timeout detection?:

          @JonB I tried both methods but none of them are working.
          With the first method, as soon as I start receiving multicast message, my program shutdown.

          With waitForReadyRead, nothing was happening, even though its on Linux.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @samy03
          Since the docs state that waitForReadyRead() may be flaky (although it says only under Windows), let's not use that. In any case it doesn't do anything we cannot do ourselves.

          As for:

          With the first method, as soon as I start receiving multicast message, my program shutdown.

          Well, you know your program should not "shutdown" in such a situation! So either examine your own code, or show us a minimal example of what does not work for you?

          1 Reply Last reply
          1
          • S Offline
            S Offline
            samy03
            wrote on last edited by samy03
            #5

            @JonB
            Here is my code:

            #include "mainwindow.h"
            #include "ui_mainwindow.h"
            #include <QtWidgets>
            #include <QtNetwork>
            #include <QXmlStreamReader>
            #include "SimpleGPIO.h"
            
            MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
            {
                ui->setupUi(this);
            
                setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
                setWindowState(Qt::WindowFullScreen);
            
                gpio_omap_mux_setup("eCAP0_in_PWM0", "128"); 	//gpio1_28 P9 header pin# 12
             this->GREEN_LED_PIN = 60;  
                    gpio_export(this->GREEN_LED_PIN);
                    gpio_set_dir(this->GREEN_LED_PIN, OUTPUT_PIN);
                    ::gpio_set_value(this->GREEN_LED_PIN, HIGH);
            
            	xmltimer(); 	//starting timer
            
                    groupAddress = QHostAddress("224.224.24.23");
            
                    udpSocket = new QUdpSocket(this); udpSocket->bind(QHostAddress::AnyIPv4, 11007, QUdpSocket::ShareAddress);
                    udpSocket->joinMulticastGroup(groupAddress);
            
                    connect(udpSocket, SIGNAL(readyRead()),
                            this, SLOT(processPendingDatagrams()));
                        
            }
            
             void MainWindow::processPendingDatagrams()
                {
                    while (udpSocket->hasPendingDatagrams())
                    {
                        QByteArray datagram;
                        datagram.resize(udpSocket->pendingDatagramSize());
                        udpSocket->readDatagram(datagram.data(), datagram.size());
                        str=datagram;
            
                        QXmlStreamReader xml(str);
            
                        timer->stop(); //stopping the timer
                        xmltimer(); //calling the timer again
            
                        //Parse the XML until we reach end of it
                        while(!xml.atEnd() && !xml.hasError()) {
                                // Read next element
                        QXmlStreamReader::TokenType token = xml.readNext();
                                //If token is just StartDocument - go to next
                                if(token == QXmlStreamReader::StartDocument) {
                                        continue;
                                }
            		}
            	}
                }
            
              void MainWindow::nomsg()
                 {
            
                     ::gpio_set_value(this->GREEN_LED_PIN, HIGH);
            
                 }
            
              void MainWindow::xmltimer()
                 {
            
                        QTimer::singleShot(5000, this, SLOT(nomsg()));
            
                 }
            

            This is just a minimal example of what I am trying to achieve here.

            JonBJ 1 Reply Last reply
            0
            • S samy03

              @JonB
              Here is my code:

              #include "mainwindow.h"
              #include "ui_mainwindow.h"
              #include <QtWidgets>
              #include <QtNetwork>
              #include <QXmlStreamReader>
              #include "SimpleGPIO.h"
              
              MainWindow::MainWindow(QWidget *parent) :
                  QMainWindow(parent),
                  ui(new Ui::MainWindow)
              {
                  ui->setupUi(this);
              
                  setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
                  setWindowState(Qt::WindowFullScreen);
              
                  gpio_omap_mux_setup("eCAP0_in_PWM0", "128"); 	//gpio1_28 P9 header pin# 12
               this->GREEN_LED_PIN = 60;  
                      gpio_export(this->GREEN_LED_PIN);
                      gpio_set_dir(this->GREEN_LED_PIN, OUTPUT_PIN);
                      ::gpio_set_value(this->GREEN_LED_PIN, HIGH);
              
              	xmltimer(); 	//starting timer
              
                      groupAddress = QHostAddress("224.224.24.23");
              
                      udpSocket = new QUdpSocket(this); udpSocket->bind(QHostAddress::AnyIPv4, 11007, QUdpSocket::ShareAddress);
                      udpSocket->joinMulticastGroup(groupAddress);
              
                      connect(udpSocket, SIGNAL(readyRead()),
                              this, SLOT(processPendingDatagrams()));
                          
              }
              
               void MainWindow::processPendingDatagrams()
                  {
                      while (udpSocket->hasPendingDatagrams())
                      {
                          QByteArray datagram;
                          datagram.resize(udpSocket->pendingDatagramSize());
                          udpSocket->readDatagram(datagram.data(), datagram.size());
                          str=datagram;
              
                          QXmlStreamReader xml(str);
              
                          timer->stop(); //stopping the timer
                          xmltimer(); //calling the timer again
              
                          //Parse the XML until we reach end of it
                          while(!xml.atEnd() && !xml.hasError()) {
                                  // Read next element
                          QXmlStreamReader::TokenType token = xml.readNext();
                                  //If token is just StartDocument - go to next
                                  if(token == QXmlStreamReader::StartDocument) {
                                          continue;
                                  }
              		}
              	}
                  }
              
                void MainWindow::nomsg()
                   {
              
                       ::gpio_set_value(this->GREEN_LED_PIN, HIGH);
              
                   }
              
                void MainWindow::xmltimer()
                   {
              
                          QTimer::singleShot(5000, this, SLOT(nomsg()));
              
                   }
              

              This is just a minimal example of what I am trying to achieve here.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @samy03
              And? I don't know how it performs. You can put some qDebug()s in, or use the debugger, to see what is actually doing, surely?

              After your code has exited MainWindow::MainWindow(), I assume your caller does go into the normal Qt event loop, it doesn't just exit?

              1 Reply Last reply
              0
              • S samy03

                I am using multicast receiver example. How can I add a timer where if I loose the multicast signal and don't get any multicast signal in a specific time, then it will set a gpio to high?
                This is what I tried but it does not work the way its supposed to.

                if (udpSocket->hasPendingDatagrams() != 1)
                {
                QTimer::singleShot(5000, this, SLOT(nomsg()));
                }
                
                
                void MainWindow::nomsg()
                {
                ::gpio_set_value(this->GREEN_LED_PIN, HIGH);
                }
                
                

                I receive 1 udp signal every second, so this program just keeps toggling the gpio to high and low.
                I just want to turn my gpio high if I don't get any multicast message in 5 seconds.

                Any help will be greatly appreciated.

                Pablo J. RoginaP Offline
                Pablo J. RoginaP Offline
                Pablo J. Rogina
                wrote on last edited by
                #7

                @samy03 said in QUdpSocket multicast receiver timeout detection?:

                I am using multicast receiver example

                I'd just modify the existing processPendingDatagrams() method (receiver.cpp) to handle the timer start/stop actions... pseudo-code (not tested):

                ...
                QTimer timerLostSignal = QTimer(5000);
                QObject::connect(timerLostSignal, &QTimer::timeout, this, &MainWindow::noMsg);
                // start checking if no datagrams are received
                timerLostSignal.start();
                ...
                ...
                void Receiver::processPendingDatagrams()
                {
                    // since we're going to read datagrams
                    // stop timer (signal is not lost yet...)
                    timerLostSignal.stop();
                
                    QByteArray datagram;
                    while (udpSocket->hasPendingDatagrams()) {
                        datagram.resize(int(udpSocket->pendingDatagramSize()));
                        udpSocket->readDatagram(datagram.data(), datagram.size());
                        statusLabel->setText(tr("Received datagram: \"%1\"")
                                             .arg(datagram.constData()));
                    }
                    // loop finished, no more datagrams to read so far
                    // start timer just in case no other datagram arrives ever
                    timerLostSignal.start();
                }
                ...
                ...
                void MainWindow::noMsg()
                {
                ::gpio_set_value(this->GREEN_LED_PIN, HIGH);
                }
                
                

                Upvote the answer(s) that helped you solve the issue
                Use "Topic Tools" button to mark your post as Solved
                Add screenshots via postimage.org
                Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                1 Reply Last reply
                1
                • S Offline
                  S Offline
                  samy03
                  wrote on last edited by
                  #8

                  I got it working just by changing the format of my timer like this:

                  newtimer = new QTimer(this);
                  newtimer->setInterval(3000);
                  newtimer->setSingleShot(true);
                  connect(newtimer, SIGNAL(timeout()), SLOT(nomsg()));
                  newtimer->start();
                  

                  and then calling newtimer to start or stop.

                  I had to do this since you cannot start or stop SingleShot timer in this "QTimer::singleShot(200, this, SLOT(updateCaption()));" format.

                  1 Reply Last reply
                  1

                  • Login

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