Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1226 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Communication avec un port COM

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Communication avec un port COM

n°693167
myst78
Posté le 06-04-2004 à 09:00:42  profilanswer
 

Salut a tous !
 
Je suis actuellement en train de developper une application pour dialoguer avec un port COM sous Windows2000 avec C++Builder
Mon probleme est que lors de l'ouverture de ce port avec la fonction CreateFile(...), j'ai une erreur comme quoi l'acces au port est refuse.
 
j'ai mon HANDLE definit comme ca :  
hPort = CreateFile ("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
 
et je test immediatement apres de la facon suivante :
if (hPort == INVALID_HANDLE_VALUE)  
ce test vaut vrai a chaque fois
 
si qqn pouvait m'eclairer...
merci d'avance
a+


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
mood
Publicité
Posté le 06-04-2004 à 09:00:42  profilanswer
 

n°693181
drasche
Posté le 06-04-2004 à 09:17:51  profilanswer
 

une simple application ne peut accéder directement au matériel sous Windows NT/2000/XP, tu dois faire un driver (accessoirement, une petite recherche sur le forum te montrera que le sujet a déjà été traité maintes fois)


---------------
Whichever format the fan may want to listen is fine with us – vinyl, wax cylinders, shellac, 8-track, iPod, cloud storage, cranial implants – just as long as it’s loud and rockin' (Billy Gibbons, ZZ Top)
n°693184
myst78
Posté le 06-04-2004 à 09:26:19  profilanswer
 

sisi justememt, des fonctions comme outp valides sous 98 par exemple ne fonctionnent plus sous NT, c'est pour cela qu'on doit utiliser un CreateFile.
j'ai vu cette utilisation apres bcp de recherches, a commencer par microsoft...
de plus des gens dans la boite ont deja procede de cette facon
 
donc je sais pas... :/


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°693295
pedro-2480
Posté le 06-04-2004 à 10:55:48  profilanswer
 

Tu as fais un GetLastError() pour cibler le problème ?


Message édité par pedro-2480 le 06-04-2004 à 10:56:39

---------------
- Pierre Baudelet -
n°693478
myst78
Posté le 06-04-2004 à 12:06:48  profilanswer
 

oui ca donnait l'erreur 5 "access denied"
mais en desinstallant le port COM et en redemarrant les pb ont disparu... mnt ca va :p
le nouveau pb c'est que le ReadFile ecrit pas dans mon buffer...  
ahlala la prog windows... :)


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°694454
myst78
Posté le 07-04-2004 à 10:37:24  profilanswer
 

*up*
 
j'ai un nouveau probleme au niveau du ReadFile cette fois
en fait le truc c'est que quand je fais une ReadFile il faut que des donnees aient ete envoyees avant (avec un WriteFile), sinon le programme plante carrement, sans aucun message d'erreur
un peu comme qd on essaye de lire dans un fichier : qd on arrive a la fin, ca plante si on gere pas le cas d'erreur
sauf que la, j'arrive pas a le gerer le cas d'erreur...
 
je poursuis mes recherches, mais ca m'arrangerait bien si quelqu'un avait une solution miracle :p


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°694591
pedro-2480
Posté le 07-04-2004 à 13:27:11  profilanswer
 

Une piste peut être le fait que tu as positionné le flag overlapped...donc tes opérations de lecture/ecriture sont asynchrones. Ainsi, ReadFile() te rend la main alors que la lecture n'est pas terminée...
 
Pour remédier à cela:
 
Récupérer la valeur de retour de ReadFile(), la traduire avec GetLastError() (attention une valeur de retour non-nulle ne veut pas dire qu'il y a succès, tu dois tester le nombre d'octets effectivement lus):
 
- Retour = ERROR_IO_PENDING: l'opération est en cours...
 
Dans ce cas, le mieux est d'attendre que l'opération se termine, une manière propre consisterait à te servir du Event que tu as passé en paramètre (dans la strucutre overlapped) au ReadFile():
Ex: WaitForSingleObject()...quand cette fonction te rend la main, c'est que:
- les données sont arrivées avant le timeout que tu as défini,
- le timeout a expiré...
 
- Retour = ERROR_HANDLE_EOF: pas de données lues (pb) -> a gérer...
 
A toi de faire le reste ! ;)


---------------
- Pierre Baudelet -
n°694832
myst78
Posté le 07-04-2004 à 16:56:03  profilanswer
 

ok merci bien ca m'a un peu inspire et je me suis debrouille
j'avais aussi un probleme de pointeur, qui faisait lire des trucs qu'il fallait pas :p
 
maintenant ca va y'a plus de problemes :)
 
