I am trying to work with read() function with serial connection.
I initialize serial port with the following settings:
bool HardwareSerial::begin(speed_t speed) {
int USB = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (USB == 1) {
std::cout << "\n Error! in Opening ttyUSB0\n" << std::endl;
} else {
std::cout << "\n ttyUSB0 Opened Successfully\n" << std::endl;
}
struct termios tty;
struct termios tty_old;
memset(&tty, 0, sizeof tty);
// Error Handling
if (tcgetattr(USB, &tty) != 0) {
std::cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << std::endl;
}
//Save old tty parameters
tty_old = tty;
// Set Baud Rate
cfsetospeed(&tty, (speed_t) speed);
cfsetispeed(&tty, (speed_t) speed);
// Setting other Port Stuff
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 1; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
// Make raw
cfmakeraw(&tty);
//Flush Port, then applies attributes
tcflush(USB, TCIFLUSH);
if (tcsetattr(USB, TCSANOW, &tty) != 0) {
std::cout << "Error " << errno << " from tcsetattr" << std::endl;
}
_USB = USB;
return true;
}
Then I periodically call class member read() function that calls stream read:
int HardwareSerial::read() {
int n = 0;
char buf;
n = ::read(_USB, &buf, 1);
std::cout << std::hex << static_cast<int> (buf) << " n:";
std::cout << n << std::endl;
}
While the port receives data read() works as expected and prints incoming bytes. But if I stop sending bytes the program hangs until some bytes will have not received. I expect that ::read will return 0, but it does not return anything and waits for incoming data. After new data is received the program continues work and ::read returns 1;
So what I missed in the configuration? I tried different VMIN and VTIME but the result is the same.