ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am just learning serial port programming in C. Normally I just use a library like they have in C#, but I wanted to learn how to do it in Linux so after a lot of time on the Internet I finally came up with something that almost works. It seems to open the serial port okay and write to it, but what I get back is just garbage and is different every time. I was wondering if someone could take a look at my code and see what I am doing wrong.
Code:
#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 */
//Initialize serial port
int initport(int fd)
{
int portstatus = 0;
struct termios options;
// Get the current options for the port...
tcgetattr(fd, &options);
// Set the baud rates to 115200...
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
// Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//options.c_cflag |= SerialDataBitsInterp(8); /* CS8 - Selects 8 data bits */
options.c_cflag &= ~CRTSCTS; // disable hardware flow control
//options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable XON XOFF (for transmit and
//receive)
//options.c_cflag |= CRTSCTS; /* enable hardware flow control */
options.c_cc[VMIN] = 0; //min carachters to be read
options.c_cc[VTIME] = 0; //Time to wait for data (tenths of seconds)
// Set the new options for the port...
//tcsetattr(fd, TCSANOW, &options);
//Set the new options for the port...
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &options)==-1)
{
perror("On tcsetattr:");
portstatus = -1;
}
else
portstatus = 1;
return portstatus;
}
/*
* 'open_port()' - Open serial port 1.
*
* Returns the file descriptor on success or -1 on error.
*/
int open_port(void)
{
int fd; /* File descriptor for the port */
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
/*
* Could not open the port.
*/
perror("open_port: Unable to open /dev/ttyUSB0 --- \n");
}
else
fcntl(fd, F_SETFL, 0);
return (fd);
}
int main(void)
{
int serial_fd = open_port();
if(serial_fd == -1)
printf("Error opening serial port /dev/ttyUSB0 \n");
else
{
printf("Serial Port /dev/ttyUSB0 is now open \n");
if(initport(serial_fd) == -1)
{
printf("Error Initializing port");
close(serial_fd);
return 0;
}
sleep(.5);
//usleep(500000);
//printf("size of data being sent = %ld", sizeof("~ver~\n\r"));
int n = write(serial_fd, "~ver~\n\r", 8);
if (n < 0)
fputs("write() of 8 bytes failed!\n", stderr);
else
{
printf("Successfully wrote 8 bytes\n");
char buffer[32];
int n = read(serial_fd, buffer, sizeof(buffer));
if (n < 0)
fputs("read failed!\n", stderr);
else
printf("Successfully read from serial port -- %s\n", buffer);
}
sleep(.5);
//usleep(500000);
printf("\n\nNow closing Serial Port /dev/ttyUSB0 \n\n");
close(serial_fd);
}
return 0;
}
There is nothing to guarantee that the buffer used to hold the incoming data will contain null-terminated string data. You should print discrete characters, limiting the count of such characters to the number returned by the read() call.
There is nothing to guarantee that the buffer used to hold the incoming data will contain null-terminated string data. You should print discrete characters, limiting the count of such characters to the number returned by the read() call.
--- rod.
Okay, yes I will do that, but I just ran it again printing out the value returned and though the write prints 8, the read always comes back with 0. So that is why I am getting garbage as there is nothing really to print. I don't really know why it is not reading though. The command I am sending it is correct and it works in a terminal.
Are you sure that the device to which you are sending echoes the data you send. If not, you cannot necessarily expect to see anything come back. Try jumpering the Tx & Rx pins of your serial port connector (almost certainly pins 2 & 3 if any kind of PC architecture). Then, all data that you send will also be recieved, and you can confirm round-trip operation of your port, and your code.
With VMIN=0 & VTIME=0, each read() returns immediately, and the return value is the number of bytes read, which may be zero. You should not try to print anything in such cases. This will probably be a quite inefficient method of polling the port.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.