RaspberryPi[45] NMEA 発生器
どこかで書いた気もするけど、いろいろ変更したので再度あげておきます。NMEAフォーマットで受信する機器ってGPSのほかにもいろいろとあるんですね。そんなときのために、事前に作っておいたテキストファイルを一行ずつ、USBポートに出力するプログラムと作りました。USBもttyUSB0とttyUSB1に対応しています。送信時間も設定できます。ボーレートも変更できるように修正してみました。ただ、ボーレートは9600とか入れるのではなく、9600なら13、38400なら15と入れるように手を抜いています。ソースコードを挙げておくので、適当に修正してください。
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <time.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/socket.h> //socket()
#include <sys/ioctl.h> //ioctl()
#include <arpa/inet.h> //htons(), inet_addr()
#define SERIAL_USB0 "/dev/ttyUSB0"
#define SERIAL_USB1 "/dev/ttyUSB1"
#define TRUE 1
#define FALSE 0
#define DATA_SIZE_CMN 256
#define MAX_LINE_LENGTH 9000
char nmea_file_name[128];
int PortNumber = 60000; // default port
int gettimeofday();
float chg_deg(float lat)
{
float deg;
int deg_int;
float minutes;
float deg_min;
deg_int = (int)lat / 100;
minutes = lat - (deg_int * 100 );
deg_min = deg_int + minutes / 60.0;
// printf("di:%d mi:%f dm:%f\n",deg_int,minutes,deg_min);
return deg_min;
}
void arg_error()
{
printf("Argment error!! type as below\n");
printf("sudo ./gen_gps -f nmea_file_name -u 0/1 -i 1 -s 20 \n");
printf("-d : display ->0/1\n");
printf("-b : baudRate: 9600->13 38400->15 \n");
printf("-f : GPS NMEA read from a file instead of real GPS. It needs nmea file name after -g\n");
printf("-u 0/1 : ttyUSB0 ->0 or ttyUSB1 ->1\n");
printf("-i # : GPS interval Typically 1 sec \n");
exit(0);
}
int main(int argc, char *argv[])
{
unsigned char msg[] = "serial port open...\n";
int fd;
struct termios tio;
int baudRate = B9600;
int i;
int k;
int arg_err_flg = FALSE;
int skip = 0;
int msg_cnt = 0;
time_t t;
FILE *file;
int loop_counter = 0;
int speed;
int usb;
int display = 0;
FILE *nmea_file;
char line;
unsigned char buf[DATA_SIZE_CMN] = {0};
unsigned char buf2[MAX_LINE_LENGTH][DATA_SIZE_CMN];
if (argc < 3)
{
arg_error();
}
// Check argv
arg_err_flg = FALSE;
for (i = 0; i < argc; i++)
{
if (strcmp(argv[i], "-d") == 0)
{
printf("stop\n");
sscanf(argv[i + 1], "%d", &display);
}
if (strcmp(argv[i], "-b") == 0)
{
sscanf(argv[i + 1], "%d", &baudRate);
}
if (strcmp(argv[i], "-f") == 0)
{
strcpy(nmea_file_name, argv[i + 1]);
}
if (strcmp(argv[i], "-u") == 0)
{
sscanf(argv[i + 1], "%d", &usb);
if (usb > 1) arg_err_flg = TRUE;
}
if (strcmp(argv[i], "-i") == 0)
{
sscanf(argv[i + 1], "%d", &speed);
speed = speed * 1000000;
}
if (arg_err_flg == TRUE) arg_error();
}
if (display == TRUE) printf("br:%d nmea_file:%s ttyUSBport:%d gps_freq :%dsec skip:%d \n", baudRate,nmea_file_name, usb, speed / 1000000, skip);
if (usb == 0) {
fd = open(SERIAL_USB0, O_RDWR);
if (fd < 0)
{
printf("USB0 open error\n");
return -1;
}
} else {
fd = open(SERIAL_USB1, O_RDWR);
if (fd < 0)
{
printf("USB1 open error\n");
return -1;
}
}
tio.c_cflag += CREAD;
tio.c_cflag += CLOCAL;
tio.c_cflag += CS8;
tio.c_cflag += 0;
tio.c_cflag += 0;
cfsetispeed( &tio, baudRate );
cfsetospeed( &tio, baudRate );
cfmakeraw(&tio);
tcsetattr( fd, TCSANOW, &tio );
ioctl(fd, TCSETS, &tio);
nmea_file = fopen(nmea_file_name, "r");
if (nmea_file == NULL)
{
printf("Could not open %s\n", nmea_file_name);
exit(0);
}
i = 0;
while (1) {
if (fgets(buf, DATA_SIZE_CMN, nmea_file) == NULL) break;
strcpy(buf2[i], buf);
if (display == TRUE) printf("R:%d: %s", i, buf2[i]);
i++;
}
fclose(nmea_file);
while (1) {
for (loop_counter = 0; loop_counter < i; loop_counter++) {
if (display == TRUE) printf("\rS:%d %s", loop_counter, buf2[loop_counter]);
write(fd, buf2[loop_counter], DATA_SIZE_CMN);
usleep(speed);
}
for (loop_counter = i; loop_counter > 0; loop_counter--) {
if (display == TRUE) printf("\rS:%d %s", loop_counter, buf2[loop_counter]);
write(fd, buf2[loop_counter], DATA_SIZE_CMN);
usleep(speed);
}
}
exit(0);
}
./gen_gps -f nmea_file_name -u 0/1 -i 1 -s 1
printf("sudo ./gen_gps -f nmea_file_name -u 0/1 -i 1 -s 20 \n");
printf("-d : display ->0/1\n");
printf("-b : baudRate: 9600->13 38400->15 \n");
printf("-f : GPS NMEA read from a file instead of real GPS. It needs nmea file name after -g\n");
printf("-u 0/1 : ttyUSB0 ->0 or ttyUSB1 ->1\n");
printf("-i # : GPS interval Typically 1 sec \n");
NMEAフォーマットはの例です。
$GNGGA,063441.20,3527.100673042,N,13937.902454837,E,4,13,0.91,205.863,M,41.731,M,4.2,2108*69
$GNVTG,240.3,T,0.0,M,13.5,N,25.0,K,A*38
$GNGGA,063441.30,3527.100823803,N,13937.903106614,E,4,13,0.91,205.863,M,41.731,M,4.2,2108*62
$GNVTG,240.3,T,0.0,M,13.5,N,25.0,K,A*38
$GNGGA,063441.40,3527.100974564,N,13937.903758391,E,4,13,0.91,205.863,M,41.731,M,4.2,2108*6F
$GNVTG,240.3,T,0.0,M,13.5,N,25.0,K,A*38