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

C++Builder Discussion :

[debutant]Transmission RS232 - Appli console [Non suivi]


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut [debutant]Transmission RS232 - Appli console
    Bonjour,
    j'ai une reception de trame (envoyée par une machine de production) a faire sur le COM1 d'un PC. D'après mon prof, il faut créer une application console en prenant en charge les objets VCL.
    J'ai cliqué sur Expert console puis selectionné VCL et Appli console.
    Ensuite si je compile et exécute le programme 'à vide', j'ai une erreur du lieur : [Lieur Erreur] Unresolved external '_main' referenced from F:\BORLAND\CBUILDER6\LIB\C0X32.OBJ

    J'ai essayé d'ajouter ce fichier au projet sans résultat, toujours la meme erreur. Si je crée une application normale, pas de problème d'exécution mais une erreur sur le type HANDLE.......

    Please HELP.

  2. #2
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut
    Bon finalement j'ai crée une application normale.

    J'ai un autre problème. Je veux lire mon port COM en continu pour réceptionner mes trames (toutes les minutes environ) mais je ne sais pas comment le boucler tout en ayant encore accès aux boutons de mon application (pour fermer le com par exemple).

    La réception marche bien mais étant donné que le programme tourne en boucle tout le temps, il est figé comme s'il était planté. Et du coup, je ne peux rien faire.
    Il faudrait que mon programme lise en continu le port et m'affiche en direct ce qu'il reçoit sans rester bloqué.
    AU secours, aidez-moi !!!

  3. #3
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    Je pense que tu devrais utiliser un TTimer ou TThread ... tout dépend de ce que tu veux faire ...

  4. #4
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut
    TThread c'est pour exécuter plusieurs codes en simultané comme des processus, c'est ça ?

    Il suffit que j'arrive à lire le COM2 (fonction ReadFile) pendant que j'affiche mes trames au-fur-et-a-mesure dans un mémo, c'est tout simple.
    Mais la lecture du port bloque mon application et je ne peux rien faire (impossible de bouger la fenetre ou de cliquer sur un bouton pour arreter la lecture, de plus il n'y a pas de rafraichissement de l'image alors ça fait ultra moche).

    Je n'ai jamais utilisé de TThread comment faire? Merci.

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    Salut,

    Je suis du même avis que Freeze.
    Je pense que le plus simple est d'utiliser un TTimer. Cela ne te bloquera pas ton programme.

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    TThread c'est pour exécuter plusieurs codes en simultané comme des processus, c'est ça ?
    Au moins, avec une simultanéïté apparente (si ta machine n'est pas un multi-processeur) ce qui suffit ici. La solution est sans doute de consulter le port d'i/o dans un thread autre que le thread principal.

  7. #7
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut
    svp un exemple d'utilisation.
    J'utilise un Timer pour rafraichir l'application (fonction Refresh) mais le timer ne fonctionne pas lorsque le programme atteint le ReadFile et attend la réception.

  8. #8
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    J'ai retrouvé ce code là :

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
     
    __fastcall TCommunication::TCommunication(bool CreateSuspended,HDC handle)
       : TThread(CreateSuspended)
    {
       FSection=new TCriticalSection();
       memset(FBuffer,0,MAXCAR);
       FHandlePort=INVALID_HANDLE_VALUE;
       memset(&FTimeout,0,sizeof(COMMTIMEOUTS));
       memset(&FInfoio,0,sizeof(OVERLAPPED));
       memset(&FConfigport,0,sizeof(DCB));
     
       TIniFile *ini=new TIniFile(ChangeFileExt(Application->ExeName,".cfg"));
       FPort=ini->ReadString("COMMUNICATION","Port","COM1");
       FParite=ini->ReadString("COMMUNICATION","Parité","Aucune");
       FVitesse=ini->ReadString("COMMUNICATION","Vitesse","38400");
       FNbBitDonnees=ini->ReadString("COMMUNICATION","Données","8");
       FNbBitStop=ini->ReadString("COMMUNICATION","Stop","1");
       delete ini;
     
       InitCommunication();
    }
    //---------------------------------------------------------------------------
    void __fastcall TCommunication::Execute()
    {
       while (!Terminated)
       {
          LireTrame();
       }
    }
    //---------------------------------------------------------------------------
    void __fastcall TCommunication::OnTerminate()
    {
       NettoyerBuffer();
       CloseHandle(FHandlePort);
    }
    //---------------------------------------------------------------------------
    void TCommunication::LireTrame(void)
    {
       char tampon[MAXTRAME];
       memset(tampon,0,MAXTRAME);
       unsigned long nboctetlu=0;
       DWORD tempsmaxi;
     
       ResetEvent(FInfoio.hEvent);
     
       if (!ReadFile(FHandlePort,tampon,MAXTRAME,&nboctetlu,&FInfoio))
       {
          if ((GetLastError())==ERROR_IO_PENDING)
          {
             tempsmaxi=GetTickCount()+TEMPSMAXI;
             while(!GetOverlappedResult(FHandlePort,&FInfoio,&nboctetlu,true))
                if (GetTickCount()>tempsmaxi)
                   break;
          }
       }
     
       if (nboctetlu!=0)
          AjouteTrame(tampon,nboctetlu);
    }
    //---------------------------------------------------------------------------
    void TCommunication::NettoyerBuffer(void)
    {
       PurgeComm(FHandlePort,PURGE_RXCLEAR);
       PurgeComm(FHandlePort,PURGE_TXCLEAR);
    }
    //---------------------------------------------------------------------------
    void TCommunication::AjouteTrame(char *trame,int nboctet)
    {
       char mess[MAXCAR];
       if (FNbCar+nboctet<MAXCAR)
       {
          memmove(&FBuffer[FNbCar],trame,nboctet);
          FNbCar+=nboctet;
          int fin;
          while(1)
          {
             if (FNbCar)
             {
                fin=0;
                for (int i=1;i<FNbCar-1;i++)
                {
                   if (FBuffer[i]==0x0D && FBuffer[i+1]==0x0A)
                   {
                      fin=i+1;
                      break;
                   }
                }
                if (fin)
                {
                   fin++;
                   memmove(mess,FBuffer,fin); mess[fin]=0;
                   Traite(mess);
                   memmove(FBuffer,&FBuffer[fin],MAXCAR-fin);
                   FNbCar-=fin;
                   memset(&FBuffer[FNbCar],0,MAXCAR-FNbCar);
                }
                else
                   break;
             }
             else
                break;
          }
       }
       else
       {
          memset(FBuffer,0,MAXCAR);
          FNbCar=0;
       }
    }
    //---------------------------------------------------------------------------
    void TCommunication::Traite(AnsiString trame)
    {
       //
    }
    //---------------------------------------------------------------------------
    void TCommunication::InitCommunication(void)
    {
       CreerHandle();
       InitParametres();
       InitTimeOut();
       InitInfoIO();
       NettoyerBuffer();
    }
    //---------------------------------------------------------------------------
    void TCommunication::CreerHandle(void)
    {
       FHandlePort=CreateFile(FPort.c_str(),
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         NULL,
                         OPEN_EXISTING,
                         FILE_FLAG_OVERLAPPED,
                         NULL);
     
       if (FHandlePort==INVALID_HANDLE_VALUE)
          ShowMessage("Le port est occupé");
       else
          SetupComm(FHandlePort,MAXTRAME,MAXTRAME);
    }
    //---------------------------------------------------------------------------
    void TCommunication::InitParametres(void)
    {
       if (!GetCommState(FHandlePort,&FConfigport))
          ShowMessage("Erreur sur la lecture de la configuration du port");
     
       FConfigport.BaudRate=FVitesse.ToIntDef(0);
       FConfigport.ByteSize=FNbBitDonnees.ToIntDef(0);
     
       if (!FParite.AnsiCompare("Aucune"))  FConfigport.Parity=NOPARITY;
       if (!FParite.AnsiCompare("Paire"))   FConfigport.Parity=EVENPARITY;
       if (!FParite.AnsiCompare("Impaire")) FConfigport.Parity=ODDPARITY;
     
       if (!FNbBitStop.AnsiCompare("1"))    FConfigport.Parity=ONESTOPBIT;
       if (!FNbBitStop.AnsiCompare("1.5"))  FConfigport.Parity=ONE5STOPBITS;
       if (!FNbBitStop.AnsiCompare("2"))    FConfigport.Parity=TWOSTOPBITS;
     
       FConfigport.fDtrControl=DTR_CONTROL_ENABLE;
       FConfigport.fRtsControl=RTS_CONTROL_ENABLE;
     
       if (!SetCommState(FHandlePort,&FConfigport))
          ShowMessage("Erreur sur l'écriture de la configuration du port");
    }
    //---------------------------------------------------------------------------
    void TCommunication::InitTimeOut(void)
    {
       FTimeout.ReadIntervalTimeout=10;
     
       FTimeout.ReadTotalTimeoutMultiplier=1;
       FTimeout.ReadTotalTimeoutConstant=100;
     
       FTimeout.WriteTotalTimeoutMultiplier=1;
       FTimeout.WriteTotalTimeoutConstant=100;
     
       SetCommTimeouts(FHandlePort,&FTimeout);
    }
    //---------------------------------------------------------------------------
    void TCommunication::InitInfoIO(void)
    {
       FInfoio.hEvent=CreateEvent(NULL,false,false,NULL);
    }
    //---------------------------------------------------------------------------
    c'est pour une communication en Thread ...

  9. #9
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut
    Je commence à comprendre comment ça fonctionne. En fait, le processeur partage l'exécution entre l'application et la fonction Execution du Tthread si j'ai bien compris.
    Ca veut dire que toutes mes fonctions qui traitent de la réception sur le port série doivent appartenir à la classe de type TThread. Les autres, je les laisse dans TForm1 (configuration, initialisation, etc..). C'est bien ça?

  10. #10
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut
    J'ai mis tout mon projet dans un zip à cette adresse si une âme charitable veut bien me donner un chti coup de pouce :
    http://btsiris.network-hosting.com/RS232/RS232.zip
    Merchi.

    Le principe :
    un PC relié à une soudeuse à ultrason de production.
    A chaque fin de soudure (toutes les 1-2 min), une trame est envoyée vers COM1 du PC avec diverses infos.
    Je lis la chaîne et je récupère la tolérance et la puissance.
    Je compare avec des intervalles de valeurs définis au départ.
    Si OK, une étiquette blanche est imprimée vers COM2 (en fait, le rouleau est déjà imprimé, il suffit de faire avancer une étiquette).
    Sinon ne rien faire.
    Afficher les chaînes reçues et les stocker dans un fichier journal.

    Les fichiers :
    - le source
    - l'executable
    - config.bat (contient la commande console d'impression sur COM2)
    - print.txt (contient du code imprimante pour faire avance une étiquette)

    Voilà, ça à rien de bien compliqué si ce n'est ce ptit problème de lecture en simultané.

  11. #11
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    Ben pour ma part j'ai tout mis dans la classe hérité de TThread ... au début du programme tu fais un new de ton objet et après tu joues juste avec les méthodes Resume ou Suspend du Thread ...

  12. #12
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    je regarde ca et je te tiens au courant ... t'as de la chance j'ai un peu de temps ...

  13. #13
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut
    Ok mais ce que je vois pas c'est pour relier les infos que je récupère des Edit dans le Form pour les utiliser dans ma classe héritée de TThread.
    J'ai refait une version de mon programme en déplacant toutes les fonctions concernant le port série.
    Mais c'est pareil si je veux fermer le port série en cliquant sur un bouton, je dois faire appel à une fonction qui est dans la classe héritée TThread, comment faire cela ?
    Ca doit pas être très compliqué mais j'avoue j'ai du mal là et en plus, on me met la pression derrière, le truk doit tourner avant ce soir !!

  14. #14
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut
    Merci Freeze mon sauveur

  15. #15
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    bon j'ai retouché un peu tout ca ... le mieux ce serait que tu puisses le tester ... si t'as une boite e-mail ...

  16. #16
    Membre confirmé Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Par défaut
    Super! Je t'ai envoyé mon mail en mp.

  17. #17
    Rédacteur
    Avatar de dvsoft
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2002
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2002
    Messages : 176
    Par défaut
    bonjour,

    Si tu ne veut pas perdre de temps, utilise donc les composants
    de turbopower, qui sont en opensource

    http://sourceforge.net/projects/tpapro/

    Bon courage
    Alain

  18. #18
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    oui enfin pour un projet d'école je crois pas que le prof va apprécier les composants tout fait ...

  19. #19
    Rédacteur
    Avatar de dvsoft
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2002
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2002
    Messages : 176
    Par défaut
    bonjour

    Citation Envoyé par Freeze
    oui enfin pour un projet d'école je crois pas que le prof va apprécier les composants tout fait ...
    j'ai une reception de trame (envoyée par une machine de production) a faire sur le COM1 d'un PC. D'après mon prof, il faut créer une application console en prenant en charge les objets VCL.
    Si j'ai bien compris la question, il faut établir une liaison entre un PC et un API en utilisant le port serie d'un PC.

    Tu passeras plus de temps a essayer d'ecrire un driver que d'utiliser un composant qui fait deja la couche basse de l'application. Je ne connais pas
    l'ensemble du probleme posé, mais je pense que c'est plutot l'analyse de la trame qui est important. Enfin moi ce que j'en dit......

    bon courage quand meme

    Alain

  20. #20
    Futur Membre du Club
    Inscrit en
    Mai 2004
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 4
    Par défaut
    Bonjour à tous,
    Je suis tmbé sur ce post et il s'avère que j'ai le même problème.
    J'avais pensé confier la gestion des messages par Thread, mais j'avoue ne pas avoir une super compétence dans la gestion des Thread.
    Il semble que Mr Freeze ai trouvé une solution intéressante. Pourrais tu nous la faire partager ?

    Merci d'avance

Discussions similaires

  1. [debutant]sortir du mode console
    Par gusgus dans le forum Débuter
    Réponses: 4
    Dernier message: 09/03/2006, 17h55
  2. Indy ou Autre composant internet avec une appli Console
    Par Oregon09 dans le forum Web & réseau
    Réponses: 3
    Dernier message: 13/11/2005, 05h07
  3. D5 - appli console et répertoire courant
    Par lolo le belge dans le forum Langage
    Réponses: 2
    Dernier message: 06/09/2005, 16h26
  4. [appli console] Repertorier les partitions d'1 système
    Par Le_magicien999 dans le forum MFC
    Réponses: 11
    Dernier message: 18/08/2005, 13h30
  5. [Appli Console]Pb exec command ac fct system(const char *)
    Par Le_magicien999 dans le forum MFC
    Réponses: 2
    Dernier message: 16/08/2005, 16h07

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