Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clearing the serial port's buffer

Tags:

This is what my function looks like to open the serial port (using Ubuntu 12.04):

int open_port(void)
{
  int fd; /* File descriptor for the port */

  fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);

  if (fd == -1)
  {
   // Could not open the port.          
   perror("open_port: Unable to open /dev/ttyUSB0 - ");
  }
  else
    fcntl(fd, F_SETFL, 0);

  struct termios options;

  tcgetattr(fd, &options); 
  //setting baud rates and stuff
  cfsetispeed(&options, B19200);
  cfsetospeed(&options, B19200);
  options.c_cflag |= (CLOCAL | CREAD);
  tcsetattr(fd, TCSANOW, &options);

  tcsetattr(fd, TCSAFLUSH, &options);

  options.c_cflag &= ~PARENB;//next 4 lines setting 8N1
  options.c_cflag &= ~CSTOPB;
  options.c_cflag &= ~CSIZE;
  options.c_cflag |= CS8;

  //options.c_cflag &= ~CNEW_RTSCTS;

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

  options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control

  return (fd);
}

What the problem is, is that when I run this program and if my serial device was already plugged in, the buffer has content in it. I need a way to clear the buffer before I start reading from it. I thought using tcsetattr(fd, TCSAFLUSH, &options); would fix this problem, by flushing the IO buffers before initializing the port, but no such luck. Any insight?

like image 532
capcom Avatar asked Oct 22 '12 14:10

capcom


People also ask

How do you flush a serial port?

Flush Serial Port Device Inputs and Outputs Create a connection to a serial port device. Write some data to the device and view the number of bytes available to be read in the input buffer. Flush both the input and output buffers. flush(device);

What is serial port buffer?

The input buffer is computer memory allocated by the serial port object to store data that is to be read from the device. When reading data from your device, the data flow follows these two steps: The data read from the device is stored in the input buffer.

What does serial flush do?

Description. Waits for the transmission of outgoing serial data to complete. (Prior to Arduino 1.0, this instead removed any buffered incoming serial data.)

What is serial port buffer size?

The size of this serial port buffer was originally only one byte, but today it is usually 16 bytes (more in higher priced serial ports).


2 Answers

I think I figured it out. For some reason, I need to add a delay before flushing. These two lines added before returning fd seem to have done the trick:

  sleep(2); //required to make flush work, for some reason
  tcflush(fd,TCIOFLUSH);
like image 113
capcom Avatar answered Sep 22 '22 01:09

capcom


The cause of this problem lies in using a USB serial port. If you use a regular serial port, you will not have this problem.

Most USB serial port drivers don't support flushing properly, probably because there's no way of knowing if there's still data in the internal shift register, FIFO or in the USB subsystem.

See also Greg's reply to a similar problem reported earlier here.

Your sleep may cure the problem, but it's only a work-around. Unfortunately there is no solution other than using a regular serial port.

like image 26
Robert Avatar answered Sep 24 '22 01:09

Robert