begin process at 2010 03 17 07:42:19
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

 > BASE COMMUNICATION SÉRIE RS232 (WIN32)

BASE COMMUNICATION SÉRIE RS232 (WIN32)


 Information sur la source

Note :
9,77 / 10 - par 13 personnes
9,77 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :API Niveau :Débutant Date de création :01/05/2004 Vu / téléchargé :42 924 / 4 547

Auteur : ymca2003

Ecrire un message privé
Commentaire sur cette source (115)
Ajouter un commentaire et/ou une note

 Description

après plusieures questions et demandes d'aides, voici le minimum vital pour lire et écrire sur les ports séries.

le handle du port est mis en variable globale (g_hComm). Peut être ajouté au parm des fct si besoin de plusieurs port ds le prog

Source

  • /******************************************************************************
  • TestCOM.c :
  • fonctions de base pour l'envoi et la réception de donner sur un port
  • série RS232.
  • ******************************************************************************/
  • #include <windows.h>
  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <conio.h>
  • /*=============================================================================
  • Définition de constantes
  • =============================================================================*/
  • #define RX_SIZE 4096 /* taille tampon d'entrée */
  • #define TX_SIZE 4096 /* taille tampon de sortie */
  • #define MAX_WAIT_READ 5000 /* temps max d'attente pour lecture (en ms) */
  • /*=============================================================================
  • Variables globales.
  • =============================================================================*/
  • /* Handle du port COM ouvert */
  • HANDLE g_hCOM = NULL;
  • /* Délais d'attente sur le port COM */
  • COMMTIMEOUTS g_cto =
  • {
  • MAX_WAIT_READ, /* ReadIntervalTimeOut */
  • 0, /* ReadTotalTimeOutMultiplier */
  • MAX_WAIT_READ, /* ReadTotalTimeOutConstant */
  • 0, /* WriteTotalTimeOutMultiplier */
  • 0 /* WriteTotalTimeOutConstant */
  • };
  • /* Configuration du port COM */
  • DCB g_dcb =
  • {
  • sizeof(DCB), /* DCBlength */
  • 9600, /* BaudRate */
  • TRUE, /* fBinary */
  • FALSE, /* fParity */
  • FALSE, /* fOutxCtsFlow */
  • FALSE, /* fOutxDsrFlow */
  • DTR_CONTROL_ENABLE, /* fDtrControl */
  • FALSE, /* fDsrSensitivity */
  • FALSE, /* fTXContinueOnXoff */
  • FALSE, /* fOutX */
  • FALSE, /* fInX */
  • FALSE, /* fErrorChar */
  • FALSE, /* fNull */
  • RTS_CONTROL_ENABLE, /* fRtsControl */
  • FALSE, /* fAbortOnError */
  • 0, /* fDummy2 */
  • 0, /* wReserved */
  • 0x100, /* XonLim */
  • 0x100, /* XoffLim */
  • 8, /* ByteSize */
  • NOPARITY, /* Parity */
  • ONESTOPBIT, /* StopBits */
  • 0x11, /* XonChar */
  • 0x13, /* XoffChar */
  • '?', /* ErrorChar */
  • 0x1A, /* EofChar */
  • 0x10 /* EvtChar */
  • };
  • /*=============================================================================
  • Fonctions du module.
  • =============================================================================*/
  • BOOL OpenCOM (int nId);
  • BOOL CloseCOM ();
  • BOOL ReadCOM (void* buffer, int nBytesToRead, int* pBytesRead);
  • BOOL WriteCOM (void* buffer, int nBytesToWrite, int* pBytesWritten);
  • /******************************************************************************
  • main : point d'entrée du programme.
  • ******************************************************************************/
  • int main()
  • {
  • /* variables locales */
  • char buffer[256];
  • int nId, nChoice, nBytesWritten, nBytesRead;
  • /* demande du numéro du port COM */
  • printf("Entrez le numero du port COM : ");
  • scanf("%d", &nId);
  • /* tentative d'ouverture */
  • printf("Ouverture et configuration du port COM%d...\r\n", nId);
  • if(!OpenCOM(nId)) return -1;
  • printf("...OK\r\n");
  • /* boucle tant que l'on ne quitte pas */
  • do
  • {
  • /* menu */
  • printf("\r\n");
  • printf("1 : Envoyer des donnees.\r\n");
  • printf("2 : Recevoir des donnees.\r\n");
  • printf("3 : Quitter.\r\n");
  • printf("Choix : ");
  • scanf("%d", &nChoice);
  • /* enoyer des données */
  • if(nChoice == 1)
  • {
  • printf("\r\n");
  • printf("Donnees a envoyer :\r\n");
  • fflush(stdin);
  • gets(buffer);
  • printf("\r\n");
  • printf("Envoi des donnees...\r\n");
  • if(WriteCOM(buffer, strlen(buffer), &nBytesWritten))
  • printf("%d octet(s) envoye(s).\r\n", nBytesWritten);
  • else
  • printf("Erreur lors de l'envoi.\r\n");
  • }
  • /* recevoir des données */
  • if(nChoice == 2)
  • {
  • printf("\r\n");
  • printf("Reception de donnees...\r\n");
  • if(ReadCOM(buffer, sizeof(buffer)-1, &nBytesRead))
  • {
  • buffer[nBytesRead] = '\0';
  • printf("%d octet(s) recu(s) :\r\n%s\r\n", nBytesRead, buffer);
  • }
  • else
  • printf("Erreur lors de la réception.\r\n");
  • }
  • }while(nChoice != 3);
  • /* fermeture du port COM et retour */
  • CloseCOM();
  • return 0;
  • }
  • /******************************************************************************
  • OpenCOM : ouverture et configuration du port COM.
  • entrée : nId : Id du port COM à ouvrir.
  • retour : vrai si l'opération a réussi, faux sinon.
  • ******************************************************************************/
  • BOOL OpenCOM(int nId)
  • {
  • /* variables locales */
  • char szCOM[16];
  • /* construction du nom du port, tentative d'ouverture */
  • sprintf(szCOM, "COM%d", nId);
  • g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
  • OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
  • if(g_hCOM == INVALID_HANDLE_VALUE)
  • {
  • printf("Erreur lors de l'ouverture du port COM%d", nId);
  • return FALSE;
  • }
  • /* affectation taille des tampons d'émission et de réception */
  • SetupComm(g_hCOM, RX_SIZE, TX_SIZE);
  • /* configuration du port COM */
  • if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb))
  • {
  • printf("Erreur lors de la configuration du port COM%d", nId);
  • CloseHandle(g_hCOM);
  • return FALSE;
  • }
  • /* on vide les tampons d'émission et de réception, mise à 1 DTR */
  • PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
  • EscapeCommFunction(g_hCOM, SETDTR);
  • return TRUE;
  • }
  • /******************************************************************************
  • CloseCOM : fermeture du port COM.
  • retour : vrai si l'opération a réussi, faux sinon.
  • ******************************************************************************/
  • BOOL CloseCOM()
  • {
  • /* fermeture du port COM */
  • CloseHandle(g_hCOM);
  • return TRUE;
  • }
  • /******************************************************************************
  • ReadCOM : lecture de données sur le port COM.
  • entrée : buffer : buffer où mettre les données lues.
  • nBytesToRead : nombre max d'octets à lire.
  • pBytesRead : variable qui va recevoir le nombre d'octets lus.
  • retour : vrai si l'opération a réussi, faux sinon.
  • -------------------------------------------------------------------------------
  • Remarques : - la constante MAX_WAIT_READ utilisée dans la structure
  • COMMTIMEOUTS permet de limiter le temps d'attente si aucun
  • caractères n'est présent dans le tampon d'entrée.
  • - la fonction peut donc retourner vrai sans avoir lu de données.
  • ******************************************************************************/
  • BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead)
  • {
  • return ReadFile(g_hCOM, buffer, nBytesToRead, pBytesRead, NULL);
  • }
  • /******************************************************************************
  • WriteCOM : envoi de données sur le port COM.
  • entrée : buffer : buffer avec les données à envoyer.
  • nBytesToWrite : nombre d'octets à envoyer.
  • pBytesWritten : variable qui va recevoir le nombre d'octets
  • envoyés.
  • retour : vrai si l'opération a réussi, faux sinon.
  • ******************************************************************************/
  • BOOL WriteCOM(void* buffer, int nBytesToWrite, int* pBytesWritten)
  • {
  • /* écriture sur le port */
  • return WriteFile(g_hCOM, buffer, nBytesToWrite, pBytesWritten, NULL);
  • }
/******************************************************************************
  TestCOM.c :
  
   fonctions de base pour l'envoi et la réception de donner sur un port
   série RS232.
******************************************************************************/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

/*=============================================================================
  Définition de constantes
=============================================================================*/
#define RX_SIZE         4096    /* taille tampon d'entrée  */
#define TX_SIZE         4096    /* taille tampon de sortie */
#define MAX_WAIT_READ   5000    /* temps max d'attente pour lecture (en ms) */


/*=============================================================================
  Variables globales.
=============================================================================*/

/* Handle du port COM ouvert */
HANDLE g_hCOM = NULL;

/* Délais d'attente sur le port COM */
COMMTIMEOUTS g_cto =
{
    MAX_WAIT_READ,  /* ReadIntervalTimeOut          */
    0,              /* ReadTotalTimeOutMultiplier   */
    MAX_WAIT_READ,  /* ReadTotalTimeOutConstant     */
    0,              /* WriteTotalTimeOutMultiplier  */
    0               /* WriteTotalTimeOutConstant    */
};

/* Configuration du port COM */
DCB g_dcb =
{
    sizeof(DCB),        /* DCBlength            */
    9600,               /* BaudRate             */
    TRUE,               /* fBinary              */
    FALSE,              /* fParity              */
    FALSE,              /* fOutxCtsFlow         */
    FALSE,              /* fOutxDsrFlow         */
    DTR_CONTROL_ENABLE, /* fDtrControl          */
    FALSE,              /* fDsrSensitivity      */
    FALSE,              /* fTXContinueOnXoff    */
    FALSE,              /* fOutX                */
    FALSE,              /* fInX                 */
    FALSE,              /* fErrorChar           */
    FALSE,              /* fNull                */
    RTS_CONTROL_ENABLE, /* fRtsControl          */
    FALSE,              /* fAbortOnError        */
    0,                  /* fDummy2              */
    0,                  /* wReserved            */
    0x100,              /* XonLim               */
    0x100,              /* XoffLim              */
    8,                  /* ByteSize             */
    NOPARITY,           /* Parity               */
    ONESTOPBIT,         /* StopBits             */
    0x11,               /* XonChar              */
    0x13,               /* XoffChar             */
    '?',                /* ErrorChar            */
    0x1A,               /* EofChar              */
    0x10                /* EvtChar              */
};

/*=============================================================================
  Fonctions du module.
=============================================================================*/
BOOL OpenCOM    (int nId);
BOOL CloseCOM   ();
BOOL ReadCOM    (void* buffer, int nBytesToRead, int* pBytesRead);
BOOL WriteCOM   (void* buffer, int nBytesToWrite, int* pBytesWritten);

