Bonjour à tous,
Je suis actuellement en stage informatique et je dois porter une application qui tourne sur WinXP vers linux. Cette application utilise le port série pour lire des données reçues sur une carte infrarouge (télécommande).
J'ai déjà réalisé une bonne partie de l'application a savoir la configuration et la connexion du port série. J'utilise Qt pour l'interface graphique et pour l'événementiel mais mon appli peut tourner sans (un test au début lance le mode graphique ou le mode console).
Voila le problème : ma lecture ne me donne pas ce que je veux. La transmission de données se fait sur 3 octets et je sais que le premier est 0x4D ('M' en ASCII-UTF8). Seulement je reçois 0x78 ('x'). Cela fait une semaine maintenant que je cherche d'où cela peut venir et je suis vraiment paumé. J'ai fait des recherches sur termios, sur un nombre incalculable de forums différents et je n'ai pas trouvé une once de réponse ou personne n'ayant le même problème que moi.
Pour la configuration du port, j'ai récupéré un code sur le net que j'ai arrangé. Je ne comprenais pas tout au début mais maintenant, cela s'éclaircit.
Voila quelques bouts de mon code, ou je pense qu'il puisse y avoir une erreur.
Configuration du port série :
Code C/C++ :
void ComConnexion::saveconfig(Port &p){
tcgetattr(fd,&oldtio); // save current port settings
// set new port settings for canonical input processing
newtio.c_cflag = p.getBAUD() | p.getDATABITS() | p.getSTOPBITS() | p.getPARITYON() | p.getPARITY();
newtio.c_cflag |= CRTSCTS | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0; //ICANON;
newtio.c_cc[VMIN]=3;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcflush(fd, TCOFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
}
Lecture sur le port :
Code C/C++ :
void ComConnexion::readconnexiongraph(){//to receive datas
char In1 = 0x00;
int i,res;
char buf[8];
res = read(fd,buf,8);//lecture non bloquante
if (res>0){
ofstream sortie("sortie.txt", ios::out);
sortie<<endl<<res;
for (i=0; i<res; i++){ //for all chars in string
if(buf[i]!=0)In1 = buf[i];
sortie<< hex << (int)In1;
}
sortie.close();
}
}
Je précise que cette fonction est inclue dans une boucle.
La classe port.cpp
Code C/C++ :
#include "port.h"
using namespace std;
void Port::AfficherHex(char In){//Affiche en hexadecimal
cout<< hex << (int)In;
}
void Port::AfficherDec(char In){//affiche en decimal
cout<< dec << (int)In;
}
void Port::AfficherHexAsc(char In){//affiche en caractere ou hexa
if ((In<32) || (In>125)){
cout<< hex << (int)In;
}
else cout<<In;
}
void Port::AfficherDecAsc(char In){//affiche en caractere ou decimal
if ((In<32) || (In>125)){
cout<< dec << (int)In;
}
else cout<<In;
}
void Port::AfficherAsc(char In){//affiche en caractere
cout<<In;
}
void Port::Enregistrer(char In){//enregistre dans un fichier
ofstream sortie("sortie.txt", ios::out);
sortie<< hex << (int)In;
sortie.close();
}
Port::Port(){//Default
Name = "/dev/ttyS2";
BAUD=B9600;
DATABITS=CS8;
STOPBITS=1;
PARITYON=0;
PARITY=0;
Afficher=&AfficherAsc;
}
Port::Port(char *N,
int Baud,
int databits,
int stopbits,
int parity,
int affichage)
{
Name = N;
setBaud(Baud);
setDataLength(databits);
setStopBit(stopbits);
setParity(parity);
switch(affichage){
case 1 :
Afficher=&AfficherHex;break;
case 2 :
Afficher=&AfficherDec;break;
case 3 :
Afficher=&AfficherHexAsc;break;
case 4 :
Afficher=&AfficherDecAsc;break;
case 5 :
default:
Afficher=&AfficherAsc;break;
case 6 :
Afficher=&Enregistrer;break;
}
}
Port::Port(char *N,
char* Baud,
char databits,
char stopbits,
char parity,
int affichage)
{
Name = N;
setBaud(Baud);
setDataLength((int)databits-48);
setStopBit((int)stopbits-48);
if(parity=='N')setParity(0);
else if(parity=='O')setParity(1);
else if(parity=='E')setParity(2);
switch(affichage){
case 1 :
Afficher=&AfficherHex;break;
case 2 :
Afficher=&AfficherDec;break;
case 3 :
Afficher=&AfficherHexAsc;break;
case 4 :
Afficher=&AfficherDecAsc;break;
case 5 :
default:
Afficher=&AfficherAsc;break;
case 6 :
Afficher=&Enregistrer;break;
}
}
Port::Port(const Port& p){
if(this!=&p){
Name = p.Name;
setBaud(p.BAUD);
setDataLength(p.DATABITS);
setStopBit(p.STOPBITS);
setParity(p.PARITY);
Afficher=p.Afficher;
}
}
void Port::setBaud(char* Baud_Rate){
int i=0;
int baud=0;
while(Baud_Rate[i]!='\0'){
baud==baud*10+(int)(Baud_Rate[i]-48);
i++;
}
setBaud(baud);
}
void Port::setBaud(int Baud_Rate){
switch (Baud_Rate){
case 38400:
default:
BAUD = B38400;break;
case 19200:
BAUD = B19200;break;
case 9600:
BAUD = B9600;break;
case 4800:
BAUD = B4800;break;
case 2400:
BAUD = B2400;break;
case 1800:
BAUD = B1800;break;
case 1200:
BAUD = B1200;break;
case 600:
BAUD = B600;break;
case 300:
BAUD = B300;break;
case 200:
BAUD = B200;break;
case 150:
BAUD = B150;break;
case 134:
BAUD = B134;break;
case 110:
BAUD = B110;break;
case 75:
BAUD = B75;break;
case 50:
BAUD = B50;break;
}
}
void Port::setDataLength(int Data_Bits){
switch (Data_Bits){
case 8:
default:
DATABITS = CS8;break;
case 7:
DATABITS = CS7;break;
case 6:
DATABITS = CS6;break;
case 5:
DATABITS = CS5;break;
}
}
void Port::setStopBit(int Stop_Bits){
switch (Stop_Bits){
case 1:
default:
STOPBITS = 0;break;
case 2:
STOPBITS = CSTOPB;break;
}
}
void Port::setParity(int Parity){
switch (Parity){
case 0:
default: //none
PARITYON = 0;
PARITY = 0;
break;
case 1: //odd
PARITYON = PARENB;
PARITY = PARODD;
break;
case 2: //even
PARITYON = PARENB;
PARITY = 0;
break;
}
}
string Port::getName(){return Name;}
long Port::getBAUD(){return BAUD;}
long Port::getDATABITS(){return DATABITS;}
long Port::getSTOPBITS(){return STOPBITS;}
long Port::getPARITYON(){return PARITYON;}
long Port::getPARITY(){return PARITY;}
Cela ne vient pas du matériel car minicom fait une bonne lecture.