none
Communication par Port Serie RS232 RRS feed

  • Question

  • Bonjour,voila je fait une petit appli qui communique avec une arduino par le port serie, jusque là ça vas je peut envoyer autant de message que je veut mais pour les lire je me trouve confronté un un petit problème, avec les code que j'ai trouvé sur le net je n'arrive récupérer des caractère qu'a un moment donné, alors que moi je voudrai pouvoir le récupérer en "temps masqué" et l'utiliser comme l’appuie sur un bouton

    jeudi 24 mai 2012 08:09

Réponses

Toutes les réponses

  • Pourquoi le pas faire un thread dédié et utiliser les API bloquantes de lecture ?

    Paul Bacelar, Ex - MVP VC++

    jeudi 24 mai 2012 09:48
    Modérateur
  • parce que je ne sais pas faire ... en tous les cas pas avec ce vocabulaire.

    dsl mais le vocabulaire n'est pas mon fort

    jeudi 24 mai 2012 12:10
  • En clair, c'est prendre le code que vous avez trouvé qui récupère les caractères mais le faire s'exécuter dans un thread distinct.

    http://fr.wikipedia.org/wiki/Thread_(informatique)


    Paul Bacelar, Ex - MVP VC++

    • Marqué comme réponse 23253 vendredi 25 mai 2012 06:20
    jeudi 24 mai 2012 15:03
    Modérateur
  • merci pour cette réponse rapide :

    je ne connaissais pas encore les thread et pour ceux qui serai dans mon cas voici un truc qui pourrais leur être utile :

    http://www.alrj.org/docs/systeme/win32thread.pdf

    vendredi 25 mai 2012 06:20
  • grâce a votre réponse je me suis mis au theard mais voila j'ai mon main, avec un theard  qui tourne et qui attend un message par liaison série, le problème et que pendant ce temps là moi je ne peut pas en envoyer par cette liaison y a t'il un moyen pour en attendre un message et pouvoir dans le même temps en envoyer?

    le theard a ppelant une fonction de communication :

    DWORD WINAPI Thread0(LPVOID lpParameter)       //attente de transmission serie par la carte Arduino vers le PC
    {
        int ordre = 0,i;
        printf("thread\n");
        while(1){
            printf("while 1\n");                    //boucle infini
            while (Mode == 0){                      //actif que en mode utilisation
                if((Bool_01 & 0x80) == 0x80)
                printf("mode == 0\n");
                printf("marche\n");
                ordre = CommunicationSerie(2, NomPort, NULL);
                MessageBox(NULL, "message reçu","POP-UP", NULL);
    
                printf("ordre %d reçu\n",ordre);
                SetEvent(event_0);        //sert a communiquer avec un second theard
            }
            printf("mode == 1\n");
            DWORD dwWaitResult;
            dwWaitResult = WaitForSingleObject(event_1, INFINITE);
        }
        return TRUE;
    }

    la zone appellé par le theard :

    case 2:{
        printf("lecture\n");
        int lettre;
        DWORD dwStoredFlags;
        BYTE octet;
        dwStoredFlags = EV_RXCHAR;
        SetCommMask (g_hCom, EV_RXCHAR);
        WaitCommEvent(g_hCom,&dwStoredFlags,NULL);
        if (dwStoredFlags & EV_RXCHAR){
            ReadFile(g_hCom,&octet,1,&NCarLus,NULL);
            lettre = octet;
            switch (lettre){
                case '0':{
                    printf("ordre :0\n");
                    CloseHandle(g_hCom);
                    return 0;
                    break;
                }
                case '1':{
                    printf("ordre : 1\n");;
                    CloseHandle(g_hCom);
                    return 1;
                    break;
                }
                case '2':{
                    printf("ordre :2\n");;
                    CloseHandle(g_hCom);
                    return 2;
                    break;
                }
                default:{
                    printf("ordre : default\n");
                    CloseHandle(g_hCom);
                    return NULL;
                    break;
                }
            }
            break;
        }
    }

    en esperrant avoir donné toutes les information nécessaires,

    la communication entre les différentes partie ce fait très bien mais par contre c'est la communication par la liaison RS232 qui les monopolisé par la fonction WaitComEvent();

    l'idéal de ce que je souhaiterais : c'est attendre un caractère tant que je n'en envoi pas.

    Merci d'avance


    • Modifié 23253 lundi 11 juin 2012 12:37
    lundi 11 juin 2012 12:14
  • Je ne comprends pas trop vos difficultés.

    Vous avez le thread principal, celui qui fait plein de truc comme l'envoie de message et vous avez un thread additionnel qui boucle sur "WaitComEvent".

    Ca, c'est le principe de base.

    Après, il faut coordonner les threads, et voici un exemple avec l'utilisation de WaitForMultipleObjects :

    http://www.codeproject.com/Articles/2682/Serial-Communication-in-Windows


    Paul Bacelar, Ex - MVP VC++

    mardi 12 juin 2012 09:43
    Modérateur
  • en fait le probleme est simple : c'est du partage de ressources, mais c'est comment m'en sortir qui pose probleme.

    J'ai une ressources qui est le port COM3 port de communication série, quand je suis sur le WaitComEvent(); je monopolise cette ressource en mode réception mais l'envoi de message nécessite aussi cette ressource mais en mode émission.

    Ce qui me gène c'est que lorsque j'attends une réception j'empêche toute émission donc alors que doit pouvoir émettre, c'est là que je coince.

    .......................................................................................................................................................

    Je suis entrain de réfléchir ... oui sa m'arrive et je m'aperçoit que mon problème est insoluble du fait que je veut écrire pendant une lecture, je vais voir pour passer a travers d'une autre manière.

    mardi 12 juin 2012 13:36
  • Là, vous vous faites des idées.

    Le matériel électroniques est tout à fais capable de lire et écrire en même temps, surtout sur une connections série où chaque sens de communications dispose d'un fil dédié.

    D'un point de vue software, c'est pareil, un thread peut être en attente sur réception d'une communication et un autre thread utilisé le même handle pour envoyer des données.

    Ne cherchez pas midi à 14 heures.


    Paul Bacelar, Ex - MVP VC++

    mardi 12 juin 2012 14:28
    Modérateur
  • a la sa pose un problème car a chaque foi que je tente d'ouvrir une seconde connexion par le même port sa échoue.

    a savoir que je ne suis pas directement en serial mais je pas par un port USB qui est reconnu comme serial, là c'est peut être le driver qui ne gère pas.

    mardi 12 juin 2012 15:29
  • Il  faut pas l'ouvrir une seconde fois, il faut utiliser le même handle.


    Paul Bacelar, Ex - MVP VC++

    mardi 12 juin 2012 16:08
    Modérateur
  • ok je vais voir ce que je peux faire

    mercredi 13 juin 2012 06:03
  •  

    Bon alors j'ai essayé votre truc(qui m'a l'air rpometteur) mais je bloc ... oui encore... dans mon premier theard j'appel cette fonction avec i = 2(j'attend en mode reception) dans mon second theard j'appel cette meme fonction avec i = 1; voila ce que je fait.

    alors est-ce que le fait d'appeler un deuxième foi la même fonction durant l'exécution de la première pose problème ou est-ce que c'est le code?

    voici ma fonction de communication :

    int port_active = 0;

    int CommunicationSerie(int i, char *NomPort,char *symbol)
    {
    DWORD NCarLus=0, NumBytes=0, Errors;
    COMSTAT Stat;
    DCB g_DCB;
    if(port_active == 0){

    g_hCom = CreateFile( NomPort, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_FLAG_RANDOM_ACCESS,NULL);

    ClearCommError(g_hCom,&Errors,&Stat);
    if(g_hCom == INVALID_HANDLE_VALUE){

    port_active = 0;
    CloseHandle(g_hCom);
    return 0 ;
    }
    else{

    PurgeComm( g_hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
    g_DCB.DCBlength = sizeof(DCB);
    GetCommState(g_hCom, &g_DCB);
    g_DCB.BaudRate = 9600 ;
    g_DCB.ByteSize = 8;
    g_DCB.fDtrControl = DTR_CONTROL_ENABLE;
    g_DCB.Parity = NOPARITY;
    g_DCB.StopBits = ONESTOPBIT;
    port_active = 1;
    }
    }
    if(port_active == 1){

    switch (i){
    //ecriture
    case 1:{
    WriteFile(g_hCom,symbol,strlen(symbol),&NumBytes,NULL)
    break;
    }
    //lecture
    case 2:{
    int lettre;
    DWORD dwStoredFlags;
    BYTE octet;
    dwStoredFlags = EV_RXCHAR;
    SetCommMask (g_hCom, EV_RXCHAR);
    WaitCommEvent(g_hCom,&dwStoredFlags,NULL);
    if (dwStoredFlags & EV_RXCHAR){
    ReadFile(g_hCom,&octet,1,&NCarLus,NULL);
    lettre = octet;
    switch (lettre){
    case '0':{
    return 0;
    break;
    }
    case '1':{
    return 1;
    break;
    }
    case '2':{
    return 2;
    break;
    }
    }
    break;
    }
    }
    }
    }


    • Modifié 23253 mercredi 13 juin 2012 08:28
    mercredi 13 juin 2012 08:22
  • Je comprend pas tout.

    Moi, j'aime bien faire simple, donc avec plusieurs fonctions.

    HANDLE InitCommunicationSerie(char *NomPort)
    {

    DWORD Errors;
        COMSTAT Stat;
    DCB dCB;

        HANDLE hCom;


            hCom = CreateFile( NomPort, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_FLAG_RANDOM_ACCESS,NULL);
            ClearCommError(hCom,&Errors,&Stat);


            if(hCom == INVALID_HANDLE_VALUE){
                return hCom ;
            }
            else{
               
                PurgeComm( hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
                dCB.DCBlength = sizeof(DCB);
                GetCommState(hCom, &g_DCB);
                dCB.BaudRate = 9600 ;
                dCB.ByteSize = 8;
                dCB.fDtrControl = DTR_CONTROL_ENABLE;
                dCB.Parity = NOPARITY;
                dCB.StopBits = ONESTOPBIT;
            }
        }

    }

    int ReadCommunicationSerie(HANDLE handle)
    {

    DWORD NCarLus=0;

    int lettre;
                    DWORD dwStoredFlags;
                    BYTE octet;
                    dwStoredFlags = EV_RXCHAR;
                    SetCommMask (handle, EV_RXCHAR);
                    WaitCommEvent(g_hCom,&dwStoredFlags,NULL);
                    if (dwStoredFlags & EV_RXCHAR){
                        ReadFile(g_hCom,&octet,1,&NCarLus,NULL);
                        lettre = octet;
                        switch (lettre){
                            case '0':{
                                return 0;
                                break;
                            }
                            case '1':{
                                return 1;
                                break;
                            }
                            case '2':{
                                return 2;
                                break;
                            }
                    }

    }

    void WriteCommunicationSerie(HANDLE handle,char *symbol)
    {

    DWORD NumBytes=0,

    WriteFile(hCom,symbol,strlen(symbol),&NumBytes,NULL);

    }



    Paul Bacelar, Ex - MVP VC++



    jeudi 14 juin 2012 08:53
    Modérateur
  • pas faut je regarde ça.

    jeudi 14 juin 2012 09:49
  • j'ai essayé mais rien a faire une foie en mode lecture pas possibilité d'écrire...

    Edit 1 : j'y pense vu que je suis en mode synchrone, il n'accepte peut être pas de faire de la lecture en même temps que l'écriture,  il faudrait essayer avec le mode asynchrone, mais j'avoue ne pas comprendre toutes les explication trouvé aussi bien sur msdn ou le net en général.

    Edit 2 : je me suis dit que le probleme etant que quand je veut ecrire il faut arreter d'attendre je pouvais peut etre faire ça :

    WaitCommEvent(g_hCom,&dwStoredFlags,NULL) | WaitForSingleObject(event_2_2,INFINITE)

    mais ça ne fonctionne pas non plus ...

    question pourquoi ?

    • Modifié 23253 samedi 16 juin 2012 08:32
    vendredi 15 juin 2012 08:55
  • personne ne sait pourquoi ?
    WaitCommEvent(g_hCom,&dwStoredFlags,NULL) | WaitForSingleObject(event_2_2,INFINITE)
    c'est considéré comme:
    WaitCommEvent(g_hCom,&dwStoredFlags,NULL) & WaitForSingleObject(event_2_2,INFINITE)
    lundi 18 juin 2012 12:33
  • Avez vous bien :

    - Appelé la fonction "InitCommunicationSerie" avant le moindre appel aux 2 autres fonctions ?

    - Partagé le handle retourné par "InitCommunicationSerie" entre le thread le lecture et celui qui écrit ?

    - Fait les appels à "ReadCommunicationSerie" dans un thread différent ce lui qui appel la fonction "WriteCommunicationSerie" ?

    "WaitCommEvent(g_hCom,&dwStoredFlags,NULL) | WaitForSingleObject(event_2_2,INFINITE)"

    Cela veut dire que l'on appel la fonction "WaitCommEvent" et à la fonction "WaitForSingleObjet" et on fait un OU "binaire" avec les valeurs de retour des 2 fonctions.

    Deux attentes au lieu d'une.

    Lisez un peu la documentation et les samples fournis, svp. :-(


    Paul Bacelar, Ex - MVP VC++


    jeudi 28 juin 2012 08:16
    Modérateur
  • Vous faite deux attentes puis vous faites la synthèse des valeurs de retour des 2 foncions.

    Paul Bacelar, Ex - MVP VC++

    jeudi 28 juin 2012 08:17
    Modérateur