/******************************************************************************
  main : point d'entrée du programme.
******************************************************************************/
int main()
{
    /* variables locales */
    char buffer[256];
    int nId, nChoice, nBytesWritten, nBytesRead;

    /* demande du numéro du port COM */
    printf("Entrez le numero du port COM : ");
    scanf("%d", &nId);

    /* tentative d'ouverture */
    printf("Ouverture et configuration du port COM%d...\r\n", nId);
    if(!OpenCOM(nId)) return -1;
    printf("...OK\r\n");

    /* boucle tant que l'on ne quitte pas */
    do
    {
        /* menu */
        printf("\r\n");
        printf("1 : Envoyer des donnees.\r\n");
        printf("2 : Recevoir des donnees.\r\n");
        printf("3 : Quitter.\r\n");
        printf("Choix : ");
        scanf("%d", &nChoice);

        /* enoyer des données */
        if(nChoice == 1)
        {
            printf("\r\n");
            printf("Donnees a envoyer :\r\n");
            fflush(stdin);
            gets(buffer);
            printf("\r\n");
            printf("Envoi des donnees...\r\n");
            if(WriteCOM(buffer, strlen(buffer), &nBytesWritten))
                printf("%d octet(s) envoye(s).\r\n", nBytesWritten);
            else
                printf("Erreur lors de l'envoi.\r\n");
        }

        /* recevoir des données */
        if(nChoice == 2)
        {
            printf("\r\n");
            printf("Reception de donnees...\r\n");
            if(ReadCOM(buffer, sizeof(buffer)-1, &nBytesRead))
            {
                buffer[nBytesRead] = '\0';
                printf("%d octet(s) recu(s) :\r\n%s\r\n", nBytesRead, buffer);
            }
            else
                printf("Erreur lors de la réception.\r\n");
        }
    }while(nChoice != 3);

    /* fermeture du port COM et retour */
    CloseCOM();
    return 0;
}

/******************************************************************************
  OpenCOM : ouverture et configuration du port COM.
  entrée : nId : Id du port COM à ouvrir.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL OpenCOM(int nId)
{
    /* variables locales */
    char szCOM[16];

    /* construction du nom du port, tentative d'ouverture */
    sprintf(szCOM, "COM%d", nId);
    g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
    if(g_hCOM == INVALID_HANDLE_VALUE)
    {
        printf("Erreur lors de l'ouverture du port COM%d", nId);
        return FALSE;
    }

    /* affectation taille des tampons d'émission et de réception */
    SetupComm(g_hCOM, RX_SIZE, TX_SIZE);

    /* configuration du port COM */
    if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb))
    {
        printf("Erreur lors de la configuration du port COM%d", nId);
        CloseHandle(g_hCOM);
        return FALSE;
    }

    /* on vide les tampons d'émission et de réception, mise à 1 DTR */
    PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
    EscapeCommFunction(g_hCOM, SETDTR);
    return TRUE;
}

/******************************************************************************
  CloseCOM : fermeture du port COM.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL CloseCOM()
{
    /* fermeture du port COM */
    CloseHandle(g_hCOM);
    return TRUE;
}

/******************************************************************************
  ReadCOM : lecture de données sur le port COM.
  entrée : buffer       : buffer où mettre les données lues.
           nBytesToRead : nombre max d'octets à lire.
           pBytesRead   : variable qui va recevoir le nombre d'octets lus.
  retour : vrai si l'opération a réussi, faux sinon.
-------------------------------------------------------------------------------
  Remarques : - la constante MAX_WAIT_READ utilisée dans la structure
                COMMTIMEOUTS permet de limiter le temps d'attente si aucun
                caractères n'est présent dans le tampon d'entrée.
              - la fonction peut donc retourner vrai sans avoir lu de données.
******************************************************************************/
BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead)
{
    return ReadFile(g_hCOM, buffer, nBytesToRead, pBytesRead, NULL);
}

/******************************************************************************
  WriteCOM : envoi de données sur le port COM.
  entrée : buffer        : buffer avec les données à envoyer.
           nBytesToWrite : nombre d'octets à envoyer.
           pBytesWritten : variable qui va recevoir le nombre d'octets
                           envoyés.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL WriteCOM(void* buffer, int nBytesToWrite, int* pBytesWritten)
{
    /* écriture sur le port */
    return WriteFile(g_hCOM, buffer, nBytesToWrite, pBytesWritten, NULL);
}


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture SPLITTER API WIN32
Source avec Zip Source avec une capture UTILISATION DE LA LIB SHLWAPI.DLL (FONCTIONS DIVERSES SUR LE...
Source avec Zip Source avec une capture WIN32ACTIVEX : CONTENEUR DE CONTRÔLES ACTIVEX EN WIN32 (API ...
Source avec Zip Source avec une capture UTILISATION SPLITTER AVEC MFC
Source avec Zip Source avec une capture EXTRACTION DES ICONES DES EXÉCUTABLES (.EXE, .DLL), (VC++, W...

 Sources de la même categorie

Source avec Zip Source avec une capture CALENDRIER (WIN64) par BruNews
Source avec Zip Source avec une capture IMPRESSION EN WIN32 API AVEC OPTIONS par racpp
Source avec Zip Source avec une capture INFOTIP SHELL EXTENSION (BULLE DE L'EXPLORATEUR WINDOWS) (WI... par racpp
Source avec Zip Source avec une capture BROUILLAGE DES FICHIERS JAVASCRIPT ET CSS(WIN32) par gagah1
Source avec Zip Source avec une capture CHANGE CURSEUR par ganjarasta

Commentaires et avis

Commentaire de greglebreton le 12/05/2004 12:16:20

Hello Ymca,

j ai essaye d utiliser ton application en brachant a mon port serie un telephone mobile.
le but etant d'envoyer des commandes At au modem.
or ca ne fonctionne pas.
En fait les donnees sont bien bufferisee mais pas envoyee au telephone.
par contre lorsque j ouvre Procom (un utilitaire pour commandes AT), les donnees bufferisee sorte alors, comme si elle etait poussee par l ouverture de cette appli vers le mobile.

J attends, ton analyse, tes commentaires.

Merci

Commentaire de ymca2003 le 12/05/2004 13:10:36

Les commandes AT nécessitent un retour chariot (0x0D, 0x0A) que ce prog n'ajoute pas à la fin des données.

Mon autre prog sur le RS232, plus complet permet cet opération.

Vérifie également le taux de transfert.

Commentaire de toninlg le 18/05/2004 13:58:06

Hello YMCA ,

J'ai voulu tester le code que tu as fait mais je n'ai pas su le compiler. J'ai le compilateur Dev-C++ , il m'indique une conversion invalide de int* en DWORD* au niveau des fonctions ReadCOM et WriteCOM.
Tu utilises quel compilateur?

Merci.

Commentaire de ymca2003 le 18/05/2004 18:53:19

compilé avec VisualC++ 6.0

l'erreuer n'est pas grave, il suffit de faire un cast lors de l'appel :

ReadFile(g_hCOM, buffer, nBytesToRead, (LPDWORD) pBytesRead, NULL);

DWORD est un entier 32 bits non signé alors que int est un entier 32 bits signés. Les pointeurs sont donc compatibles mais selon les compilos et les niaveaux de warnings et erreurs ça passe pas tout seul.

Commentaire de johnbalaise le 06/07/2004 11:07:39

bonjour

jâi le meme pb avec int* en DWORD* et j'ai pas trop compris ta réponse. On fait comment ton cast ?
Merci

Commentaire de sebby_06200 le 06/07/2004 13:47:26

Bonjour ymca2003,
moi aussi j ai du mal avec devc++
c pour ca que je te dérange avec mon mail
j essaie de faire marcher le prog soit disant simple qui est en ligne sur le forum j avais la meme erreur que toi et je l ai résolu avec un cast
par contre j arrive pas à l'exécuter et comme j ai du mal à comprendre comment marche le prog j aimerais le voir marcher pour que ca m aide un peu

merci beaucoup d avance parce que je suis vraiment just au niveau du timing
au fait tu peux directement m ecrire a cette adresse: www.sebby@wanadoo.fr
merci et a+

Commentaire de ymca2003 le 07/07/2004 10:37:18

les 2 casts à faire sont :

return ReadFile(g_hCOM, buffer, nBytesToRead, (DWORD*)pBytesRead, NULL);

return WriteFile(g_hCOM, buffer, nBytesToWrite, (DWORD*)pBytesWritten, NULL);

Commentaire de sebby_06200 le 08/07/2004 15:48:21

bonjour
ce prog utilise les threads?
parce que je dois bloquer l'exec du prog tant quon n'a pas envoyé un octet
j ai essayé de placer dans le tableau buffer un caractère qui, tant qu'il n'est pas changé entraine un Sleep puis des qu'il change, l'exec continue (il est remplacé par le caractère correspondant à l'octet envoyé)
voici le prog
(je suis pas sur d'avoir absoluement tout compris, si des commentaires que j'ai rajouté sont faux n'hésitez pas à m'expliquer) merci beaucoup par avance

/*   fonctions de base pour l'envoi et la réception de donner sur un port    */
/*   série RS232.                                                            */
/*****************************************************************************/

#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;conio.h&gt;
/*Dos Specific functions in conio.h Not very portable as conio.h is NOT in the
ANSI standard library and does not appear on the Sun or Linux machines. */

/*=============================================================================
    Définition de constantes
=============================================================================*/
#define RX_SIZE      4096   /* taille tampon d'entrée   */
#define TX_SIZE      4096   /* taille tampon de sortie */
#define MAX_WAIT_READ    90   /* temps max d'attente pour lecture (en ms) */
/*On prend un temps de 90 ms car il faut à la centrale un retour qui intervient
avant 100 ms pour réaliser le café*/

/*paramètres de configuration du port série RS232 par défaut*/
#define BAUD 1200
#define NBBITS 8
#define BITSSTOP TWOSTOPBITS
#define PARITE EVENPARITY
/*différents types de parités: NOPARITY EVENPARITY(paire) ODDPARITY(impaire)*/
/*Rem: il y en a d'autres*/

/*=============================================================================
    Variables globales.
=============================================================================*/

/* Handle du port COM ouvert */
HANDLE g_hCOM = NULL;

/* Délais d'attente sur le port COM */
COMMTIMEOUTS g_cto =
{
    MAX_WAIT_READ,  /*  ReadIntervalTimeOut          */
    0,              /*  ReadTotalTimeOutMultiplier   */
    MAX_WAIT_READ,  /*  ReadTotalTimeOutConstant     */
    0,              /*  WriteTotalTimeOutMultiplier  */
    0               /*  WriteTotalTimeOutConstant    */
};

/* Configuration du port COM */
DCB g_dcb =
{
    sizeof(DCB),        /* DCBlength            */
    BAUD,               /* BaudRate             */
    TRUE,               /* fBinary              */
    FALSE,              /* fParity              */
    FALSE,              /* fOutxCtsFlow         */
    FALSE,              /* fOutxDsrFlow         */
    DTR_CONTROL_ENABLE, /* fDtrControl          */
    FALSE,              /* fDsrSensitivity      */
    FALSE,              /* fTXContinueOnXoff    */
    FALSE,              /* fOutX                */
    FALSE,              /* fInX                 */
    FALSE,              /* fErrorChar           */
    FALSE,              /* fNull                */
    RTS_CONTROL_ENABLE, /* fRtsControl          */
    FALSE,              /* fAbortOnError        */
    0,                  /* fDummy2              */
    0,                  /* wReserved            */
    0x100,              /* XonLim               */
    0x100,              /* XoffLim              */
    NBBITS,             /* ByteSize             */
    PARITE,             /* Parity               */
    BITSSTOP,           /* StopBits             */
    0x11,               /* XonChar              */
    0x13,               /* XoffChar             */
    '?',                /* ErrorChar            */
    0x1A,               /* EofChar              */
    0x10                /* EvtChar              */
};

/*=============================================================================
    Fonctions du module.
=============================================================================*/
BOOL OpenCOM    (int nId);
BOOL CloseCOM    ();
BOOL ReadCOM    (void* buffer, int nBytesToRead, int* pBytesRead);
BOOL WriteCOM    (void* buffer, int nBytesToWrite, int* pBytesWritten);

/******************************************************************************
    main : point d'entrée du programme.
******************************************************************************/
int main()
{
    /* variables locales */
    char buffer[2];
    int nId, nChoice, nBytesWritten, nBytesRead;

    /* demande du numéro du port COM */
    printf("Entrez le numero du port COM : ");
    scanf("%d", &nId);

    /* tentative d'ouverture */
    printf("Ouverture et configuration du port COM%d...\r\n", nId);
    if(!OpenCOM(nId)) return -1;
    printf("........OK\r\n");

    /* boucle tant que l'on ne quitte pas */
    do
    {
        /* menu */
        printf("\r\n");
        printf("1 : Envoyer des donnees.\r\n");
        printf("2 : Recevoir des donnees.\r\n");
        printf("3 : Dialoguer avec machine.\r\n");
        printf("4 : Quitter.\r\n");
        printf("Choix : ");
        scanf("%d", &nChoice);

        /* envoyer des données */
        if(nChoice == 1)
        {
            printf("\r\n");
            printf("Donnees a envoyer :\r\n");
            fflush(stdin);       /*write all buffered data for the given output*/
            gets(buffer);        /*get string from keyboard*/
            printf("\r\n");
            printf("Envoi des donnees...\r\n");
            if(WriteCOM(buffer, strlen(buffer), &nBytesWritten))
                printf("%d octet(s) envoye(s).\r\n", nBytesWritten);
            else
                printf("Erreur lors de l'envoi.\r\n");
        }

        /* recevoir des données */
        if(nChoice == 2)
        {
            printf("\r\n");
            printf("Reception de donnees...\r\n");
            /*On doit attendre que l'utilisateur appuie sur une touche*/
            buffer[0]='a';

            do
            {
               if(ReadCOM(buffer, sizeof(buffer)-1, &nBytesRead))
               {
                   buffer[nBytesRead] = '\0';
                   printf("%d octet(s) recu(s) :\r\n%s\r\n", nBytesRead, buffer);
               }
               else
               {
                   printf("Erreur lors de la reception.\r\n");
                   Sleep(100);
                }
             }while(buffer[0]=='a');
        }

        if(nChoice == 3)
        {
            printf("commander un cafe avec le boitier\r\n");
            if(ReadCOM(buffer, sizeof(buffer)-1, &nBytesRead))
            {
                buffer[nBytesRead] = '\0';
                printf("%d octet(s) recu(s) :\r\n%s\r\n", nBytesRead, buffer);
                printf("char qui a ete pris en compte: %c\n",buffer[0]);
            }
            else
                printf("Erreur lors de la reception.\r\n");

            if(WriteCOM(buffer, strlen(buffer), &nBytesWritten))
                printf("%d octet(s) envoye(s).\r\n", nBytesWritten);
            else
                printf("Erreur lors de l'envoi.\r\n");
        }
    }while(nChoice != 4);

    /* fermeture du port COM et retour */
    CloseCOM();
    return 0;
}

/******************************************************************************
    OpenCOM : ouverture et configuration du port COM.
    entrée : nId : Id du port COM à ouvrir.
    retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL OpenCOM(int nId)
{
    /* variables locales */
    char szCOM[16];  /*Pourquoi 16 ?*/

    /* construction du nom du port, tentative d'ouverture */
    sprintf(szCOM, "COM%d", nId);
    /*O/P data in the same way as 'printf' but put it into a string.*/
    g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
    /*permet de créer un fichier pour y écrire et y lire des données*/
    /*
    szCOM -&gt; ame of the file or other allowed object to create or open
    GENERIC_READ|GENERIC_WRITE -&gt; Allow the program to read/write data from the file or other object
    0 -&gt; security attributes (0 for Windows &gt; 95)
    OPEN_EXISTING -&gt; Open an existing file
    FILE_ATTRIBUTE-_SYSTEM -&gt; A system file, used exclusively by the operating system
    */

    if(g_hCOM == INVALID_HANDLE_VALUE)
    {
        printf("Erreur lors de l'ouverture du port COM%d", nId);
        return FALSE;
    }

    /* affectation taille des tampons d'émission et de réception */
    SetupComm(g_hCOM, RX_SIZE, TX_SIZE);

    /* configuration du port COM */
    if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb))
    {
        printf("Erreur lors de la configuration du port COM%d", nId);
        CloseHandle(g_hCOM);
        return FALSE;
    }

    /* on vide les tampons d'émission et de réception, mise à 1 DTR */
    PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
    EscapeCommFunction(g_hCOM, SETDTR);
    return TRUE;
}

/******************************************************************************
    CloseCOM : fermeture du port COM.
    retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL CloseCOM()
{
    /* fermeture du port COM */
    CloseHandle(g_hCOM);
    return TRUE;
}

/******************************************************************************
    ReadCOM : lecture de données sur le port COM.
    entrée : buffer      : buffer où mettre les données lues.
             nBytesToRead : nombre max d'octets à lire.
             pBytesRead  : variable qui va recevoir le nombre d'octets lus.
    retour : vrai si l'opération a réussi, faux sinon.
-------------------------------------------------------------------------------
    Remarques : - la constante MAX_WAIT_READ utilisée dans la structure
                COMMTIMEOUTS permet de limiter le temps d'attente si aucun
                caractères n'est présent dans le tampon d'entrée.
                - la fonction peut donc retourner vrai sans avoir lu de données.
******************************************************************************/
BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead)
{
    return ReadFile(g_hCOM, buffer, nBytesToRead, (LPDWORD)pBytesRead, NULL);
}

