Lecture /dev/ttyUSB0 en C
Fermé
ABouras
Messages postés
26
Date d'inscription
vendredi 16 novembre 2012
Statut
Membre
Dernière intervention
7 décembre 2012
-
20 nov. 2012 à 16:19
totof31 Messages postés 163 Date d'inscription lundi 29 octobre 2012 Statut Membre Dernière intervention 30 avril 2013 - 21 nov. 2012 à 15:00
totof31 Messages postés 163 Date d'inscription lundi 29 octobre 2012 Statut Membre Dernière intervention 30 avril 2013 - 21 nov. 2012 à 15:00
A voir également:
- Lecture /dev/ttyUSB0 en C
- Telecharger dev c++ - Télécharger - Langages
- Massgrave dev - Accueil - Windows
- Confirmation de lecture whatsapp - Guide
- Dev home. - Télécharger - Développement
- Accusé de lecture gmail - Guide
11 réponses
ABouras
Messages postés
26
Date d'inscription
vendredi 16 novembre 2012
Statut
Membre
Dernière intervention
7 décembre 2012
20 nov. 2012 à 17:25
20 nov. 2012 à 17:25
Mon programme est le suivant :
Cette fois-ci, plus d'erreurs, mais les caractères affichés sont étranges :
les dollars $$$$ sont représentés par des carrés contenant 4 chiffres, bref .... je rappel que je voudrais avoir :
J'ai essayé en mettant %c, %d, %x dans le printf, mais évidemment aucun ne fonctionne correctement ...
Merci !
bool readMessage(int file, unsigned int nCountMax) { int i; size_t nbytes; ssize_t bytes_read; if (file != -1) { i = 0; char message[100]; char data[100]; while (i<nCountMax && data != ".") { if (read(file, data, 1) == -1) { printf("reception error\n"); printf("code errno = %d\n", errno); return false; } else { nbytes = sizeof(data); bytes_read = read(file, data, nbytes); message[i] = *data; printf("%c", message[i]); i++; } } message[i] = 0; return true; } };
Cette fois-ci, plus d'erreurs, mais les caractères affichés sont étranges :
$$$$QUC U$C $$$$JQMJ' J$Cz(HSQ'Q'y UKUNiQUMJ
les dollars $$$$ sont représentés par des carrés contenant 4 chiffres, bref .... je rappel que je voudrais avoir :
CHARS : 15931 SENTENCES = 0 CHECKSUM : 58 Heading : 55 Tilt: -46 Roll:2 CHARS : .....
J'ai essayé en mettant %c, %d, %x dans le printf, mais évidemment aucun ne fonctionne correctement ...
Merci !
totof31
Messages postés
163
Date d'inscription
lundi 29 octobre 2012
Statut
Membre
Dernière intervention
30 avril 2013
74
20 nov. 2012 à 17:46
20 nov. 2012 à 17:46
Salut,
Je ne comprends pas très bien :
bytes_read = read(file, data, nbytes);
retourne bytes_read caractères (au maximum nbytes)
Avec :
message[i] = *data;
printf("%c", message[i]);
tu ne lis et n'affiches qu'un seul caractère !
Il faut regarder la valeur retournée par bytes_read. Il ne faut donc pas faire :
if (read(file, data, 1) == -1)
mais :
bytes_read = read(file, data, nbytes); // A UN SEUL ENDROIT
if (bytes_read...
else...
Je ne comprends pas très bien :
bytes_read = read(file, data, nbytes);
retourne bytes_read caractères (au maximum nbytes)
Avec :
message[i] = *data;
printf("%c", message[i]);
tu ne lis et n'affiches qu'un seul caractère !
Il faut regarder la valeur retournée par bytes_read. Il ne faut donc pas faire :
if (read(file, data, 1) == -1)
mais :
bytes_read = read(file, data, nbytes); // A UN SEUL ENDROIT
if (bytes_read...
else...
totof31
Messages postés
163
Date d'inscription
lundi 29 octobre 2012
Statut
Membre
Dernière intervention
30 avril 2013
74
20 nov. 2012 à 17:58
20 nov. 2012 à 17:58
Autre chose : tu ne dois pas faire
data != "."
data est le nom d'un tableau (pointeur à l'adresse du tableau), on ne peut pas le comparer à un caractère.
data != "."
data est le nom d'un tableau (pointeur à l'adresse du tableau), on ne peut pas le comparer à un caractère.
ABouras
Messages postés
26
Date d'inscription
vendredi 16 novembre 2012
Statut
Membre
Dernière intervention
7 décembre 2012
21 nov. 2012 à 09:38
21 nov. 2012 à 09:38
Ok, maintenant j'ai le code suivant :
Et j'obtient le code errno 11 [Resource temporarily unavailable] ... pourquoi ?
Merci.
#include <stdio.h> #include <stdlib.h> #include <termios.h> #include <sys/fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include "serial_port.h" void read_Serial_Port(const char* DEVICE_PORT) { int file; struct termios options; unsigned int nCountMax = 60; bool b; file = open(DEVICE_PORT, O_RDONLY | O_NOCTTY | O_NDELAY); if(file == -1){perror("Unable to open the serial port\n");} 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; printf("Reading serial port ...\n\n"); b = readMessage(file, nCountMax); if (b == 0){printf("Error while reading serial port\n");} else printf("\nSerial port read successful\n"); close(file); printf("Serial port closed\n"); }; bool readMessage(int file, unsigned int nCountMax) { int i; size_t nbytes; ssize_t bytes_read; if (file != -1) { i = 0; char message[100] = {0}; char data[1] = ""; nbytes = sizeof(data); while (i<nCountMax) { bytes_read = read(file, data, nbytes); if (bytes_read < 0) { printf("read failed, errno code = %d [%s]\n", errno, strerror(errno)); return false; } else { message[i] = *data; printf("%c", message[i]); i++; } } message[i] = 0; return true; } }
Et j'obtient le code errno 11 [Resource temporarily unavailable] ... pourquoi ?
Merci.
totof31
Messages postés
163
Date d'inscription
lundi 29 octobre 2012
Statut
Membre
Dernière intervention
30 avril 2013
74
21 nov. 2012 à 10:08
21 nov. 2012 à 10:08
Je ne me focaliserais pas trop sur le cas d'erreur pour l'instant. Attention également à ton test :
- si bytes_read est nul, tu affiches quand même un caractère...
- si bytes_read est > à 1, tu n'affiches qu'un seul caractère alors que tu en as dépilés plusieurs
Avec un minimum de changements, je te suggère d'essayer le code suivant :
et laisse tomber errno pour l'instant. Tu pourras toujours sortir avec un ctrl-C si ça ne marche pas.
Si ça marche, tu pourras améliorer en faisant un truc du genre :
Autres choses :
- tu ne donnes pas le code qui appelle read_Serial_Port
- tu fais bien un tcgetattr pour modifier les paramètres de com, mais tu dois ensuite enregistrer les valeurs modifiées avec tcsetattr (est-ce bien nécessaire d'ailleurs, d'où viennent ces valeurs/ce code ? Tu utilises un périphérique USB qui émule un port série, il n'est pas toujours nécessaire dans ce cas de changer la vitesse de com qui est potentiellement fictive)
- si bytes_read est nul, tu affiches quand même un caractère...
- si bytes_read est > à 1, tu n'affiches qu'un seul caractère alors que tu en as dépilés plusieurs
Avec un minimum de changements, je te suggère d'essayer le code suivant :
bytes_read = read(file, data, 1); if (bytes_read > 0) { message[i] = *data; printf("%c", message[i]); i++; }
et laisse tomber errno pour l'instant. Tu pourras toujours sortir avec un ctrl-C si ça ne marche pas.
Si ça marche, tu pourras améliorer en faisant un truc du genre :
bytes_read = read(file, data, nbytes); if (bytes_read > 0) { for (j=0;j<bytes_read;j++) printf("%c", data[j]); i+=bytes_read; ...
Autres choses :
- tu ne donnes pas le code qui appelle read_Serial_Port
- tu fais bien un tcgetattr pour modifier les paramètres de com, mais tu dois ensuite enregistrer les valeurs modifiées avec tcsetattr (est-ce bien nécessaire d'ailleurs, d'où viennent ces valeurs/ce code ? Tu utilises un périphérique USB qui émule un port série, il n'est pas toujours nécessaire dans ce cas de changer la vitesse de com qui est potentiellement fictive)
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
ABouras
Messages postés
26
Date d'inscription
vendredi 16 novembre 2012
Statut
Membre
Dernière intervention
7 décembre 2012
Modifié par ABouras le 21/11/2012 à 10:23
Modifié par ABouras le 21/11/2012 à 10:23
Merci pour ta réponse, en faisant la première modif que tu me proposes :
J'obtiens sur le prompteur ceci :
Mais les caractères sont incompréhensibles ...
bool readMessage(int file, unsigned int nCountMax) { int i; size_t nbytes; ssize_t bytes_read; if (file != -1) { i = 0; char message[100] = {0}; char data[1] = ""; nbytes = sizeof(data); while (i<nCountMax) { bytes_read = read(file, data, 1); if (bytes_read >0) { message[i] = *data; printf("%c", message[i]); i++; } } message[i] = 0; return true; } }
J'obtiens sur le prompteur ceci :
Start read_Serial_Port function ... Serial port open successful ! Reading serial port ... CJ*$ CzQC*H Q$U$u[-CJQ$U$[CJ CJQ$U$0 S SCJMQ$U$ Serial port read successful Serial port closed
Mais les caractères sont incompréhensibles ...
totof31
Messages postés
163
Date d'inscription
lundi 29 octobre 2012
Statut
Membre
Dernière intervention
30 avril 2013
74
21 nov. 2012 à 10:32
21 nov. 2012 à 10:32
Alors essaie tout de même de jouer sur la vitesse de com :
- fait bien un tcsetattr()
- et si ça ne marche toujours pas, essaie d'autres vitesses standards
- fait bien un tcsetattr()
- et si ça ne marche toujours pas, essaie d'autres vitesses standards
totof31
Messages postés
163
Date d'inscription
lundi 29 octobre 2012
Statut
Membre
Dernière intervention
30 avril 2013
74
21 nov. 2012 à 10:33
21 nov. 2012 à 10:33
pardon, je viens de voir le tcsetattr
totof31
Messages postés
163
Date d'inscription
lundi 29 octobre 2012
Statut
Membre
Dernière intervention
30 avril 2013
74
21 nov. 2012 à 10:38
21 nov. 2012 à 10:38
Du coup, peux-tu essayer en commentant le tcsetattr ? Quand tu fais screen /dev/... tu ne changes pas les paramètres par défaut...
Peux-tu aussi donner le code d'appel de read_serial_port STP ?!
Peux-tu aussi donner le code d'appel de read_serial_port STP ?!
ABouras
Messages postés
26
Date d'inscription
vendredi 16 novembre 2012
Statut
Membre
Dernière intervention
7 décembre 2012
21 nov. 2012 à 10:42
21 nov. 2012 à 10:42
Non toujours pas, quelque soit la vitesse en Baud, je reçois ces caractères bizzares.
Autre chose, tu me demandais l'utilisation de la fonction read_Serial_Port(const char* DEVICE_PORT), j'ai juste fais un main() :
De plus, je remarque qu'en faisant cat /dev/ttyUSB0, j'obtiens les même caractères bizarres, mais si je fais un screen /dev/ttyUSB0, j'obtiens les bonnes données ... Comment faire pour afficher correctement mes données comme avec la commande screen au lieu de cat ?
Autre chose, tu me demandais l'utilisation de la fonction read_Serial_Port(const char* DEVICE_PORT), j'ai juste fais un main() :
int main() { const char* DEVICE_PORT = "/dev/ttyUSB0"; printf("Start read_Serial_Port function ...\n"); read_Serial_Port(DEVICE_PORT); }
De plus, je remarque qu'en faisant cat /dev/ttyUSB0, j'obtiens les même caractères bizarres, mais si je fais un screen /dev/ttyUSB0, j'obtiens les bonnes données ... Comment faire pour afficher correctement mes données comme avec la commande screen au lieu de cat ?
ABouras
Messages postés
26
Date d'inscription
vendredi 16 novembre 2012
Statut
Membre
Dernière intervention
7 décembre 2012
Modifié par ABouras le 21/11/2012 à 11:11
Modifié par ABouras le 21/11/2012 à 11:11
C'est bon ça marche !!!!!!!!!!!!!!!!!! merci beaucoup !!!!!!!!!
Dernière chose, j'aimerais recevoir les données :
de manière régulière, bloc par bloc. Là je reçois genre une seule fois, 60 caractères d'un coup (j'ai mis nCountMax = 60 dans la fonction pour essayer) :
puis si je réexecute :
Bref ... comment faire pour recevoir les données régulièrement ? Il faudrait que j'affiche les bloc en commençant par CHARS, puis que le bloc s'arrête sur le nombre de Roll, ensuite il recommence sur CHARS, ainsi de suite ...
Ensuite j'essayerai d'écrire ces données dans un fichier texte proprement de cette manière :
Dernière chose, j'aimerais recevoir les données :
CHARS : 15931 SENTENCES = 0 CHECKSUM : 58 Heading : 55 Tilt: -46 Roll:2 CHARS : .....
de manière régulière, bloc par bloc. Là je reçois genre une seule fois, 60 caractères d'un coup (j'ai mis nCountMax = 60 dans la fonction pour essayer) :
: -47 Roll: 1 CHARS : 3CHARS : 3809 SENTENCES : 0 CHECKSU
puis si je réexecute :
t: -46 Roll: 1 CHARS : CHECKSUM : 53 Heading: 53 Tilt: -46
Bref ... comment faire pour recevoir les données régulièrement ? Il faudrait que j'affiche les bloc en commençant par CHARS, puis que le bloc s'arrête sur le nombre de Roll, ensuite il recommence sur CHARS, ainsi de suite ...
Ensuite j'essayerai d'écrire ces données dans un fichier texte proprement de cette manière :
CHARS : 15931 SENTENCES = 0 CHECKSUM : 58 Heading : 55 Tilt: -46 Roll:2 CHARS : 15931 SENTENCES = 1 CHECKSUM : 59 Heading : 55 Tilt: -46 Roll:1 CHARS : 15931 SENTENCES = 0 CHECKSUM : 58 Heading : 54 Tilt: -45 Roll:1 ...
totof31
Messages postés
163
Date d'inscription
lundi 29 octobre 2012
Statut
Membre
Dernière intervention
30 avril 2013
74
21 nov. 2012 à 11:19
21 nov. 2012 à 11:19
Cool !
Qu'as-tu fait pour que ça marche finalement ?
Pour afficher les blocs il faut repérer les séquences qui t'intéressent. Il y a plusieurs façons de faire, essaie de regarder les fonctions strstr ou strtok ou sscanf...
Qu'as-tu fait pour que ça marche finalement ?
Pour afficher les blocs il faut repérer les séquences qui t'intéressent. Il y a plusieurs façons de faire, essaie de regarder les fonctions strstr ou strtok ou sscanf...
ABouras
Messages postés
26
Date d'inscription
vendredi 16 novembre 2012
Statut
Membre
Dernière intervention
7 décembre 2012
21 nov. 2012 à 11:30
21 nov. 2012 à 11:30
Ok je vais regarder ça ... Voici mon code :
D'ailleurs il n'y a pas une fonction pour compter le nombre de caractère reçu en un seul paquet ? parce que moi pour l'instant j'utilise à la main nCountMax = 60 ce qui m'affiche exactement 60 caratères, mais j'ai pris cette valeur pif juste pour tester ...
#include <stdio.h> #include <stdlib.h> #include <termios.h> #include <sys/fcntl.h> #include <unistd.h> #include <errno.h> #include <string.h> #include "serial_port.h" void read_Serial_Port(const char* DEVICE_PORT) { int file; struct termios options; unsigned int nCountMax = 60; bool b; file = open(DEVICE_PORT, O_RDONLY | O_NOCTTY | O_NDELAY); if(file == -1){perror("Unable to open the serial port\n");} 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; printf("Reading serial port ...\n\n"); b = readMessage(file, nCountMax); if (b == 0){printf("Error while reading serial port\n");} else printf("\nSerial port read successful\n"); close(file); printf("Serial port closed\n"); }; bool readMessage(int file, unsigned int nCountMax) { int i,j; ssize_t bytes_read; if (file != -1) { i = 0; char data[1] = ""; while (i<nCountMax) { bytes_read = read(file, data, sizeof(data)); if (bytes_read > 0) { printf("%c", data[0]); i += bytes_read; } } return true; } };
D'ailleurs il n'y a pas une fonction pour compter le nombre de caractère reçu en un seul paquet ? parce que moi pour l'instant j'utilise à la main nCountMax = 60 ce qui m'affiche exactement 60 caratères, mais j'ai pris cette valeur pif juste pour tester ...
totof31
Messages postés
163
Date d'inscription
lundi 29 octobre 2012
Statut
Membre
Dernière intervention
30 avril 2013
74
21 nov. 2012 à 15:00
21 nov. 2012 à 15:00
Si, c'est justement la fonction read : elle retourne au maximum sizeof(data), mais ce qui dans ton cas vaut 1. Essaie :
char data[1000];
int j;
bytes_read = read(file, data, sizeof(data));
if (bytes_read > 0)
{
for (j=0; j < bytes_read; j++)
printf("%c", data[j]);
}
Ton problème, c'est que des données sont envoyées en permanence, donc pas facile de savoir si tu as tout reçu ou pas, ou si tu commences à recevoir de nouvelles données, etc.
Si le rythme d'envoi des données est suffisamment lent, tu peux éventuellement utiliser un compteur qui s'incrémente à chaque fois que bytes_read est <= 0. Au delà d'une certaine valeur, tu peux ainsi savoir que tu as atteint la fin d'un bloc
char data[1000];
int j;
bytes_read = read(file, data, sizeof(data));
if (bytes_read > 0)
{
for (j=0; j < bytes_read; j++)
printf("%c", data[j]);
}
Ton problème, c'est que des données sont envoyées en permanence, donc pas facile de savoir si tu as tout reçu ou pas, ou si tu commences à recevoir de nouvelles données, etc.
Si le rythme d'envoi des données est suffisamment lent, tu peux éventuellement utiliser un compteur qui s'incrémente à chaque fois que bytes_read est <= 0. Au delà d'une certaine valeur, tu peux ainsi savoir que tu as atteint la fin d'un bloc