IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

[D7] CONSEILS – APPLI INDUS – PORTS COM


Sujet :

API, COM et SDKs Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif Avatar de fredfred
    Inscrit en
    Septembre 2002
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 161
    Par défaut [D7] CONSEILS – APPLI INDUS – PORTS COM
    Salut à tous

    J’ai besoin de conseils pour migrer en Delphi 7 une appli industrielle Windev qui doit communiquer avec divers matériels via les ports COM.

    N’ayant jamais travaillé avec les ports COM, je ne sais pas quelle méthode mettre en place. J’ai déjà récupéré via la FAQ la bibliothèque ComPort.

    Ensuite, pour la communication continue avec l’une des machines, j’hésite entre utiliser des timers et les threads (les timers je connais, pas les threads)

    Le principe est le suivant : tous les dixièmes de seconde, l’appli interroge un appareil, via une séquence d’instructions.

    Une interrogation d’état se fait sous cette forme :

    - l’appli envoie ENQ
    - la machine retourne ACK
    - l’appli envoie STX / SOH / …. / ETX
    - la machine répond ACK

    et ainsi de suite (je pourrai développer cette partie si besoin)

    Problème : à chaque fois que le programme attend une réponse de la machine, il y a une boucle qui est sensée gérer les timeouts. Cette boucle, de type while, dure trois secondes, sauf si la machine envoie une réponse de taille égale à celle attendue, ou si la machine répond NAK. J’ai l’impression que cette gestion des timeouts via une boucle bloque le programme et les utilisateurs n’ont plus la main, et que ce n’est pas la bonne manière de faire.

    Ensuite, l’utilisation de timer pour la répétition des interrogations pose le problème suivant : si les utilisateurs souhaitent interrompre la communication, le bouton dédié ne répond pas tant que le programme est en cours d’interrogation. Le timer a beau être arrêté, les trames continuent de circuler sur le port, et les boucles de timeouts provoquent des délais dans l’arrêt du système.

    Donc, pour palier à tous ces problèmes, je cherche la meilleure solution en matière de gestion des ports COM, de timeout et de répétition de procédures avec arrêt instantané sur demande manuelle.

    Merci pour vos conseils et vos idées (et aussi d’avoir eu la patience de lire mon roman jusqu’au bout).

  2. #2
    Membre Expert

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2002
    Messages : 1 296
    Par défaut
    Je pense qu'il faudrait mieux que tu utilises une gestion asynchrone pour la réception.
    http://nono40.developpez.com/tutorie.../2005/comport/

  3. #3
    Membre très actif Avatar de fredfred
    Inscrit en
    Septembre 2002
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 161
    Par défaut
    ok, il faut que j'essaie tout ça.

    Dans les exemples d'utilisation de Comport, l'auteur explique qu'il vaut mieux utiliser un timer pour gérer la reception asynchrone.
    Si j'ai bien capté, il faudrait un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    Var
      ReadASyncPtr:PAsync = Nil;
      vgl_chaine :string;
      vgl_Long :integer;
     
    procedure TForm1.btnRecevoirAsyncClick(Sender: TObject);
    begin
      // MAJ composants
      btnRecevoirASync.Enabled := False;
      // Mise à jour du time out demandé
      Comport1.Timeouts.ReadTotalConstant := seTimeOut.Value * 1000;
      // Supression de ce qui traine dans le buffer d'entrée
      Comport1.ClearBuffer(True,False);
      // Init de la structure de suivi
      InitAsync(ReadAsyncPtr);
     
        // Lecture non-bloquante de la longueur demandée
        vgl_chaine:='';
        Comport1.ReadStrAsync(vgl_chaine,seLongueur.Value,ReadAsyncPtr);
     
        Timer1.enabled;
    end;
     
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      if Comport1.IsAsyncCompleted(ReadAsyncPtr) then
      begin
        // récupération du résultat de la lecture de la chaine
        vgl_Long:= Comport1.WaitForAsync(ReadAsyncPtr);
        SetLength(vgl_chaine,vgl_Long);
        DoneAsync(ReadAsyncPtr);
     
        Timer1.Disabled;
        FinReception;
      end;  
    end;
     
    procedure TForm1.FinReception;
    begin
      // MAJ composants
      Memo1.Lines.Add('Fin envoi asynchrone '+IntToStr(vgl_Long)+' caractère(s) reçu(s):'+vgl_chaine);
      btnRecevoirASync.Enabled := True;
    end;

    et prévoir d'arrêter le timer en cas de timout du Comport.

    J'ai bon ?

  4. #4
    Membre Expert Avatar de philnext
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    1 553
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 553
    Par défaut
    Salut je n'utilise pas Comport mais TurboPower Async Pro qui doit être un peu similaire.
    Le principe général est d'utiliser les évènements, ne pas faire de boucle while ou de wait !!!

    Quand tu crées (en déposant sur une fiche par exemple) ton Port tu as accès à un event lié à la réception de caractère style ComPortRxChar dans lequel tu vas définir ce que tu fais quand tu reçois un caractère.

    Donc ton prog. fonctionne ainsi :
    1/ Tu mets en place une variable bACK=True qui indique que tu attends un ACK.
    2/ Tu envoies ton ENQ
    3/ Tu déclenches un timer de 3 secondes (qui est un timeout).

    =Dans ton évènement
    ComPortRxChar, si bACK est à True, tu lis les caractères reçus, si tu reçois ACK tu arrètes le Timer et tu passes à la suite.
    =Si le Timer se déclenche c'est que tu n'as pas eu de réponse dans les 3 secondes et tu gères une erreur.




Discussions similaires

  1. lire/écrire sur un port com sans le monopoliser
    Par totofweb dans le forum Windows
    Réponses: 4
    Dernier message: 26/07/2004, 13h23
  2. [socket] envoyer des données vers un port com
    Par Slimer dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 20/07/2004, 17h35
  3. [debutant][Port COM]
    Par Shooter dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 06/07/2004, 09h43
  4. [javaComm]Communication port COM
    Par gui4593 dans le forum Entrée/Sortie
    Réponses: 11
    Dernier message: 04/06/2004, 12h35
  5. port com
    Par jeremi dans le forum C
    Réponses: 12
    Dernier message: 16/09/2002, 11h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo