LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-05-2008, 04:42 AM   #1
windell
LQ Newbie
 
Registered: Jun 2004
Posts: 12

Rep: Reputation: 0
serial port not filling buffer entirely


Hi, I'm writing a program that fetches 38 byte samples via the serial port. After each fetch I print out the amount of bytes read and then print out the hex representation of the array of characters. I throw away 4 bytes from the beginning of each sample therefore I only want to read 34 bytes each pass through the program.

During a run, most of the new byte counts are 34 however some of them are 33, 7 etc. In addition, when I print the hex representation not all of the characters print. For example for a 34 byte character array, only 13 bytes printed out.

I have the serial port setup for non-canonical reading however...i followed a tutorial so I do not know the if I am setting up a serial port properly for my application.

I have a feeling that it has to do with the serial port forcing itself to return before 34 bytes are read. And the printf is taking too long so the program stops it and moves on.

I would like to make sure that I am reading sold 34 bytes each pass and would like to print them to the screen for debugging.

Any pointers would be greatly appreciated!

I have pasted my configuration code and read code below. init_port is the function called to do the configuration.

Code:
int main()
{
char port_name[] = "/dev/ttyUSB0";	//set port name here.
int fd;

//-------------open ports---------------------------------
fd = open(port_name, O_RDWR | O_NOCTTY | O_NDELAY);

if (fd == -1){
	perror("unable to open /dev/ttyUSB0\n");
	return 1;
}
else
{
	printf("Connected to %s\n",port_name);
	fcntl(fd,F_SETFL,0);
}
//----------------------------------------------------------

//initialize the port for use.
initport(fd);

char received[READ_BYTES+1];

while (1)
{
//printf("--------------------------------------------------------------------------\n");
find_sync_bytes(fd);
readport(fd,received);
print_str_to_hex(received);		//print the string in hex form.
}
//-----------------------------------------------------------
//close the serial port.
close(fd);
return 0;
}
Code:
int readport(int fd, unsigned char *result){
	int new_bytes,bytes_read_tot;
	new_bytes=0;
	result[0]=0x00;	//clear buffer before reading it.

	new_bytes = read(fd,result,READ_BYTES);
	printf("new_bytes: %d\n",new_bytes);
	if(new_bytes<0){
			if(errno == EAGAIN){
				printf("SERIAL EAGAIN ERROR\n");
				return 0;
			}	
			else{
				printf("SERIAL read error %d %s\n",errno,strerror(errno));
				return 0;
			}
		}//end if.
//	}//end for.
	result[new_bytes] = 0x00;	//terminate string.
	//result[bytes_read_tot] = 0x00;	//terminate string.

	return 1;
}//end readport function.

int initport(int fd){
	struct termios options;
	tcgetattr(fd, &options);	//get the current options for the port.
	cfsetispeed(&options, B115200);	//set baud rate for input port.
	cfsetospeed(&options, B115200);	//set baud rate for output port.

	//enable the receiver and set local mode.
	options.c_cflag |= (CLOCAL | CREAD);

	options.c_cflag &= ~PARENB;
	options.c_cflag &= ~CSTOPB;
       	options.c_cflag &= ~CSIZE;
	options.c_cflag |= CS8;

	//raw input set.
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

	//set the new options for the port.
	tcsetattr(fd, TCSANOW, &options);

	return 1;	
}//end initport function.

void print_str_to_hex(unsigned char *char_string){
	int i;
	printf("hex representation:\n");
	for(i=0;char_string[i]!=0x00;i++){
		printf("%02X ",char_string[i]);	
	}//end for.
	printf("\n");
}//end of str_to_hex function.

int find_sync_bytes(int fd){
	int read_count =0;		//initialize read count to zero.
	int sync_count =0;		//initialize sync characters to zero.
	int in_sync =0;			//assume that the buffer is not yet insync.
	unsigned char buffer[10];
	//while four sync bytes have not been read and max read count has not been exceeded...
	while((read_count<MAX_TRIES) && (sync_count<4)){
		buffer[0]=0x00;		//set first element to \0.
		read(fd,buffer,1);	//read and store a single byte.
	if(buffer[0]==0xFF)		//if char is sync char...
		sync_count++;
	else
		sync_count=0;
	if(sync_count==4)		//if sync count is four...
		in_sync=1;		//raise in_sync flag.
	else
		in_sync=0;		//otherwise keep the flag low.
	read_count++;
	}//end while.
	if(read_count>=MAX_TRIES)
		printf("Can't find sync characters.\n");	//let user know can't find sync chars.
return 0;
}//end find_sync_bytes function.
 
Old 08-05-2008, 10:12 AM   #2
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,786

Rep: Reputation: 282Reputation: 282Reputation: 282
Your print routine will only print till it finds 0x00. Any chance that that occures in the received data as well? If so, it explains the problem where you only print e.g. 13 hex values.

As binary data can contain any value from 0x00 to 0xFF, I would not use your approach for the print function but pass a length as well.

If you want to make sure that you receive 34 bytes, you must read (in a loop) till you've got 34

Code:
newbytes=0;
do
{
    newbytes+=read(fd,&result[newbytes],READ_BYTES);
} while(newbytes<34);
You need to polish it as you might get 33, next 7 making a total of 40 and your result buffer might be smaller.

And last but not least, your transmitting side might do some funnies as well like sending 33 bytes and placing the last byte in the next packet or not transmitting it at all.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
flush the serial buffer fizgig10 Linux - General 1 09-21-2009 03:29 AM
Querying serial buffer mmcshmi11 Linux - Software 2 07-09-2008 12:43 AM
Query buffer with serial port /dev/ttyS0 mmcshmi11 Linux - Hardware 2 07-08-2008 04:24 PM
Serial Port Buffer Overrun damiendusha Linux - Hardware 1 06-22-2006 02:56 AM
message logs filling up w/ wlan0 buffer too small error sordomudo11 Linux - Hardware 0 04-13-2004 09:13 PM


All times are GMT -5. The time now is 08:02 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration