Working with serial in C on Linux is not as simple as opening a file and reading from it (though in some circumstances that can work).
You should open the file using open() not fopen(), then use tcgetattr() and tcsetattr() etc to configure the port.
For example:
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
struct termios oldsettings, newsettings;
int fd;
// This signal handler will close the port cleanly leaving
// it in the same state it started in
void sighandler(int sig) {
if (sig == SIGINT) {
if (fd >= 0) {
// Restore the settings to original
tcsetattr(fd, TCSANOW, &oldsettings);
// Close the port
close(fd);
printf("Program teminated. Thank you for playing.\n");
// Exit the program
exit(0);
}
}
}
int main(int argc, char *argv) {
// Trap CTRL-C to close the port properly
signal(SIGINT, &sighandler);
fd = open("/dev/ttyACM0", O_RDWR);
if (fd < 0) {
fprintf(stderr, "Error opening serial port: %s\n", strerror(errno));
return 10;
}
// Save the settings
tcgetattr(fd, &oldsettings);
// Grab the current settings again to modify
tcgetattr(fd, &newsettings);
// Set the baud rate
cfsetispeed(&newsettings, B9600);
cfsetospeed(&newsettings, B9600);
// Make it a raw port
cfmakeraw(&newsettings);
// Apply the settings
tcsetattr(fd, TCSANOW, &newsettings);
char c;
printf("Press CTRL-C to terminate\n");
while (read(fd, &c, 1) == 1) {
printf("Got character 0x%02x\n", c);
}
fprintf(stderr, "Reception terminated: %s\n", strerror(errno));
return 0;
}
No one ever said programming C was easy. It makes you appreciate just how much work the Arduino API does behind the scenes for you...