/******************************************************************************
    WriteCOM : envoi de données sur le port COM.
    entrée : buffer     : buffer avec les données à envoyer.
             nBytesToWrite : nombre d'octets à envoyer.
             pBytesWritten : variable qui va recevoir le nombre d'octets
                             envoyés.
    retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL WriteCOM(void* buffer, int nBytesToWrite, int* pBytesWritten)
{
    /* écriture sur le port */
    return WriteFile(g_hCOM, buffer, nBytesToWrite, (LPDWORD)pBytesWritten, NULL);
}

Commentaire de sebby_06200 le 08/07/2004 17:00:19

Autant pour moi
je viens de trouver grace a l aide de ymca2003 qui m avai envoyé un mail avec des explications en plus
désolé

Commentaire de Maxaks le 10/10/2004 13:06:41

Salut

J'ai un leger souci avec ton code, le truc c'est quà la récéption je n'arrive pas a afficher les données du buffer, je recois des octets mais je n'arrive pas a les afficher en gros

Il se peut aussi que ca viennent de la carte que j'ai branché au pc, mais je 'nai aucun moyen de verifier :(

Merci d'avance

Commentaire de ymca2003 le 10/10/2004 16:52:23

les octets reçus correspondent à des données binaires ou à des caractères ASCII ?
- 1 er cas : afficher le code hexa des octets dans une boucle.
- 2nd cas : ajouter un caractère nul à la fin et afficher comme une chaîne.

Commentaire de Maxaks le 11/10/2004 11:49:15

C'est du binaire apparement, j'ai alors remplacé le %s du printf() par %x pour afficher le buffer en hexa (c'est comme ca qu'on fait non ? ^^ )

du coup ca m'affiche des résultats plus ou moins louches :

Reception de donnees...
8 octet(s) recu(s) :
22fe78


Reception de donnees...
0 octet(s) recu(s) :
22fe78


:)

Commentaire de ymca2003 le 11/10/2004 18:28:57

il faut faure une boucle d'affichage :
for(int i = 0; i < nBytesRead; i++)
printf("%02X ", buffer[i]);

Commentaire de wajih_ml le 22/11/2004 14:39:21

salut ymca2003

comment utiliser ton program pour envoyer cette trame:
1 octet pour l'adresse
1 octet pour code fonction
n octet pour chanp de donnee
2 octet pour le crc16

exemple
01 03 152316 1296 (en hexadecimal)

merci d'avance

Commentaire de ymca2003 le 22/11/2004 14:45:47

BYTE addr = 0x1;
BYTE fct = 0x3;
BYTE data[] = "\x15\x23\x16";
int n = sizeof(data)/sizeof(data[0]);
WORD crc16 = 0x1296;

BYTE buffer[256];
buffer[0] = addr;
buffer[1] = fct;
memcpy(&buffer[2], data, n);
*((WORD*)(&buffer[2+n])) = crc16;

int BytesWritten;
WriteCOM(buffer, n+4, &BytesWritten)

Commentaire de wajih_ml le 24/11/2004 23:22:09

salut ymca2003

en fait j'ai un projet de fin d'etude qui consiste a communiquer
avec une centrale de mesure "recdigit POWER" via un adaptateur rs485/rs232
et cela suivant le protocole modbus/jbus
le probleme que le programme "TestCOM.c" ne marche po : il me renvoi les meme donnees que
j' ai deja transmi .
est ce que cette source marche avec une communication "pc/central de mesure" sous modbus?
as tu une solution ou eventuellement un code source qui peut marcher avec ce type de communication

exemple trame a envoyer:

05(n esclave)|03(n fonction)| 00  38(adresse 1er mot:2octet)|00 02(nombre de mot:2octet)|44 42 (crc:2octet)

       trame a recevoir(reponse):
