Reputation: 11
I am using fgets in a small C program - running under Ubuntu - to read data coming from Arduino via its FTDI USB/Serial converter. I am using low level I/O function from GNU libc (since I want - in the future - be able to control baud rate etc) and then promoting from descriptor to stream in order to use higher leve I/O functions. The observed behaviour of my program suggests that the fgets function does not block until the line terminator is acquired (as in my opinion it should do).
Any explanation?
The codes of my programs are here -> PC side:
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#define bufLen 81
int main(void) {
int fd; /* File descriptor for the port */
FILE * f; /* port will be identified also as stream 'f'*/
char buf[bufLen];
fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY);
if (fd == -1) {perror(""); return errno;}
else {
f = fdopen(fd, "r+t");
while (1) {
if (fgets(buf,bufLen,f)) {
printf("{%s}\n",buf);
sleep(1);
} else {
{perror("ahhhh! ");}
}
}
}
return 0;
}
-> Arduino side:
char ar[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
int k1 = 0, k2 = 0;
void setup() {
// initialize serial:
Serial.begin(9600);
}
void loop() {
Serial.print(ar[k1]);
k1 = (++k1) % 26;
k2 = (++k2) % 5;
if (k2==0) {Serial.println();}
delay(300);
}
And the result of run..
xxx@RevoR3600:~/CProg$ ./SerialPort
ahhhh! : Success
ahhhh! : Success
ahhhh! : Success
...
... (many identical lines...)
...
ahhhh! : Success
ahhhh! : Success
{AP}
{A}
{BCD}
{E
}
{FGHIJ
}
^C
xxx@RevoR3600:~/CProg$
Upvotes: 0
Views: 284
Reputation: 11
After sleeping one night on it and two more hours of digging this site (and testing) I finally came across a solution right here; sorry I was not able to find it before posting (I can't figure out why); now it is matter for me to study exactly why the found solution is working (and why there is still a minor problem: some strange characters acquired on starting). Thanks (and apology) to everybody has read my post.
Here is the working (test) code:
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<unistd.h>
#include<fcntl.h>
#include<termios.h>
#define bufLen 81
int main() {
char buf[bufLen];
struct termios tty;
FILE * f;
int fd=open("/dev/ttyACM0",O_RDWR | O_NOCTTY);
if(fd == -1) {
perror("Unable to open /dev/ttyACM1\n");
return -1;
} else {
if(tcgetattr(fd, &tty)!=0) {perror("tcgetatt() error"); return -1;}
else {
cfsetospeed(&tty, B9600);
cfsetispeed(&tty, B9600);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tty.c_cflag |= CLOCAL | CREAD;
tty.c_iflag |= IGNPAR | IGNCR;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_lflag |= ICANON;
tty.c_oflag &= ~OPOST;
tcsetattr(fd, TCSANOW, &tty);
if (!(f = fdopen(fd, "r+t"))) {perror("fdopen() error"); return -1;}
while (1) {
fgets(buf,bufLen,f);
printf("%s--\n",buf);
}
}
}
close(fd);
return 0;
}
Upvotes: 1