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);

}

5
  • 1
    stackoverflow.com/questions/6947413/… - 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 Commented May 22, 2014 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? Commented May 22, 2014 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. Commented May 22, 2014 at 15:56
  • I tried it by changing the 3rd argument of read(). But, still it remains the same. Commented May 22, 2014 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. Commented May 22, 2014 at 16:04

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. It is the problem from hardware side.
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.