Your program does not properly open() the serial port for reading it.
In fact it repeatedly opens it two times every iteration of the for loop.
The device should be opened only once by your program.
Instead of
for (i=0; i<50; i++) {
fcntl(open_port(), F_SETFL, FNDELAY);
bytes_read = read(open_port(), buf, nbytes);
}
the main program should be structured like
fd = open_port();
if (fd < 0) {
/* handle error condition */
}
rc = fcntl(fd, F_SETFL, FNDELAY);
if (rc < 0) {
/* handle error condition */
}
for (i=0; i<50; i++) {
bytes_read = read(fd, buf, nbytes);
if (bytes_read < 0) {
/* handle error condition */
}
}
close(fd);
Your program is too "simple". It sets only a few attributes, and doesn't bother to check the return codes of system calls.
Is this supposed to be canonical or non-canonical (aka raw) mode (i.e. is the data ASCII text or binary)?
Refer to this Serial Programming Guide for proper setup of the serial port.
read data from a USB port
USB is a bus.
The device your program reads from is a serial port attached to that USBus.
Second coding issue
Your original code may print garbage data.
nbytes = sizeof(buf);
bytes_read = read(open_port(), buf, nbytes);
printf("%s ", buf);
buf[0]=0;
The bytes returned by the read() operation are not likely to be terminated by a NULL byte, so a string operation on that read buffer could exceed the bounds of the allocated array.
Code that would not misbehave would be something like:
nbytes = sizeof(buf) - 1;
bytes_read = read(fd, buf, nbytes);
if (bytes_read < 0) {
/* handle error condition */
} else {
buf[bytes_read] = 0; /* append terminator */
printf("%s ", buf);
}
Note that nbytes is one less than the allocated size of the buffer.
This is to ensure that there is an available byte to store the string terminator byte when the read() operation returns a "full" buffer of nbytes.
For efficiency the assignment of nbytes should be performed before entering the for loop, rather than within the loop.