QRSS Rx Network receiver. A receiver to sample a segment of RF spectrum and send this data to a server for further processing and display. NXP mbed Design Challenge entry (Honorable Mention). Published in Circuit Cellar, Feb 2012
Dependencies: NetServices mbed DNSResolver
gps.cpp@0:82ff15078322, 2012-01-25 (annotated)
- Committer:
- claytong
- Date:
- Wed Jan 25 20:32:53 2012 +0000
- Revision:
- 0:82ff15078322
1.0 (initial public release)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
claytong | 0:82ff15078322 | 1 | /*--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 2 | |
claytong | 0:82ff15078322 | 3 | QRSS Receiver Application |
claytong | 0:82ff15078322 | 4 | |
claytong | 0:82ff15078322 | 5 | by Clayton ZL3TKA/VK1TKA |
claytong | 0:82ff15078322 | 6 | clayton@isnotcrazy.com |
claytong | 0:82ff15078322 | 7 | |
claytong | 0:82ff15078322 | 8 | GPS Module |
claytong | 0:82ff15078322 | 9 | |
claytong | 0:82ff15078322 | 10 | ---------------------------------------------------------------------------*/ |
claytong | 0:82ff15078322 | 11 | // include files |
claytong | 0:82ff15078322 | 12 | |
claytong | 0:82ff15078322 | 13 | #include "gps.h" |
claytong | 0:82ff15078322 | 14 | #include "comms.h" |
claytong | 0:82ff15078322 | 15 | |
claytong | 0:82ff15078322 | 16 | // Definitions |
claytong | 0:82ff15078322 | 17 | |
claytong | 0:82ff15078322 | 18 | #define GPS_DEBUG 0 |
claytong | 0:82ff15078322 | 19 | |
claytong | 0:82ff15078322 | 20 | // comments |
claytong | 0:82ff15078322 | 21 | |
claytong | 0:82ff15078322 | 22 | // Macros |
claytong | 0:82ff15078322 | 23 | |
claytong | 0:82ff15078322 | 24 | // Local Data |
claytong | 0:82ff15078322 | 25 | |
claytong | 0:82ff15078322 | 26 | // Global Data |
claytong | 0:82ff15078322 | 27 | TGPSController GPSModule; |
claytong | 0:82ff15078322 | 28 | |
claytong | 0:82ff15078322 | 29 | |
claytong | 0:82ff15078322 | 30 | // Function Prototypes |
claytong | 0:82ff15078322 | 31 | |
claytong | 0:82ff15078322 | 32 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 33 | // TGPSController Class Methods |
claytong | 0:82ff15078322 | 34 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 35 | |
claytong | 0:82ff15078322 | 36 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 37 | // |
claytong | 0:82ff15078322 | 38 | // Constructor |
claytong | 0:82ff15078322 | 39 | // |
claytong | 0:82ff15078322 | 40 | TGPSController::TGPSController() : |
claytong | 0:82ff15078322 | 41 | PPSInput( p30 ), |
claytong | 0:82ff15078322 | 42 | GPSPort( p28, p27 ), |
claytong | 0:82ff15078322 | 43 | GPSUpLED( LED3 ), |
claytong | 0:82ff15078322 | 44 | PPSEvent( p30 ), |
claytong | 0:82ff15078322 | 45 | bPulsed( false ), |
claytong | 0:82ff15078322 | 46 | uiPPSCapture( 0 ), |
claytong | 0:82ff15078322 | 47 | uiLOscCapture( 0 ) |
claytong | 0:82ff15078322 | 48 | { |
claytong | 0:82ff15078322 | 49 | // clear current and last line |
claytong | 0:82ff15078322 | 50 | szCurrentLine[0] = 0; |
claytong | 0:82ff15078322 | 51 | szLastLine[0] = 0; |
claytong | 0:82ff15078322 | 52 | bNewLine = false; |
claytong | 0:82ff15078322 | 53 | } |
claytong | 0:82ff15078322 | 54 | |
claytong | 0:82ff15078322 | 55 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 56 | // |
claytong | 0:82ff15078322 | 57 | // Initialise routine |
claytong | 0:82ff15078322 | 58 | // |
claytong | 0:82ff15078322 | 59 | void TGPSController::Init() |
claytong | 0:82ff15078322 | 60 | { |
claytong | 0:82ff15078322 | 61 | // Set up GPS port |
claytong | 0:82ff15078322 | 62 | GPSPort.baud( 4800 ); |
claytong | 0:82ff15078322 | 63 | |
claytong | 0:82ff15078322 | 64 | // capture 1PPS event |
claytong | 0:82ff15078322 | 65 | PPSEvent.rise( this, &TGPSController::PPSPulse ); |
claytong | 0:82ff15078322 | 66 | |
claytong | 0:82ff15078322 | 67 | // Start timeout timer |
claytong | 0:82ff15078322 | 68 | GPSMsgTimeout.start(); |
claytong | 0:82ff15078322 | 69 | GPSPulseTimeout.start(); |
claytong | 0:82ff15078322 | 70 | |
claytong | 0:82ff15078322 | 71 | // Set up timer hardware |
claytong | 0:82ff15078322 | 72 | LPC_PINCON->PINSEL0 |= ( (0x3<<8) | (0x3<<10) ); // enable CAP2.0, CAP2.1 |
claytong | 0:82ff15078322 | 73 | LPC_SC->PCONP |= 1 << 22; // power up TIMER2 (PCONP[22]) |
claytong | 0:82ff15078322 | 74 | LPC_SC->PCLKSEL1 &= ~(0x3<<12); |
claytong | 0:82ff15078322 | 75 | LPC_SC->PCLKSEL1 |= (0x1<<12); // Timer2 PCLK = CCLK |
claytong | 0:82ff15078322 | 76 | LPC_TIM2->TCR = 0x2; // reset timer |
claytong | 0:82ff15078322 | 77 | LPC_TIM2->CTCR = 0x0; // timer mode |
claytong | 0:82ff15078322 | 78 | LPC_TIM2->PR = 0; // no prescale |
claytong | 0:82ff15078322 | 79 | LPC_TIM2->MCR = 0x0; // no match |
claytong | 0:82ff15078322 | 80 | LPC_TIM2->CCR = (1<<0) | (1<<3); // Capture rising edges on both CAP2.0 & CAP2.1 |
claytong | 0:82ff15078322 | 81 | LPC_TIM2->TCR = 1; // start the timer |
claytong | 0:82ff15078322 | 82 | } |
claytong | 0:82ff15078322 | 83 | |
claytong | 0:82ff15078322 | 84 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 85 | // |
claytong | 0:82ff15078322 | 86 | // Poll routine |
claytong | 0:82ff15078322 | 87 | // |
claytong | 0:82ff15078322 | 88 | void TGPSController::Poll() |
claytong | 0:82ff15078322 | 89 | { |
claytong | 0:82ff15078322 | 90 | // Test for a 1PPS pulse |
claytong | 0:82ff15078322 | 91 | if ( bPulsed ) |
claytong | 0:82ff15078322 | 92 | { // 1PPS from the GPS unit |
claytong | 0:82ff15078322 | 93 | bPulsed = false; |
claytong | 0:82ff15078322 | 94 | GPSPulseTimeout.reset(); |
claytong | 0:82ff15078322 | 95 | |
claytong | 0:82ff15078322 | 96 | // flush out any old serial data |
claytong | 0:82ff15078322 | 97 | while ( GPSPort.readable() ) |
claytong | 0:82ff15078322 | 98 | GPSPort.getc(); |
claytong | 0:82ff15078322 | 99 | #if GPS_DEBUG>2 |
claytong | 0:82ff15078322 | 100 | printf( "***1PPS***\r\n" ); |
claytong | 0:82ff15078322 | 101 | #endif |
claytong | 0:82ff15078322 | 102 | // Record capture data to comms module |
claytong | 0:82ff15078322 | 103 | Comms.RecordPPSTimestamps( uiPPSCapture, uiLOscCapture, GPSRecord ); |
claytong | 0:82ff15078322 | 104 | } |
claytong | 0:82ff15078322 | 105 | |
claytong | 0:82ff15078322 | 106 | // Test for GPS serial port data |
claytong | 0:82ff15078322 | 107 | while ( GPSPort.readable() ) |
claytong | 0:82ff15078322 | 108 | { |
claytong | 0:82ff15078322 | 109 | char cNextChar = GPSPort.getc(); |
claytong | 0:82ff15078322 | 110 | #if GPS_DEBUG>3 |
claytong | 0:82ff15078322 | 111 | printf( "%c", cNextChar ); |
claytong | 0:82ff15078322 | 112 | #endif |
claytong | 0:82ff15078322 | 113 | if ( ParseData(cNextChar) ) |
claytong | 0:82ff15078322 | 114 | { // have a completed GPS sentence |
claytong | 0:82ff15078322 | 115 | GPSMsgTimeout.reset(); |
claytong | 0:82ff15078322 | 116 | // analysis the sentence data |
claytong | 0:82ff15078322 | 117 | int iStatus = ProcessGPSData(); |
claytong | 0:82ff15078322 | 118 | if ( iStatus==0 ) |
claytong | 0:82ff15078322 | 119 | { // good sentence |
claytong | 0:82ff15078322 | 120 | #if GPS_DEBUG>0 |
claytong | 0:82ff15078322 | 121 | printf( "Time: %d\r\n", GPSRecord.iGPSTimeSeconds ); |
claytong | 0:82ff15078322 | 122 | printf( "Lat: %d\r\n", GPSRecord.iGPSLatMicroDegrees ); |
claytong | 0:82ff15078322 | 123 | printf( "Long: %d\r\n", GPSRecord.iGPSLongMicroDegrees ); |
claytong | 0:82ff15078322 | 124 | printf( "Alt: %d\r\n", GPSRecord.iGPSAltitudeMeters ); |
claytong | 0:82ff15078322 | 125 | printf( "Sats: %d\r\n", GPSRecord.iGPSSatellites ); |
claytong | 0:82ff15078322 | 126 | printf( "Qual: %d\r\n", GPSRecord.iGPSQuality ); |
claytong | 0:82ff15078322 | 127 | #endif |
claytong | 0:82ff15078322 | 128 | } |
claytong | 0:82ff15078322 | 129 | } |
claytong | 0:82ff15078322 | 130 | } |
claytong | 0:82ff15078322 | 131 | |
claytong | 0:82ff15078322 | 132 | // Test for GPS timeout (no data) |
claytong | 0:82ff15078322 | 133 | if ( GPSMsgTimeout.read_ms()>GPS_MSGTIMEOUT ) |
claytong | 0:82ff15078322 | 134 | { // No GPS messages for a period |
claytong | 0:82ff15078322 | 135 | #if GPS_DEBUG>1 |
claytong | 0:82ff15078322 | 136 | printf( "GPS Timeout - setting to offline\r\n" ); |
claytong | 0:82ff15078322 | 137 | #endif |
claytong | 0:82ff15078322 | 138 | GPSRecord.iGPSQuality = 0; // set quality to 0 - invalid data |
claytong | 0:82ff15078322 | 139 | GPSMsgTimeout.reset(); |
claytong | 0:82ff15078322 | 140 | // Record invalid GPS status to comms module |
claytong | 0:82ff15078322 | 141 | Comms.RecordPPSTimestamps( 0, 0, GPSRecord ); |
claytong | 0:82ff15078322 | 142 | } |
claytong | 0:82ff15078322 | 143 | |
claytong | 0:82ff15078322 | 144 | // Test for GPS timeout (no 1PPS) |
claytong | 0:82ff15078322 | 145 | if ( GPSPulseTimeout.read_ms()>GPS_PULSETIMEOUT ) |
claytong | 0:82ff15078322 | 146 | { // No GPS pulse for a period |
claytong | 0:82ff15078322 | 147 | // we just forward data to Comms module with invalid capture data |
claytong | 0:82ff15078322 | 148 | Comms.RecordPPSTimestamps( 0, 0, GPSRecord ); |
claytong | 0:82ff15078322 | 149 | GPSPulseTimeout.reset(); |
claytong | 0:82ff15078322 | 150 | } |
claytong | 0:82ff15078322 | 151 | |
claytong | 0:82ff15078322 | 152 | } |
claytong | 0:82ff15078322 | 153 | |
claytong | 0:82ff15078322 | 154 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 155 | // |
claytong | 0:82ff15078322 | 156 | // Parse data from the GPS |
claytong | 0:82ff15078322 | 157 | // Return true if a completed valid sentence is received |
claytong | 0:82ff15078322 | 158 | // |
claytong | 0:82ff15078322 | 159 | #define EXPECT_CHAR(CC) if (cChr==CC)iParseState++; else iParseState=0;ResetNumber() |
claytong | 0:82ff15078322 | 160 | #define PARSE_NUMBER(NN) if(cChr==','){NN=ParseNum;ResetNumber();iParseState++;break;}if (!ParseNumber(cChr))iParseState=0 |
claytong | 0:82ff15078322 | 161 | #define PARSE_CHARACTER(CH) if(cChr==','){CH=cCharacter;ResetNumber();iParseState++;break;}cCharacter=cChr |
claytong | 0:82ff15078322 | 162 | // |
claytong | 0:82ff15078322 | 163 | bool TGPSController::ParseData( char cChr ) |
claytong | 0:82ff15078322 | 164 | { |
claytong | 0:82ff15078322 | 165 | ucChecksum ^= cChr; |
claytong | 0:82ff15078322 | 166 | switch ( iParseState ) |
claytong | 0:82ff15078322 | 167 | { |
claytong | 0:82ff15078322 | 168 | case 0: |
claytong | 0:82ff15078322 | 169 | if ( cChr=='$' ) |
claytong | 0:82ff15078322 | 170 | iParseState++; |
claytong | 0:82ff15078322 | 171 | ucChecksum = 0; |
claytong | 0:82ff15078322 | 172 | break; |
claytong | 0:82ff15078322 | 173 | case 1: EXPECT_CHAR('G'); break; |
claytong | 0:82ff15078322 | 174 | case 2: EXPECT_CHAR('P'); break; |
claytong | 0:82ff15078322 | 175 | case 3: EXPECT_CHAR('G'); break; |
claytong | 0:82ff15078322 | 176 | case 4: EXPECT_CHAR('G'); break; |
claytong | 0:82ff15078322 | 177 | case 5: EXPECT_CHAR('A'); break; |
claytong | 0:82ff15078322 | 178 | case 6: EXPECT_CHAR(','); break; |
claytong | 0:82ff15078322 | 179 | case 7: PARSE_NUMBER( GPSTime ); break; |
claytong | 0:82ff15078322 | 180 | case 8: PARSE_NUMBER( GPSLatitude ); break; |
claytong | 0:82ff15078322 | 181 | case 9: PARSE_CHARACTER( GPSLatNS ); break; |
claytong | 0:82ff15078322 | 182 | case 10: PARSE_NUMBER( GPSLongitude ); break; |
claytong | 0:82ff15078322 | 183 | case 11: PARSE_CHARACTER( GPSLongEW ); break; |
claytong | 0:82ff15078322 | 184 | case 12: PARSE_NUMBER( GPSQuality ); break; |
claytong | 0:82ff15078322 | 185 | case 13: PARSE_NUMBER( GPSSatellites ); break; |
claytong | 0:82ff15078322 | 186 | case 14: PARSE_NUMBER( GPSDOP ); break; |
claytong | 0:82ff15078322 | 187 | case 15: PARSE_NUMBER( GPSAltitude ); break; |
claytong | 0:82ff15078322 | 188 | case 16: PARSE_CHARACTER( GPSAltType ); break; |
claytong | 0:82ff15078322 | 189 | case 17: PARSE_NUMBER( GPSHeight ); break; |
claytong | 0:82ff15078322 | 190 | case 18: PARSE_CHARACTER( GPSHeightType ); break; |
claytong | 0:82ff15078322 | 191 | case 19: EXPECT_CHAR(','); |
claytong | 0:82ff15078322 | 192 | ucFinalChecksum = ucChecksum; |
claytong | 0:82ff15078322 | 193 | break; |
claytong | 0:82ff15078322 | 194 | case 20: EXPECT_CHAR('*'); break; |
claytong | 0:82ff15078322 | 195 | case 21: iParseState++; |
claytong | 0:82ff15078322 | 196 | if ( (cChr>='0') && (cChr<='9') ) |
claytong | 0:82ff15078322 | 197 | ucMsgChecksum = (cChr-'0') << 4; |
claytong | 0:82ff15078322 | 198 | else if ( (cChr>='A') && (cChr<='F') ) |
claytong | 0:82ff15078322 | 199 | ucMsgChecksum = (cChr-'A'+10) << 4; |
claytong | 0:82ff15078322 | 200 | else |
claytong | 0:82ff15078322 | 201 | iParseState = 0; |
claytong | 0:82ff15078322 | 202 | break; |
claytong | 0:82ff15078322 | 203 | case 22: iParseState++; |
claytong | 0:82ff15078322 | 204 | if ( (cChr>='0') && (cChr<='9') ) |
claytong | 0:82ff15078322 | 205 | ucMsgChecksum |= (cChr-'0'); |
claytong | 0:82ff15078322 | 206 | else if ( (cChr>='A') && (cChr<='F') ) |
claytong | 0:82ff15078322 | 207 | ucMsgChecksum |= (cChr-'A'+10); |
claytong | 0:82ff15078322 | 208 | else |
claytong | 0:82ff15078322 | 209 | iParseState = 0; |
claytong | 0:82ff15078322 | 210 | break; |
claytong | 0:82ff15078322 | 211 | case 23: // don't care about char (should be a CR) |
claytong | 0:82ff15078322 | 212 | // just check the results |
claytong | 0:82ff15078322 | 213 | if ( ucMsgChecksum==ucFinalChecksum ) |
claytong | 0:82ff15078322 | 214 | { // Checksum okay |
claytong | 0:82ff15078322 | 215 | // reset |
claytong | 0:82ff15078322 | 216 | iParseState = 0; |
claytong | 0:82ff15078322 | 217 | // return valid message |
claytong | 0:82ff15078322 | 218 | return true; |
claytong | 0:82ff15078322 | 219 | } |
claytong | 0:82ff15078322 | 220 | #if GPS_DEBUG>0 |
claytong | 0:82ff15078322 | 221 | else |
claytong | 0:82ff15078322 | 222 | printf( "!GPS Check failed - got %02X wanted %02X\r\n", (int)ucMsgChecksum, (int)ucFinalChecksum ); |
claytong | 0:82ff15078322 | 223 | #endif |
claytong | 0:82ff15078322 | 224 | // reset |
claytong | 0:82ff15078322 | 225 | iParseState = 0; |
claytong | 0:82ff15078322 | 226 | break; |
claytong | 0:82ff15078322 | 227 | } |
claytong | 0:82ff15078322 | 228 | |
claytong | 0:82ff15078322 | 229 | #if GPS_DEBUG>2 |
claytong | 0:82ff15078322 | 230 | // report parser state |
claytong | 0:82ff15078322 | 231 | printf( ":%d:", iParseState ); |
claytong | 0:82ff15078322 | 232 | #endif |
claytong | 0:82ff15078322 | 233 | |
claytong | 0:82ff15078322 | 234 | // GPS sentence note yet completed |
claytong | 0:82ff15078322 | 235 | return false; |
claytong | 0:82ff15078322 | 236 | } |
claytong | 0:82ff15078322 | 237 | |
claytong | 0:82ff15078322 | 238 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 239 | // |
claytong | 0:82ff15078322 | 240 | // Parse a number character by character |
claytong | 0:82ff15078322 | 241 | // If character is invalid, returns false |
claytong | 0:82ff15078322 | 242 | // |
claytong | 0:82ff15078322 | 243 | bool TGPSController::ParseNumber( char cChar ) |
claytong | 0:82ff15078322 | 244 | { |
claytong | 0:82ff15078322 | 245 | // process digits |
claytong | 0:82ff15078322 | 246 | if ( (cChar>='0') && (cChar<='9') ) |
claytong | 0:82ff15078322 | 247 | { |
claytong | 0:82ff15078322 | 248 | ParseNum.uiNumber = (ParseNum.uiNumber*10) + (cChar-'0'); |
claytong | 0:82ff15078322 | 249 | ParseNum.iNumberLen++; |
claytong | 0:82ff15078322 | 250 | if ( ParseNum.iNumberDecimals>=0 ) |
claytong | 0:82ff15078322 | 251 | ParseNum.iNumberDecimals++; |
claytong | 0:82ff15078322 | 252 | return true; |
claytong | 0:82ff15078322 | 253 | } |
claytong | 0:82ff15078322 | 254 | if ( cChar=='.' ) |
claytong | 0:82ff15078322 | 255 | { |
claytong | 0:82ff15078322 | 256 | if ( ParseNum.iNumberDecimals>=0 ) |
claytong | 0:82ff15078322 | 257 | return false; // a second decimal point! |
claytong | 0:82ff15078322 | 258 | ParseNum.iNumberDecimals = 0; |
claytong | 0:82ff15078322 | 259 | return true; |
claytong | 0:82ff15078322 | 260 | } |
claytong | 0:82ff15078322 | 261 | if ( cChar=='-' ) |
claytong | 0:82ff15078322 | 262 | { |
claytong | 0:82ff15078322 | 263 | if ( ParseNum.iNumberLen>0 ) |
claytong | 0:82ff15078322 | 264 | return false; // '-' must be the first character |
claytong | 0:82ff15078322 | 265 | ParseNum.iNumberSign = -1; |
claytong | 0:82ff15078322 | 266 | return true; |
claytong | 0:82ff15078322 | 267 | } |
claytong | 0:82ff15078322 | 268 | // otherwise an invalid character |
claytong | 0:82ff15078322 | 269 | return false; |
claytong | 0:82ff15078322 | 270 | } |
claytong | 0:82ff15078322 | 271 | |
claytong | 0:82ff15078322 | 272 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 273 | // |
claytong | 0:82ff15078322 | 274 | // Reset the number parser |
claytong | 0:82ff15078322 | 275 | // |
claytong | 0:82ff15078322 | 276 | void TGPSController::ResetNumber( ) |
claytong | 0:82ff15078322 | 277 | { |
claytong | 0:82ff15078322 | 278 | ParseNum.uiNumber = 0; |
claytong | 0:82ff15078322 | 279 | ParseNum.iNumberLen = 0; |
claytong | 0:82ff15078322 | 280 | ParseNum.iNumberSign = 1; |
claytong | 0:82ff15078322 | 281 | ParseNum.iNumberDecimals = -1; |
claytong | 0:82ff15078322 | 282 | cCharacter = 0; |
claytong | 0:82ff15078322 | 283 | } |
claytong | 0:82ff15078322 | 284 | |
claytong | 0:82ff15078322 | 285 | |
claytong | 0:82ff15078322 | 286 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 287 | // |
claytong | 0:82ff15078322 | 288 | // Process the data from the GPS message |
claytong | 0:82ff15078322 | 289 | // Returns 0 if all data is good, or an error code |
claytong | 0:82ff15078322 | 290 | // |
claytong | 0:82ff15078322 | 291 | int TGPSController::ProcessGPSData( ) |
claytong | 0:82ff15078322 | 292 | { |
claytong | 0:82ff15078322 | 293 | // check Quality |
claytong | 0:82ff15078322 | 294 | if ( GPSQuality.iNumberLen<1 ) return 10; |
claytong | 0:82ff15078322 | 295 | if ( GPSQuality.iNumberDecimals!=-1 ) return 11; |
claytong | 0:82ff15078322 | 296 | if ( GPSQuality.iNumberSign!=1 ) return 12; |
claytong | 0:82ff15078322 | 297 | // check Satellites |
claytong | 0:82ff15078322 | 298 | if ( GPSSatellites.iNumberLen<1 ) return 20; |
claytong | 0:82ff15078322 | 299 | if ( GPSSatellites.iNumberDecimals!=-1 ) return 21; |
claytong | 0:82ff15078322 | 300 | if ( GPSSatellites.iNumberSign!=1 ) return 22; |
claytong | 0:82ff15078322 | 301 | // Store sats and quality parameters |
claytong | 0:82ff15078322 | 302 | GPSRecord.iGPSSatellites = GPSSatellites.uiNumber; |
claytong | 0:82ff15078322 | 303 | GPSRecord.iGPSQuality = GPSQuality.uiNumber; |
claytong | 0:82ff15078322 | 304 | // Check quality level |
claytong | 0:82ff15078322 | 305 | if ( GPSQuality.uiNumber<1 ) return 100; // no fix |
claytong | 0:82ff15078322 | 306 | // check Time |
claytong | 0:82ff15078322 | 307 | if ( GPSTime.iNumberLen<6 ) return 30; |
claytong | 0:82ff15078322 | 308 | if ( GPSTime.iNumberSign!=1 ) return 32; |
claytong | 0:82ff15078322 | 309 | // check Latitude |
claytong | 0:82ff15078322 | 310 | if ( GPSLatitude.iNumberLen!=7 ) return 40; |
claytong | 0:82ff15078322 | 311 | if ( GPSLatitude.iNumberDecimals!=3 ) return 41; |
claytong | 0:82ff15078322 | 312 | if ( GPSLatitude.iNumberSign!=1 ) return 42; |
claytong | 0:82ff15078322 | 313 | if ( (GPSLatNS!='N') && (GPSLatNS!='S') ) return 43; |
claytong | 0:82ff15078322 | 314 | // check Longitude |
claytong | 0:82ff15078322 | 315 | if ( GPSLongitude.iNumberLen!=8 ) return 50; |
claytong | 0:82ff15078322 | 316 | if ( GPSLongitude.iNumberDecimals!=3 ) return 51; |
claytong | 0:82ff15078322 | 317 | if ( GPSLongitude.iNumberSign!=1 ) return 52; |
claytong | 0:82ff15078322 | 318 | if ( (GPSLongEW!='E') && (GPSLongEW!='W') ) return 53; |
claytong | 0:82ff15078322 | 319 | // check Altitude |
claytong | 0:82ff15078322 | 320 | if ( GPSAltitude.iNumberLen<1 ) return 60; |
claytong | 0:82ff15078322 | 321 | // Don't care about DOPs and Height and Types |
claytong | 0:82ff15078322 | 322 | // Translate & Store parameters |
claytong | 0:82ff15078322 | 323 | |
claytong | 0:82ff15078322 | 324 | // discard fractions of seconds |
claytong | 0:82ff15078322 | 325 | while ( (GPSTime.iNumberDecimals--)>0 ) |
claytong | 0:82ff15078322 | 326 | GPSTime.uiNumber /= 10; |
claytong | 0:82ff15078322 | 327 | |
claytong | 0:82ff15078322 | 328 | int32_t iHours = GPSTime.uiNumber/10000; |
claytong | 0:82ff15078322 | 329 | int32_t iMins = (GPSTime.uiNumber/100)%100; |
claytong | 0:82ff15078322 | 330 | int32_t iSecs = GPSTime.uiNumber%100; |
claytong | 0:82ff15078322 | 331 | GPSRecord.iGPSTimeSeconds = iSecs + (60*iMins) + (3600*iHours); |
claytong | 0:82ff15078322 | 332 | |
claytong | 0:82ff15078322 | 333 | int32_t iDegrees = GPSLatitude.uiNumber / 100000; |
claytong | 0:82ff15078322 | 334 | int32_t iMilliMinutes = GPSLatitude.uiNumber % 100000; |
claytong | 0:82ff15078322 | 335 | GPSRecord.iGPSLatMicroDegrees = (iMilliMinutes * 100 / 6) + (iDegrees*1000000); |
claytong | 0:82ff15078322 | 336 | if ( GPSLatNS=='S' ) |
claytong | 0:82ff15078322 | 337 | GPSRecord.iGPSLatMicroDegrees = -GPSRecord.iGPSLatMicroDegrees; |
claytong | 0:82ff15078322 | 338 | |
claytong | 0:82ff15078322 | 339 | iDegrees = GPSLongitude.uiNumber / 100000; |
claytong | 0:82ff15078322 | 340 | iMilliMinutes = GPSLongitude.uiNumber % 100000; |
claytong | 0:82ff15078322 | 341 | GPSRecord.iGPSLongMicroDegrees = (iMilliMinutes * 100 / 6) + (iDegrees*1000000); |
claytong | 0:82ff15078322 | 342 | if ( GPSLongEW=='W' ) |
claytong | 0:82ff15078322 | 343 | GPSRecord.iGPSLatMicroDegrees = -GPSRecord.iGPSLatMicroDegrees; |
claytong | 0:82ff15078322 | 344 | |
claytong | 0:82ff15078322 | 345 | GPSRecord.iGPSAltitudeMeters = GPSAltitude.uiNumber * GPSAltitude.iNumberSign; |
claytong | 0:82ff15078322 | 346 | while ( (GPSAltitude.iNumberDecimals--)>0 ) |
claytong | 0:82ff15078322 | 347 | GPSRecord.iGPSAltitudeMeters /= 10; |
claytong | 0:82ff15078322 | 348 | |
claytong | 0:82ff15078322 | 349 | return 0; |
claytong | 0:82ff15078322 | 350 | } |
claytong | 0:82ff15078322 | 351 | |
claytong | 0:82ff15078322 | 352 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 353 | // |
claytong | 0:82ff15078322 | 354 | // PPS Event routine |
claytong | 0:82ff15078322 | 355 | // |
claytong | 0:82ff15078322 | 356 | void TGPSController::PPSPulse() |
claytong | 0:82ff15078322 | 357 | { |
claytong | 0:82ff15078322 | 358 | // indicate we have pulsed |
claytong | 0:82ff15078322 | 359 | bPulsed = true; |
claytong | 0:82ff15078322 | 360 | |
claytong | 0:82ff15078322 | 361 | // capture timer capture registers |
claytong | 0:82ff15078322 | 362 | // 1PPP = CAP2.0 |
claytong | 0:82ff15078322 | 363 | // LOsc (/4096) = CAP2.1 |
claytong | 0:82ff15078322 | 364 | uiPPSCapture = LPC_TIM2->CR0; |
claytong | 0:82ff15078322 | 365 | uiLOscCapture = LPC_TIM2->CR1; |
claytong | 0:82ff15078322 | 366 | |
claytong | 0:82ff15078322 | 367 | } |
claytong | 0:82ff15078322 | 368 | |
claytong | 0:82ff15078322 | 369 | /* |
claytong | 0:82ff15078322 | 370 | GPS Messages: |
claytong | 0:82ff15078322 | 371 | |
claytong | 0:82ff15078322 | 372 | GGA - essential fix data which provide 3D location and accuracy data. |
claytong | 0:82ff15078322 | 373 | |
claytong | 0:82ff15078322 | 374 | $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47 |
claytong | 0:82ff15078322 | 375 | |
claytong | 0:82ff15078322 | 376 | Where: |
claytong | 0:82ff15078322 | 377 | GGA Global Positioning System Fix Data |
claytong | 0:82ff15078322 | 378 | 123519 Fix taken at 12:35:19 UTC |
claytong | 0:82ff15078322 | 379 | 4807.038,N Latitude 48 deg 07.038' N |
claytong | 0:82ff15078322 | 380 | 01131.000,E Longitude 11 deg 31.000' E |
claytong | 0:82ff15078322 | 381 | 1 Fix quality: 0 = invalid |
claytong | 0:82ff15078322 | 382 | 1 = GPS fix (SPS) |
claytong | 0:82ff15078322 | 383 | 2 = DGPS fix |
claytong | 0:82ff15078322 | 384 | 3 = PPS fix |
claytong | 0:82ff15078322 | 385 | 4 = Real Time Kinematic |
claytong | 0:82ff15078322 | 386 | 5 = Float RTK |
claytong | 0:82ff15078322 | 387 | 6 = estimated (dead reckoning) (2.3 feature) |
claytong | 0:82ff15078322 | 388 | 7 = Manual input mode |
claytong | 0:82ff15078322 | 389 | 8 = Simulation mode |
claytong | 0:82ff15078322 | 390 | 08 Number of satellites being tracked |
claytong | 0:82ff15078322 | 391 | 0.9 Horizontal dilution of position |
claytong | 0:82ff15078322 | 392 | 545.4,M Altitude, Meters, above mean sea level |
claytong | 0:82ff15078322 | 393 | 46.9,M Height of geoid (mean sea level) above WGS84 |
claytong | 0:82ff15078322 | 394 | ellipsoid |
claytong | 0:82ff15078322 | 395 | (empty field) time in seconds since last DGPS update |
claytong | 0:82ff15078322 | 396 | (empty field) DGPS station ID number |
claytong | 0:82ff15078322 | 397 | *47 the checksum data, always begins with * |
claytong | 0:82ff15078322 | 398 | |
claytong | 0:82ff15078322 | 399 | |
claytong | 0:82ff15078322 | 400 | VTG - Velocity made good. The gps receiver may use the LC prefix instead of GP if it is emulating Loran output. |
claytong | 0:82ff15078322 | 401 | |
claytong | 0:82ff15078322 | 402 | $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48 |
claytong | 0:82ff15078322 | 403 | |
claytong | 0:82ff15078322 | 404 | where: |
claytong | 0:82ff15078322 | 405 | VTG Track made good and ground speed |
claytong | 0:82ff15078322 | 406 | 054.7,T True track made good (degrees) |
claytong | 0:82ff15078322 | 407 | 034.4,M Magnetic track made good |
claytong | 0:82ff15078322 | 408 | 005.5,N Ground speed, knots |
claytong | 0:82ff15078322 | 409 | 010.2,K Ground speed, Kilometers per hour |
claytong | 0:82ff15078322 | 410 | *48 Checksum |
claytong | 0:82ff15078322 | 411 | |
claytong | 0:82ff15078322 | 412 | |
claytong | 0:82ff15078322 | 413 | |
claytong | 0:82ff15078322 | 414 | $GPGGA,,,,,,0,05,,,,,,,*63 |
claytong | 0:82ff15078322 | 415 | $GPGGA,,,,,,0,02,,,,,,,*64 |
claytong | 0:82ff15078322 | 416 | $GPGGA,,,,,,0,03,,,,,,,*65 |
claytong | 0:82ff15078322 | 417 | $GPGGA,120609.46,3515.405,S,14904.873,E,0,04,2.24,718,M,14,M,,*42 |
claytong | 0:82ff15078322 | 418 | $GPVTG,000.0,T,346.7,M,0.000,N,0.000,K*48 |
claytong | 0:82ff15078322 | 419 | $GPGGA,120610.46,3515.405,S,14904.873,E,1,04,2.24,718,M,14,M,,*4B |
claytong | 0:82ff15078322 | 420 | $GPVTG,000.0,T,346.7,M,0.000,N,0.000,K*48 |
claytong | 0:82ff15078322 | 421 | $GPGGA,120611.46,3515.405,S,14904.873,E,1,04,2.24,718,M,14,M,,*4A |
claytong | 0:82ff15078322 | 422 | $GPVTG,000.0,T,346.7,M,0.000,N,0.000,K*48 |
claytong | 0:82ff15078322 | 423 | $GPGGA,120612.46,3515.405,S,14904.873,E,1,04,2.24,718,M,14,M,,*49 |
claytong | 0:82ff15078322 | 424 | |
claytong | 0:82ff15078322 | 425 | */ |
claytong | 0:82ff15078322 | 426 | |
claytong | 0:82ff15078322 | 427 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 428 | // END |
claytong | 0:82ff15078322 | 429 | //--------------------------------------------------------------------------- |
claytong | 0:82ff15078322 | 430 |