05(n esclave)|03(n fonction)| 04(nb d'octet lus)|PFORT1 pfaibe1(valeur mot n1)|PFORT2 pfaibe2(valeur mot n1)|CRC - -


sinon j'ai pas bien compri cette portion du code:

BYTE buffer[256];
buffer[0] = addr;
buffer[1] = fct;
memcpy(&buffer[2], data, n);
*((WORD*)(&buffer[2+n])) = crc16;

int BytesWritten;
WriteCOM(buffer, n+4, &BytesWritten)

pouvez vous m'envoyer (dans le 4UM ou par e-mail) la place dans le programme principal
ou je peut introduir cette portion de code.

E-MAIL : wajih_ml@lycos.com

Mille merci ..

Commentaire de hxpicard le 13/01/2005 16:47:23

Salut, j'asseiller d'utiliser ton programme pour envoyer et recevoir des commandes d'un Omegabus D1131. mais ça ne marche pas. je suis pas un grand spécialiste de la communcation RS232 en C++. j'aimerais savoir si tu aurais une idée de comment modifier le soft pour le faire fonctionner avec mon convertisseur. Merci

email: hugo.picard@usherbrooke.ca

Commentaire de ymca2003 le 13/01/2005 16:54:00

Essaye avec Serial (dans mes sources), un prog plus complet qui permet de communiquer avec un appareil connecté au RS232 en tapant des commandes.

Sinon, vérifier les paramètres du port (vitesse en particulier)

Commentaire de hxpicard le 13/01/2005 17:47:00

Merci, ca fonctionne très bien avec ton programme Serial. En meme temps, il y a t'il un moyen facile de lui faire faire la meme commande a une meme intervalle de temps en d'enregistrer ces résultats dans un fichier? Si des fois tu peux me donner un petit coup de pouce pour faire ça je serais bien contant

merci

Commentaire de ymca2003 le 13/01/2005 18:01:05

Si ça marche avec serial, cela doit pouvoir marcher avec l'exemple de base.

Pour envoyer la commande à un intervalle de temps régulier il va falloir un timer.

en gros ce qu'il faut :
- avoir une variable global avec la commande à envoyer (un tableau de BYTE et une variable qui donne le nombre d'octets.
- ouvrir le port avec les bons paramètres (vitesse...)
- créer un Timer avec SetTimer et donner un pointeur sur une fonction TimerProc qui sera appelée régulièrement (pas besoin de fenêtre HWND).
- dans cette fonction, appeler WriteCom avec le buffer global de la commande.

pour la réponse il y a 2 possibilités :
- faire un thread qui s'occupera de lire tout ce qui est reçu sur le port et de le sauvegarder quelque part.
- appeler ReadCom juste après avoir envoyer la commande en paramétrant MAX_WAIT_READ pour attendre un délai max la réponse.

pour l'enregistement dans un fichier, il suffit d'écrire dedans les buffers (envoyés ou reçus.

Commentaire de loto le 23/02/2005 17:01:35

Yep!
J'ai un petit soucis avec ton programme. Lorsqu'on envoie les données on les recoit accompagnées de plein de chiffres qui reviennent. Je comprend pas trop ce qu'il se passe, j'envoie notre code pour voir si qqun arrive a trouver notre problème.
Pour info le programme nous servira à lire des nombres binaires qui sortent d'une carte de transmission fabriqués par nos soins.

Voila le code :


/******************************************************************************
  TestCOM.c :
  
   fonctions de base pour l'envoi et la réception de donner sur un port
   série RS232.
******************************************************************************/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>

/*=============================================================================
  Définition de constantes
=============================================================================*/
#define RX_SIZE         4096    /* taille tampon d'entrée  */
#define TX_SIZE         4096    /* taille tampon de sortie */
#define MAX_WAIT_READ   5000    /* temps max d'attente pour lecture (en ms) */


/*=============================================================================
  Variables globales.
=============================================================================*/

/* Handle du port COM ouvert */
HANDLE g_hCOM = NULL;

/* Délais d'attente sur le port COM */
COMMTIMEOUTS g_cto =
{
    MAX_WAIT_READ,  /* ReadIntervalTimeOut          */
    0,              /* ReadTotalTimeOutMultiplier   */
    MAX_WAIT_READ,  /* ReadTotalTimeOutConstant     */
    0,              /* WriteTotalTimeOutMultiplier  */
    0               /* WriteTotalTimeOutConstant    */
};

/* Configuration du port COM */
DCB g_dcb =
{
    sizeof(DCB),        /* DCBlength            */
    75,                 /* BaudRate             */
    TRUE,               /* fBinary              */
    FALSE,              /* fParity              */
    FALSE,              /* fOutxCtsFlow         */
    FALSE,              /* fOutxDsrFlow         */
    DTR_CONTROL_ENABLE, /* fDtrControl          */
    FALSE,              /* fDsrSensitivity      */
    FALSE,              /* fTXContinueOnXoff    */
    FALSE,              /* fOutX                */
    FALSE,              /* fInX                 */
    FALSE,              /* fErrorChar           */
    FALSE,              /* fNull                */
    RTS_CONTROL_ENABLE, /* fRtsControl          */
    FALSE,              /* fAbortOnError        */
    0,                  /* fDummy2              */
    0,                  /* wReserved            */
    0x100,              /* XonLim               */
    0x100,              /* XoffLim              */
    8,                  /* ByteSize             */
    NOPARITY,           /* Parity               */
    ONESTOPBIT,         /* StopBits             */
    0x11,               /* XonChar              */
    0x13,               /* XoffChar             */
    '?',                /* ErrorChar            */
    0x1A,               /* EofChar              */
    0x10                /* EvtChar              */
};

/*=============================================================================
  Fonctions du module.
=============================================================================*/
BOOL OpenCOM    (int nId);
BOOL CloseCOM   ();
BOOL ReadCOM    (void* buffer, int nBytesToRead, int* pBytesRead);
BOOL WriteCOM   (void* buffer, int nBytesToWrite, int* pBytesWritten);

/******************************************************************************
  main : point d'entrée du programme.
******************************************************************************/

int puissance (int i){
    int Tmp =1, n ;
        for (n=0; n<i; n++){
            Tmp = Tmp*2;
        }
        return Tmp;
}


        
      

int main()
{
    /* variables locales */
    int buffer[10];
    int Nb,a,i, nId, nChoice, nBytesWritten, nBytesRead;

    /* demande du numéro du port COM */
    printf("Entrez le numero du port COM : ");
    scanf("%d", &nId);

    /* tentative d'ouverture */
    printf("Ouverture et configuration du port COM%d...\r\n", nId);
    if(!OpenCOM(nId)) return -1;
    printf("...OK\r\n");

    /* boucle tant que l'on ne quitte pas */
    do
    {
        /* menu */
        printf("\r\n");
        
        printf("2 : Envoyer des donnees.\r\n");
        printf("3 : Recevoir des donnees.\r\n\n");
        printf("4 : Quitter.\r\n");
        printf("Choix : ");
        scanf("%d", &nChoice);

        
        /* envoyer des données */
        if(nChoice == 2)
        {
            printf("\r\n");
            printf("Donnees a envoyer :\r\n");
            fflush(stdin);
            scanf("%d",&buffer);
            printf("\r\n");
            printf("Envoi des donnees...\r\n");
            if(WriteCOM(buffer, 10, &nBytesWritten)) {
                WriteCOM(buffer, 10, &nBytesWritten);
                printf("%d octet(s) envoye(s).\r\n", nBytesWritten);
            }
            else
                printf("Erreur lors de l'envoi.\r\n");
            
        }
        
        
        /* recevoir des données */
        if(nChoice == 3)
        {
            printf("\r\n");
            printf("Reception de donnees...\r\n");
            if(ReadCOM(buffer, 10, &nBytesRead))
            {
                //buffer[nBytesRead] = '\0';
                //printf("le nombre est %d \r\n", buffer);
                //for(int i = 0; i < nBytesRead; i++)
                for(int i = 0; i < 10; i++)
                                printf("%d", buffer[i]);
            }
            else
                printf("Erreur lors de la réception.\r\n");
        }
    }while(nChoice != 4);

    /* fermeture du port COM et retour */
    CloseCOM();
    return 0;
}

/******************************************************************************
  OpenCOM : ouverture et configuration du port COM.
  entrée : nId : Id du port COM à ouvrir.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL OpenCOM(int nId)
{
    /* variables locales */
    char szCOM[16];

    /* construction du nom du port, tentative d'ouverture */
    sprintf(szCOM, "COM%d", nId);
    g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
    if(g_hCOM == INVALID_HANDLE_VALUE)
    {
        printf("Erreur lors de l'ouverture du port COM%d", nId);
        return FALSE;
    }

    /* affectation taille des tampons d'émission et de réception */
    SetupComm(g_hCOM, RX_SIZE, TX_SIZE);

    /* configuration du port COM */
    if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb))
    {
        printf("Erreur lors de la configuration du port COM%d", nId);
        CloseHandle(g_hCOM);
        return FALSE;
    }

    /* on vide les tampons d'émission et de réception, mise à 1 DTR */
    PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
    EscapeCommFunction(g_hCOM, SETDTR);
    return TRUE;
}

/******************************************************************************
  CloseCOM : fermeture du port COM.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL CloseCOM()
{
    /* fermeture du port COM */
    CloseHandle(g_hCOM);
    return TRUE;
}

/******************************************************************************
  ReadCOM : lecture de données sur le port COM.
  entrée : buffer       : buffer où mettre les données lues.
           nBytesToRead : nombre max d'octets à lire.
           pBytesRead   : variable qui va recevoir le nombre d'octets lus.
  retour : vrai si l'opération a réussi, faux sinon.
-------------------------------------------------------------------------------
  Remarques : - la constante MAX_WAIT_READ utilisée dans la structure
                COMMTIMEOUTS permet de limiter le temps d'attente si aucun
                caractères n'est présent dans le tampon d'entrée.
              - la fonction peut donc retourner vrai sans avoir lu de données.
******************************************************************************/
BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead)
{
    return ReadFile(g_hCOM, buffer, nBytesToRead, (DWORD*)pBytesRead, NULL);
}

/******************************************************************************
  WriteCOM : envoi de données sur le port COM.
  entrée : buffer        : buffer avec les données à envoyer.
           nBytesToWrite : nombre d'octets à envoyer.
           pBytesWritten : variable qui va recevoir le nombre d'octets
                           envoyés.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL WriteCOM(void* buffer, int nBytesToWrite, int* pBytesWritten)
{
    /* écriture sur le port */
    return WriteFile(g_hCOM, buffer, nBytesToWrite, (DWORD*)pBytesWritten, NULL);
}

Commentaire de pirana le 12/04/2005 10:22:51

Bonjour ymca2003, merci pour ce super code ...
Je suis relativement débutant dans le domaine de la programmation

J'essaye d'envoyé la trame suivante:

1 octet de prise de controle (du PIC que je voudrais commander) : 13

attente de 50 ms

1 octet de réponse : OK : 06

comparer l'octet recu

émission du 2048 octets

avec 0.5ms d'attente apres chaques octets envoyés.


Et recevoir la trame suivante:

1 octet de controle 13

reception de 2048 octets découpés par mot de 8octets et stocké dans un tableau

1 octet de fin


Merci Andr0

Commentaire de novice54 le 09/06/2005 14:27:06

Salut YMCA2003,
j'essaie d'utiliser ton programme car je dois faire communiquer le PC avec un régulateur de four mais j'ai un problème de compilation au niveau de ReadCOM et WriteCOM: ça me met
"invalid conversion from int* to 'DWORD*'
Je t'avoue que je n'y comprends rien. J'ai essayé sous VC++ et devC++ et ça me met la même erreur.
Merci de m'aider

Commentaire de ymca2003 le 09/06/2005 15:42:34

Comme un peu plus haut dans les réponses, il y A 2 casts à faire
les 2 casts à faire sont :

return ReadFile(g_hCOM, buffer, nBytesToRead, (DWORD*)pBytesRead, NULL);

return WriteFile(g_hCOM, buffer, nBytesToWrite, (DWORD*)pBytesWritten, NULL);

Commentaire de rakma le 13/06/2005 23:39:42

ymca2003,

Je tiens à te remercier pour ton code source, je l'utilise pour une communication entre mon PC et un micro controlleur. Je t'ai d'ailleurs mis dans ma page des remerciements dans un de mes sites Internet.
J'aurais une petite question à te poser. Est il possible avec ce code source de connaitre le nombre d'octets qui sont dans le buffer de lecture, prêt à être lu?
Merci d'avance.
Séphane(Rakma).

Commentaire de ymca2003 le 14/06/2005 08:58:37

Pour savoir le nombre d'octets prêt à lire :
COMSTAT cs = {0};
DWORD dwErrors;
ClearCommError(hCom, &dwErrors, &cs);

=> cs.cbInQue contient le nombre d'octets pret à lire.
=> permet de lire directement le bon nombre.

Commentaire de rakma le 15/06/2005 09:26:16

YMCA2003,
Merci pour ta réponse si rapide !!!!!
Je suis désolé, je vais encore t'embeter une fois. Ce n 'est pas de ma faute :)), c'est Dev-C++ qui est suceptible ;)

Pour la ligne concernant " ClearCommError(hCom, &dwErrors, &cs); "
Il me met :

