IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Lecture et affichage du signal d'une souris série RS232 en C


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2009
    Messages : 2
    Par défaut Lecture et affichage du signal d'une souris série RS232 en C
    Bonjour à tous,

    Je vous sollicite car mes connaissances en programmation C sont fort limitées.

    J'aimerai afficher le déplacement d'une souris RS232 et le temps en milli secondes entre chaque incrément de déplacement

    Il semblerait que:
    le protocole des souris RS232 utilise 1 bit de start, 7 bits de données, pas de parité, et 1 bit de stop, ceci a 1200 bits/sec. Les données sont envoyées par paquets de 3 octets, constituant le télégramme suivant :

    octet d7 d6 d5 d4 d3 d2 d1 d0
    1 X 1 LB RB dy7 dy6 dx7 dx6
    2 X 0 dx5 dx4 dx3 dx2 dx1 dx0
    3 X 0 dy5 dy4 dy3 dy2 dy1 dy0

    LB (left button), RB (right button), vaut 1 quand le bouton gauche, droit, est pressé.
    Les mouvements en x (dx) et en y (dy) sont codés sur 8 bits dont les bits de poids faibles se trouvent sur les octets 2 et 3 et le reste dans le premier octet.

    Voici le code que j'ai pour l'instant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    #include <sys/types.h>
          #include <sys/stat.h>
          #include <fcntl.h>
          #include <termios.h>      // settins du port serie
          #include <stdio.h>
     
     
            // baudrate settings are defined in <asm/termbits.h>,
            // which is included by <termios.h>
     
          #define BAUDRATE B1200
          #define ADRESSE_PORT "/dev/ttyS0"  // numero du port
          #define _POSIX_SOURCE 1           // POSIX compliant source
          #define FALSE 0
          #define TRUE 1
     
          volatile int STOP=FALSE;
     
          main()
          {
            int fd, c, res;
            struct termios oldtio, newtio;
            char buf[255];  // nombre max de caracteres ds le buffuer pr une lecture
     
                // Open modem device for reading and writing and not as controlling tty
                // because we don't want to get killed if linenoise sends CTRL-C.
     
            fd = open(ADRESSE_PORT, O_RDWR | O_NOCTTY );
     
                // O_NOCTTY flag tells UNIX that this program doesn't want to be the "controlling terminal" for that port. If you don't specify this then any input (such as keyboard abort signals and so forth) will affect your process. Programs like getty(1M/8) use this feature when starting the login process, but normally a user program does not want this behavior.
     
            if (fd <0) {perror(ADRESSE_PORT); exit(-1); }
     
            tcgetattr(fd,&oldtio);    // save current port settings
     
            bzero(&newtio, sizeof(newtio));  // clear struct for new port settings
     
            newtio.c_cflag = BAUDRATE | CRTSCTS | CS7 | CLOCAL | CREAD;
     
                // BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
                // CRTSCTS : output hardware flow control (only used if the cable has
                //           all necessary lines. See sect. 7 of Serial-HOWTO)
                // CS8     : 8n1 (8bit,no parity,1 stopbit)
                // CLOCAL  : local connection, no modem contol
                // CREAD   : enable receiving characters
     
            newtio.c_iflag = IGNPAR;
     
                // IGNPAR  : ignore bytes with parity errors
                // ICRNL   : map CR to NL (otherwise a CR input on the other computer
                //           will not terminate input)
                // otherwise make device raw (no other input processing)
     
            newtio.c_oflag = 0;
     
                // set input mode (non-canonical, no echo,...)
     
            newtio.c_lflag = 0;  // Raw output
     
                // initialize all control characters
                // default values can be found in /usr/include/termios.h, and are given
                // in the comments, but we don't need them here
     
            newtio.c_cc[VTIME]    = 0;   // inter-character timer --> sets the character timer
            newtio.c_cc[VMIN]     = 6;   // blocking read until 5 chars received. sets the minimum number of characters to receive before satisfying the read
     
                // now clean the modem line and activate the settings for the port
     
            tcflush(fd, TCIFLUSH);
            tcsetattr(fd,TCSANOW,&newtio);
     
                // terminal settings done, now handle input
                // In this example, inputting a 'z' at the beginning of a line will
                // exit the program.
     
            while (STOP==FALSE) {  // loop until we have a terminating condition
     
                // read blocks program execution until a line terminating character is
                // input, even if more than 255 chars are input. If the number
                // of characters read is smaller than the number of chars available,
                // subsequent reads will return the remaining chars. res will be set
                // to the actual number of characters actually read
     
     
            res = read(fd,buf,255);   // returns after 5 chars have been input
            buf[res]=0;
     
            printf("%s\n", buf);
     
            if (buf[0]=='z') STOP=TRUE;
     
            }
     
            tcsetattr(fd,TCSANOW,&oldtio);  // restore the old port settings
     
          }
    Quelle fonction (et comment) utiliser pour afficher le temps dans la boucle (entre chaque signal envoyé par la souris)?
    <time.h> ne permet d'afficher qu'en secondes?

    Comment faire pour afficher en binaire les 3 octets constituant le télégramme décrit polus haut?

    PS: je suis sous linux kubuntu.

    D'avance, un grand merci.

  2. #2
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2009
    Messages : 2
    Par défaut
    Bonjour à tous,
    Voici ou j'en suis pour le moment: (pas bien loin )

    Après quelques valeurs, les octets se décalent
    (le 1 est en position 2, le 2 est en position 3 et le 3 est en position 1 et ainsi de suite)
    Et j'en ai parfois plus que 3 par lecture alors que la souris n'en envoie que 3.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    046 037 068 000 000 24009 usec
    007 035 064 000 000 27987 usec
    063 033 065 000 000 23992 usec
    007 001 077 000 000 24110 usec
    005 062 077 010 005 76173 usec
    072 014 039 000 005 15797 usec
    075 038 045 000 005 23897 usec
    078 062 032 000 005 24002 usec
    Je me demande si il y a une erreur dans mon code ou si je n'utilise pas le bon type de transmission (canonique, non canonique,...) qui est décris dans ce lien:
    http://www.docmirror.net/fr/linux/ho...OWTO.html#toc3

    J'ai besoin de votre aide car je ne sais vraiment que faire!
    Un grand merci d'avance.
    Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
          #include <sys/time.h>  //temps
          #include <unistd.h>
    //-----------------------------------------------------------------------------
          #include <sys/types.h>
          #include <sys/stat.h>
          #include <fcntl.h>
          #include <termios.h>   // settins du port serie
          #include <stdio.h>
    //-----------------------------------------------------------------------------
          #include <stdlib.h>   //fichier
    //-----------------------------------------------------------------------------
          #define BAUDRATE B1200    // baudrate settings sont définis dans <asm/termbits.h>, qui est inclus par <termios.h>
          #define ADRESSE_PORT "/dev/ttyS0"  // numero du port
          #define _POSIX_SOURCE 1            // source conforme à POSIX
    //---------------- Timer ------------------------------------------------------
            struct timeval tv1,tv2;
            struct timezone tz;
            long long delta_temps;
    //----------------- Fichier ---------------------------------------------------
            int mesure_impulsions;  //ecriture ds le fichier
            char nom_fichier[200] ; // On initialise la variable à 0
    //-----------------------------------------------------------------------------
            volatile int STOP=0;
            int fd, c, res;
            struct termios oldtio, newtio;
            char buf[255];  // nombre max de caracteres dans le buffuer pour une lecture
            char dep_x, dep_y;
            int deplacement_x();
            int deplacement_y();
    //-----------------------------------------------------------------------------
    // Open modem device pour lecture + écriture et pas comme controleur tty car on ne veut pas etre détruit si on recoit un caractère CTRL-C.
          main()
          {
            printf("Mesure \n\nVeuillez introduire le nom du fichier: ");
            scanf("%s", &nom_fichier); // On demande d'entrer le nom
     
            fd = open(ADRESSE_PORT, O_RDWR | O_NOCTTY );// O_NOCTTY flag dit que ce progr n'est pas un "controlling terminal" pour ce port. Si on ne le spécifie pas, chaque input (such as keyboard abort signals and so forth) va affecter le process. normally a user program does not want this behavior.
            if (fd <0) {perror(ADRESSE_PORT); exit(-1); }
            tcgetattr(fd,&oldtio);    // sauve config courante
            bzero(&newtio, sizeof(newtio));  //  on initialise la structure à zéro
            newtio.c_cflag = BAUDRATE | CRTSCTS | CS7 | CLOCAL | CREAD;     // BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
                                                                            // CRTSCTS : contrôle de flux matériel (uniquement utilisé si le câble a les lignes nécessaires. Voir la section 7 du Serial-HOWTO).
                                                                            // CS8     : 8n1 (8bit,no parity,1 stopbit)
                                                                            // CLOCAL  : connexion locale, pas de contrôle par le modem
                                                                            // CREAD   : permet la réception des caractères
     
            newtio.c_iflag = IGNPAR;    // IGNPAR  : ignore les octets ayant une erreur de parité.
                                        // ICRNL   : transforme CR en NL (sinon un CR de l'autre côté de la ligne ne terminera pas l'entrée). sinon, utiliser l'entrée sans traitement (device en mode raw).
            newtio.c_oflag = 0;     // positionne le mode de lecture(non-canonical, no echo,...)
            newtio.c_lflag = 0;     // si ICANON  : active l'entrée en mode canonique désactive toute fonctionnalité d'echo, et n'envoit pas de signal au programme appelant.
                // initialize all control characters
                // default values can be found in /usr/include/termios.h, and are given in the comments, but we don't need them here
            newtio.c_cc[VTIME]    = 0;   // timer inter-caractères non utilisé
            newtio.c_cc[VMIN]     = 3;   // read bloquant jusqu'à ce que 3 caractères soient lus
    // now clean the modem line and activate the settings for the port
            tcflush(fd, TCIFLUSH);
            tcsetattr(fd,TCSANOW,&newtio);
                //  la configuration du terminal est faite, à présent on traite les entrées
    //--------------------------------------------------------------------------------
            while (STOP==0) {  // boucle jusqu'à condition de terminaison read bloque l'exécution du programme jusqu'à ce qu'un caractère de fin de ligne soit lu, même si plus de 255 caractères sont saisis.
                               //Si le nombre de caractères lus est inférieur au nombre de caractères disponibles, des read suivant retourneront les caractères restants.
                               //res sera positionné au nombre de caractères effectivement lus
            res = read(fd,buf,255);   // returns after xxx chars have been input
            buf[res]=0;
            gettimeofday(&tv2, &tz);
            delta_temps=(tv2.tv_sec-tv1.tv_sec) * 1000000L + (tv2.tv_usec-tv1.tv_usec); //calcul delta temps
    //-----------------------AFFICHAGE ECRAN--------------------------------------------------------------
            //deplacement_x();
            //deplacement_y();
            gettimeofday(&tv1, &tz);
            char octet1,octet2,octet3;
            //octet1=buf[0];
            //octet2=buf[1];
            //octet3=buf[2];
     
            printf("%03d %03d %03d %03d %03d", buf[0], buf[1], buf[2], buf[3], buf[4]);
            //printf("%02d %02d %02d", octet1, octet2, octet3);//affiche les deplacamants x et y
            printf("  %d microsec\n", delta_temps);//affiche le temps
    //-----------------------ECRITURE FICHIER------------------------------------------------------------
            mesure_impulsions = fopen(nom_fichier, "a+");//ecriture ds fichier
            fprintf(mesure_impulsions,"%03d %03d %03d %03d %03d %d usec\n", buf[0], buf[1], buf[2], buf[3], buf[4], delta_temps);
     
            fclose(mesure_impulsions);
    //---------------------------------------------------------------------------------------------------
           if (buf[0]=='z') STOP=1;
            }
            tcsetattr(fd,TCSANOW,&oldtio);  // restaure les anciens paramètres du port
          }

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/05/2013, 09h26
  2. Lecture et affichage d'une séquence d'images
    Par Nates dans le forum OpenCV
    Réponses: 14
    Dernier message: 18/05/2011, 14h11
  3. Réponses: 4
    Dernier message: 28/12/2008, 21h46
  4. Comment capturer les données sur une liaison série RS232
    Par jef Orome dans le forum Windows Serveur
    Réponses: 3
    Dernier message: 02/04/2007, 18h14
  5. Réponses: 5
    Dernier message: 30/03/2006, 11h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo