问题
This code is reading data from RFID module(EM-18) .I have a big problem here. When my application was running and I was passing RFID card from em module, It was reading data in 2 part. First read 8 byte's card ID then send 4 bytes. Like this:
[root@FriendlyARM /fgit]# ./RFIDMonitor -qws
enter the port name:
ttySAC3
open_port: succesfully open port
open_port: succesfully open port
RFID MONITORING => '010B7528'
RFID MONITORING => '297E'
RFID MONITORING => '010B7528'
RFID MONITORING => '297E'
I changed VMIN and VTime but the result did not change.
This is my code:
if(!fork())
{
while(1)
{
memset(buf2,'\0',MAXDATASIZE);
//------------------------------------------------
if ((numbytes = read(fd,buf2, MAXDATASIZE-1)) != -1)
{
buf2[numbytes] = '\0';
printf("RFID MONITORING => '%s'\n",buf2);
}
}
}
This is my config :
int openport(void)
{
cout<<"enter the port name:\n";
string portname="";
cin>>portname;
portname="/dev/"+portname;
fd=open(portname.c_str(),O_RDWR|O_NOCTTY|O_NDELAY);
if (fd==-1)
{
//printf("open_port: unable to open port \n");
return -1;
}
else
{
//printf("open_port: succesfully open port \n");
fcntl(fd,F_SETFL,0);
return 1;
}
}
//-------------------------------------
void closeport(void)
{
close(fd);
}
//-------------------------------------
void configport(void)
{
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
/* Error Handling */
if ( tcgetattr ( fd, &tty ) != 0 ) {
std::cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << std::endl;
}
/* Save old tty parameters */
tty_old = tty;
/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B9600);
cfsetispeed (&tty, (speed_t)B9600);
/* Setting other Port Stuff */
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] =1;// change to 0 and 5
tty.c_cc[VTIME] = 10;// change to 0 and 5
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
/* Make raw */
cfmakeraw(&tty);
/* Flush Port, then applies attributes */
tcflush( fd, TCIFLUSH );
if ( tcsetattr ( fd, TCSANOW, &tty ) != 0) {
std::cout << "Error " << errno << " from tcsetattr" << std::endl;
}
}
I want to show like this (all data in one part)
RFID MONITORING => '010B7528297E
回答1:
read only reads what is available to be read. If you have to read the whole the whole thing, keep reading until you have the whole thing.
while(1)
{
memset(buf2,'\0',MAXDATASIZE);
int bytesread = 0;
//------------------------------------------------
//Keep going until the whole message has been read
while (bytesread != MAXDATASIZE-1)
{
//read less on successive reads, but write further into buffer
if ((numbytes = read(fd,buf2[bytesread], MAXDATASIZE-1-bytesread)) == -1)
{
printf("Error in reading data");
// handle error. Probably reopen port and resynch with RFID
}
else
{
// keep track of where we are in accumulating
bytesread += numbytes;
}
}
buf2[bytesread] = '\0';
printf("RFID MONITORING => '%s'\n",buf2);
}
回答2:
I solve the problem ( just append that with sleep 1 second)
int numbytes;
char buf2[MAXDATASIZE];
//*****************************
// SerialCodes
//*****************************]
fd=-1;
while(fd==-1)
{
int a=openport();
if(a==1)
{
pid_t pid;
if((pid=fork()))
{
qDebug()<<("%d",pid);
while(1)
{
//------------------------------------------------
if ((numbytes = read(fd,buf2, MAXDATASIZE-1)) == -1)
{
//qDebug()<<("Error in reading data");
}
else
{
buf2[numbytes] = '\0';
usleep(10000);
QString s1(buf2);
memset(buf2,'\0',MAXDATASIZE);
read(fd,buf2, MAXDATASIZE-1) ;
QString s2(buf2);
memset(buf2,'\0',MAXDATASIZE);
qDebug()<<("RFID MONITORING => '%s'\n",s1+s2);
kill(pid,SIGTERM);
break;
}
}
}
}
}
来源:https://stackoverflow.com/questions/35680497/how-to-change-this-code-to-read-all-data-from-serial-port-in-one-part-not-2-par