81 expected constructor, destructor, or type conversion before '(' token
81 expected `,' or `;' before '(' token

Tu aurais une idée d'ou cela peut venir ??
Merci d'avance !!
Rakma

Commentaire de ymca2003 le 15/06/2005 09:35:51

Alors là je vois pas trop. Il y a peu-être un ; manquant à la ligne d'avant ou le nom d'une variable qui n'est pas correct (ceux que j'ai mis sont des exemples genre hCom).

Si tu mettait un peu de code au dessus et en dessous de cette ligne je pourrais peu-être d'aider.

Commentaire de rakma le 15/06/2005 10:05:18

J'ai trop honte, je crois que j'ai touché le fond :)
En fait j'avais collé cet extrait à l'exterieur du main, c'est sur que à l'interieur, ca marche tout de suite mieux !!!
En suite j'ai changé le hCom en g_hCOM pour pouvoir l'utiliser avec ton code, ca marche super bien !!!
Merci beaucoup pour ton aide YMCA2003, j'avais vraiment besoin de connaitre le nb d'octets dans le buffer de lecture ...
Bon courage pour la Suite !
Rakma

Commentaire de zizo1 le 18/07/2005 14:17:17

Merci Nix,Pour votre aide.
Est ce que qq'un peut m'aider à savoir la nomenclature des broches d'un port COM/paralléle.

zizo1...?

Commentaire de misterzinzin le 09/09/2005 21:05:51

http://www.cppfrance.com/code.aspx?ID=33724

j'ai fait une version c++ (dans une classe) merci pour ton aide ymca...

ps: j'ai ajoute 2 ou 3 modif que j'ai trouvé dans ces commentaire et dans d'autre sources...

souyez indulgent... j'ai fait cette classe en une soiree en face de star academy...

Commentaire de nitrique le 14/10/2005 09:30:18

Bonjour et merci pour ce code Bien pratique.
Seulement, pour mon cas, il y a des choses qui ne vont pas:

Je doit me connecter sur un port virtuel (Port USB qui simule un port COM) et ça ne fonctionne pas, il ne peut pas se connecter:
    g_hCOM = CreateFile(szCOM,GENERIC_READ |GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,NULL); // Plante
J'ai donc essayé de changer qq paramètres:
    g_hCOM = CreateFile(szCOM,GENERIC_READ,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_READONLY,0);
Car je n'ai besoin que de lire sur ce port, mais sans grands résultats.

Commentaire de nitrique le 14/10/2005 09:42:09

En fait, j'ai trouvé (Grace à la source de misterzinzin)

J'ai fait:
sprintf(szCOM, "\\\\.\\COM%d", nId); // Modifie pour prendre les port com>9
et FILE_ATTRIBUTE_READONLY dans CreateFile();

Et ca marche !

Commentaire de misterzinzin le 15/10/2005 21:01:38

heureuxque ma source t'ai servi a qq chose nitrique.

cependant je dois relancer cet honneur un niveau plus haut car je n'ai fait qu'englober ces ligne de code dans une classe. toute les source viennent de ce site... enfin je pense

Commentaire de dbiare le 06/12/2005 17:13:23

J’ai perdu une semaine de développement à cause de la gestion des ports qui est différente sous XP par rapport à 98 et c’est ce source qui m’a sauvé !
Il est trop TOP !!!  Trop top parce que efficace et très simple donc facilement implantable dans une application perso

Commentaire de dushit le 10/01/2006 18:59:34

on fai comment pour envoyer en hexa depuis la console
faut modofier koi dans le code??
merci bcp
dushit

Commentaire de ymca2003 le 12/01/2006 05:24:40

donnnées à écrire en hexa et majuscule,
ex :
01AB42BEF4

/* envoyer des données */
if(nChoice == 1)
{
  unsigned char tmp[256];
  int i, len;

  printf("\r\n");
  printf("Donnees a envoyer :\r\n");
  fflush(stdin);
  gets(buffer);
  printf("\r\n");
  printf("Envoi des donnees...\r\n");

  len = strlen(buffer);
  for(i = 0; i < len/2; i++)
  {
    tmp[i] = (buffer[2*i] <= '9') ? buffer[2*i]-'0' : buffer[2*i]-'A'+10;
    tmp[i] = (tmp[i]<<8) | ((buffer[2*i+1] <= '9') ? buffer[2*i+1]-'0' : buffer[2*i+1]-'A'+10);
  }

  if(WriteCOM(tmp, len/2, &nBytesWritten))
    printf("%d octet(s) envoye(s).\r\n", nBytesWritten);
  else
    printf("Erreur lors de l'envoi.\r\n");
}

Commentaire de dushit le 17/01/2006 14:05:20

bonjour,
je voulais savoir comment on peut faire pour recuperer les donnees recu (elle sont binaire normalement??) puis les ecrire dans un fichier. C'est pour recupere une photo prise par une camera brancher sur le port serie et qui se commande avec des trames hexa.

Merci
dushit

Commentaire de ymca2003 le 17/01/2006 15:49:15

BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead)
{
    DWORD dw;
    BOOL res = ReadFile(g_hCOM, buffer, nBytesToRead, (LPDWORD)pBytesRead, NULL);

    WriteFile(hFile, buffer, *pBytesRead, &dw, NULL);

    return res;
}

hFile étant le fichier de destination tu peux également utiliser fwrite.
les données étant dans buffer et de longueur *pBytesRead

Commentaire de dushit le 17/01/2006 17:55:04

Merci de repondre aussi vite , c'est tres gentil.
j'ai une petite erreur en compilant , pour declarer le fichier c'est FILE* hfile?? je sais plus trop.
de plus , mon fichier etant un .jpg  , je doit faire comment pour le sauvergarder en .jpg.
(l'erreur c'est: error C2065: 'hFile' : undeclared identifier).
Merci beaucoup
dushit

Commentaire de dushit le 17/01/2006 17:55:54

Merci de repondre aussi vite , c'est tres gentil.
j'ai une petite erreur en compilant , pour declarer le fichier c'est FILE* hfile?? je sais plus trop.
de plus , mon fichier etant un .jpg  , je doit faire comment pour le sauvergarder en .jpg.
(l'erreur c'est: error C2065: 'hFile' : undeclared identifier).
Merci beaucoup
dushit

Commentaire de ymca2003 le 17/01/2006 18:22:41

le hFile est un HANDLE ouvert par CreateFile
tu peux utiliser FILE* f avec fopen et fwrite

Commentaire de dushit le 17/01/2006 18:39:55

mai qd je compile readCom ca me met cette erreur : error C2065: 'hFile' : undeclared identifier dc je voi pa comment faire.
desole de te saouler avec ca , mai je suis vraiment nul en programmation...
Merci bcp en tous cas!

Commentaire de ymca2003 le 17/01/2006 19:08:07

HANDLE hFile = CreateFile("toto.jpg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
WriteFile(hFile, buffer, *pBytesRead, &dw, NULL);
CloseHandle(hFile);

ou

FILE* f = fopen("toto.jpg", "wb");
fwrite(buffer, 1, *pBytesRead, f);
fclose(f);

l'ouverture doit se faire au début du prog;
la fermeture à la fin;
l'écriture dans la fct de lecture

Commentaire de dushit le 07/02/2006 15:50:25

salut,
je voulais savoir comment faire pour envoyer des trames en hexa mais coder en "dur".
car je dois envoyer une trame de conf puis recevoir la ack, puis reenvoyer une trames pour prendre la photo et enfin recevoir les bits qui constitue la photo.
tout cela doit etre dans 1 seul menu ( jai rajouter en 0 : envoie/recoie).
je pensai a une writecom(), readcom() ou il faut afficher le ack sur la console, un writecom() puis la fonction readcom() avec la creation du fichier jpeg.
Mais dans writecom() je mai quoi en parametre pour coder en "dur" et en hexa?
Merci d'avance de ton aide.
Dushit

Commentaire de ymca2003 le 07/02/2006 17:00:39

déclare :
char trame [] = "\xf7\xe5\x35";
pour 0xf7, 0xe5, 0x35

Commentaire de dushit le 07/02/2006 18:02:29

par exemple, si je veut envoyer AA0105000000 en dur je code ca comment?
et pour afficher le ack sur la console?
dans:

BOOL WriteCOM(void* buffer, int nBytesToWrite, int* pBytesWritten)
{
    /* écriture sur le port */
    return WriteFile(g_hCOM, buffer, nBytesToWrite, (DWORD*)pBytesWritten, NULL);
}

je modifie koi?
car c le buffer qui est ecrit? donc il faut que j'initialise le buffer avec mon code hexa??
Merci

Commentaire de ymca2003 le 07/02/2006 19:14:05

char buffer [] = "\xAA\x01\x05\x00\x00\x00";
int nb;
WriteCOM(buffer, 6, &nb);

Commentaire de dushit le 07/02/2006 20:40:06

jai fai ca mai jai une erreur que jarrive pa a voir!!


if(nChoice == 0)
{
//envoi init
char buffer [] = "\xAA\x01\x00\x07\x07\x07";
int nb;
WriteCOM(buffer, 6, &nb);
//recoi ack
if(ReadCOM(buffer, sizeof(buffer)-1, &nBytesRead))
            {
                buffer[nBytesRead] = '\0';
                printf("%d octet(s) recu(s) :\r\n%s\r\n", nBytesRead, buffer);
            }
            else
{
                printf("Erreur lors de la réception.\r\n");
}
//envoi getpicture ERREUR ICI: error C2143: syntax error : missing ';'

                         //before 'type'
char buffer [] = "\xAA\x04\x05\x00\x00\x00";
WriteCOM(buffer, 6, &nb);
//recup image
if(ReadCOM(buffer, sizeof(buffer)-1, &nBytesRead))
            {
                buffer[nBytesRead] = '\0';
                printf("%d octet(s) recu(s) :\r\n%s\r\n", nBytesRead, buffer);
            }
            else
{
                printf("Erreur lors de la réception.\r\n");
}

sinon est ce que le int nb c le mm, je le declare une seul fois??

Commentaire de ymca2003 le 08/02/2006 08:54:59

buffer est déclarer 2 fois.
Pour en utiliser 2 différents, il faut leur donner des noms différents.
De plus, en C les déclarations de variables doivent être en début de bloc.

Commentaire de dushit le 08/02/2006 13:03:06

est ce que je peu faire ca:
WriteCOM("\xAA\x01\x05\x00\x00\x00", 6, &nb);
il  fau passer par char buffer[]??
Merci
}

Commentaire de dushit le 08/02/2006 13:04:58

est ce que lon peu faire ca
WriteCOM("\xAA\x01\x05\x00\x00\x00", 6, &nb);
ou fau passr par char buffer[]
Merci }

Commentaire de ymca2003 le 08/02/2006 19:20:34

oui c'est possible.

Commentaire de dushit le 14/02/2006 13:39:35

salut,
je voulais savoir comment en fesait pour transormer les donnee recu en hexa en binaire car la photo doit "etre remplie de donnee binaire" .
Merci d'avance
dushit

Commentaire de BassoV13 le 04/03/2006 00:35:08

salut, je viens de tester ton source et j'ai un pti soucis :
Je communique avec un GPS et par exemple je lui envoie la commande AT+LOCIDT? et lui doit me renvoyer ceci -> +LOCIDT: "354475000033841"

J'envoie donc la commande avec l'option 1 mais rien ne s'affiche en retour avec l'option 2. En mode debug je vois que dans buffer il y a juste ma commande AT+LOCIDT? mais pas la reponse.
D'ou cela peut-il venir ?
Merci par avance

Commentaire de KaYaStar le 09/03/2006 13:15:02

Et sous linux, personne ne sait comment on fait?
Svp
car je dois récupere les données d'une centrale météo via la liaison rs 232, mais pas moyen !
Merci de votre aide

