RS232 timeout

virtuoze Messages postés 7 Date d'inscription jeudi 26 janvier 2012 Statut Membre Dernière intervention 2 février 2012 - 31 janv. 2012 à 17:41
virtuoze Messages postés 7 Date d'inscription jeudi 26 janvier 2012 Statut Membre Dernière intervention 2 février 2012 - 2 févr. 2012 à 15:06
voici mon code :
MAIN:
#include <cstdlib>
#include 
#include <windows.h>
#include <string.h>
#include <stdio.h>


#include "class_RS232.h"
unsigned char Trame_GetStatut[] = {0x01, 0x03, 0x00, 0x40, 0x00, 0x01, 0x85, 0xDE};
unsigned char Trame_1[] = {0x01, 0x05, 0x00, 0x44, 0x00, 0x00, 0x8D, 0xDF};
unsigned char Trame_2[] = {0x01, 0x06, 0x00, 0x47, 0x05, 0x00, 0x3A, 0x8F};


using namespace std;


void Affichage(unsigned char* P_Message, int NbCaracteresAAfficher)
{
    int L_index;

    for (L_index = 0; L_index < NbCaracteresAAfficher; L_index++)
    {
        printf("%x ", P_Message[L_index]);

    }
}


//#################################################################

int main(int argc, char** argv)
{

    //char messageRecu[25];
    //T_PORT_COM COM1;
    // COM1 = connexion_port();
    //macom.Envoie_reception_trame(COM1, messageRecu);
    //affichage(messageRecu);
    DWORD Nombre_de_bit_lu = 0;
    unsigned char L_messageRecu[25];
    DWORD Nombre_de_carac_recu = 0;
    int L_NbCarAEmettre;

    class_RS232 Ma_com;
    int L_Choix = 0;



    Ma_com.connexion_port(1, CBR_9600, 8, NOPARITY);

    cout << "Menu : Choisissez la trame a envoyer" << endl;
    cout << "1 - GetStatut" << endl;
    cout << "2 - Relay_Control " << endl;
    cout << "3 - LED" << endl << endl;

    cout << " Saisissez votre choix : ";
    cin >> L_Choix;

    switch (L_Choix)
    {
        case 1:
            Affichage(Trame_GetStatut, 8);
            Ma_com.WriteCOM(Trame_GetStatut, 8, &Nombre_de_bit_lu);
            break;
        case 2: Ma_com.WriteCOM(Trame_1, 8, &Nombre_de_bit_lu);
            break;
        case 3: Ma_com.WriteCOM(Trame_2, 8, &Nombre_de_bit_lu);
            break;
    }

    //Ma_com.WriteCOM(Trame_GetStatut,8,&Nombre_de_bit_lu);
    L_NbCarAEmettre = 8;
    Ma_com.ReadCOM(L_messageRecu, L_NbCarAEmettre, &Nombre_de_carac_recu);
    cout << " nbre caracteres recus : " << Nombre_de_carac_recu << endl;
    cout << "avant affichage" << endl;

    Affichage(L_messageRecu, Nombre_de_carac_recu);
    Ma_com.CloseCOM();

}




MA CLASS RS232:
.h

#ifndef CLASS_RS232_H
#define	CLASS_RS232_H
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
#include 
#define TAILLE_TABLEAU 25

class class_RS232
{
public:

    class_RS232();
    ~class_RS232();
    bool ReadCOM(unsigned char* P_messageRecu, int nBytesToRead, DWORD* NombreCarRecu);
    bool WriteCOM(unsigned char* Trame_a_Envoyer, int nBytesToWrite, DWORD* NombreOctetsEcrits);
    void connexion_port(int NumPort, int baude_rate, int taille_data, bool bit_parity);
    //friend void Affichage(class_RS232 P_RS232);
    bool CloseCOM();


private:

    COMMTIMEOUTS g_cto;
    DCB dcb;
    HANDLE hCom;
    int TimeoutRead;
    BOOL fSuccess;
    char sizeCom;
};

#endif	/* CLASS_RS232_H */



.cpp
#include "class_RS232.h"
#include <stdlib.h>
#include <conio.h>
#include 
#include <string.h>
#include <windows.h>
#include "class_RS232.h"
#include 
#include <winbase.h>

using namespace std;
#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) */

void class_RS232::connexion_port(int NumPort, int baude_rate, int taille_data, bool bit_parity)
{
    char sizeCom[6];
    sprintf(sizeCom, "COM%d", NumPort);




    hCom = CreateFileA(sizeCom,
            GENERIC_READ | GENERIC_WRITE,
            0, // comm devices must be opened w/exclusive-access
            NULL, // pas de securité
            OPEN_EXISTING, //  devices OPEN_EXISTING
            0, // not overlapped I/O
            NULL // hTemplate must be NULL for comm devices
            );

    if (hCom == INVALID_HANDLE_VALUE)
    {

        std::cout << "probleme dans l'ouverture du port com " << GetLastError();





        fSuccess = GetCommState(hCom, &dcb);

        if (!fSuccess)
        {

            std::cout << "erreur lors de la configuration du port " << GetLastError();

        }



        dcb.BaudRate = baude_rate; //CBR_9600;     // baud rate
        taille_data dcb.ByteSize taille_data; //8;             // taille data, xmit, rcv
        dcb.Parity = bit_parity; //NOPARITY;        // no parity bit


        fSuccess = SetCommState(hCom, &dcb);

        if (!fSuccess)
        {

            std::cout << "erreur lors de la configuration du port " << GetLastError();

        }

    }

}

class_RS232::class_RS232()
{



    int TimeoutRead = 500;

    g_cto.ReadIntervalTimeout = MAX_WAIT_READ;
    g_cto.ReadTotalTimeoutMultiplier = 0;
    g_cto.ReadTotalTimeoutConstant = TimeoutRead;
    g_cto.WriteTotalTimeoutMultiplier = 0;
    g_cto.WriteTotalTimeoutConstant = 0;

    SetCommTimeouts(hCom,&g_cto);



}

class_RS232::~class_RS232()
{

}

bool class_RS232::ReadCOM(unsigned char* P_messageRecu, int nBytesToRead, DWORD* NombreCarRecu)
{
    //return ReadFile(g_hCOM, buffer, nBytesToRead, (LPDWORD)pBytesRead, NULL);
    cout << "ReadCom" << endl;



    return ReadFile(hCom, P_messageRecu, nBytesToRead, NombreCarRecu, NULL);
    //std::cout << " nbre caractere ecrit :" << NombreOctetsEcrits;
}

bool class_RS232::WriteCOM(unsigned char* Trame_a_Envoyer, int nBytesToWrite, DWORD*NombreOctetsEcrits)
{

    return WriteFile(hCom, Trame_a_Envoyer, nBytesToWrite, NombreOctetsEcrits, NULL);

}

bool class_RS232::CloseCOM()
{
    CloseHandle(hCom);
    cout << "Close Done" << endl;
    return true;
}



Mon soucis est le suivant : Le code marche mais je suis obliger dans ma fonction ReadCOM et WriteCom de marquer le nombres de caractere qui sera envoyé et reçus , mais selon la trame envoyer et la configuration du module qui reçoit ma trame la reponse sera plus ou moins grande c'est pour cela que je cherche une solution permettant d'evité de noter en brut le nombres de caractère qui sera lus dans ma fonction Readfile.
j'ai trouvé la solution du timeout pour faire en sorte que lorsque le delais entre la reception des caractères est trop long il coupe la connexion , mais je sait pas comment m'en servir pour eviter de rentrer en dur le nombre de caractère à lire .
J'espère etre claire dans mes explications , sinon expliqué moi ce que vous ne comprenais pas et j'essayerai d'etre plus claire.

En vous remerciant d'avance pour vos réponse!

2 réponses

cs_louis14 Messages postés 793 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 10 février 2021 8
1 févr. 2012 à 09:23
Bonjour,
Si tu as dans tes trames un caractère de fin de message, tu peux aussi voir à détecter le caractère de fin de message , mais avec le time out en plus.
Tu peux chercher les fichier de SerialEx de Ramon de Klein, http://www.codeproject.com/KB/system/serial.aspx?msg=328248
qui contient la solution à ton problème.
Bon codage


louis
0
virtuoze Messages postés 7 Date d'inscription jeudi 26 janvier 2012 Statut Membre Dernière intervention 2 février 2012
2 févr. 2012 à 15:06
Je suis aller voir ton lien Louis mais je t'avourais que ca ne pas pas aider plus que sa .
Je ne trouve toujours pas le moyens d'éviter de rentrer en dur le nombre de caractère à recevoir.
0
Rejoignez-nous