#include #include #include #include #include #include #include #include #include "LatLong-UTMconversion.h" #define READGPS_MINI 10 FILE *readgps_serialsetup(char *path); struct eivadata readgps_read(FILE *term); int readgps_close(FILE *term); int latitude_int, longitude_int; struct eivadata { struct tm time; double northing, easting; double latitude, longitude; char raw_latitude[50]; char raw_longitude[50]; char zone[4]; char tsource; }; FILE *readgps_serialsetup(char *path) { FILE *term; int tset; termios options; tset = open(path, O_RDWR | O_NOCTTY); if (tset < 0) return NULL; tcgetattr(tset, &options); options.c_iflag |= IGNBRK; options.c_iflag |= IGNPAR; options.c_iflag &= ~INLCR; options.c_iflag &= ~INPCK; options.c_iflag &= ~PARMRK; options.c_iflag &= ~ISTRIP; options.c_iflag &= ~IXOFF; options.c_iflag &= ~IXON; options.c_iflag &= ~ONLCR; options.c_iflag &= ~OCRNL; options.c_iflag &= ~ICRNL; options.c_iflag &= ~BRKINT; options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cc[VTIME]=0; options.c_cc[VMIN]=1; options.c_cflag |= CS8; options.c_lflag &= ~ICANON; options.c_lflag &= ~ECHO; options.c_lflag &= ~ECHOE; options.c_lflag &= ~ECHONL; options.c_lflag &= ~ISIG; tcsetattr(tset, TCSANOW, &options); close(tset); term = fopen(path, "a+"); return term; } struct eivadata readgps_read(FILE *term) { struct eivadata eiva; int state = 0; int cnum; char minibuff[READGPS_MINI]; int chr; char lath, longh; time_t ct; /* Read PGRMF sentences, and put them in global eivadata structure eiva */ while (state < 10) { chr = fgetc(term); switch (state) { case 1: /* Skip GPS week number */ case 2: /* Skip GPS seconds */ case 5: /* Skip GPS leap seconds */ if (chr == ',') { cnum = 0; state++; } break; case 3: /* UTC date */ /* Day of month */ if (cnum < 2) { minibuff[cnum] = chr; if (cnum == 1) { minibuff[2] = '\0'; eiva.time.tm_mday = atoi(minibuff); } } /* Month */ else if (cnum < 4) { minibuff[cnum - 2] = chr; if (cnum == 3) { minibuff[2] = '\0'; eiva.time.tm_mon = atoi(minibuff); } } /* Year */ else if (cnum < 6) { minibuff[cnum - 4] = chr; if (cnum == 5) { minibuff[2] = '\0'; eiva.time.tm_year = atoi(minibuff) + 100; } } /* Date finished? */ if (chr == ',') { if (cnum > 4) eiva.tsource = 'G'; else eiva.tsource = 'S'; cnum = 0; state++; } else cnum++; break; case 4: /* UTC time */ /* Hours */ if (cnum < 2) { minibuff[cnum] = chr; if (cnum == 1) { minibuff[2] = '\0'; eiva.time.tm_hour = atoi(minibuff); } } /* Minutes */ else if (cnum < 4) { minibuff[cnum - 2] = chr; if (cnum == 3) { minibuff[2] = '\0'; eiva.time.tm_min = atoi(minibuff); } } /* Seconds */ else if (cnum < 6) { minibuff[cnum - 4] = chr; if (cnum == 5) { minibuff[2] = '\0'; eiva.time.tm_sec = atoi(minibuff); } } /* Time finished? */ if (chr == ',') { /* Valid GPS data? If not, use system time */ if (eiva.tsource == 'S') gmtime_r(&ct, &eiva.time); /* Next token */ cnum = 0; state++; } else cnum++; break; case 6: /* Latitude */ if (chr == ',') { minibuff[cnum] = '\0'; strcpy(eiva.raw_latitude, minibuff); // Get original GPS data string eiva.latitude = atof(minibuff); latitude_int = (int) (eiva.latitude / 100); eiva.latitude = (( eiva.latitude - (latitude_int * 100)) / 60) + latitude_int; // Jan Inges påfunn: //eiva.latitude = ((eiva.latitude - ((double)(int)eiva.latitude)) / 60) + ((double)(int)eiva.latitude / 100); cnum = 0; state++; } else { minibuff[cnum] = chr; cnum++; } break; case 7: /* Latitude hemisphere */ if (chr == ',') state++; else lath = chr; break; case 8: /* Longitude */ if (chr == ',') { minibuff[cnum] = '\0'; strcpy(eiva.raw_longitude, minibuff); // Get original GPS data string eiva.longitude = atof(minibuff); longitude_int = (int) (eiva.longitude / 100); eiva.longitude = (( eiva.longitude - (longitude_int * 100)) / 60) + longitude_int; // Jan Inges påfunn - feil!!! : // eiva.longitude = ((eiva.longitude - ((double)(int)eiva.longitude)) / 60) + ((double)(int)eiva.longitude / 100); cnum = 0; state++; } else { minibuff[cnum] = chr; cnum++; } break; case 9: /* Longitude hemisphere */ if (chr == ',') { state++; /* All done */ if (lath == 'S') eiva.latitude -= eiva.latitude + eiva.latitude; if (longh == 'W') eiva.longitude -= eiva.longitude + eiva.longitude; LLtoUTM(23, eiva.latitude, eiva.longitude, eiva.northing, eiva.easting, eiva.zone); /* Convert to UTM */ } else longh = chr; break; default: /* PGRMF sentence? */ if (chr == '$') if (fgetc(term) == 'P') if (fgetc(term) == 'G') if (fgetc(term) == 'R') if (fgetc(term) == 'M') if (fgetc(term) == 'F') { time(&ct); gmtime_r(&ct, &eiva.time); fgetc(term); state = 1; } break; } } return eiva; } int readgps_close(FILE *term) { return fclose(term); }