Commentaire de yous1981 le 03/05/2006 10:20:39

salut tout le monde,
j'ai un souci avec le programme de YMCA2003,j'arrive pas à lire mes données sur le port par contre j'arrive à ecrire,en fait, avant de connecter mon pc à un modem via RS232 ,je veux verifier au debut que le port  fonctionne comme il faut,je transmets la trame des donnees par un pc et j'essaye de la recevoir par un autre,le probleme c'est que le programme  m'affiche" 0 octet recu" jai verifier avec un oscillo que le signal est bien present à l'entrée du port du pc recepteur.Je vous attends messieurs les programmeur si vous avez des solutions à me proposer.

Commentaire de rin01 le 19/07/2006 10:37:32

Bonjour,
Merci pour ce code qui m'a bien aidé.
J'aimerai savoir quel est le type de données reçues?
dans la déclaration il y a un "void *buffer" et si on souhaite récupérer les données sous forme d'entier ou hexa, est-ce que  quelqu'un sait comment faire svp?

Commentaire de ThibB le 25/07/2006 16:07:25

J'ai un peu la même question que toi Rin01, c'est à dire que je n'arrive pas vraiment à traiter les données que je recoit ...
Je suis parti de ce code pour créer un programme permettant de communiquer avec un GPS Bluetooth, et je voudrais à chaque paquet que je recoit vérifier qu'il est un format de trame correct.

Théoriquement ceci :
ReadCOM(buffer, 9, &nBytesRead);
printf("buf[0] : %.2X - buf[1] : %.2X\n",buffer[0],buffer[1]);

Devrait afficher cela (je verifie les données recu à l'aider d'un sniffer):
buf[0] : AA - buf[1] : 55

Mais ca affiche quelque chose comme (change à chaque execution, la reponse est pourtant toujours la même) :
buf[0] : F1 - buf[1] : AF

Est ce quelqu'un aurait une explication ? Merci ;)

Commentaire de yous1981 le 26/07/2006 17:58:52

Il faut déclarer buf en tant que unsigned char:  unsigned char buf[tail_buf].
bon courage.

Commentaire de tiluz le 06/09/2006 12:06:18

Comment faire pour ajouter un "linefeed" après les caractères envoyé.

QQ1 Peut m'aider??????????????????????

Commentaire de yous1981 le 06/09/2006 16:41:39

cest quoi "linefeed"?????????????????

Commentaire de BassoV13 le 06/09/2006 17:14:30

merci pour tout maintenant ca marche ...

Commentaire de tiluz le 07/09/2006 13:29:31

Linefeed (LF) est un caractère saut de ligne (ascii)
retourné lorsque l'on presse ENTER.

Commentaire de yous1981 le 07/09/2006 14:54:11

tu ajoute "/n/r" au message  soit directement soit par la fonction strcat

Commentaire de tiluz le 07/09/2006 15:30:10

En fait j'aimerais le faire directement dans la fenêtre de commande pour que le saut de ligne soit envoyé à la fin du message par le port série jusqu au recepteur

Commentaire de tiluz le 07/09/2006 15:35:20

Par exemple lorque j'envoie une chaîne de caractère avec labview dans la fenêtre d'ecriture je tape ENTER ä la fin de mon message, et quand je l'envoie au récepteur (robot)celui ci comprend qu il sgit d'une instruction. Sans ce saut de ligne après la chaîne de caractères le robot recoit le message mais n'agit pas.

Commentaire de BruNews le 07/09/2006 15:36:00 administrateur CS

A l'endroit sera aussi bien: "\r\n"

Commentaire de tiluz le 07/09/2006 16:13:17

Je dois le taper dans la fen^tre de commande après les caractère que j'envoie ou modifier le code???????????

Commentaire de BruNews le 07/09/2006 16:34:20 administrateur CS

Aucune idée de ton prog mais je ferais ainsi:

Edit d'envoi sous classé pour intercepter le ENTER clavier et que le retour charrit ne s'insère pas.
Dans editProc quand tu interceptes ENTER:
char *psz;
int len;
len = GetWindowTextLenght(hedit);
psz = (char*) malloc(len + 3);
GetWindowText(hedit, psz, len + 1);
psz[len] = '\r'; psz[len+1] = '\n'; psz[len+2] = 0;
JappelleMaFuncDenvoi(psz, len + 2);
free(psz);
SetWindowText(hedit, 0); // VIDANGE LE TEXTE
return 0;

Commentaire de tiluz le 07/09/2006 16:40:59

mon prog est celui du haut de la pagge (TESTcom.c)

Commentaire de yous1981 le 07/09/2006 17:02:07

cest ce que jutilise pour envoyer des commande vers des modem de transmission de données et ca marche nikel:
WriteCOM("commande\r\n", strlen("commande\r\n"), &nBytesWritten);

Commentaire de arb le 20/09/2006 14:06:23

Salut

Super ce bout de code. Je communique avec un microcontrolleur sur une carte externe. J'ai juste un souci à 115200 pour la vitesse. 57600 ça passe, mais pas plus haut !!!
Pourtant je n'ai pas de soucis côté carte car j'ai un logiciel en Visual Basic qui communique à 115200.
Par contre je n'utilise aucun control de flux, peut être faut il faire des modifs dans l'init de la structure DCB. j'envoie 129 octets à 115200 pour info.
Merci de votre aide, ou de pistes pour m'aiguiller car je suis sec !!!!

Commentaire de moniteur le 22/09/2006 23:50:41

Merci pour cette petite source.
Elle nécessite quelques modifications pour être utilisable mais elle pose les bases et le minimum vital à savoir sans code superflue.

Commentaire de clipper le 22/11/2006 16:27:52

Bonjour,

J'ai moi aussi un souci d'utilisation de ce code
J'ai un modem GSM auquel j'envois une commande AT+CSQ
et j'attends une réponse du style +CSQ : 31,0.
J'envois ma commande par l'option 1,
mais il me retourne ma commande.

Pour info quand je suis en réception je reçois des éléments
à la mise sous tension du modem.

Merci pour les explications à venir.

:-)

Commentaire de yous1981 le 23/11/2006 01:55:26

bonjour
jai deja adapter ce code pour envoyer des sms par un modem GSM/GPRS et samarchait nikel tu me laisse ton mail je te lenvoye dans les jours ki viennent
bon courage

Commentaire de arb le 23/11/2006 08:30:51

Salut

Super ce bout de code. Je communique avec un microcontrolleur sur une carte externe. J'ai juste un souci à 115200 pour la vitesse. 57600 ça passe, mais pas plus haut !!!
Pourtant je n'ai pas de soucis côté carte car j'ai un logiciel en Visual Basic qui communique à 115200.
Par contre je n'utilise aucun control de flux, peut être faut il faire des modifs dans l'init de la structure DCB. j'envoie 129 octets à 115200 pour info.
Merci de votre aide, ou de pistes pour m'aiguiller car je suis sec !!!!

Commentaire de _Syl_ le 07/12/2006 15:44:39

Top !

Commentaire de skraati le 06/01/2007 06:17:12

bonjour,
J'ai utilisé un logiciel pour communiquer avec une balance et ça a marché(il y a un cable qui relie le pc et la balance).Maintenant,je dois les relier par modem de type "OLITEC self memory 33600" et la communication entre la balance et le pc ne passe pas.
Quelqu'un peut-il m'aider pour ça?
merci.

Commentaire de victorcoasne le 06/03/2007 16:36:43

Bravo je met 10/10 ce qui te fait passe de 9.67 à 9.71 !
Super Source et encore bravo !

Commentaire de Gy0m le 16/04/2007 09:51:40

Bonjour

Je vien de tester ton programme, avec les port COM1 et COM2 ca marche nikel, mais je souhaite communiquer avec le port COM13 mais il n'arrive pas a ouvrir le port COM13...

Si quelqu'un sait d'ou cela peut venir, je suis prenneur!!!!

++

Commentaire de victorcoasne le 16/04/2007 22:34:30

Tout dépend à quoi te sert le COM13..

Commentaire de Gy0m le 17/04/2007 10:46:19

J'y ai branché un téléphone mobile, c'est un port USB en fait.

Commentaire de victorcoasne le 17/04/2007 19:44:48

Le port COM doit demandé a être ouvert par le téléphone via une application JAVA.

Commentaire de charifsba3i le 31/05/2007 20:30:56

Bonjour,
Merci pour ce code

je voulais savoir comment on peut faire pour transmitre un fichier texte qui existe sur mon disque vers un autre pc  
j’ai essayé modifier ce code pour réaliser cette fonction mais j’ai pas réussi.

Merci de m'aider.

Commentaire de misterzinzin le 10/06/2007 09:12:18

tu devrai plutot utiliser tcp/ip avec les sockets.
en cherchant un peut tu devrai trouver facilement et en plus tu pourrais même transmettre tes fichier a travers internet...

sinon pour le port série, fait gaffe que chaque pc doit avoir la même configuration du port (vitesse, parité, nombre de bit d'arrêt, contrôle de flux)
et aussi que le cable doit être croisé.
un bon moyen pour tester la liaison est d'utiliser hyper terminal sur les 2 pc sur le port com 1 (ou autre en fonction du pc) et de taper du texte pour voir s'il apparait sur l'autre écran ;-)

et pour avoir de l'aide sur ton programme tu devrai peut etre le mettre sur ce site... parce que "mon programme ne marche pas, merci de m'aider" ca n'est pas très parlant ;-)

Commentaire de taras67 le 11/06/2007 10:42:02

Salut!
J'ai un petit souci, j'aimerais envoyé automatiquement des instructions via le RS232. J'ai utilisé ta fonction "writeCOM" pour envoyer le buffer suivant (l'instruction que je dois envoyé est "ldd:?" suivi d'un retour chariot:

char buffer[256];
buffer[0]='l';
buffer[1]='d';
buffer[2]='d';
buffer[3]=':';
buffer[4]='?';
buffer[5]='/n';
buffer[6]='/0';
Ensuite j'envoie le buffer en utilisant writeCOM. Enfin, je fais un readCOM pour récupérer la réponse de mon bidule branché sur le port série. Apparemment tout se passe bien puisque chaque fonction me renvoie des "true" mais le buffer renvoyé par readCOM est vide...

J'ai un autre problème (qui pourrait expliqué le premier), mes fonctions writefile et readfile renvoie des "int" et non des booléens. J'ai fait les modifs adéquates pour que sa compile correctement mais du coup, je suis pas sûr que ces fonctions fassent le bon boulot... Je suis un peu perdu là donc si quelqu'un pouvait m'aider...
Merci d'avance,

Commentaire de taras67 le 11/06/2007 11:18:30

Bon je suis désolé d'avoir posé ma question "idiote"... En fait... J'ai honte de le dire mais je vais pas laisser chercher quelqu'un sur ce problème alors que la raison de ce problème est simple: j'avais oublié de brancher le cable... la loose. Donc en fait, il reste juste la deuxime question (qui n'empeche pas le prog de fonctionner): Pourquoi mes fonctions writefile et readfile renvoient des "int" alors qu'elles sont sensées renvoyer des "bool". je sais pas si ça peut aider mais j'utilise VC++ et winXP.
Encore désolé pour le msg précédent :p

Commentaire de misterzinzin le 12/06/2007 10:47:04

comment peut tu dire que tes fonction renvois des int et pas des bool ? sinon généralement, une fonction (en C) renvois un entier pour signaler si tout c'est bien passé. de plus, en principe il est impossible de renvoyer un bool et on renvois généralement un int (on pourrais mettre un byte mais bon...)

Commentaire de taras67 le 12/06/2007 11:01:47

Merci pour ta réponse. En fait, d'après les fonctions WriteCom & ReadCom que j'ai trouvé sur cette page, les fonctions writefile et readfile sont sensées retourné des "bool" non? Je déduis ça du fait que les fonctions WriteCom & ReadCom sont du genre:

bool WriteCom(...){
return WriteFile(...);
}

En même temps, je suis vraiment un novice en C, donc je me trompe certainement.
Mais quand j'essaye de me servir de ces fonctions, j'ai une erreur de compilation qui me dit que les fonctions writefile et readfile renvoient des "int" et que la conversion int->bool pose problème. le compilateur précise que :

int__cdecl WriteFile(...)

Commentaire de misterzinzin le 13/06/2007 23:19:33

bool est surement une déclaration qu'il te manque qq part... met des int a la place ;-)

Commentaire de ncir le 14/06/2007 13:53:28

Bonjour
Merci pour cette source, c'est une geste de noblesse.
Je viens de tester ton source et j'ai un pti soucis :
je communique avec un détecteur de métal en utilisant un microcontroleur via port série RS232 et je besoin uniquement du l'étape de reception des données (c.a.d présence ou absence de métal). J'ai essayé avec ton source il m'indique toujours c ci:
Reception des donnees...
0 octet(s) reçue(s):
1244800
svp j'ai un travail urgent et merci d'avance

Commentaire de ncir le 14/06/2007 16:33:53

En fait, j'ai utilisé ce code.





/******************************************************************************
  TestCOM.c :
  
   fonctions de base pour l'envoi et la réception de donner sur un port
   série RS232.
******************************************************************************/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

/*=============================================================================
  Définition de constantes
=============================================================================*/
#define RX_SIZE         4096    /* taille tampon d'entrée  */
#define TX_SIZE         4096    /* taille tampon de sortie */
#define MAX_WAIT_READ   1000    /* temps max d'attente pour lecture (en ms) */


/*=============================================================================
  Variables globales.
=============================================================================*/

/* Handle du port COM ouvert */
HANDLE g_hCOM = NULL;

/* Délais d'attente sur le port COM */
COMMTIMEOUTS g_cto =
{
    MAX_WAIT_READ,  /* ReadIntervalTimeOut          */
    0,              /* ReadTotalTimeOutMultiplier   */
    MAX_WAIT_READ,  /* ReadTotalTimeOutConstant     */
    0,              /* WriteTotalTimeOutMultiplier  */
    0               /* WriteTotalTimeOutConstant    */
};

/* Configuration du port COM */
DCB g_dcb =
{
    sizeof(DCB),        /* DCBlength            */
    9600,               /* BaudRate             */
    TRUE,               /* fBinary              */
    FALSE,              /* fParity              */
    FALSE,              /* fOutxCtsFlow         */
    FALSE,              /* fOutxDsrFlow         */
    DTR_CONTROL_ENABLE, /* fDtrControl          */
    FALSE,              /* fDsrSensitivity      */
    FALSE,              /* fTXContinueOnXoff    */
    FALSE,              /* fOutX                */
    FALSE,              /* fInX                 */
    FALSE,              /* fErrorChar           */
    FALSE,              /* fNull                */
    RTS_CONTROL_ENABLE, /* fRtsControl          */
    FALSE,              /* fAbortOnError        */
    0,                  /* fDummy2              */
    0,                  /* wReserved            */
    0x100,              /* XonLim               */
    0x100,              /* XoffLim              */
    8,                  /* ByteSize             */
    NOPARITY,           /* Parity               */
    ONESTOPBIT,         /* StopBits             */
    0x11,               /* XonChar              */
    0x13,               /* XoffChar             */
    '?',                /* ErrorChar            */
    0x1A,               /* EofChar              */
    0x10                /* EvtChar              */
};

/*=============================================================================
  Fonctions du module.
=============================================================================*/
BOOL OpenCOM    (int nId);
BOOL CloseCOM   ();
BOOL ReadCOM    (void* buffer, int nBytesToRead, int* pBytesRead);

/******************************************************************************
  main : point d'entrée du programme.
******************************************************************************/
int main()
{
    /* variables locales */
    char buffer[256];
    int nId, nChoice,  nBytesRead;

    /* demande du numéro du port COM */
    printf("Entrez le numero du port COM : ");
    scanf("%d", &nId);

    /* tentative d'ouverture */
    printf("Ouverture et configuration du port COM%d...\r\n", nId);
    if(!OpenCOM(nId)) return -1;
    printf("...OK\r\n");

    /* boucle tant que l'on ne quitte pas */
    do
    {
        /* menu */
        printf("\r\n");
        printf("2 : Recevoir des donnees.\r\n");
        printf("3 : Quitter.\r\n");
        printf("Choix : ");
        scanf("%d", &nChoice);


        /* recevoir des données */
        if(nChoice == 2)
        {
            printf("\r\n");
            printf("Reception de donnees...\r\n");
            if(ReadCOM(buffer, sizeof(buffer)-1, &nBytesRead))
            {
                buffer[nBytesRead] = '\0';
                printf("%d octet(s) recu(s) :\r\n%d\r\n", nBytesRead,  buffer);

            }
            else
                printf("Erreur lors de la réception.\r\n");
        }
    }while(nChoice != 3);

    /* fermeture du port COM et retour */
    CloseCOM();
    return 0;
}

/******************************************************************************
  OpenCOM : ouverture et configuration du port COM.
  entrée : nId : Id du port COM à ouvrir.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL OpenCOM(int nId)
{
    /* variables locales */
    char szCOM[16];

    /* construction du nom du port, tentative d'ouverture */
    sprintf(szCOM, "COM%d", nId);
    g_hCOM = CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
    if(g_hCOM == INVALID_HANDLE_VALUE)
    {
        printf("Erreur lors de l'ouverture du port COM%d", nId);
        return FALSE;
    }

    /* affectation taille des tampons d'émission et de réception */
    SetupComm(g_hCOM, RX_SIZE, TX_SIZE);

    /* configuration du port COM */
    if(!SetCommTimeouts(g_hCOM, &g_cto) || !SetCommState(g_hCOM, &g_dcb))
    {
        printf("Erreur lors de la configuration du port COM%d", nId);
        CloseHandle(g_hCOM);
        return FALSE;
    }

    /* on vide les tampons d'émission et de réception, mise à 1 DTR */
    PurgeComm(g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
    EscapeCommFunction(g_hCOM, SETDTR);
    return TRUE;
}

/******************************************************************************
  CloseCOM : fermeture du port COM.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL CloseCOM()
{
    /* fermeture du port COM */
    CloseHandle(g_hCOM);
    return TRUE;
}

/******************************************************************************
  ReadCOM : lecture de données sur le port COM.
  entrée : buffer       : buffer où mettre les données lues.
           nBytesToRead : nombre max d'octets à lire.
           pBytesRead   : variable qui va recevoir le nombre d'octets lus.
  retour : vrai si l'opération a réussi, faux sinon.
-------------------------------------------------------------------------------
  Remarques : - la constante MAX_WAIT_READ utilisée dans la structure
                COMMTIMEOUTS permet de limiter le temps d'attente si aucun
                caractères n'est présent dans le tampon d'entrée.
              - la fonction peut donc retourner vrai sans avoir lu de données.
******************************************************************************/
BOOL ReadCOM(void* buffer, int nBytesToRead, int* pBytesRead)
{
    return ReadFile(g_hCOM, buffer, nBytesToRead, (LPDWORD)pBytesRead, NULL);
}

Commentaire de misterzinzin le 14/06/2007 19:16:46

ajoute #define BOOL  int
au debut du fichier ...

Commentaire de ncir le 14/06/2007 19:39:36

Merci MISTERZINZIN
J'essayerais demain parce que je suis un peu loin de labo
Mais pardent moi MISTERZINZIN, je suis un mecanicien, je ne comprend pas trop en ce langage(VC++),
concernat ce ci(#define BOOL  int)je le met juste au début du code?

Merci de m'aider

Commentaire de ncir le 15/06/2007 09:30:45

Bonjour MISTERZINZIN
J'ai bien ajouté si que vous demandez et encore le meme resultat:
    Reception des donnees...
    0 octet(s) reçue(s):
    1244800
Merci pour les explications à venir.

Commentaire de misterzinzin le 15/06/2007 16:59:42

de mémoire, la fonction de lecture s'arrête automatique après un certain temps même si le port série n'a pas reçu de donnée. est tu sur que ton port série reçoit bien des données ?

Commentaire de muuller le 25/06/2007 12:21:17

Bonjour YMCA,
j'utilise VC++ et j'arrive à le compiler.Cependant,je voudrais envoyer 4 bytes sur le port RS232 pour faire commuter les entrées d'un appareil(matrice de commutation) sur ses sorties.
Les Bytes sont :
1 byte pour le n° de l'instruction
1 byte pour le n° de l'entrée à commuter
1 byte pour le n° de la sortie sur laquelle il faut commuter l'entrée
1 byte pour le n° de la machine.
Ces bytes doivent être envoyés en hexa ou en decimal.
Comment je peut faire ça avec ton prog car hélas, je suis nul en prog
Merci d'avance!!!

Commentaire de julian60 le 28/06/2007 09:39:16

Tout simplement super...

Merci

Commentaire de bracqjean le 01/02/2008 10:15:26 10/10

Très bon programme

Commentaire de zak8er le 13/03/2008 16:47:46

Bonjour très bon programme,je voudrai savoir qu'est-ce que je dois modifier pour  envoyer du code ASCII à la place des octets.
Merci de votre réponse.  

Commentaire de quentennis le 19/08/2008 11:47:40 10/10

Salut ymca

J'ai une question à propos de ton code
Je l'utilise à une vitesse de 115200bps, et j'envoie la trame FFAF 10 fois. Lorsque je compile le code et que je demande la réception, j'obtiens :
50 octet(s) reçu(s)
FFAF

Comment se fait il que je ne lis qu'une seule fois ma chaine de caractères (que j'ai envoyée 10 fois), et qu'il me dise que le nombre d'octets reçus soit de 50 ? Je ne comprends vraiment pas

Merci pour votre aide

Commentaire de Golgfag le 23/10/2008 14:34:07 10/10

Bonjour,
J'ai aussi une petite question (peut etre de novice ;) )
Alors j'ai un projet d'automatisation d'envoi de configuration sur switch.
Il y as énormément de ligne a envoyer sur le port Console de mes switch.
Ton programme fonctionne mais pas pour un grande nombre d'envoi. Par exemple j'ai reussi a faire passé trois commandes:  

char buffer[256]=" \r\n en \r\n conf t \r\n hostname test \r\n";

Mais si je met toute mes commandes comme ceci ca ne passe pas biensur...
Je suis novice dans le milieu de la prog je suis plutot dans celui du réseau, je remerci d'avance celui ou celle qui sera capable de m'aidé.

Commentaire de victorcoasne le 23/10/2008 19:04:17

Essaye de faire un petit Sleep(50) entre tes commandes.

Commentaire de fabrice91 le 08/01/2009 17:42:13 9/10

Salut YMCA,

Merci beaucoup de nous mettre à dispo tes codes, j'ai une question à te poser :

j'ai utilisé ton code en rajoutant la partie pour entrer les commandes en hexa (cf post du 12/01/2006 05:24:40) et qd je l'utilise tel quel cela ne fonctionne pas (je souhaite écrire les données suivante que j'écris tel quel dans la fenêtre de commande une fois avoir choisit l'envoie de données : 02363130313031323220202020203103 dsl c'est un peu long) les données sont reçu mais pas de réaction de la machine, par contre en écrivant "en dur" dans le code :  WriteCOM("\x02\x36\x31\x30\x31\x30\x31\x32\x32\x20\x20\x20\x20\x20\x31\x03", 16, &nb);
cela fonctionne... As tu une explication? (j'écris pas correctement la commande, ou la conversion en hexa dans le code est erronée...

Merci d'avance pour ta réponse

Commentaire de fabrice91 le 13/01/2009 17:09:05

Re...

J'ai une seconde question, de débutant, c'est sûr... bref, tu mets au début de ton code que "le handle du port est mis en variable globale (g_hComm) Peut être ajouté au parm des fct si besoin de plusieurs port ds le prog". Et bien j'ai essayé, en ajoutant un pointeur du handle dans chacune des fonctions. A la compilation aucune erreurs, mais quand je le lance et que le prog me demande le num du port, le prog plante. Peux tu me donner un coup de main s'il te plait?

Merci d'avance.

PS : Le but final est de faire une dll des 4 fonctions sans qu'il y ait de variable globale...

Commentaire de fabrice91 le 14/01/2009 14:45:17

Voila mon code de la dll avec le handle passé en argument. Le code se compile (et me créer une dll), sf que lorsque je souhaite utiliser la dll, cela ne fonctionne pas. Le problème vient de la dll, mais d'ou?...

Merci d'avance pour l'aide que vous pourrez (j'espère) m'apporter.
(les deux fichiers dllFAB_pointeur.h et dllFAB_pointeur.c):

dllFAB_pointeur.h :

#ifndef __dllFAB_pointeur_H__
#define __dllFAB_pointeur_H__
#define DllImport   __declspec(dllimport)

#include <windows.h>

/*  To use this exported function of dll, include this header
// *  in your project.
// */
//
//#ifdef BUILD_DLL
//    #define DLL_EXPORT __declspec(dllexport)
//#else
//    #define DLL_EXPORT __declspec(dllimport)
//#endif
//
//
//#ifdef __cplusplus
//extern "C"
//{
//#endif
//
//void DLL_EXPORT SomeFunction(const LPCSTR sometext);
//
//#ifdef __cplusplus
//}
//#endif
BOOL DllImport OpenCOM (HWND *g_hCOM, int nId);
BOOL DllImport CloseCOM (HWND *g_hCOM);
BOOL DllImport ReadCOM (HWND *g_hCOM, void* buffer, int nBytesToRead, int* pBytesRead);
BOOL DllImport WriteCOM (HWND *g_hCOM, void* buffer, int nBytesToWrite, int* pBytesWritten);

#endif


dllFAB_pointeur.c :


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "dllFAB_pointeur.h"

/*=============================================================================
  Définition de constantes
=============================================================================*/
#define RX_SIZE         4096    /* taille tampon d'entrée  */
#define TX_SIZE         4096    /* taille tampon de sortie */
#define MAX_WAIT_READ   3000    /* temps max d'attente pour lecture (en ms) */
#define DllExport   __declspec(dllexport)


/******************************************************************************
  OpenCOM : ouverture et configuration du port COM.
  entrée : nId : Id du port COM à ouvrir.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL DllExport OpenCOM(HWND *g_hCOM, int nId)
{
    /* variables locales */
    char szCOM[16];
    /* Délais d'attente sur le port COM */
    COMMTIMEOUTS g_cto =
    {
        MAX_WAIT_READ,  /* ReadIntervalTimeOut          */
        0,              /* ReadTotalTimeOutMultiplier   */
        MAX_WAIT_READ,  /* ReadTotalTimeOutConstant     */
        0,              /* WriteTotalTimeOutMultiplier  */
        0               /* WriteTotalTimeOutConstant    */
    };

    /* Configuration du port COM */
    DCB g_dcb =
    {
        sizeof(DCB),        /* DCBlength            */
        9600,               /* BaudRate             */
        TRUE,               /* fBinary              */
        FALSE,              /* fParity              */
        FALSE,              /* fOutxCtsFlow         */
        FALSE,              /* fOutxDsrFlow         */
        DTR_CONTROL_ENABLE, /* fDtrControl          */
        FALSE,              /* fDsrSensitivity      */
        FALSE,              /* fTXContinueOnXoff    */
        FALSE,              /* fOutX                */
        FALSE,              /* fInX                 */
        FALSE,              /* fErrorChar           */
        FALSE,              /* fNull                */
        RTS_CONTROL_ENABLE, /* fRtsControl          */
        FALSE,              /* fAbortOnError        */
        0,                  /* fDummy2              */
        0,                  /* wReserved            */
        0x100,              /* XonLim               */
        0x100,              /* XoffLim              */
        8,                  /* ByteSize             */
        NOPARITY,           /* Parity               */
        ONESTOPBIT,         /* StopBits             */
        0x11,               /* XonChar              */
        0x13,               /* XoffChar             */
        '?',                /* ErrorChar            */
        0x1A,               /* EofChar              */
        0x10                /* EvtChar              */
    };


    /* construction du nom du port, tentative d'ouverture */
    sprintf(szCOM, "COM%d", nId);
    *g_hCOM = (HWND)CreateFile(szCOM, GENERIC_READ|GENERIC_WRITE, 0, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
    if(*g_hCOM == INVALID_HANDLE_VALUE)
    {
        printf("Erreur lors de l'ouverture du port COM%d", nId);
        return FALSE;
    }

    /* affectation taille des tampons d'émission et de réception */
    SetupComm(*g_hCOM, RX_SIZE, TX_SIZE);
    /* configuration du port COM */
    if(!SetCommTimeouts(*g_hCOM, &g_cto) || !SetCommState(*g_hCOM, &g_dcb))
    {
        printf("Erreur lors de la configuration du port COM%d", nId);
        CloseHandle(*g_hCOM);
        return FALSE;
    }

    /* on vide les tampons d'émission et de réception, mise à 1 DTR */
    PurgeComm(*g_hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
    EscapeCommFunction(*g_hCOM, SETDTR);
    return TRUE;
}

/******************************************************************************
  CloseCOM : fermeture du port COM.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL DllExport CloseCOM(HWND *g_hCOM)
{
    /* fermeture du port COM */
    CloseHandle(*g_hCOM);
    return TRUE;
}

/******************************************************************************
  ReadCOM : lecture de données sur le port COM.
  entrée : buffer       : buffer où mettre les données lues.
           nBytesToRead : nombre max d'octets à lire.
           pBytesRead   : variable qui va recevoir le nombre d'octets lus.
  retour : vrai si l'opération a réussi, faux sinon.
-------------------------------------------------------------------------------
  Remarques : - la constante MAX_WAIT_READ utilisée dans la structure
                COMMTIMEOUTS permet de limiter le temps d'attente si aucun
                caractères n'est présent dans le tampon d'entrée.
              - la fonction peut donc retourner vrai sans avoir lu de données.
******************************************************************************/
BOOL DllExport ReadCOM(HWND *g_hCOM, void* buffer, int nBytesToRead, int* pBytesRead)
{
    /*return ReadFile(g_hCOM, buffer, nBytesToRead, pBytesRead, NULL);*/
    return ReadFile(*g_hCOM, buffer, nBytesToRead, (DWORD*)pBytesRead, NULL);/*ajout d'un cast*/
}

/******************************************************************************
  WriteCOM : envoi de données sur le port COM.
  entrée : buffer        : buffer avec les données à envoyer.
           nBytesToWrite : nombre d'octets à envoyer.
           pBytesWritten : variable qui va recevoir le nombre d'octets
                           envoyés.
  retour : vrai si l'opération a réussi, faux sinon.
******************************************************************************/
BOOL DllExport WriteCOM(HWND *g_hCOM, void* buffer, int nBytesToWrite, int* pBytesWritten)
{
    /* écriture sur le port */
    /*return WriteFile(g_hCOM, buffer, nBytesToWrite, pBytesWritten, NULL);*/
    return WriteFile(*g_hCOM, buffer, nBytesToWrite, (DWORD*)pBytesWritten, NULL);

}


BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;

case DLL_PROCESS_DETACH:
break;

case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;
}

/* Returns TRUE on success, FALSE on failure */
return TRUE;
}


Commentaire de victorcoasne le 14/01/2009 17:09:12

Normalement tu dois récupérer le handle de l'attachement DLL.
Après je sais pas si tu peux l'utiliser dans ce code.

Commentaire de fabrice91 le 14/01/2009 17:49:47

Qu'entends tu par "attachement DLL"?

Commentaire de victorcoasne le 14/01/2009 18:12:56

case DLL_PROCESS_ATTACH:
Te dit quand la DLL est attachée au programme qui l'appelle et donne son handle.

Commentaire de fabrice91 le 15/01/2009 09:52:14

Dsl, je n'ai pas été très clair (ou alors j'ai pas compris, ce qui est probable), qd je parle du handle, il s'agit de celui renvoyé par la fonction createfile() donc le handle du port série (variable : g_hCOM)
En fait je voudrais simplement rajouter par rapport au code initial dans chacune des 4 fonctions le paramètre g_hCOM (le handle du port série), et en faire une dll. Voila tout

Commentaire de elbuey76 le 04/02/2009 19:43:55

Bonjour a tous,

J'ai pris un peu de temps pour comprendre le code, je l'ai compris et integré les fonctions qui m'interesse dans mon propre programme.
Resultat: les données sont envoyé nikel, le programme marche bien, puis tout a coup impossible de quitter l'application, le pc mouline pendant 1/4 d'heure pour fermer le programme.
Je bidouille un peu mon code, je commence a avoir des erreur de compilation "permission denied"...
En faite cette erreur aparait aléatoirement, quelque fois meme en compilant un code qui marchait deja !

Finalement je fini par deduire que c'est le closehandle() qui pose probleme pour quitter l'appli.
Donc je reprend le programme original de YMCA, meme chose, impossible de quitter le programme et de temps a autre une erreur de compilation, alors qu'au debut il marchait  bien.


Quelqu'un a une idée ? Merci

Commentaire de victorcoasne le 05/02/2009 09:35:58

Tu réalise une boucle infinie sûrement.
Essaye de faire ça en thred avec une implémentation d'un timeout et d'un compteur de lectures pour voir s'il va trop vite.
Sans ton code on ne peut pas t'aider.
Sinon tu poste ça sur le forum.
Pour le pb de compilation tu as sûrement demandé à Windows de le débugger ou alors il est encore en execution.

Commentaire de elbuey76 le 06/02/2009 21:57:01

Merci mais j'ai trouvé mon erreur, j'ai baisser la vitesse de transmission a 2 bauds pour pouvoir voir quelque chose sur mon vieu oscillo, du coup l'envoi des octets (et le petit temps a 0 qui suit) qui prennent habituelement une dizaine de nanosecondes on pris 5 minutes, le programme attendai pour fermer...

Commentaire de imedo le 07/04/2009 16:20:47

salut ymca2003,
merci pour ton code
je suis entrain de faire un prog partie client partie serveur pour communiquer entre eu sur le port serie
le client permet d'ecrire de trame stocker dans un fichier sur le port serie et le serveur permet de lire le trame ecrit sur le port.
comment je peut utiliser votre code pour envoyer de donnee stocker dans un fichier.
merci pour votre aide.

 Ajouter un commentaire




Nos sponsors


Sondage...

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,733 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales