Solutions for the GPS experiments for LPC812 MAX

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
embeddedartists
Date:
Sun Nov 24 12:43:53 2013 +0000
Commit message:
First version

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Nov 24 12:43:53 2013 +0000
@@ -0,0 +1,249 @@
+#include "mbed.h"
+
+Serial pc(USBTX, USBRX); // tx, rx
+Serial uart(P0_4, P0_0);
+
+/**
+* Data structure for the GPS values
+*/
+typedef struct gpsData {
+    uint8_t satellitesUsed[20];
+    uint8_t utcTime[20];
+    uint8_t altitude[20];
+    uint8_t bufLatitude[20];
+    uint8_t bufLongitude[20];
+    int positionFixed;
+    int northSouthIndicator;
+    int eastWestIndicator;
+    int latitude;
+    int longitude;
+} gpsData;
+
+static uint8_t END_OF_MESSAGE = '\0';
+static uint8_t DIVIDER = ',';
+
+// The parsed data
+static gpsData data;
+
+/*****************************************************************************
+** Function name: hasPattern
+**
+** Descriptions: Tests if pBuf starts with pPattern.
+**
+** parameters: Buffer to search and pattern to match
+** Returned value: 1 if pBuf starts with pPattern, 0 otherwise
+**
+*****************************************************************************/
+static uint8_t hasPattern(uint8_t *pBuf, uint8_t *pPattern)
+{
+    while(*pBuf != END_OF_MESSAGE && *pPattern != END_OF_MESSAGE) {
+        if(*pBuf != *pPattern) {
+            return 0;
+        }
+        pPattern++;
+        pBuf++;
+    }
+    return 1;
+}
+/*****************************************************************************
+** Function name: pointToNextValue
+**
+** Descriptions:    Moves past the next divider
+**
+** parameters: Pointer to the string to search
+** Returned value: None
+**
+*****************************************************************************/
+static void pointToNextValue(uint8_t **ppBuf)
+{
+    while(**ppBuf != END_OF_MESSAGE) {
+        if (**ppBuf == DIVIDER) {
+            (*ppBuf)++; // point to the start of next value
+            break;
+        }
+        (*ppBuf)++;
+    }
+}
+/*****************************************************************************
+** Function name: convertCordinateToDegree
+**
+** Descriptions: Converts the pBuf string which is in the
+** "ddmm.mmmm" format into an integer representation
+**
+** parameters: The buffer, the resulting integer and the
+** length of the buffer
+** Returned value: None
+**
+*****************************************************************************/
+static void convertCordinateToDegree(uint8_t *pBuf, int* pDegree, int len)
+{
+    int index = 0;
+    int sum = 0;
+    int deg = 0;
+    int min = 0;
+    int div = 0;
+    int pow = 1;
+    for (index = len; index >=0; index--) {
+        if (pBuf[index] == '.') {
+            div = 1;
+            continue;
+        }
+        sum += pow * (pBuf[index] & 0x0F);
+        if (index > 0) {
+            pow *= 10;
+            div *= 10;
+        }
+    }
+
+    div = pow / div;
+    deg = sum / (div*100);
+    min = sum - (deg*div*100);
+    
+    // convert to decimal minutes
+    min = (min * 100) / 60;
+    *pDegree = (deg*div*100) + min;
+    if (div > 10000) {
+        // normalize minutes to 6 decimal places
+        *pDegree /= (div / 10000);
+    }
+}
+/*****************************************************************************
+** Function name: parseUTC
+**
+** Descriptions:    Extracts the UTC time string in hhmmss.sss,
+** ignoring the .sss part and stores the result
+** as a string in data.utcTime.
+**
+** parameters: The buffer
+** Returned value: None
+**
+*****************************************************************************/
+static void parseUTC(uint8_t **ppBuf)
+{
+    int index = 0;
+    // parse utc hhmmss.sss
+    while(**ppBuf != END_OF_MESSAGE) {
+        if(**ppBuf == '.') {
+            pointToNextValue(ppBuf);
+            break; //reached end of the value
+        }
+        data.utcTime[index++] = **ppBuf;
+        if(index == 2 || index == 5) {
+            //Add divider
+            data.utcTime[index++] = ':';
+        }
+        (*ppBuf)++;
+    }
+    data.utcTime[index] = '\0';
+}
+/*****************************************************************************
+** Function name: parseLatitude
+**
+** Descriptions: Extracts the latitude information and stores
+** the result as an integer in data.latitude.
+**
+** parameters: The buffer
+** Returned value: None
+**
+*****************************************************************************/
+static void parseLatitude(uint8_t **ppBuf)
+{
+    int index = 0;
+    while(**ppBuf != END_OF_MESSAGE) {
+        if (**ppBuf == DIVIDER) {
+            (*ppBuf)++; //reached end of the value
+            break;
+        }
+        data.bufLatitude[index++] = **ppBuf;
+        (*ppBuf)++;
+    }
+    convertCordinateToDegree((uint8_t *) &data.bufLatitude, &data.latitude, 8);
+}
+/*****************************************************************************
+** Function name: GPSRetreiveData
+**
+** Descriptions: Reads and parses the next set of GPS data.
+**
+** parameters:  None
+** Returned value: The parsed information
+**
+*****************************************************************************/
+const gpsData* GPSRetreiveData(void)
+{
+    uint8_t * pattern = (uint8_t*)"GPGGA";
+    while (1) {
+        uint8_t buf[100];
+        uint8_t ch = 0;
+        uint8_t *ptr = 0;
+        int index = 0;
+        
+        // Retrieve the first byte
+        //if (!UARTGetChar(&ch))
+        //    continue;
+        ch = uart.getc();
+            
+        // look for "$GPGGA," header
+        if (ch != '$') {
+            continue;
+        }
+        
+        // Retrieve the next six bytes
+        for (index=0; index<6; index++) {
+            buf[index] = uart.getc();
+        }
+        
+        //Check if its Global Positioning System fixed Data
+        if (hasPattern((uint8_t*)&buf, pattern) == 0) {
+            continue;
+        }
+        
+        //Retrieve the data from the GPS module
+        for (index=0; index<100; index++) {
+            buf[index] = uart.getc();
+            if (buf[index] == '\r') {
+                buf[index] = END_OF_MESSAGE;
+                break;
+            }
+        }
+        ptr = &buf[0];
+        
+        //parse UTC time
+        parseUTC(&ptr);
+        
+        //parse Latitude
+        parseLatitude(&ptr);
+        break;
+    }
+    return &data;
+}
+static void displayGpsData(const gpsData* pData)
+{
+    //Time
+    printf("\n%s\n", pData->utcTime);
+
+    //Latitude (in ddmmmmmm format, convert to dd.mmmmmm)
+    printf("Latitude: %d.%06d\n", pData->latitude/1000000, pData->latitude%1000000);
+
+    //Longitude (in ddmmmmmm format, convert to dd.mmmmmm)
+    printf("Longitude: %d.%06d\n", pData->longitude/1000000, pData->longitude%1000000);
+
+    //Number of satellites in view
+    printf("#Satellites: %s\n", pData->satellitesUsed);
+}
+
+int main (void)
+{
+    //initialize the UART to 9600bps 8N1
+    uart.baud(9600);
+    //uart.format(8, Serial::None, 1);
+    
+    pc.printf("Waiting for GPS data...\n");
+    
+    //enter forever loop
+    while(1)
+    {
+        const gpsData* pData = GPSRetreiveData();
+        displayGpsData(pData);
+        wait(1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Nov 24 12:43:53 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f
\ No newline at end of file