EmbeddedArtists AB
/
lpc812_exp_solution_exp-port-gps
Solutions for the GPS experiments for LPC812 MAX
Diff: main.cpp
- Revision:
- 0:a1d4ae5fb9fa
--- /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); + } +}