Solutions for the GPS experiments for LPC812 MAX

Dependencies:   mbed

Committer:
embeddedartists
Date:
Sun Nov 24 12:43:53 2013 +0000
Revision:
0:a1d4ae5fb9fa
First version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 0:a1d4ae5fb9fa 1 #include "mbed.h"
embeddedartists 0:a1d4ae5fb9fa 2
embeddedartists 0:a1d4ae5fb9fa 3 Serial pc(USBTX, USBRX); // tx, rx
embeddedartists 0:a1d4ae5fb9fa 4 Serial uart(P0_4, P0_0);
embeddedartists 0:a1d4ae5fb9fa 5
embeddedartists 0:a1d4ae5fb9fa 6 /**
embeddedartists 0:a1d4ae5fb9fa 7 * Data structure for the GPS values
embeddedartists 0:a1d4ae5fb9fa 8 */
embeddedartists 0:a1d4ae5fb9fa 9 typedef struct gpsData {
embeddedartists 0:a1d4ae5fb9fa 10 uint8_t satellitesUsed[20];
embeddedartists 0:a1d4ae5fb9fa 11 uint8_t utcTime[20];
embeddedartists 0:a1d4ae5fb9fa 12 uint8_t altitude[20];
embeddedartists 0:a1d4ae5fb9fa 13 uint8_t bufLatitude[20];
embeddedartists 0:a1d4ae5fb9fa 14 uint8_t bufLongitude[20];
embeddedartists 0:a1d4ae5fb9fa 15 int positionFixed;
embeddedartists 0:a1d4ae5fb9fa 16 int northSouthIndicator;
embeddedartists 0:a1d4ae5fb9fa 17 int eastWestIndicator;
embeddedartists 0:a1d4ae5fb9fa 18 int latitude;
embeddedartists 0:a1d4ae5fb9fa 19 int longitude;
embeddedartists 0:a1d4ae5fb9fa 20 } gpsData;
embeddedartists 0:a1d4ae5fb9fa 21
embeddedartists 0:a1d4ae5fb9fa 22 static uint8_t END_OF_MESSAGE = '\0';
embeddedartists 0:a1d4ae5fb9fa 23 static uint8_t DIVIDER = ',';
embeddedartists 0:a1d4ae5fb9fa 24
embeddedartists 0:a1d4ae5fb9fa 25 // The parsed data
embeddedartists 0:a1d4ae5fb9fa 26 static gpsData data;
embeddedartists 0:a1d4ae5fb9fa 27
embeddedartists 0:a1d4ae5fb9fa 28 /*****************************************************************************
embeddedartists 0:a1d4ae5fb9fa 29 ** Function name: hasPattern
embeddedartists 0:a1d4ae5fb9fa 30 **
embeddedartists 0:a1d4ae5fb9fa 31 ** Descriptions: Tests if pBuf starts with pPattern.
embeddedartists 0:a1d4ae5fb9fa 32 **
embeddedartists 0:a1d4ae5fb9fa 33 ** parameters: Buffer to search and pattern to match
embeddedartists 0:a1d4ae5fb9fa 34 ** Returned value: 1 if pBuf starts with pPattern, 0 otherwise
embeddedartists 0:a1d4ae5fb9fa 35 **
embeddedartists 0:a1d4ae5fb9fa 36 *****************************************************************************/
embeddedartists 0:a1d4ae5fb9fa 37 static uint8_t hasPattern(uint8_t *pBuf, uint8_t *pPattern)
embeddedartists 0:a1d4ae5fb9fa 38 {
embeddedartists 0:a1d4ae5fb9fa 39 while(*pBuf != END_OF_MESSAGE && *pPattern != END_OF_MESSAGE) {
embeddedartists 0:a1d4ae5fb9fa 40 if(*pBuf != *pPattern) {
embeddedartists 0:a1d4ae5fb9fa 41 return 0;
embeddedartists 0:a1d4ae5fb9fa 42 }
embeddedartists 0:a1d4ae5fb9fa 43 pPattern++;
embeddedartists 0:a1d4ae5fb9fa 44 pBuf++;
embeddedartists 0:a1d4ae5fb9fa 45 }
embeddedartists 0:a1d4ae5fb9fa 46 return 1;
embeddedartists 0:a1d4ae5fb9fa 47 }
embeddedartists 0:a1d4ae5fb9fa 48 /*****************************************************************************
embeddedartists 0:a1d4ae5fb9fa 49 ** Function name: pointToNextValue
embeddedartists 0:a1d4ae5fb9fa 50 **
embeddedartists 0:a1d4ae5fb9fa 51 ** Descriptions: Moves past the next divider
embeddedartists 0:a1d4ae5fb9fa 52 **
embeddedartists 0:a1d4ae5fb9fa 53 ** parameters: Pointer to the string to search
embeddedartists 0:a1d4ae5fb9fa 54 ** Returned value: None
embeddedartists 0:a1d4ae5fb9fa 55 **
embeddedartists 0:a1d4ae5fb9fa 56 *****************************************************************************/
embeddedartists 0:a1d4ae5fb9fa 57 static void pointToNextValue(uint8_t **ppBuf)
embeddedartists 0:a1d4ae5fb9fa 58 {
embeddedartists 0:a1d4ae5fb9fa 59 while(**ppBuf != END_OF_MESSAGE) {
embeddedartists 0:a1d4ae5fb9fa 60 if (**ppBuf == DIVIDER) {
embeddedartists 0:a1d4ae5fb9fa 61 (*ppBuf)++; // point to the start of next value
embeddedartists 0:a1d4ae5fb9fa 62 break;
embeddedartists 0:a1d4ae5fb9fa 63 }
embeddedartists 0:a1d4ae5fb9fa 64 (*ppBuf)++;
embeddedartists 0:a1d4ae5fb9fa 65 }
embeddedartists 0:a1d4ae5fb9fa 66 }
embeddedartists 0:a1d4ae5fb9fa 67 /*****************************************************************************
embeddedartists 0:a1d4ae5fb9fa 68 ** Function name: convertCordinateToDegree
embeddedartists 0:a1d4ae5fb9fa 69 **
embeddedartists 0:a1d4ae5fb9fa 70 ** Descriptions: Converts the pBuf string which is in the
embeddedartists 0:a1d4ae5fb9fa 71 ** "ddmm.mmmm" format into an integer representation
embeddedartists 0:a1d4ae5fb9fa 72 **
embeddedartists 0:a1d4ae5fb9fa 73 ** parameters: The buffer, the resulting integer and the
embeddedartists 0:a1d4ae5fb9fa 74 ** length of the buffer
embeddedartists 0:a1d4ae5fb9fa 75 ** Returned value: None
embeddedartists 0:a1d4ae5fb9fa 76 **
embeddedartists 0:a1d4ae5fb9fa 77 *****************************************************************************/
embeddedartists 0:a1d4ae5fb9fa 78 static void convertCordinateToDegree(uint8_t *pBuf, int* pDegree, int len)
embeddedartists 0:a1d4ae5fb9fa 79 {
embeddedartists 0:a1d4ae5fb9fa 80 int index = 0;
embeddedartists 0:a1d4ae5fb9fa 81 int sum = 0;
embeddedartists 0:a1d4ae5fb9fa 82 int deg = 0;
embeddedartists 0:a1d4ae5fb9fa 83 int min = 0;
embeddedartists 0:a1d4ae5fb9fa 84 int div = 0;
embeddedartists 0:a1d4ae5fb9fa 85 int pow = 1;
embeddedartists 0:a1d4ae5fb9fa 86 for (index = len; index >=0; index--) {
embeddedartists 0:a1d4ae5fb9fa 87 if (pBuf[index] == '.') {
embeddedartists 0:a1d4ae5fb9fa 88 div = 1;
embeddedartists 0:a1d4ae5fb9fa 89 continue;
embeddedartists 0:a1d4ae5fb9fa 90 }
embeddedartists 0:a1d4ae5fb9fa 91 sum += pow * (pBuf[index] & 0x0F);
embeddedartists 0:a1d4ae5fb9fa 92 if (index > 0) {
embeddedartists 0:a1d4ae5fb9fa 93 pow *= 10;
embeddedartists 0:a1d4ae5fb9fa 94 div *= 10;
embeddedartists 0:a1d4ae5fb9fa 95 }
embeddedartists 0:a1d4ae5fb9fa 96 }
embeddedartists 0:a1d4ae5fb9fa 97
embeddedartists 0:a1d4ae5fb9fa 98 div = pow / div;
embeddedartists 0:a1d4ae5fb9fa 99 deg = sum / (div*100);
embeddedartists 0:a1d4ae5fb9fa 100 min = sum - (deg*div*100);
embeddedartists 0:a1d4ae5fb9fa 101
embeddedartists 0:a1d4ae5fb9fa 102 // convert to decimal minutes
embeddedartists 0:a1d4ae5fb9fa 103 min = (min * 100) / 60;
embeddedartists 0:a1d4ae5fb9fa 104 *pDegree = (deg*div*100) + min;
embeddedartists 0:a1d4ae5fb9fa 105 if (div > 10000) {
embeddedartists 0:a1d4ae5fb9fa 106 // normalize minutes to 6 decimal places
embeddedartists 0:a1d4ae5fb9fa 107 *pDegree /= (div / 10000);
embeddedartists 0:a1d4ae5fb9fa 108 }
embeddedartists 0:a1d4ae5fb9fa 109 }
embeddedartists 0:a1d4ae5fb9fa 110 /*****************************************************************************
embeddedartists 0:a1d4ae5fb9fa 111 ** Function name: parseUTC
embeddedartists 0:a1d4ae5fb9fa 112 **
embeddedartists 0:a1d4ae5fb9fa 113 ** Descriptions: Extracts the UTC time string in hhmmss.sss,
embeddedartists 0:a1d4ae5fb9fa 114 ** ignoring the .sss part and stores the result
embeddedartists 0:a1d4ae5fb9fa 115 ** as a string in data.utcTime.
embeddedartists 0:a1d4ae5fb9fa 116 **
embeddedartists 0:a1d4ae5fb9fa 117 ** parameters: The buffer
embeddedartists 0:a1d4ae5fb9fa 118 ** Returned value: None
embeddedartists 0:a1d4ae5fb9fa 119 **
embeddedartists 0:a1d4ae5fb9fa 120 *****************************************************************************/
embeddedartists 0:a1d4ae5fb9fa 121 static void parseUTC(uint8_t **ppBuf)
embeddedartists 0:a1d4ae5fb9fa 122 {
embeddedartists 0:a1d4ae5fb9fa 123 int index = 0;
embeddedartists 0:a1d4ae5fb9fa 124 // parse utc hhmmss.sss
embeddedartists 0:a1d4ae5fb9fa 125 while(**ppBuf != END_OF_MESSAGE) {
embeddedartists 0:a1d4ae5fb9fa 126 if(**ppBuf == '.') {
embeddedartists 0:a1d4ae5fb9fa 127 pointToNextValue(ppBuf);
embeddedartists 0:a1d4ae5fb9fa 128 break; //reached end of the value
embeddedartists 0:a1d4ae5fb9fa 129 }
embeddedartists 0:a1d4ae5fb9fa 130 data.utcTime[index++] = **ppBuf;
embeddedartists 0:a1d4ae5fb9fa 131 if(index == 2 || index == 5) {
embeddedartists 0:a1d4ae5fb9fa 132 //Add divider
embeddedartists 0:a1d4ae5fb9fa 133 data.utcTime[index++] = ':';
embeddedartists 0:a1d4ae5fb9fa 134 }
embeddedartists 0:a1d4ae5fb9fa 135 (*ppBuf)++;
embeddedartists 0:a1d4ae5fb9fa 136 }
embeddedartists 0:a1d4ae5fb9fa 137 data.utcTime[index] = '\0';
embeddedartists 0:a1d4ae5fb9fa 138 }
embeddedartists 0:a1d4ae5fb9fa 139 /*****************************************************************************
embeddedartists 0:a1d4ae5fb9fa 140 ** Function name: parseLatitude
embeddedartists 0:a1d4ae5fb9fa 141 **
embeddedartists 0:a1d4ae5fb9fa 142 ** Descriptions: Extracts the latitude information and stores
embeddedartists 0:a1d4ae5fb9fa 143 ** the result as an integer in data.latitude.
embeddedartists 0:a1d4ae5fb9fa 144 **
embeddedartists 0:a1d4ae5fb9fa 145 ** parameters: The buffer
embeddedartists 0:a1d4ae5fb9fa 146 ** Returned value: None
embeddedartists 0:a1d4ae5fb9fa 147 **
embeddedartists 0:a1d4ae5fb9fa 148 *****************************************************************************/
embeddedartists 0:a1d4ae5fb9fa 149 static void parseLatitude(uint8_t **ppBuf)
embeddedartists 0:a1d4ae5fb9fa 150 {
embeddedartists 0:a1d4ae5fb9fa 151 int index = 0;
embeddedartists 0:a1d4ae5fb9fa 152 while(**ppBuf != END_OF_MESSAGE) {
embeddedartists 0:a1d4ae5fb9fa 153 if (**ppBuf == DIVIDER) {
embeddedartists 0:a1d4ae5fb9fa 154 (*ppBuf)++; //reached end of the value
embeddedartists 0:a1d4ae5fb9fa 155 break;
embeddedartists 0:a1d4ae5fb9fa 156 }
embeddedartists 0:a1d4ae5fb9fa 157 data.bufLatitude[index++] = **ppBuf;
embeddedartists 0:a1d4ae5fb9fa 158 (*ppBuf)++;
embeddedartists 0:a1d4ae5fb9fa 159 }
embeddedartists 0:a1d4ae5fb9fa 160 convertCordinateToDegree((uint8_t *) &data.bufLatitude, &data.latitude, 8);
embeddedartists 0:a1d4ae5fb9fa 161 }
embeddedartists 0:a1d4ae5fb9fa 162 /*****************************************************************************
embeddedartists 0:a1d4ae5fb9fa 163 ** Function name: GPSRetreiveData
embeddedartists 0:a1d4ae5fb9fa 164 **
embeddedartists 0:a1d4ae5fb9fa 165 ** Descriptions: Reads and parses the next set of GPS data.
embeddedartists 0:a1d4ae5fb9fa 166 **
embeddedartists 0:a1d4ae5fb9fa 167 ** parameters: None
embeddedartists 0:a1d4ae5fb9fa 168 ** Returned value: The parsed information
embeddedartists 0:a1d4ae5fb9fa 169 **
embeddedartists 0:a1d4ae5fb9fa 170 *****************************************************************************/
embeddedartists 0:a1d4ae5fb9fa 171 const gpsData* GPSRetreiveData(void)
embeddedartists 0:a1d4ae5fb9fa 172 {
embeddedartists 0:a1d4ae5fb9fa 173 uint8_t * pattern = (uint8_t*)"GPGGA";
embeddedartists 0:a1d4ae5fb9fa 174 while (1) {
embeddedartists 0:a1d4ae5fb9fa 175 uint8_t buf[100];
embeddedartists 0:a1d4ae5fb9fa 176 uint8_t ch = 0;
embeddedartists 0:a1d4ae5fb9fa 177 uint8_t *ptr = 0;
embeddedartists 0:a1d4ae5fb9fa 178 int index = 0;
embeddedartists 0:a1d4ae5fb9fa 179
embeddedartists 0:a1d4ae5fb9fa 180 // Retrieve the first byte
embeddedartists 0:a1d4ae5fb9fa 181 //if (!UARTGetChar(&ch))
embeddedartists 0:a1d4ae5fb9fa 182 // continue;
embeddedartists 0:a1d4ae5fb9fa 183 ch = uart.getc();
embeddedartists 0:a1d4ae5fb9fa 184
embeddedartists 0:a1d4ae5fb9fa 185 // look for "$GPGGA," header
embeddedartists 0:a1d4ae5fb9fa 186 if (ch != '$') {
embeddedartists 0:a1d4ae5fb9fa 187 continue;
embeddedartists 0:a1d4ae5fb9fa 188 }
embeddedartists 0:a1d4ae5fb9fa 189
embeddedartists 0:a1d4ae5fb9fa 190 // Retrieve the next six bytes
embeddedartists 0:a1d4ae5fb9fa 191 for (index=0; index<6; index++) {
embeddedartists 0:a1d4ae5fb9fa 192 buf[index] = uart.getc();
embeddedartists 0:a1d4ae5fb9fa 193 }
embeddedartists 0:a1d4ae5fb9fa 194
embeddedartists 0:a1d4ae5fb9fa 195 //Check if its Global Positioning System fixed Data
embeddedartists 0:a1d4ae5fb9fa 196 if (hasPattern((uint8_t*)&buf, pattern) == 0) {
embeddedartists 0:a1d4ae5fb9fa 197 continue;
embeddedartists 0:a1d4ae5fb9fa 198 }
embeddedartists 0:a1d4ae5fb9fa 199
embeddedartists 0:a1d4ae5fb9fa 200 //Retrieve the data from the GPS module
embeddedartists 0:a1d4ae5fb9fa 201 for (index=0; index<100; index++) {
embeddedartists 0:a1d4ae5fb9fa 202 buf[index] = uart.getc();
embeddedartists 0:a1d4ae5fb9fa 203 if (buf[index] == '\r') {
embeddedartists 0:a1d4ae5fb9fa 204 buf[index] = END_OF_MESSAGE;
embeddedartists 0:a1d4ae5fb9fa 205 break;
embeddedartists 0:a1d4ae5fb9fa 206 }
embeddedartists 0:a1d4ae5fb9fa 207 }
embeddedartists 0:a1d4ae5fb9fa 208 ptr = &buf[0];
embeddedartists 0:a1d4ae5fb9fa 209
embeddedartists 0:a1d4ae5fb9fa 210 //parse UTC time
embeddedartists 0:a1d4ae5fb9fa 211 parseUTC(&ptr);
embeddedartists 0:a1d4ae5fb9fa 212
embeddedartists 0:a1d4ae5fb9fa 213 //parse Latitude
embeddedartists 0:a1d4ae5fb9fa 214 parseLatitude(&ptr);
embeddedartists 0:a1d4ae5fb9fa 215 break;
embeddedartists 0:a1d4ae5fb9fa 216 }
embeddedartists 0:a1d4ae5fb9fa 217 return &data;
embeddedartists 0:a1d4ae5fb9fa 218 }
embeddedartists 0:a1d4ae5fb9fa 219 static void displayGpsData(const gpsData* pData)
embeddedartists 0:a1d4ae5fb9fa 220 {
embeddedartists 0:a1d4ae5fb9fa 221 //Time
embeddedartists 0:a1d4ae5fb9fa 222 printf("\n%s\n", pData->utcTime);
embeddedartists 0:a1d4ae5fb9fa 223
embeddedartists 0:a1d4ae5fb9fa 224 //Latitude (in ddmmmmmm format, convert to dd.mmmmmm)
embeddedartists 0:a1d4ae5fb9fa 225 printf("Latitude: %d.%06d\n", pData->latitude/1000000, pData->latitude%1000000);
embeddedartists 0:a1d4ae5fb9fa 226
embeddedartists 0:a1d4ae5fb9fa 227 //Longitude (in ddmmmmmm format, convert to dd.mmmmmm)
embeddedartists 0:a1d4ae5fb9fa 228 printf("Longitude: %d.%06d\n", pData->longitude/1000000, pData->longitude%1000000);
embeddedartists 0:a1d4ae5fb9fa 229
embeddedartists 0:a1d4ae5fb9fa 230 //Number of satellites in view
embeddedartists 0:a1d4ae5fb9fa 231 printf("#Satellites: %s\n", pData->satellitesUsed);
embeddedartists 0:a1d4ae5fb9fa 232 }
embeddedartists 0:a1d4ae5fb9fa 233
embeddedartists 0:a1d4ae5fb9fa 234 int main (void)
embeddedartists 0:a1d4ae5fb9fa 235 {
embeddedartists 0:a1d4ae5fb9fa 236 //initialize the UART to 9600bps 8N1
embeddedartists 0:a1d4ae5fb9fa 237 uart.baud(9600);
embeddedartists 0:a1d4ae5fb9fa 238 //uart.format(8, Serial::None, 1);
embeddedartists 0:a1d4ae5fb9fa 239
embeddedartists 0:a1d4ae5fb9fa 240 pc.printf("Waiting for GPS data...\n");
embeddedartists 0:a1d4ae5fb9fa 241
embeddedartists 0:a1d4ae5fb9fa 242 //enter forever loop
embeddedartists 0:a1d4ae5fb9fa 243 while(1)
embeddedartists 0:a1d4ae5fb9fa 244 {
embeddedartists 0:a1d4ae5fb9fa 245 const gpsData* pData = GPSRetreiveData();
embeddedartists 0:a1d4ae5fb9fa 246 displayGpsData(pData);
embeddedartists 0:a1d4ae5fb9fa 247 wait(1);
embeddedartists 0:a1d4ae5fb9fa 248 }
embeddedartists 0:a1d4ae5fb9fa 249 }