Examples and demos
There are several basic examples provided with the library.
Parse block of data
In this example, block of data is prepared as big string array and sent to processing function in single shot. Application can then check if GPS signal has been detected as valid and use other data accordingly.
1/**
2 * This example uses direct processing function
3 * to process dummy NMEA data from GPS receiver
4 */
5#include <string.h>
6#include <stdio.h>
7#include "lwgps/lwgps.h"
8
9/* GPS handle */
10lwgps_t hgps;
11
12/**
13 * \brief Dummy data from GPS receiver
14 */
15const char gps_rx_data[] = ""
16 "$GPRMC,183729,A,3907.356,N,12102.482,W,000.0,360.0,080301,015.5,E*6F\r\n"
17 "$GPRMB,A,,,,,,,,,,,,V*71\r\n"
18 "$GPGGA,183730,3907.356,N,12102.482,W,1,05,1.6,646.4,M,-24.1,M,,*75\r\n"
19 "$GPGSA,A,3,02,,,07,,09,24,26,,,,,1.6,1.6,1.0*3D\r\n"
20 "$GPGSV,2,1,08,02,43,088,38,04,42,145,00,05,11,291,00,07,60,043,35*71\r\n"
21 "$GPGSV,2,2,08,08,02,145,00,09,46,303,47,24,16,178,32,26,18,231,43*77\r\n"
22 "$PGRME,22.0,M,52.9,M,51.0,M*14\r\n"
23 "$GPGLL,3907.360,N,12102.481,W,183730,A*33\r\n"
24 "$PGRMZ,2062,f,3*2D\r\n"
25 "$PGRMM,WGS84*06\r\n"
26 "$GPBOD,,T,,M,,*47\r\n"
27 "$GPRTE,1,1,c,0*07\r\n"
28 "$GPRMC,183731,A,3907.482,N,12102.436,W,000.0,360.0,080301,015.5,E*67\r\n"
29 "$GPRMB,A,,,,,,,,,,,,V*71\r\n";
30
31int
32main() {
33 /* Init GPS */
34 lwgps_init(&hgps);
35
36 /* Process all input data */
37 lwgps_process(&hgps, gps_rx_data, strlen(gps_rx_data));
38
39 /* Print messages */
40 printf("Valid status: %d\r\n", hgps.is_valid);
41 printf("Latitude: %f degrees\r\n", hgps.latitude);
42 printf("Longitude: %f degrees\r\n", hgps.longitude);
43 printf("Altitude: %f meters\r\n", hgps.altitude);
44
45 return 0;
46}
Parse received data from interrupt/DMA
Second example is a typical use case with interrupts on embedded systems.
For each received character, application uses ringbuff
as intermediate buffer.
Data are later processed outside interrupt context.
Note
For the sake of this example, application implements interrupts as function call in while loop.
1#include "lwgps/lwgps.h"
2#include "lwrb/lwrb.h"
3#include <string.h>
4
5/* GPS handle */
6lwgps_t hgps;
7
8/* GPS buffer */
9lwrb_t hgps_buff;
10uint8_t hgps_buff_data[12];
11
12/**
13 * \brief Dummy data from GPS receiver
14 * \note This data are used to fake UART receive event on microcontroller
15 */
16const char
17gps_rx_data[] = ""
18 "$GPRMC,183729,A,3907.356,N,12102.482,W,000.0,360.0,080301,015.5,E*6F\r\n"
19 "$GPRMB,A,,,,,,,,,,,,V*71\r\n"
20 "$GPGGA,183730,3907.356,N,12102.482,W,1,05,1.6,646.4,M,-24.1,M,,*75\r\n"
21 "$GPGSA,A,3,02,,,07,,09,24,26,,,,,1.6,1.6,1.0*3D\r\n"
22 "$GPGSV,2,1,08,02,43,088,38,04,42,145,00,05,11,291,00,07,60,043,35*71\r\n"
23 "$GPGSV,2,2,08,08,02,145,00,09,46,303,47,24,16,178,32,26,18,231,43*77\r\n"
24 "$PGRME,22.0,M,52.9,M,51.0,M*14\r\n"
25 "$GPGLL,3907.360,N,12102.481,W,183730,A*33\r\n"
26 "$PGRMZ,2062,f,3*2D\r\n"
27 "$PGRMM,WGS84*06\r\n"
28 "$GPBOD,,T,,M,,*47\r\n"
29 "$GPRTE,1,1,c,0*07\r\n"
30 "$GPRMC,183731,A,3907.482,N,12102.436,W,000.0,360.0,080301,015.5,E*67\r\n"
31 "$GPRMB,A,,,,,,,,,,,,V*71\r\n";
32static size_t write_ptr;
33static void uart_irqhandler(void);
34
35int
36main() {
37 uint8_t rx;
38
39 /* Init GPS */
40 lwgps_init(&hgps);
41
42 /* Create buffer for received data */
43 lwrb_init(&hgps_buff, hgps_buff_data, sizeof(hgps_buff_data));
44
45 while (1) {
46 /* Add new character to buffer */
47 /* Fake UART interrupt handler on host microcontroller */
48 uart_irqhandler();
49
50 /* Process all input data */
51 /* Read from buffer byte-by-byte and call processing function */
52 if (lwrb_get_full(&hgps_buff)) { /* Check if anything in buffer now */
53 while (lwrb_read(&hgps_buff, &rx, 1) == 1) {
54 lwgps_process(&hgps, &rx, 1); /* Process byte-by-byte */
55 }
56 } else {
57 /* Print all data after successful processing */
58 printf("Latitude: %f degrees\r\n", hgps.latitude);
59 printf("Longitude: %f degrees\r\n", hgps.longitude);
60 printf("Altitude: %f meters\r\n", hgps.altitude);
61 break;
62 }
63 }
64
65 return 0;
66}
67
68/**
69 * \brief Interrupt handler routing for UART received character
70 * \note This is not real MCU, it is software method, called from main
71 */
72static void
73uart_irqhandler(void) {
74 /* Make interrupt handler as fast as possible */
75 /* Only write to received buffer and process later */
76 if (write_ptr < strlen(gps_rx_data)) {
77 /* Write to buffer only */
78 lwrb_write(&hgps_buff, &gps_rx_data[write_ptr], 1);
79 ++write_ptr;
80 }
81}
Distance and bearing
Library provides calculation of distance and bearing between 2
coordinates on earth.
This is useful if used with autonomnous devices to understand in which direction
device has to move to reach end point while knowing start coordinate.
1#include "lwgps/lwgps.h"
2
3/* Distance and bearing results */
4lwgps_float_t dist, bear;
5
6/* New York coordinates */
7lwgps_float_t lat1 = 40.685721;
8lwgps_float_t lon1 = -73.820465;
9
10/* Munich coordinates */
11lwgps_float_t lat2 = 48.150906;
12lwgps_float_t lon2 = 11.554176;
13
14/* Go from New York to Munich */
15/* Calculate distance and bearing related to north */
16lwgps_distance_bearing(lat1, lon1, lat2, lon2, &dist, &bear);
17printf("Distance: %f meters\r\n", (float)dist);
18printf("Initial bearing: %f degrees\r\n", (float)bear);
19
20/* Go from Munich to New York */
21/* Calculate distance and bearing related to north */
22lwgps_distance_bearing(lat2, lon2, lat1, lon1, &dist, &bear);
23printf("Distance: %f meters\r\n", (float)dist);
24printf("Initial bearing: %f degrees\r\n", (float)bear);