Why cannot I read data from a serial port?
I'm not sure what has happened but the following settings finally worked. I will share it with you as I got a lot of help here on Stackoverflow:
serial = open(name.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(serial, F_SETFL,0);
tcgetattr(serial, &options);
options.c_ispeed = _baudRate;
options.c_ospeed = _baudRate;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_iflag &= ~(INPCK|PARMRK|ISTRIP);
options.c_cflag &= ~CSTOPB;
options.c_cflag |= CREAD |CLOCAL ;
options.c_cc[VMIN]=0;
options.c_cc[VTIME]=10;
options.c_cflag &= ~CRTSCTS; // turn off hardware flow control
options.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off sowftware flow control
options.c_lflag &= ~ICANON;
options.c_lflag &= ~ISIG;
options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes
options.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
options.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
tcflush(serial, TCIFLUSH);
tcsetattr(serial, TCSANOW, &options);
Can't get C to write and read serial port
First,
if (buff=msg)
is assignment, not comparison :) The latter is ==
.
Second,
if (buff == msg)
is actually pointer comparison, not string comparison. For string comparison, see strcmp()
from C standard library.
Third,
char *buff;
...
rd=read(fd,buff,sizeof(msg));
buff
is left uninitialized - there's no memory allocated for it, so you're happy enough it doesn't crash at all.
Well, there is more to check, but listed above is already enough to prevent the program from functioning correctly.
As an advice: try to put a debugging printf
below the read
line to see what is actually read from the port. And remember, the data read from the port is not guaranteed to be zero-terminated (see zero-terminated strings
for reference), so you have to watch for this also (either add a zero after the actual data, or somehow limit string operations on the buffer, like using strncmp()
instead of strcmp()
).
C++ Serial port reading issue: does ioctl(FIONREAD) set a wrong value?
This code worked a few days ago but now it isn't anymore.
Fickle program behavior usually indicates improper or incomplete initialization.
Your termios initialization only configures the baudrate and character framing, and everything else is left to chance.
See Setting Terminal Modes Properly
and Serial Programming Guide for POSIX Operating Systems.
Your revised code still has not properly resolved this issue.
The code never initializes the termios structure options
by calling the tcgetattr() function.
For sample code see my answer to How to open, read, and write from serial port in C?
options.c_lflag = 0;
That is not considered the proper way of assigning a termios element.
options.c_cc[VMIN] = 1;
Non-canonical mode requires definition of both the VMIN and VTIME entries.
Your code uses whatever garbage value that exists at the location for VTIME.
See Linux Blocking vs. non Blocking Serial Read.
FIONREAD which doesn't write the correct number to the bytes_available-var (anymore).
Negative descriptions, i.e. what does not occur, are not as helpful or specific as descriptions of what does occur.
So what kind of values are you getting back?
Why do you think it is "wrong"?
More importantly, why aren't you checking the return value from each syscall, especially this ioctl() that you think is giving you problems?
Most likely is that the ioctl() failed, did not update your bytes_available
variable, and returned an error code.
Instead of first checking for a good return, your code unconditionally uses the returned argument.
Another answer that critiques your code is misleading. Flow control can be disabled. Your code is broken because it doesn't do proper initialization and is not checking for error returns, not because the comm link is "deadlocked".
In your revised code:
bytes_read = read(serial, buf, datalength-bytes_in_msg);
usleep(1000);
A sleep or delay before and/or after a blocking read is superfluous.
write() to serial port fails when called twice
I think that your send buffer is getting full and you are using a non-blocking socket which means that instead of waiting for the buffer to clear like in a blocking socket, the process just returns the "Resource temporarily unavailable error". See this thread for more info: What can cause a “Resource temporarily unavailable” on sock send() command
Related Topics
Dos2Unix: Binary Symbol Found, Skipping Binary File
Setting Environment Variable with Leading Digit in Bash
Dynamic Listening Ports Inside Docker Container
Programmatically Disable Hardware Prefetching on Amd Systems
Linux Kernel Changing Default CPU Scheduler
How Linux Scheduler Schedules Processes on Multi-Core Processors
Convert Charset from a Entire Project to Utf-8
Upgrading PHPmyadmin (And Other Packages) on Debian Squeeze
Golang Os/Exec, Realtime Memory Usage
How to Create a Virtual Device in Linux
How to Read/Write From/To a Linux /Proc File from Kernel Space
Does Each Unix File Description Have Its Own Read/Write Buffers
Docker with '-User' Can Not Write to Volume with Different Ownership