char * itoa_left_pad(char *buf, char *bufend, Int i, bool positive_sign=false, char pad='0') { typename signed_for_int<Int>::unsigned_t n=i; if (i<0) { n=-n; // see comment above for itoa #ifdef __clang__ #include "warning_pop.h" #endif #ifdef _MSC_VER #pragma warning( pop ) #endif *buf='-'; } else if (positive_sign) *buf='+'; char * r=utoa(bufend, n); assert(buf<r); left_pad(buf+1, r, pad); return buf; }
char *utoa_left_pad(char *buf, char *bufend, Int n, char pad='0') { char *r=utoa(bufend, n); assert(buf<=r); left_pad(buf, r, pad); return buf; }
// Processes a just-completed term // Returns true if new sentence has just passed checksum test and is validated bool Gps::term_complete() { if (_is_checksum_term) { unsigned char checksum = 16 * from_hex(_term[0]) + from_hex(_term[1]); if (checksum == _parity) { if (_gps_fixed) { _last_time_fix = _new_time_fix; _last_position_fix = _new_position_fix; switch(_sentence_type) { case _GPS_SENTENCE_GPRMC: strcpy(_rmc_time, _new_time); strcpy(_date, _new_date); strcpy(_lat, _new_lat); strcpy(_lon, _new_lon); strcpy(_speed, _new_speed); strcpy(_course, _new_course); break; case _GPS_SENTENCE_GPGGA: strcpy(_gga_time, _new_time); strcpy(_lat, _new_lat); strcpy(_lon, _new_lon); strcpy(_altitude, _new_altitude); break; } // Return a valid object only when we've got two rmc and gga // messages with the same timestamp if (! strcmp(_gga_time, _rmc_time)) return true; } } return false; } // the first term determines the sentence type if (_term_number == 0) { if (!strcmp(_term, _GPRMC_TERM)) _sentence_type = _GPS_SENTENCE_GPRMC; else if (!strcmp(_term, _GPGGA_TERM)) _sentence_type = _GPS_SENTENCE_GPGGA; else _sentence_type = _GPS_SENTENCE_OTHER; return false; } if (_sentence_type != _GPS_SENTENCE_OTHER && _term[0]) switch((_sentence_type == _GPS_SENTENCE_GPGGA ? 200 : 100) + _term_number) { case 101: // Time in both sentences case 201: strncpy(_new_time, _term, 6); _new_time[6] = 'h'; _new_time[7] = '\0'; _new_time_fix = millis(); break; case 102: // GPRMC validity ('A'=fixed, 'V'=no fix yet) _gps_fixed = _term[0] == 'A'; break; case 103: // Latitude case 202: strncpy(_new_lat, _term, 7); // APRS format: 3020.12N (DD, MM.MM, Hemisphere) _new_lat[7] = '\0'; _new_position_fix = millis(); break; case 104: // N/S case 203: _new_lat[7] = _term[0]; _new_lat[8] = '\0'; break; case 105: // Longitude case 204: strncpy(_new_lon, _term, 8); // APRS format: 00143.13W (DD, MM.MM, Hemisphere) _new_lon[8] = '\0'; break; case 106: // E/W case 205: _new_lon[8] = _term[0]; _new_lon[9] = '\0'; break; case 107: // Speed (GPRMC) // TODO: This is highly dependant on the venus 634 flpx GPS, where course/speed // is already left-padded with zeros. strncpy(_new_speed, _term, 3); _new_speed[3] = '\0'; break; case 108: // Course (GPRMC) strncpy(_new_course, _term, 3); _new_course[3] = '\0'; break; case 109: // Date (GPRMC) strncpy(_new_date, _term, 6); _new_date[6] = '\0'; break; case 206: // Fix data (GPGGA) _gps_fixed = _term[0] > '0'; break; case 209: // Altitude (GPGGA) long altitude = parse_decimal(); // altitude in cm // 10000 ft = 3048 m // x ft = altitude mt --> x = 100 * altitude (in cm) / 3048 altitude = (altitude * 25) / 762; // APRS needs feet left_pad(_new_altitude, altitude, 6); _new_altitude[6] = '\0'; break; } return false; }