1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
| /*********************************************************************************
| * Copyright: (C) 2023 LingYun IoT System Studio.
| * All rights reserved.
| *
| * Filename: pack_gps.c
| * Description: This file is GPS NMEA format string parser example
| *
| * Version: 1.0.0(2023年07月10日)
| * Author: Guo Wenxue <guowenxue@gmail.com>
| * ChangeLog: 1, Release initial version on "2023年07月10日 17时21分35秒"
| *
| ********************************************************************************/
|
| #include <stdio.h>
| #include <stdlib.h>
| #include <string.h>
|
| #define GPS_RAWDATA "\
| $GPGSA,A,3,18,05,15,24,23,13,29,,,,,,2.2,1.1,1.9*3C\r\n\
| $GPRMC,091859.000,A,3029.6909,N,11423.6327,E,0.23,200.08,100723,,,A*65\r\n\
| $GPGGA,091900.000,3029.6909,N,11423.6326,E,1,07,1.1,28.2,M,-13.7,M,,0000*40\r\n"
|
| typedef struct gps_fix_s
| {
| char time[32]; /* GPS UTC time, formt: hhmmss */
| char status; /* A: Valid V:Invalid */
| float latitude; /* Latitude */
| char lat; /* N: North S: South */
| float longitude; /* Longitude */
| char lon; /* E: East W: West */
| float speed; /* Speed over ground, meters/sec */
| float track; /* Course made good (relative to true north) */
| } gps_fix_t;
|
| int proc_gprmc(char *buf, int size, gps_fix_t *info);
|
| int main (int argc, char **argv)
| {
| char buf[] = GPS_RAWDATA;
| gps_fix_t info;
|
| proc_gprmc(buf, strlen(buf), &info);
|
| return 0;
| }
|
| /*
| * $GPRMC,024216.000,A,3029.6651,N,11423.6251,E,0.08, 156.95,100723,,,A*65
| * 1 024216.000 UTC time format: HHMMSS, 10:42:16(BeiJing)
| * 2 A Status of Fix:
| * A = Autonomous, valid;
| * D = Differential, valid;
| * V = invalid
| *
| * 3,4 3029.6651,N Latitude format: ddmm.mmmm, Latitude 30 deg. 29.6651 min North
| * 5,6 11423.6251,E Longitude: dddmm.mmmm, Longitude 114 deg. 23.6251 min East
| * 7 0.08 Speed over ground, Knots
| * 8 156.95 Course Made Good, True north
| * 9 100723 Date of fix ddmmyy. 2023-07-10
| * 10,11 ,, Magnetic variation
| * 12 A FAA mode indicator (NMEA 2.3 and later)
| * A=autonomous,
| * D=differential,
| * E=Estimated,
| * M=Manual input mode,
| * N=not valid,
| * S=Simulator,
| * V=Valid
| * 13 *68 mandatory nmea_checksum
| */
|
| #define DD(s) ((int)((s)[0]-'0')*10+(int)((s)[1]-'0'))
| int proc_gprmc(char *buf, int size, gps_fix_t *info)
| {
| char *ptr_start=NULL;
| char *ptr_end=NULL;
| char hhmmss[12]={0x0};
| char ddmmyy[12]={0x0};
|
| if( !buf || size<=0 || !info )
| {
| printf("Invalid input arguments\n");
| return -1;
| }
|
| printf("GPS receive raw data:\n%s\n", buf);
|
| if( !(ptr_start=strstr(buf, "$GPRMC")) )
| {
| printf("$GPRMC keywords not matched\n");
| return -2;
| }
|
| if( !(ptr_end=strchr(ptr_start, 0x0D)) )
| {
| printf("$GPRMC data not integrated\n");
| return -3;
| }
|
| *ptr_end = '\0';
|
| memset(info, 0, sizeof(*info));
| sscanf(ptr_start, "$GPRMC,%[^,],%c,%f,%c,%f,%c,%f,%f,%[^,]",
| hhmmss, &info->status, &info->latitude, &info->lat,
| &info->longitude, &info->lon, &info->speed, &info->track, ddmmyy);
|
| snprintf(info->time, sizeof(info->time), "%04d-%02d-%02d %02d:%02d:%02d",
| DD(ddmmyy+4)+2000, DD(ddmmyy+2), DD(ddmmyy),
| DD(hhmmss)+8, DD(hhmmss+2), DD(hhmmss+4));
|
| if( info->status == 'A' )
| {
| printf("NMEA0183: %s lat=%.2f(%c) lon=%.2f(%c) speed=%.2f, track=%.2f\n",
| info->time, info->latitude, info->lat,
| info->longitude, info->lon, info->speed, info->track);
| }
| else if( info->status == 'V' )
| {
| printf("NMEA0183: Invalid data\n");
| }
|
| return 0;
| }
|
|