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.

Minimum example code
 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.

Example of buffer
 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.

Distance and bearing calculation
 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);