Club robotique de Sophia-Antipolis

Accueil > POBOTpedia > Programmation > Snippets > Communication avec le port série en C++ sous Linux

Communication avec le port série en C++ sous Linux

samedi 7 juillet 2012, par Laurent Ba.

Voici une petite classe pour le port série en C++. Autant sur micro-contrôleur le C c’est bien [1] [2]autant sur une carte disposant d’un système d’exploitation Linux comme la Raspberry Pi, ça peut être pratique de passer au C++.

Pour bien débuter sans devoir compiler et lier beaucoup de bibliothèques entre elles, comme boost ou LibSerial en embarqué.
Je sais pas vraiment ce que ca vaut mais en tout cas ça m’est bien utile. je vous laisse le soin de develloper la methode read.

Voici la classe :


/*
* =====================================================================================
*
* Filename : serial.cpp
*
* Description : open/write to serial port (alpha)
*
* Version : 1.0
* Created : 06/07/2012 12:22:14
* Revision : none
* Compiler : gcc
*
* Author : LaurentB
*
* =====================================================================================
*/
#include

<stdlib.h>

#include

<string.h>

#include

<stdlib.h>

#include

<stdio.h>

#include

<unistd.h>

#include

<fcntl.h>

#include

<termios.h>

#include
#include

<pthread.h>

#define LG_BUFFER 1024

using namespace std ;

/*
* =====================================================================================
* Class : Serial
* Description : open/write to serial port
* =====================================================================================
*/
class Serial

public :

Serial(const char *acm = "/dev/ttyACM0", speed_t vitesse = 9600)

memset(&tio,0,sizeof(tio)) ;
tio.c_iflag=0 ; //IGNPAR ;
tio.c_oflag=0 ;
tio.c_cflag=CS8|CREAD|CLOCAL ; // 8n1, see termios.h for more information
tio.c_lflag=0 ;
tio.c_cc[VMIN]=1 ;
tio.c_cc[VTIME]=5 ;

tty_fd = open( acm, O_RDWR | O_NONBLOCK) ;
if(tty_fd < 0)
perror("open") ;
printf("file => %s\n", acm) ;
exit(EXIT_FAILURE) ;

this->setBaud(vitesse) ;

void setBaud(speed_t vitesse)

if (vitesse < 51)
setspeed(B50) ;
else if (vitesse < 76)
setspeed(B75) ;
else if (vitesse < 111)
setspeed(B110) ;
else if (vitesse < 135)
setspeed(B134) ;
else if (vitesse < 151)
setspeed(B150) ;
else if (vitesse < 201)
setspeed(B200) ;
else if (vitesse < 301)
setspeed(B300) ;
else if (vitesse < 601)
setspeed(B600) ;
else if (vitesse < 1201)
setspeed(B1200) ;
else if (vitesse < 1801)
setspeed(B1800) ;
else if (vitesse < 2401)
setspeed(B2400) ;
else if (vitesse < 4801)
setspeed(B4800) ;
else if (vitesse < 9601)
setspeed(B9600) ;
else if (vitesse < 19201)
setspeed(B19200) ;
else if (vitesse < 34001)
setspeed(B38400) ;
else if (vitesse < 57601)
setspeed(B57600) ;
else
setspeed(B115200) ;

void putchar(char c)

write(tty_fd,&c,1) ;

void putchar(char *c, int n)

write(tty_fd,c,n) ;

void readSerial()

// en attendant la nouvelle version
nb_read = read(tty_fd, buffer, LG_BUFFER) ;
write(STDOUT_FILENO, buffer, nb_read) ;

void fclose()

if (close(tty_fd)<0)
perror("close") ;
exit(EXIT_FAILURE) ;

private :

void setspeed(speed_t vitesse)

cfsetospeed(&tio, vitesse) ;
cfsetispeed(&tio, vitesse) ;
tcsetattr(tty_fd,TCSANOW,&tio) ;

int nb_read ;
unsigned char buffer[LG_BUFFER] ;
struct termios tio ;
int tty_fd ;

 ; /* ----- end of class Serial ----- */

int main()

// exemple d’utilisation

Serial arduino("/dev/ttyUSB0") ;
Serial exotic("/dev/ttyACM0") ;

arduino.putchar(’t’) ;
arduino.setBaud(15200) ;

char ma_chaine_c[]="c\0\255\255" ;
exotic.putchar(ma_chaine_c,4) ;

sleep(1) ;

ma_chaine_c[3]= ’\0’ ;
exotic.putchar(ma_chaine_c,4) ;
sleep(1) ;

char another=’r’ ;
exotic.putchar(another) ;

exotic.fclose() ;
arduino.fclose() ;

return 0 ;

// fin du code, ne recopiez pas ce qui suit (bug de l’éditeur)

Et voilà, plus qu’à lancer un PC sous Linux ou notre RPi favorite, à copier tout ça dans un fichier serial.cpp et à compiler (avec la commande g++ à ne pas confondre avec gcc qui ne fait que du C). Si vous ne précisez rien, le compilateur sort un exécutable a.out que l’on peut lancer.

Voici le test sans Arduino connectée :

pi@raspberrypi:~/tests_cpp$ g++ serial.cpp
pi@raspberrypi:~/tests_cpp$ ./a.out
open: No such file or directory
file => /dev/ttyUSB0
pi@raspberrypi:~/tests_cpp$

D’autres tests à venir lors de nos ateliers, et des articles utilisant cette classe dans les sections de nos robots (voir Nono).


[1note de la rédaction : nos robots à base d’Arduino se programment en C++ depuis des années, mais bon...

[2Certes, mais il faut avouer que la plupart des utilisateurs programment leurs arduinos en language arduino ou en C

Un message, un commentaire ?

modération a priori

Attention, votre message n’apparaîtra qu’après avoir été relu et approuvé.

Qui êtes-vous ?

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici
  • Ce formulaire accepte les raccourcis SPIP [->url] {{gras}} {italique} <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document