Partage
  • Partager sur Facebook
  • Partager sur Twitter

[QT]Créer une fonction utilisant QSerialPort

    25 mai 2019 à 18:54:27

    Bonjour ou bonsoir à tous,

    J'ai besoin de votre aide concernant la création d'une fonction utilisant la classe QSerialPort.

    Le fonctionnement global de la fonction est là mais j'ai du mal à transformer tout ça en code.

    Le but de cette fonction sera:

    -envoyer une adresse (de type "\FE\01\XX\XX\XX") via liaison série toutes les secondes jusqu'à ce que le buffer de réception soit plein

    -si le buffer est plein et qu'en le lisant on obtient la même adresse que celle envoyée alors on vide le buffer

    -quand le buffer est vide la boucle s'exécute encore mais cette fois-ci l'adresse sera( "\FE\02\XX\XX\XX") et ainsi de suite

    En lisant la documentation Qt je suis tombé sur "bool QSerialPort::canReadLine()" qui retourne true ou false si le buffer est rempli, je peux donc utiliser cela pour déclencher ma fonction.

    Le problème étant que j'ai énormément de mal à mettre en place le code en partant des idées que j'ai sur le papier, je ne sais pas non plus si mes choix sont les bons. Si quelqu'un peut m'aider à dessiner la structure que prendra ma fonction

    Merci d'avance

    -
    Edité par Greedy 25 mai 2019 à 18:55:15

    • Partager sur Facebook
    • Partager sur Twitter
      25 mai 2019 à 20:42:09

      Tu es sur que le buffer a besoin d'être plein pour être lu? De quel buffer parles-tu? Du buffer de réception  du système d'exploitation ou du tiens?

      En principe, on déclenche une action dès qu'il y a réception de données. Il existe une fonction waitForReadyread pour cela. J'ai noté que tu comptais utiliser canReadLine, mais malgré la doc, je n'arrive pas à déterminer ce qu'on appelle une "ligne": normalement, il devrait s'agir d'une suite de caractères terminée par un saut de ligne. Je ne sais pas si c'est ton cas.

      Quoiqu'il en soit, il est préférable de travailler par événement avec Qt. Pour ma part, ce que je fais, c'est d'appeler une fonction qui va traiter toute donnée entrante dès que le signal readyRead est émis. Reste à vérifier si une trame complète est reçue pour la traiter ultérieurement.

      • Partager sur Facebook
      • Partager sur Twitter
        25 mai 2019 à 21:56:45

        zoup a écrit:

        Tu es sur que le buffer a besoin d'être plein pour être lu? De quel buffer parles-tu? Du buffer de réception  du système d'exploitation ou du tiens?

        En principe, on déclenche une action dès qu'il y a réception de données. Il existe une fonction waitForReadyread pour cela. J'ai noté que tu comptais utiliser canReadLine, mais malgré la doc, je n'arrive pas à déterminer ce qu'on appelle une "ligne": normalement, il devrait s'agir d'une suite de caractères terminée par un saut de ligne. Je ne sais pas si c'est ton cas.

        Quoiqu'il en soit, il est préférable de travailler par événement avec Qt. Pour ma part, ce que je fais, c'est d'appeler une fonction qui va traiter toute donnée entrante dès que le signal readyRead est émis. Reste à vérifier si une trame complète est reçue pour la traiter ultérieurement.

        Dans mon cas je cherche à comparer ce que j'ai envoyé avec ce qu'il y aura dans le buffer de réception.

        Je vais m'intéresser à la fonction waitForReadyRead qui me semble coller bien plus à ce que je cherche.

        J'espère également que la comparaison de trame entre ce que j'ai envoyé et ce qu'il y a dans le buffer de réception se fera sans problèmes

        • Partager sur Facebook
        • Partager sur Twitter
          26 mai 2019 à 0:20:35

          Si tu as une interface graphique et que le timeout de waitForReadyRead est trop grand, tu risques de perturber le fonctionnement de cette interface graphique.

          L'utilisation des événements est plus logique et finalement plus simple à mon avis.

          • Partager sur Facebook
          • Partager sur Twitter
            26 mai 2019 à 1:02:02

            zoup a écrit:

            Si tu as une interface graphique et que le timeout de waitForReadyRead est trop grand, tu risques de perturber le fonctionnement de cette interface graphique.

            L'utilisation des événements est plus logique et finalement plus simple à mon avis.


            Effectivement j'utilise une GUI mais le truc c'est que je travail via PyQt car l'interface s'exécute sur un RaspberryPi, du coup j'ai du mal à voir l'implémentation via PyQt.

            En lisant la doc de waitForReadyRead j'ai vu qu'on pouvait désactiver le time out en initialisant msecs à -1 (ça me va vu que je cherche seulement le retour positif)

            • Partager sur Facebook
            • Partager sur Twitter
              26 mai 2019 à 20:16:56

              si tu désactives le timeout, le programme reste bloqué tant qu'aucune donnée n'est reçue.
              • Partager sur Facebook
              • Partager sur Twitter
                27 mai 2019 à 4:11:06

                zoup a écrit:

                si tu désactives le timeout, le programme reste bloqué tant qu'aucune donnée n'est reçue.


                On m'a conseillé de suivre  cette démarche pour mon problème qu'en penses-tu? Ça me se coller à se que je cherche à faire, me restera plus qu'à voir comment intégrer tout cela dans une fonction plus globale que j’appellerai avec un clique de bouton.

                Mais je me pose une question, si je souhaite envoyer une même trame toutes les secondes c'est possible tout en surveillant le buffer de réception?

                En gros est-il possible de répéter une fonction write() toutes les secondes tout en utilisant readyRead() et read() pour attendre une réponse puis lire cette réponse?

                • Partager sur Facebook
                • Partager sur Twitter
                  27 mai 2019 à 8:32:22

                  Concernant l'envoi d'une trame toutes les secondes, il suffit d'instancier un QTimer qui enverra un signal timeout à chaque seconde.

                  Quant à la démarche du site, "the good way" est la solution que je t'ai proposée plus haut. CQFD.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    27 mai 2019 à 12:30:35

                    zoup a écrit:

                    Concernant l'envoi d'une trame toutes les secondes, il suffit d'instancier un QTimer qui enverra un signal timeout à chaque seconde.

                    Quant à la démarche du site, "the good way" est la solution que je t'ai proposée plus haut. CQFD.


                    Merci beaucoup pour ton aide tout ça me parait maintenant un peu plus clair, il me faut maintenant travailler sur cette grosse fonction
                    • Partager sur Facebook
                    • Partager sur Twitter

                    [QT]Créer une fonction utilisant QSerialPort

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown