[C] Lecteur port série windows.h (readFile()) + SDL

Lecteur port série windows.h (readFile()) + SDL [C] - C - Programmation

Marsh Posté le 20-11-2011 à 19:09:48    

Bonjour,
 
Pour un de mes projets, je réalise un script utilisant la SDL, et lisant des données issues d'un de mes ports série (envoyées par une carte arduino). Or, il semble qu'il est ait un conflit entre la SDL et les fonctions telles que readFile().
 
Voici mon code sans mon code du main afin qu'il soit moins lourd :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4. #include <string.h>
  5. #include <windows.h>
  6. #include <SDL/SDL.h>
  7. #define RX_SIZE     500000   /* taille tampon d'entrée  */
  8. #define TX_SIZE     500000   /* taille tampon de sortie */
  9. #define MAX_WAIT_READ   2500  /* temps max d'attente pour lecture (en ms) */
  10. HANDLE g_hCOM = NULL;
  11. COMMTIMEOUTS g_cto =
  12. {
  13.   MAX_WAIT_READ,  /* ReadIntervalTimeOut      */
  14.   0,        /* ReadTotalTimeOutMultiplier   */
  15.   MAX_WAIT_READ,  /* ReadTotalTimeOutConstant   */
  16.   0,        /* WriteTotalTimeOutMultiplier  */
  17.   0         /* WriteTotalTimeOutConstant  */
  18. };
  19. /* Configuration du port COM */
  20. DCB g_dcb =
  21. {
  22.   sizeof(DCB),    /* DCBlength      */
  23.   9600,         /* BaudRate       */
  24.   TRUE,         /* fBinary        */
  25.   FALSE,        /* fParity        */
  26.   FALSE,        /* fOutxCtsFlow     */
  27.   FALSE,        /* fOutxDsrFlow     */
  28.   DTR_CONTROL_ENABLE, /* fDtrControl      */
  29.   FALSE,        /* fDsrSensitivity    */
  30.   FALSE,        /* fTXContinueOnXoff  */
  31.   FALSE,        /* fOutX        */
  32.   FALSE,        /* fInX         */
  33.   FALSE,        /* fErrorChar       */
  34.   FALSE,        /* fNull        */
  35.   RTS_CONTROL_ENABLE, /* fRtsControl      */
  36.   FALSE,        /* fAbortOnError    */
  37.   0,          /* fDummy2        */
  38.   0,          /* wReserved      */
  39.   0x100,        /* XonLim         */
  40.   0x100,        /* XoffLim        */
  41.   8,          /* ByteSize       */
  42.   NOPARITY,       /* Parity         */
  43.   ONESTOPBIT,     /* StopBits       */
  44.   0x11,         /* XonChar        */
  45.   0x13,         /* XoffChar       */
  46.   '?',        /* ErrorChar      */
  47.   0x1A,         /* EofChar        */
  48.   0x10        /* EvtChar        */
  49. };
  50. BOOL OpenCOM  (int nId);
  51. BOOL CloseCOM   ();
  52. BOOL ReadCOM  (void* buffer, int nBytesToRead, int* pBytesRead);
  53. void pause();
  54. int main(int argc, char *argv[]){
  55.   SDL_Init(SDL_INIT_VIDEO); // Initialisation de la SDL
  56.   SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE); // Ouverture de la fenêtre
  57.   pause(); // Mise en pause du programme
  58.   SDL_Quit(); // Arrêt de la SDL
  59.   return EXIT_SUCCESS; // Fermeture du programme
  60. }
  61. BOOL OpenCOM(int nId){
  62.   /* variables locales */
  63.   char szCOM[16];
  64.   /* construction du nom du port, tentative d'ouverture */
  65.   sprintf(szCOM, "COM%d", nId);
  66.   g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
  67.             OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
  68.   if(g_hCOM == INVALID_HANDLE_VALUE){
  69.     printf("Erreur lors de l'ouverture du port COM%d", nId);
  70.     return FALSE;
  71.   }
  72.   /* affectation taille des tampons d'émission et de réception */
  73.   SetupComm(g_hCOM, RX_SIZE, TX_SIZE);
  74.   /* configuration du port COM */
  75.   if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb)){
  76.     printf("Erreur lors de la configuration du port COM%d", nId);
  77.     CloseHandle(g_hCOM);
  78.     return FALSE;
  79.   }
  80.   /* on vide les tampons d'émission et de réception, mise à 1 DTR */
  81.   PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
  82.   EscapeCommFunction(g_hCOM, SETDTR);
  83.   return TRUE;
  84. }
  85. BOOL CloseCOM(){
  86.   /* fermeture du port COM */
  87.   CloseHandle(g_hCOM);
  88.   return TRUE;
  89. }
  90. BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead){
  91.   return ReadFile(g_hCOM, buffer, nBytesToRead, pBytesRead, NULL);
  92. }
  93. void pause()
  94. {
  95.   int continuer = 1;
  96.   SDL_Event event;
  97.   while (continuer){
  98.     SDL_WaitEvent(&event);
  99.     switch(event.type){
  100.       case SDL_QUIT:
  101.         continuer = 0;
  102.     }
  103.   }
  104. }


 
Lorsque que je n'utilise pas la SDL, aucun problème, mais quand je l'utilise, il m'empêche d'utiliser cette fonction
Voici mon erreur :
 
http://www.legeekcafe.com/upload/img/1297error.PNG

Reply

Marsh Posté le 20-11-2011 à 19:09:48   

Reply

Marsh Posté le 20-11-2011 à 20:38:41    

Bonsoir,
 
L'erreur est pourtant claire. Le compilateur te dit qu'il ne peut pas convertir int * en DWORD *. Il faut donc que tu changes le prototype de ta fonction ReadCOM en utilisant un DWORD * plutot qu'un int * pour le 3eme paramètre.

Reply

Marsh Posté le 23-11-2011 à 15:22:24    

Salut,
 
j'ai trouvé beaucoup mieux que ça. Mon code est en C++. Je le passe en C, et je n'ai plus besoin de convertir

Reply

Marsh Posté le 21-04-2012 à 14:35:31    

Bonjour,
 
Je tente de réaliser un programme en C qui envoi et recoit des données via un port série. Cependant je ne trouve rien qui m'aide vraiment sur internet.  
fab@c++ pourrait tu poster ton code afin que je puisse voir un exemple qui fonctionne ?
 
Merci.

Reply

Marsh Posté le 21-04-2012 à 15:22:40    

Salut,
 
Mon code récupère une chaîne qu'il stocke dans un fichier texte. Voici le genre de chaîne que je récupère via le port série :
 

Code :
  1. 111111111111111111111111111111111111111111111111 196 202 179 255 1111111111111111111111111111111111111111111111111111111111111111111111 197 201 181 255 1111111111111111111111111111111111111111111111


 
Et voici mon code c++ . Attention, il possède une partie SDL. Si t'as des questions, n'hésite pas à poster
 

Code :
  1. #include <conio.h>
  2. #include <string.h>
  3. #include <windows.h>
  4. #include <SDL/SDL.h>
  5. #define RX_SIZE 16000
  6. #define TX_SIZE 16000
  7. #define MAX_WAIT_READ 1000
  8. HANDLE g_hCOM = NULL;
  9. COMMTIMEOUTS g_cto ={
  10.   MAX_WAIT_READ,0,MAX_WAIT_READ,0,0
  11. };
  12. DCB g_dcb ={
  13.   sizeof(DCB),9600,TRUE,FALSE,FALSE,FALSE,DTR_CONTROL_ENABLE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,RTS_CONTROL_ENABLE,FALSE,0,0,0x100,0x100,8,NOPARITY,ONESTOPBIT,0x11,0x13,'?',0x1A,0x10
  14. };
  15. BOOL OpenCOM  (int nId);
  16. BOOL CloseCOM   ();
  17. static BOOL ReadCOM  (void* buffer, int nBytesToRead, int* pBytesRead);
  18. int main(int argc, char *argv[]){
  19.   //SDL ici
  20.   SDL_Surface *ecran = NULL, *rectangle_1 = NULL, *rectangle_2 = NULL, *rectangle_3 = NULL, *rectangle_4 = NULL;
  21.   SDL_Rect position_1, position_2, position_3, position_4;
  22.   SDL_Init(SDL_INIT_VIDEO);
  23.   ecran = SDL_SetVideoMode(480,480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF );
  24.   rectangle_1 = SDL_CreateRGBSurface(SDL_HWSURFACE, 240,240, 32, 0, 0, 0, 0);
  25.   rectangle_2 = SDL_CreateRGBSurface(SDL_HWSURFACE, 240,240, 32, 0, 0, 0, 0);
  26.   rectangle_3 = SDL_CreateRGBSurface(SDL_HWSURFACE, 240,240, 32, 0, 0, 0, 0);
  27.   rectangle_4 = SDL_CreateRGBSurface(SDL_HWSURFACE, 240,240, 32, 0, 0, 0, 0);
  28.   position_1.x = 0; position_1.y = 240;
  29.   position_2.x = 240; position_2.y = 240;
  30.   position_3.x = 0; position_3.y = 0;
  31.   position_4.x = 240; position_4.y = 0;
  32.   SDL_WM_SetCaption("electronic eye", NULL);
  33.   //fin SDL
  34.   static const unsigned short int nId=4; //relatif à l'affichage
  35.   static unsigned char buffer[200]; //le buffer qui contient la chaîne récupérée via le port série
  36.   static int nBytesRead;
  37.   static unsigned short int i=0;
  38.   static unsigned short int sensor[10] = {0};
  39.   static unsigned char sensor_1[1];
  40.   static unsigned char sensor_3[]="1111111111 ";
  41.   FILE *fichier = NULL;
  42.   if(!OpenCOM(nId)) return -1;
  43.   while(1) { //boucle de la SDL
  44.     if(ReadCOM(buffer, sizeof(buffer)-2, &nBytesRead)){ //ON lit le port série
  45.       buffer[nBytesRead] = '\0';
  46.       fichier = fopen("test.txt", "w+" );  //on enregistre dans le fichier
  47.       fputs(buffer, fichier);
  48.       fclose(fichier);
  49.       fichier = fopen("test.txt", "r+" );
  50.       if (fichier != NULL){  // on récupère et on affiche
  51.         fscanf(fichier, "%s %d %d %d %d", &sensor_1[0], &sensor[0], &sensor[1], &sensor[2], &sensor[3]);
  52.         fclose(fichier);
  53.         if(sensor[0]>255 || sensor[0]<0 || sensor[0]==111) sensor[0]=((sensor[1]+sensor[2]+sensor[3])/3);
  54.         if(sensor[1]>255 || sensor[1]<0 || sensor[1]==111) sensor[1]=((sensor[0]+sensor[2]+sensor[3])/3);
  55.         if(sensor[2]>255 || sensor[2]<0 || sensor[2]==111) sensor[2]=((sensor[1]+sensor[0]+sensor[3])/3);
  56.         if(sensor[3]>255 || sensor[3]<0 || sensor[3]==111) sensor[3]=((sensor[1]+sensor[2]+sensor[0])/3);
  57.         SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, sensor[0],sensor[0],sensor[0]));
  58.         SDL_FillRect(rectangle_1, NULL, SDL_MapRGB(ecran->format, sensor[0],sensor[0],sensor[0]));
  59.         SDL_BlitSurface(rectangle_1, NULL, ecran, &position_1);
  60.         SDL_FillRect(rectangle_2, NULL, SDL_MapRGB(ecran->format, sensor[1],sensor[1],sensor[1]));
  61.         SDL_BlitSurface(rectangle_2, NULL, ecran, &position_2);
  62.         SDL_FillRect(rectangle_3, NULL, SDL_MapRGB(ecran->format, sensor[2],sensor[2],sensor[2]));
  63.         SDL_BlitSurface(rectangle_3, NULL, ecran, &position_3);
  64.         SDL_FillRect(rectangle_4, NULL, SDL_MapRGB(ecran->format, sensor[3],sensor[3],sensor[3]));
  65.         SDL_BlitSurface(rectangle_4, NULL, ecran, &position_4);
  66.         SDL_Flip(ecran);
  67.       }
  68.     }
  69.     i++;
  70.   }
  71.   CloseCOM();
  72.   SDL_Quit();
  73.   return 0;
  74. }
  75. BOOL OpenCOM(int nId){
  76.   char szCOM[16];
  77.   sprintf(szCOM, "COM%d", nId);
  78.   g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
  79.             OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
  80.   if(g_hCOM == INVALID_HANDLE_VALUE){
  81.     printf("Erreur lors de l'ouverture du port COM%d", nId);
  82.     return FALSE;
  83.   }
  84.   SetupComm(g_hCOM, RX_SIZE, TX_SIZE);
  85.   if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb)){
  86.     printf("Erreur lors de la configuration du port COM%d", nId);
  87.     CloseHandle(g_hCOM);
  88.     return FALSE;
  89.   }
  90.   PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
  91.   EscapeCommFunction(g_hCOM, SETDTR);
  92.   return TRUE;
  93. }
  94. BOOL CloseCOM(){
  95.   CloseHandle(g_hCOM);
  96.   return TRUE;
  97. }
  98. static BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead){
  99.   return ReadFile(g_hCOM, buffer, nBytesToRead, pBytesRead, NULL);
  100. }

Reply

Marsh Posté le 21-04-2012 à 15:41:44    

Merci pour ton code, je suis débutante en C et n'y connais pas grand chose, c'est donc un peu compliquer pour moi...
 
Je suis en stage et je cherche à communiquer via les ports séries de windows avec un calibrateur et un multimètre, je voudrais donc pouvoir à la fois lire et écrire sur les ports. Je dois envoyer des commandes du type "MEAS?" pour que l'appareil me revoie la valeur mesurée.
En attendant de trouver une solution pour utiliser les port séries directement en c j'utilise l'hyperterminal que j'ouvre avec mon programme et ou j'écris virtuellement des commandes, mais cette solution me semble un peu lourde puisqu'elle nécessite l'ouverture de plusieurs fenêtres.  
Pourrait tu m'expliquer à quoi sert la SDL.
Si je comprend bien il me suffit de retirer tout ce qui concerne la SDL pour pouvoir utiliser les ports séries ?  
 
Merci d'avance pour votre aide.

Reply

Marsh Posté le 21-04-2012 à 19:04:01    

Mon programme avait pour but d'afficher un écran à partir de données récupérées par des capteurs d'une carte arduino. La SDL sert juste à l'affichage. On peut donc enlever toutes les partie relatives à l'affichage en SDL pour pouvoir exécuter ce programme en mode console.
Pour ma part, j'ai beaucoup cherché pour la lecture sur le port, mais je ne sais pas trop comment écrire. je pense, ce code utilisant la lib windows.h, qu'il suffit de s'intéresser à cette lib pour s'avoir comment écrire sur un port série.
 
Voilà :)

Reply

Marsh Posté le 21-04-2012 à 20:19:03    

Merci de ta réponse je vais essayer et ca, et te tiens au courant du résultat ;-)

Reply

Marsh Posté le 22-04-2012 à 16:48:42    

J'ai fait des tests du coup mais je rencontre un problème.
J'ai ajouter la partie écriture que j'ai trouvé sur le net faite sur le même modèle que ta partie lecture, mais quand j'envoi des données au calibrateur et il ne semble pas les recevoir, de même pour la lecture, il ne renvoi rien. J'ai vérifier les paramètres baudrate, databits, stopbit qui sont bon mais je ne sais pas a quoi correspondent les autres.
Quel compilateur utilisais tu ? Peut tu me dire à quoi sert le "static" tout a la fin pour la lecture du port ?

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed