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

Linux Discussion :

Lecture port série sur LINUX


Sujet :

Linux

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 46
    Points : 25
    Points
    25
    Par défaut Lecture port série LINUX et manipulation de char
    Bonjour !

    Un module (GPS + boussole électronique) envoie par Xbee des informations à une clé USB XStick que j'essaye de récupérer avec un programme en C. Voici mon programme :
    Les fonctions :
    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
    #include <sys/fcntl.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include "serial_port.h"
     
    int openSerialPort(const char* DEVICE_PORT)
    {
    	struct termios options;
    	int file = open(DEVICE_PORT, O_RDONLY | O_NOCTTY | O_NDELAY);
     
    	if(file == -1){perror("Unable to open the serial port\n");}
    	else {printf("Serial port open successful !\n");}
     
    	tcgetattr(file, &options); 			
    	cfsetispeed(&options, B9600); 					
    	cfsetospeed(&options, B9600); 					
    	options.c_cflag |= (CLOCAL | CREAD); 			  
    	options.c_cflag |= PARENB; 					
    	options.c_cflag |= PARODD; 						 					
    	options.c_cflag &= ~CSIZE; 						
    	options.c_cflag |= CS8;	
     
    	return file;		
    };
     
    bool readMessage(int file, char* message, int nbCharToRead)
    {
        int i;
    	char buf[100];
     
        if (file != -1)
        {
    	    i = 0; 
    		if (read(file, &buf, sizeof(buf)) > 0)
    		{
    			while(buf[i]!='\n'|| i<nbCharToRead-1) //saut à la ligne ou depassement du nb de char
    			{
    				message[i] = buf[0]; //remplissage de message char par char
    				i++;
    			}
    			message[i] = '\0';
    			printf("message : %c", message[i]);
    			return true;
    		}
    		else
    		{
    			printf("Reception error !\n");
    			return false;
    		}
        }
        return false;
    };
    Le main() :
    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
    int main()
    {
    	int file;
    	int nbCharToRead = 50; //Taille maximale d'une ligne (toujours < 50 caracteres)
    	bool retRead;
    	char message[nbCharToRead];
    	const char* DEVICE_PORT = "/dev/ttyUSB1";
     
    	//=================================== OPEN SERIAL PORT ===================================//
    	printf("Open serial port ... ");
       	file = openSerialPort(DEVICE_PORT);
     
       	//=================================== READ SERIAL PORT ===================================//
       	printf("Read serial port ...\n\n");
    	retRead = readMessage(file, message, nbCharToRead);
     
       	//====================================== CLOSE FILE =====================================//
       	close(file);
    	printf("Serial port closed\n");
    }
    J'aimerai obtenir, à chaque appel de la fonction readMessage (que je mettrai plus tard dans une boucle ou Thread), voir une des lignes envoyées par le module. Pour info, un message entier envoyé par le module est constitué de 2 ou 3 lignes (selon que le GPS est actif ou non), typiquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Heading: 274 Tilt: 7 Roll: -11 
    LAT=48.715961 LON=2.203730 SAT=5 PREC=300 
    CHARS=32386 SENTENCES=275 CSUM ERR=1
    Seulement, je j'obtiens sur le prompteur à l'exécution, soit "message : " (le message est vide), soit "Reception error ! Serial port closed" ... Bref ça marche pas du tout !

    Pouvez-vous m'aider svp ?
    Merci d'avance !

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 46
    Points : 25
    Points
    25
    Par défaut
    Bonjour, voici mon nouveau code de lecture :
    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
    bool readMessage(int file, char* message, int nbCharToRead)
    {
            int i;
    	char buf[] = "0";
    	message = (char*)malloc(sizeof(*message));
            if (file != -1)
            {
    	        i = 0; 
    	        while(buf != "\n") 										
    	        {
                            printf("Pas de retour à la ligne ...\n");
    		        if (read(file, &buf, sizeof(buf)) > 0) 				
    		        {
    		                message = (char*)realloc(message, sizeof(char)*(i+1)); printf("new sizeof(message) = %d\n", sizeof(*message));
    			        message[i] = buf[0]; printf("%c\n", message[i]);
    			        i++; printf("i = %d\n", i);
    			        if (i == nbCharToRead) break;					
    		        }
    		        else {printf("Reception error !\n"); return false; free(message);}
    	         }
    	         printf("Retour à la ligne ...\n");														
    	         message[i] = '\0';										
    	         printf("message : %c", message[i]);
    	         return true;
            }
            else {printf("Error while reading file !\n"); return false;}
    };
    Mais ça ne fonctionne toujours pas, le prompteur affiche :
    - soit "L'application s'est terminée par un signal : SIGSEGV"
    - soit "Reception error !"

    Personne pour m'aider ?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 46
    Points : 25
    Points
    25
    Par défaut Lecture port série sur LINUX
    Bonjour j'aimerais lire sur le port série /dev/ttyUSB0, le message suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Heading: 274 Tilt: 7 Roll: -11  
    LAT=48.715961 LON=2.203730 SAT=5 PREC=300  
    CHARS=32386 SENTENCES=275 CSUM ERR=1
    Voici mon code de lecture (après ouverture du fichier) :
    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
    bool readMessage(int file, char* message, int nbCharToRead)
    {
    	int i;
    	char buf[] = "0";
    	message = (char*)malloc(sizeof(*message));
            if (file != -1)
            {
    	        i = 0; 
    	        while(buf != "\n") 
    		{
    			printf("Pas de retour à la ligne ...\n");
    			if (read(file, &buf, sizeof(buf)) > 0) 				
    			{
    			        message = (char*)realloc(message, sizeof(char)*(i+1)); printf("new sizeof(message) = %d\n", sizeof(*message));
    				message[i] = buf[0]; printf("%c\n", message[i]);
    				i++; printf("i = %d\n", i);
    				if (i == nbCharToRead) break;					
    			}
    			else {printf("Reception error !\n\n"); return false; free(message);}
    		}														
    		message[i] = '\0';										
    		printf("message : %c", message[i]);
    		return true;
        }
        else {printf("Error while reading file !\n"); return false;}
    };
    Je veux lire à chaque appel de cette fonction, une ligne du message (que j'ai donné au début de ce post) en détectant les retour à la ligne "\n". A son exécution, j'obtiens soit "Reception error !", soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    message : A
    i = 1
    message : AS
    i = 2
    message : AS:
    i = 3
    message : AS:4
    i = 4
    Reception error !
    et il s'arrête à un nombre d'itération à chaque fois différent, mais pas plus grand que 5 ... Alors qu'en lisant le fichier /dev/ttyUSB0 avec la commande cat ou screen sur le terminal, ça fonctionne très bien ...

    Quelqu'un pour m'aider ?
    Merci d'avance !

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 46
    Points : 25
    Points
    25
    Par défaut
    J'ai rééecris ma fonction lecture :

    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
    bool readMessage(int file, char* message, int nbCharToRead)
    {
    	int i,car;
    	char* buf = (char*)malloc(sizeof(char)); printf("sizeof(*buf) : %d\n",sizeof(buf));
    	message = (char*)malloc(sizeof(char)*(nbCharToRead+1)); printf("sizeof(*message) : %d\n",sizeof(message));
    	if (file != -1)
        {
    	    i = 0;
    	    while(strchr(buf,'\n') == NULL)
    		{
    			car = read(file, buf, sizeof(*buf));
    			if (car > 0)
    			{
    				message[i] = buf[0]; printf("message : %s\n", message);
    				i++; printf("i = %d\n", i);
    			}
    			else if (car == 0);
    			else {printf("Reception error !\n\n"); return false; free(message);}
    		}
    		printf("Retour à la ligne ...\n");
    		message[i] = '\0';
    		printf("message : %s", message);
    		return true;
        }
        else {printf("Error while reading file !\n"); return false;}
    };
    Mais j'ai toujours le même problème, je n'arrive pas à obtenir la ligne entière, il s'arrête avant ...

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 46
    Points : 25
    Points
    25
    Par défaut
    ça y est ça marche, j'ai enlever le else (erreur) ! :

    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
    bool readMessage(int file, char* message, int nbCharToRead)
    {
    	int i,car;
    	char buf[2] = {0};
        if (file != -1)
        {
    	    i = 0;
    	    while(buf[0] != '\n')
    		{
    			car = read(file, &buf, sizeof(buf));
    			if (car > 0)
    			{
    				message[i] = buf[0];
    				i++;
    			}
    			else if (car == 0);
    		}
    		message[i] = '\0';
    		return true;
        }
        else {printf("Error while reading file !\n"); return false;}
    };
    Donc là j'affiche un bout d'une ligne jusqu'au retour à la ligne, mais j'aimerais maintenant afficher une ligne entière. Pour cela, mon algo est le suivant :
    1) trouver un saut de ligne
    2) afficher et enregistrer dans message[] les caractères qui suivent ce retour à la ligne jusqu'au prochain saut de ligne.

    et ainsi de suite (je ferai ensuite une boucle dans le main pour afficher ligne par ligne le message). Ma fonction readMessage doit juste afficher et enregistrer une seule ligne complète.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture port série aléatoire linux
    Par alfybe dans le forum C
    Réponses: 9
    Dernier message: 02/09/2013, 11h57
  2. [pyserial] lecture port série sur arduino
    Par blaster68 dans le forum Déploiement/Installation
    Réponses: 1
    Dernier message: 07/03/2013, 09h00
  3. Pb fonction read sur port série - GCC LINUX
    Par Signal40 dans le forum POSIX
    Réponses: 5
    Dernier message: 02/08/2010, 20h33
  4. Lecture sur port série sous Linux
    Par DangerousBowlOfJelly dans le forum C
    Réponses: 6
    Dernier message: 28/03/2008, 17h00
  5. [Série] Accès au port série sous linux
    Par ghost dans le forum Entrée/Sortie
    Réponses: 10
    Dernier message: 10/10/2007, 10h43

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