Thanks everyone for the help. Here is a working example that should compile
and run.
This may help others looking to connect a GPS.
/* Demo code to connect to a GPS. Most units should connect at 4800 Baud while
the Garmin GPS18 5 Hz defaults to 19200.
The program will take three arguments. Device name, 1 = 4800; 2 = 19200,
logfile
Example:
./a.out /dev/ttyAM1 1 logfile.txt
The general sequence is New, Open, Configure, Read, Close
Functions:
close_port
open_port
read_port
port_configuration
print_configuration
main
*/
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
/* Used to close the port
file_id file_descriptor returned form open
*/
int close_port(int file_id)
{
return close(file_id);
}
/* Used to open the port, returns file descriptor or -1 on fail
device_name serial device name
*/
int open_port(char* device_name)
{
int file_id;
file_id = open(device_name, O_RDONLY | O_NOCTTY | O_NDELAY);
if(file_id == -1)
{
printf("Failed to open device\n");
return -1;
}
else
{
printf("Open succeeded with result %d\n", file_id);
}
return file_id;
}
/* Read 50 sentences from file_id, print them to the console and log them into
a file
file_id file desciptor from open
filename file name to open for logging
*/
int read_port(int file_id, char* filename)
{
char buffer[512];
int total = 0;
int lines = 0;
int result = 0;
fd_set rfds;
struct timeval tv;
FILE* logfile;
logfile = fopen(filename, "a");
FD_ZERO(&rfds);
FD_SET(file_id, &rfds);
while(lines < 50)
{
tv.tv_sec = 1;
tv.tv_usec = 0;
/* Pause on select until data arrives or 1 second */
result = select(file_id + 1, &rfds, NULL, NULL, &tv);
if (result == -1)
{
printf("Error during select\n");
continue;
}
if(!result)
{
printf("No data within a second. Result = %d\n", result);
}
if(FD_ISSET(file_id, &rfds) == 0)
{
printf("Data received for a socket other than the GPS\n");
continue;
}
/* Read the data */
result = 0;
result = read(file_id, buffer, 511);
printf("result = %d\n", result);
fwrite(buffer, result, 1, logfile);
total += result;
lines++;
/* Add terminator and print if non-zero */
if(result > 0)
{
buffer[result] = '\0';
printf("%s\n", buffer);
}
}
printf("%d total characters recieved\n", total);
fclose(logfile);
}
/* Configure the port, printing the configuration before and after the changes
file_id file desciptor from open
speed 1 for 4800; 2 for 19200
*/
void port_configuration(int file_id, int speed)
{
struct termios options;
int err;
char err_str[16]= "tcgetattr error";
err = tcgetattr (file_id, &options);
if(err)
{
printf("Error of %d calling tcgetattr\n", err);
perror(err_str);
}
printf("Before configuration reset\n");
printf("speed in %u out %u\n", cfgetispeed(&options),
cfgetispeed(&options));
printf("mode in %u out %u\n", options.c_iflag, options.c_oflag);
printf("control flag %u\n", options.c_cflag);
printf("local flag %u\n", options.c_lflag);
if(speed == 1)
{
cfsetispeed (&options, B4800);
cfsetospeed (&options, B4800);
}
else if(speed == 2)
{
cfsetispeed (&options, B19200);
cfsetospeed (&options, B19200);
}
tcsetattr (file_id, TCSANOW, &options);
if(err)
{
printf("Error of %d calling tcsetattr\n", err);
perror(err_str);
}
tcgetattr (file_id, &options);
if(err)
{
printf("Error of %d calling tcgetattr\n", err);
perror(err_str);
}
printf("After configuration reset\n");
printf("speed in %u out %u\n", cfgetispeed(&options),
cfgetispeed(&options));
printf("mode in %u out %u\n", options.c_iflag, options.c_oflag);
printf("control flag %u\n", options.c_cflag);
printf("local flag %u\n", options.c_lflag);
}
/* Print the port configuration without making changes
file_id file desciptor from open
*/
void print_configuration(int file_id)
{
struct termios options;
int err;
char err_str[16]= "tcgetattr error";
err = tcgetattr (file_id, &options);
if(err)
{
printf("Error of %d calling tcgetattr\n", err);
perror(err_str);
}
printf("speed in %u out %u\n", cfgetispeed(&options),
cfgetispeed(&options));
printf("mode in %u out %u\n", options.c_iflag, options.c_oflag);
printf("control flag %u\n", options.c_cflag);
printf("local flag %u\n", options.c_lflag);
}
int main(int argc, char **argv)
{
int file_id = 0;
int running = 1;
int the_char;
char device_name[256];
int speed;
char** endptr;
int x;
if(argc < 4)
{
printf("serial_tester <device> <speed> <logfile>\n");
return 0;
}
else
{
for(x = 0; x < argc; x++)
{
printf("arg[%d] = %s\n", x, argv[x]);
}
}
strcpy(device_name, argv[1]);
/* Print menu */
while(running)
{
if(the_char != 10)
{
printf("Q = quit; O = Open; R = Read; C = Configure; N
= New device; P =
Print configuration; W = Close\n");
}
the_char = getc(stdin);
if(the_char == 10) continue;
switch(the_char)
{
case 'q':
case 'Q':
{
running = 0;
printf("Quitting\n");
break;
}
case 'r':
case 'R':
{
read_port(file_id, argv[3]);
break;
}
case 'o':
case 'O':
{
file_id = open_port(device_name);
break;
}
case 'n':
case 'N':
{
file_id = 0;
break;
}
case 'p':
case 'P':
{
print_configuration(file_id);
break;
}
case 'c':
case 'C':
{
if(file_id > 0)
{
switch((argv[2])[0])
{
case '1':
{
speed = 1;
break;
}
case '2':
{
speed = 2;
break;
}
default:
{
printf("Invalid speed
selection defaulting to 4800
Baud\n");
speed = 1;
break;
}
}
port_configuration(file_id, speed);
}
else
{
printf("New device must be configured
first\n");
}
break;
}
case 'w':
case 'W':
{
printf("Closing\n");
close_port(file_id);
break;
}
default:
{
printf("Invalid choice of %d\n", the_char);
break;
}
}
}
printf("Exiting\n");
}
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|