RaspberryPi[33] GPSデータから任意のNMEAを記録

GPSを受信&記録するプログラムを書いているとデータ量が大きくなるので必要なNMEAのデータだけを記録したい時があります。GPSからのデータはシリアルで受信しますが、取り込む際に1行ごとに奇麗にバッファに格納されるわけではなく、2つのNMEAがくっついたり、また途中で切れたります。そこで、受信バッファを1バイトごとに読み込み改行(0xa)が来たら、一旦ここでファイルに記録し、もし、まだ、バッファにデータがあるならその次のバッファを付けて、また改行が来たらファイルに書き込むプログラムを書いてみました。

strcmp(“$GPGGA”, header) == 0)を修正して必要なNMEAヘッダをORでつなげていけばそれらのファイルは記録されます。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <time.h>

#define SERIAL_PORT "/dev/ttyACM0"

int main(int argc, char *argv[]) {
    unsigned char msg[] = "serial port open...\n";
    unsigned char cfn[255];      // current file name based on size
    unsigned char buf[255];
    unsigned char buf2[255];
    char header[16];
    int fd;
    struct termios tio;
    int baudRate = B115200;
    int i;
    int cnt;
    int msg_cnt;
    int nmea_cnt;
    int cng_file;
    int len;
    int ret;
    int size;
    int disp;
    int store_hour;
    time_t t;
    FILE *file;
    struct tm *local;

    fd = open(SERIAL_PORT, O_RDWR);
    if (fd < 0) {
        printf("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);

    cnt      = 0;
    msg_cnt  = 0;
    nmea_cnt = 0;
    cng_file = 1;

    if(argc >1) disp = 1;
    else disp = 0;

    while(1) {
        if(cng_file == 1){       // generate file name
            t     = time(NULL);
            local = localtime(&t);
            sprintf(cfn, "/media/pi/ボリュウームラベル名/rtk%02d%02d%02d%02d.txt", local->tm_mon+1, local->tm_mday, local->tm_hour, local->tm_min);
            cng_file   = 0;
            store_hour = local->tm_hour;
            if(disp == 1) printf("File create %s\n", cfn);
        }

        len = read(fd, buf, sizeof(buf));

        if (0 < len) {
            for( i = 0; i < len; i++ ) {

                if(0) {
                    printf("%c", buf[i]);
                    if(buf[i]==0xa) printf("#\n");
                }

                buf2[msg_cnt] = buf[i];
                if(buf[i] == 0xa) {


                    buf2[msg_cnt+1] = '\0';
                    msg_cnt = 0;
                    sscanf(buf2, "%[^,]", header);
                    if(
                      (strcmp("$GPGGA", header) == 0) || (strcmp("$GNGGA", header) == 0)
                      ||
                      (strcmp("$GPRMC", header) == 0) || (strcmp("$GNRMC", header) == 0)
                      ){
                        file = fopen(cfn, "a");

                        if(disp == 1) printf("%d %s", nmea_cnt, buf2);
                        fprintf(file, "%s", buf2);
                        fclose(file);

                        nmea_cnt++;
                    }
                }
                else msg_cnt++;
            }
        }
        cnt++;

        t     = time(NULL);
        local = localtime(&t);
        if(store_hour != local->tm_hour) {
            cng_file = 1;
            cnt      = 0;
        }
    }

    close(fd);
    return 0;
}