Utilisation port série

Bonjour tout le monde, j’aimerai pouvoir utiliser mon port RS232 afin de récupérer des trames provenant d’un capteur et de lui en envoyer. Petit problème, la communication s’effectue en mode non canonique (lecture s’effectuant par trame de longueur définie et non pas par trame terminée par un retour chariot). J’ai essayé pas mal de truc et ma configuration du port n’est toujours pas bonne.

Comment configurer correctement un port com pour s’en servir en mode non canonique 19200bds, No parity, 8 databits, 1 stopbit et pas de flow control), comment lire et écrire dessus, j’ai lu le how-to de serial programming et j’ai encore du mal.

Il y a pas à dire le mode canonique c’est largement plus sympa pour l’envoi et la réception de trames.

[code]#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define BAUDRATE B19200
#define MODEMDEVICE “/dev/ttyS0”
#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_s[255];

fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); 
if (fd <0) {
	perror(MODEMDEVICE); 
	exit (-1);
}
/* Configuration du port */
fcntl(fd, F_SETFL, 0);

tcgetattr(fd,&oldtio);
bzero(&newtio, sizeof(newtio));

/* mode RAW, pas de mode canonique, pas d’écho /
newtio.c_iflag = IGNBRK;
newtio.c_lflag = 0;
newtio.c_oflag = 0;
/
Controle de flux hardware /
newtio.c_cflag |= ~(CREAD | CRTSCTS);
/
1 caractère suffit /
newtio.c_cc[VMIN] = 1;
/
Donnée disponible immédiatement /
newtio.c_cc[VTIME] = 0;
/
Inhibe le contrôle de flux XON/XOFF /
newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
/
8 bits de données, pas de parité /
newtio.c_cflag &= ~(PARENB | CSIZE);
newtio.c_cflag |= CS8;
/
Gestion des signaux modem */
newtio.c_cflag &= ~CLOCAL;
tcsetattr(fd, TCSANOW, &newtio);

while (1) {
	res = read(fd,buf,255);
	buf[res]=0;
	printf(":%X:%d\n", buf, res);
}
printf("test\n");
tcsetattr(fd,TCSANOW,&oldtio);

}[/code]

J’ai ce code qui fonctionne avec un multimètre

[code]#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>

#define LG_BUFFER 1024

void

setspeed (struct termios * config, speed_t vitesse)
{
cfsetispeed (config, vitesse);
cfsetospeed (config, vitesse);
}

int

main (int argc, char * argv [])
{
char * nom_tty = « /dev/ttyS0 »;
int fd_tty = -1;
struct termios configuration;
struct termios sauvegarde;

char    buffer [1024];
int     nb_lus,i;

int     option;

char	cr[]="\n";


fd_tty = open (nom_tty, O_RDWR | O_NONBLOCK);  // Ouverture du premier port serie
if (fd_tty < 0) {
	perror (nom_tty);
	exit (1);
}
if (tcgetattr (fd_tty, & configuration) != 0) { // lecture de la configuration du port et sauvegarde de celui ci dans la structure configuration
	perror ("tcgetattr");
	exit (1);
}
configuration . c_cflag	&= ~ CLOCAL;
tcsetattr (fd_tty, TCSANOW, & configuration);

// <Attention changement !!!>
fd_tty = open (nom_tty, O_RDWR /*| O_NONBLOCK */); // Reouverture du premier port serie
// </Fin changement>
if (fd_tty < 0) {
perror (nom_tty);
exit (1);
}
fprintf (stderr, « Port série ouvert \n »);
tcgetattr (fd_tty, & configuration);
memcpy (& sauvegarde, & configuration, sizeof (struct termios));
cfmakeraw (& configuration);
setspeed (& configuration, B1200); // vitesse 1200 bits/s
configuration . c_cflag &= ~ PARENB;
configuration . c_cflag &= ~ CSIZE;
configuration . c_cflag |= CS7; // taille des donneés 7 bits
configuration .c_cflag |= CSTOPB; // 2 bits de stops
//
//configuration.c_lflag |= ICANON;

            //configuration.c_cc[VEOF]=0x0d; // caractere retour chariot est définit comme caractere de fin de ligne
	configuration.c_cc[VMIN]=2; // On bloque au minimum jusque l'on ait 255 carcateres
	configuration.c_cc[VTIME]=5; // On tolère un temps d'attentes entre caractere de 5*0,1s=0,5s

// </Attention fin changement>

if (tcsetattr (fd_tty, TCSANOW, & configuration) < 0) { // application des nouveaux parametres sur notre port serie
	perror ("tcsetattr");
	exit (1);
}
fprintf (stderr, "Port série configuré \n");


write(fd_tty,cr,strlen(cr)); // demande d'une acquisition au multimetre
				// à l'aide de l'émission d'un caractere sur la liaision série
puts("write 1");puts(cr);
//sleep(2);	// petite temporistion de 2 secondes
nb_lus=read(fd_tty,buffer,255);	//lecture de 255 caracteres au grand maximum sur la liason serie
printf("nb_lus=%d\n",nb_lus);
if (nb_lus<0)	exit(1);
buffer[nb_lus]=0; // on force le caractere fin de chaine
puts("write 2");puts(buffer);


close (fd_tty); // fermeture du descripteur de la liason serie
fd_tty = open (nom_tty, O_RDWR | O_NONBLOCK); //reouverture de la liaision serie
sauvegarde . c_cflag |= CLOCAL;
tcsetattr (fd_tty, TCSANOW, & sauvegarde); //reintialisaton de la liaison serie à l'aide de la configuaration d'origine
close (fd_tty);// fermeture du descripteur de la liaison serie
return (0);

}