merci et puis peut etre a bientot pour de nouveaux soucis ;)


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°698152
myst78
Posté le 13-04-2004 à 12:09:50  profilanswer
 

me revoila !!! :p
bon cette fois j'ai un soucis un peu plus grave
en fait, les donnes sont transmises octet par octet sur le port COM, mais apparement, le bit de poids fort ne passe pas. Du coup, c'est comme si il valait toujours 0, ce qui est embettant pour les valeurs negatives par exemple.
 
voila, je cherche des experts en transmission de donnees sur le port serie (c'est ptet pu le bon forum du coup...) parce que la je comprends vraiment pas ce aui se passe  :pt1cable:


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°698170
cricri_
Posté le 13-04-2004 à 12:20:07  profilanswer
 

t'est bien en 8 bits sans parité ?

mood
Publicité
Posté le 13-04-2004 à 12:20:07  profilanswer
 

n°698177
myst78
Posté le 13-04-2004 à 12:30:04  profilanswer
 

oui oui... 8 bit et aucune parite... :/


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°698186
cricri_
Posté le 13-04-2004 à 12:37:55  profilanswer
 

Peux-tu poster ton bout de code qui fait l'init et qui formate / envoit les datas ?

n°698197
_darkalt3_
Proctopathe
Posté le 13-04-2004 à 12:46:33  profilanswer
 

Même si c'est pas propre, ceci fonctionne très bien:
 

Code :
  1. class WinSerial {
  2. private:
  3.    int NumPort;
  4.    HANDLE hComm;
  5.    char portName[4];
  6.    DCB dcb;
  7.    char bufferIn[1024];
  8.    char bufferOut[1024];
  9. public:
  10. WinSerial(int numPort) {
  11.  NumPort=numPort;
  12.  wsprintf(portName,"COM%d",numPort);
  13.       //synchrone
  14.  hComm=CreateFile( portName,
  15.        GENERIC_READ | GENERIC_WRITE,
  16.        0,
  17.        0,
  18.        OPEN_EXISTING,
  19.        FILE_FLAG_OVERLAPPED,
  20.        0);
  21.  if (hComm==INVALID_HANDLE_VALUE) {
  22.   //printf("Handle NOTOK\n" );
  23.   exit(1);
  24.  }
  25.  FillMemory(&dcb,sizeof(dcb),0);
  26.  dcb.DCBlength=sizeof(dcb);
  27.       BuildCommDCB("9600,e,7,1",&dcb);
  28.  SetCommMask(hComm,EV_RXCHAR ||EV_RXFLAG); //alerte si caractere arrivé dans l'input
  29.  SetupComm(hComm,4096,1024);               //1024=taille max du bufferOut
  30.  SetCommState(hComm,&dcb);
  31. }
  32.    bool Ecrire(char *buffer) {
  33.       unsigned long nbreRetour;
  34.       if (WriteFile(hComm, buffer, strlen(buffer), &nbreRetour, NULL)) return true;
  35.       else return false;
  36.    }
  37.    bool EcrireChar(char c) {
  38.       unsigned long nbreRetour;
  39.       if (WriteFile(hComm, &c, 1, &nbreRetour, NULL)) return true;
  40.       else return false;
  41.    }
  42.    char LireChar() {
  43.       char c;
  44.       bool retour;
  45.       DWORD NbreLu;
  46.       retour=ReadFile(hComm,&c,1,(LPDWORD)&NbreLu,NULL);
  47.       return c;
  48.    }
  49. }

n°698206
myst78
Posté le 13-04-2004 à 12:51:04  profilanswer
 

la fonction qui ouvre le port COM :

Code :
  1. bool openCOMport(HANDLE& hPort, char* name, long baudRate, BYTE byteSize, char parity, int stopBits)
  2. {
  3.     bool bResult;   //boolean which indicates if the port has opened successfully
  4.     hPort = CreateFile (name,
  5.                         GENERIC_READ | GENERIC_WRITE,
  6.                         0,
  7.                         0,
  8.                         OPEN_EXISTING,
  9.                         FILE_ATTRIBUTE_NORMAL,
  10.                         0);
  11.     if (hPort == INVALID_HANDLE_VALUE)   //opening failed
  12.     {
  13.         bResult = false;
  14.         ShowMessage("pb ouverture port COM" );
  15.     }
  16.     else //COM port opened
  17.     {
  18.         //clearing of the buffer
  19.         PurgeComm(hPort,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
  20.         g_DCB.DCBlength = sizeof(DCB);  //initialization of COM port
  21.         GetCommState(hPort, &g_DCB);    //current configuration
  22.         //DCB modification
  23.         g_DCB.BaudRate = baudRate;
  24.         g_DCB.ByteSize = byteSize;
  25.         g_DCB.Parity = parity;
  26.         g_DCB.fParity = true;
  27.         g_DCB.StopBits = stopBits;
  28.         SetCommState(hPort, &g_DCB);     //configuration of serial link
  29.         timeouts.ReadIntervalTimeout = MAXDWORD;
  30.         timeouts.ReadTotalTimeoutMultiplier = 0;
  31.         timeouts.ReadTotalTimeoutConstant = 0;
  32.         timeouts.WriteTotalTimeoutMultiplier =5;
  33.         timeouts.WriteTotalTimeoutConstant = 5;
  34.         SetCommTimeouts(hPort, &timeouts);
  35.         bResult = true;
  36.     }
  37.     return bResult;
  38. }


 
 
L'envoi des donnees

Code :
  1. bool sendData(HANDLE hPort, const BYTE* buffer, int nCount)
  2. {
  3.     bool bResult;
  4.     unsigned long numBytes = 0;
  5.     if (hPort == NULL)  //COM port hasn't been opened
  6.         bResult = false;
  7.     else
  8.     {
  9.         WriteFile(hPort, buffer, nCount, &numBytes, NULL);
  10.         bResult = true;
  11.     }
  12.     return bResult;
  13. }


 
La creation du buffer :
en fait, j'ai une structure qui contient un tableau de 22 entiers 16bits
je les decoupe en 2 entiers 8bits chacun que je stock dans le buffer

Code :
  1. BYTE* createBuffer(TFuK_Msg* frame)
  2. {
  3.     BYTE* buffer = new BYTE[40];
  4.     BYTE* pTmp;
  5.     for (int i=0; i<20; i++)
  6.     {
  7.         pTmp = (BYTE*)&frame->DW[i]; //DW c'est le nom du tableau d'entiers
  8.         *(buffer+(2*i)) = *pTmp;
  9.         *(buffer+((2*i)+1)) = *(pTmp+1);
  10.     }
  11.     return buffer; //ici j'ai teste, le buffer vaut bien ce que je veuxqu'il vale...
  12. }


 
 
voila, je sais pas si c'est exactement ca que tu voulais... :p


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°698335
cricri_
Posté le 13-04-2004 à 15:13:14  profilanswer
 

Et comment appeles-tu la fonction openComPort ?

n°698339
myst78
Posté le 13-04-2004 à 15:20:01  profilanswer
 

Code :
  1. //les constantes globales
  2. const int CONNECTION_SPEED = 19200;
  3. const int BYTE_SIZE = 8;
  4. const char PARITY = NOPARITY;
  5. const int STOP_BITS = 1;
  6. //l'appel de openCOMport
  7. if (!openCOMport(hPort1, "COM1", CONNECTION_SPEED, BYTE_SIZE, PARITY, STOP_BITS))
  8.     //cas d'erreur
  9. else
  10.     //cas ou ca s'est ben ouvert


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°698411
myst78
Posté le 13-04-2004 à 16:40:08  profilanswer
 

ca maaaaarche YOUPIIII !!!  :sol:


---------------
Fleur de métal, entité invulnérable, vêtue tant bien que mal, d'une muraille inébranlable...
n°698503
cricri_
Posté le 13-04-2004 à 18:20:26  profilanswer
 

Et c'était quoi le pb ?

n°698507
myst78
Posté le 13-04-2004 à 18:27:17  profilanswer
 

j'ai bidouillé un peu partout : des signed char* (ou unsigned je sais plus) partout pour mes buffers d'ecriture et de lecture, des valeurs dans la DCB, et puis j'ai utilisé des constantes predefinies (NOPARITY, ONESTOPBIT)...  
mais en fait je suis pas sûr parce qu'avec tous les changements que j'ai fait et refait ben moi-meme je suis un peu perdu :/
je crois que j'ai ete plus rigoureux sur les initialisations et toute la programmation au niveau du port, à part ca je sais pas trop...
 
donc ouais, c'est pas une super demarche de programmeur, mais tant pis, l'important pour l'instant c'est que ca marche...  
si jamais ca replante ben... ca replantera pas !! :D


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Communication avec un port COM

 

Sujets relatifs
Hébergement SQL avec port 3306 accessiblecommunication entre les plugins et le coeur d'une application POO
Dialoger avec un périphérique via la port RS-232C[C]problème read sur port série
[C] Fonctions pour le port COMProgrammation du port SDIO
Communication entre un service NT et une IHMCommunication objet et servlet
[RESOLU]Problème de communication (DataInputStream & DataOutputStream) 
Plus de sujets relatifs à : Communication avec un port COM


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR