PC <-> Arduino serial problems

I'm having serious issues when interfacion arduino with C code on my linux box.

the code on the linux box is like this:

a loop
write(fd, "get", 3); // tell arduino to send data
read(fd, &buffer, 8); // read 8 bytes;
end of loop

the first time i read, it returns crap.
the second time too.
the third time starts working.

I can solve it with a sleep(1) before reading, but it's not desired.
I've coded too, a loop with a select call for polling the file descriptor for incoming data, and i get a timeout for the first and second time.

I really don't know whats happening, i need help!

What kind of crap?

What kind of Arduino? If it's a Diecimila, opening the serial port will reset the board, meaning that your first few bytes will go to the bootloader. That might be the data you're seeing.

mmm can you explain it with more detail?

There's some more info here: http://www.arduino.cc/en/Tutorial/Bootloader

but that is not my problem, since i can wait a minute before sending data, and it generates the same error.
my problem is that when i do a write, and then a read, i will get random data. If i put a sleep(1) between write and read, i get a good result.

read() is not guaranteed to return the number of bytes you ask for, and I see you aren't checking the return status to find out how many bytes are actually read.

My guess is that your sub-optimal use of read() combined with the much greater speed of the desktop is causing the problem. Put read() in a loop to get characters until you have the buffer full, then go on to the next step in the program.

-j

i tried using a loop with select calls, and i got always 1-2 timeouts. After that, i got good results.
also, the sleep(1) is incredible, since it removes the error always.

sleep() only hides the problem, it doesn't fix it.

IIRC, select() only tells you if the fd has data available for reading, not how many characters are available.

Good programming practice dictates that you should pay attention to the number of bytes that read() actually reports being read and fill your input buffer until the desired number of bytes have been read, especially when there is such a speed difference between the devices (e.g. your desktop screaming along at 3GHz connected to the Arduino running at 16MHz).

-j

mmm i'll try that, thanks for the tip. ::slight_smile:

ahhh thanks for the tips, finally i did it.
here is the working function:

int fdread(int fd, void *buffer, int size, int timeout) {  // timeout in milliseconds
  char *ptr = (char*)buffer;
  int received = 0;
  long int tout;
  struct timespec current;

  clock_gettime(CLOCK_REALTIME, &current);
  tout = current.tv_nsec + (timeout*1000000);
      
  while((received < size) && (tout > current.tv_nsec)) {
    if (read(fd, ptr, 1) == 1) {
      ptr++;
      received++;
    }
    clock_gettime(CLOCK_REALTIME, &current);
  }
  return received;
}