[/code]

J’aime bien le mode brut. Mais cela dépend de l’application.

Pareil, mais je me suis surtout dépanné grâce à ce bouquin.

J’ai essayé de m’inspirer de ce que tu avais fait dans ton code et j’y ai trouvé des choses intéressantes comme la fonction cfmakeraw mais je suis toujours bloqué, je n’arrive toujours pas à communiquer avec ce capteur. :cry:

Tu as quoi comme message?
Il bloque où le programme par rapport à mon code (vu qu’il a pas mal de message qu’il affiche afin de savoir où il y a un problème)?
Quel type de capteur que tu utilises?
As tu fais un test entre deux PC?

Mon problème vient de la configuration de mon port je pense ou peut-être de la manière dont je me sers des fonctions pour dialoguer avec. Le type du capteur, peut importe, la seule chose qui est importante est : mode non canonique 19200bds, No parity, 8 databits, 1 stopbit et pas de flow control (pas de Xon Xoff, pas CRTSCTS). J’ai essayé de faire communiquer mon pc avec un autre ordinateur avec docklight dessus (programme très sympatique pour pouvoir envoyer/recevoir des trames sur le port série), je n’arrive pas à communiquer avec et pourtant ce pc communique très bien avec le capteur grâce à ce programme.

Mon code bloque sur le read ce qui veut dire que je n’arrive pas à recevoir. J’ai tenté d’implémenter une émission avec write mais il n’envoie aucune trame. 'est pour cela que je pense que la configuration laisse à désirer, si quelqu’un pouvait m’aider sur ce point cela serait sympa.

Je cherche à recevoir des données caractère par caractère et à envoyer des trames à ce capteur. (capteur de débit liquide)

Et DTR/DSR?
Je ne connais pas ton programme de test doc… mais tu devrais peut être faire un essai avec gtkterm (il est inclus dans la sarge).

En dessous à droite de la fenêtre principal on peut bien observer l’état de DTR/DSR. Et en plus on peut visuliser les octets en hexadécimal très pratique quand on travaille en mode brut avec des formats de trame.

Docklight est un programme très bien fait pour la communication en mode terminal, il tourne sur windows sur une autre machine que ma machine de développement. Très pratique et très complet, à tester au moins une fois si vous avez encore un windows.

voici donc les paramètres de configuration de mon gtk term pour qu’il communique avec mon capteur :

Port : /dev/ttyS0
Vitesse : 19200
Parité : none
Bits : 8
Bit de stop : 1
Contrôle de flux : none

Pour ce qui est des indicateurs en bas à droite de ma fenêtre principale, DTR et RTS sont noircis, le reste est grisé. Est ce que dans mon programme j’ai mal effectué la configuration ? Est ce que j’utilise mal les fonctions de lecture et écriture ?

Je suppose que tu as utlisé gtkterm.

Par Défaut gtkterm valide DTR et RTS (donc noircis comme sur la photo).
Et dans ce cas est que ça marche?

Fait un essai en dévalidant DTR et RTS ( grisés comme CD sur la capture d’écran).
Si ça ne fonctionne pas dans ce cas et que c’était au positive dans le premier cas cela veut dire au moins qu’il utiise DTR et qu’il faudra que tu le valides dans ton programme.

Il me semble quand on parle de contrôle de flux cela concerne seulement RTS/CTS.

Oui pardon je parlais du paramètrage de mon gtk term. La communication par gtk term fonctionne même si l’on grise DTR et RTS.

Pour le contrôle du flux, il n’y a pas que RTS/CTS qui existe, il y a aussi le Xon et Xoff.