1

I am reading the Sensor data (broadcasted on RS232) with read() function. The data rate is 264 Bytes / Sec.

I am using the following code to read the data (I just needed to read 60 Bytes).

int BytesToRead = 60;
unsigned char* iBuffer = new unsigned char[BytesToRead];
int ret = read(COM, iBuffer, BytesToRead);

cout<<ret<<endl;    

if (ret == 0) {
cout<<"Error Reading COM Port"<<endl;
exit(EXIT_FAILURE);         // Error Handling
} 
delete[] iBufer;

And this program is returning random bytes (~30).

I am a beginner for C++ programming. Sorry, If I am doing some stupid mistake.

Thanks.

My COM function:

int Connect(const char *DeviceName){

long BAUD = B115200;
long DATABITS = CS8;            // CS8 = 8n1 Config.(8 bits, No parity, 1 Stop Bit)
long VMIN_CC = 1;           // 1 input byte is enough to return from read()
long VTIME_CC = 0;          // Inter-character timer
long STOPBITS = 0;          // Defined with CS8
long PARITYON = 0;          // NONE (Ref.: IH2 Azzura Hand User Guide)
long PARITY = 0;            // NONE (Ref.: IH2 Azzura Hand User Guide)


struct termios config;          // Configuration of the termios structure
fd_set rdset;               // File discription set

//Basic serial interface configuration  
//iflag = Input flag || oflag = Output flag || lflag = No-line processing flag
//c_cflag = Caracter processing flag || c_cc = Special character flag

memset(&config,0,sizeof(config));
config.c_iflag = 0;             // Turning OFF Input processing
config.c_oflag = 0;             // Turning OFF Output processing
config.c_lflag = 0; 
config.c_cflag = DATABITS |CREAD|CLOCAL;// Enable the receiver and set local mode
config.c_cc[VMIN] = VMIN_CC;        
config.c_cc[VTIME] = VTIME_CC;      

//Opening the Port for communication
int com = open(DeviceName, O_RDWR | O_NOCTTY);

//Error Handling    
if (com < 0) {
cout<<"ERROR!! Opening Port \n"<<"Sys:"<<strerror(errno)<<endl;
exit(EXIT_FAILURE);
} else {cout<<"Serial Communication (Opening Port): "<<strerror(errno)<<endl;}

//Setting the BaudRate for Communcation
cfsetispeed(&config, BAUD);
cfsetospeed(&config, BAUD);

//Applying Configuration / Attributes
int Attr = tcsetattr(com, TCSANOW, &config);

//Error Handling
if(Attr < 0){
    cout<<"ERROR!! Setting Attributes \n"<<"Sys:"<< strerror(errno)<<endl;
    exit(EXIT_FAILURE);
    } else {cout<<"Serial Communication (Setting Attributes): "<<strerror(errno)<<endl;}

return(com);

}

Uday
  • 45
  • 6
  • 1
    http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c - if I'm not mistaken, read() is not obliged to return all bytes requested, so if it returns less than what you need you need to call it again. Or make the call blocking as in the link, so read waits until all bytes are available. Also the 3rd argument is size_t, not int – stijn May 22 '14 at 15:46
  • Also post how you construct the `COM` object. Like stijn points out, the third param to the read(...) should be a size_t (unsigned integer type), and not an int. When you say "random bytes" do you mean you get 30 meaningful bytes, and 30 bad ones? Or do you only get 30 bytes all of garbage? – sabhiram May 22 '14 at 15:53
  • 1
    @stijn: Making `BytesToRead` a `size_t` would be better style, but making it an `int` is not an error. The argument is implicitly converted to the correct type, and as long as the number of bytes doesn't exceed `INT_MAX` (which is at least 32767), using `int` won't cause any actual problems. – Keith Thompson May 22 '14 at 15:56
  • I tried it by changing the 3rd argument of read(). But, still it remains the same. – Uday May 22 '14 at 16:02
  • @All Thanks [Its solved] The first Cycle I am sending a command to the electronics for setting sampling rate. So there is a random byte transmission. But, if I wait for a while (some milli seconds), The function returns right amount of bytes requested. – Uday May 22 '14 at 16:04

2 Answers2

4

I am assuming this is a Linux system.... Your BytesToRead variable is only a suggestion to read() in that read() will try to read up to BytesToRead. If read() returns less than your requested amount, then fewer bytes were available to be read. From the linux manpage on read

... It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal...

It is possible that your sensor is not sending the data you expect, or you are not giving it enough time to transfer all of the data, or there is some other logic/hardware problem that is not apparent from your code example.

Justin H.
  • 143
  • 8
1

read() is not guaranteed to return the number of bytes requested:

From the read(2) Linux manpage:

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.

crashmstr
  • 28,043
  • 9
  • 61
  • 79
Mark Nunberg
  • 3,551
  • 15
  • 18