LEcture GPS Xbee sous interruption

Committer:
pascalreygner
Date:
Wed Jul 11 12:47:09 2018 +0000
Revision:
1:fba6b514d8d7
Parent:
0:0a05d691ce34
Child:
2:824735b4c3a3
Version 11/7/2018

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pascalreygner 0:0a05d691ce34 1 /* Gestion carte GPS au format XBEE
pascalreygner 0:0a05d691ce34 2 * fournisseur : Embedded Artists
pascalreygner 0:0a05d691ce34 3 * Réf : EA-ACC-023
pascalreygner 0:0a05d691ce34 4 * utilise Chipset MT3339 (Mediatek Labs)
pascalreygner 0:0a05d691ce34 5 */
pascalreygner 0:0a05d691ce34 6
pascalreygner 0:0a05d691ce34 7 #include <gps-ea-acc023.h>
pascalreygner 0:0a05d691ce34 8 #include "mbed.h"
pascalreygner 0:0a05d691ce34 9 #include <stdlib.h>
pascalreygner 0:0a05d691ce34 10 #include <stdio.h>
pascalreygner 0:0a05d691ce34 11 #include "Threads.h"
pascalreygner 0:0a05d691ce34 12
pascalreygner 0:0a05d691ce34 13 using namespace gpsxbee_MT3339;
pascalreygner 0:0a05d691ce34 14 static GpsXbee gpsxbee;
pascalreygner 0:0a05d691ce34 15 RawSerial gps_uart(P4_22, P4_23);
pascalreygner 0:0a05d691ce34 16
pascalreygner 0:0a05d691ce34 17 void GpsXbee::GpsXbeeInit(void)
pascalreygner 0:0a05d691ce34 18 {
pascalreygner 0:0a05d691ce34 19 InitRMC();
pascalreygner 0:0a05d691ce34 20 NmeaSentence = NMEA_INVALID;
pascalreygner 1:fba6b514d8d7 21 gpsTrameRMC = TRAME_WAIT;
pascalreygner 1:fba6b514d8d7 22 gpsTrameGGA = TRAME_WAIT;
pascalreygner 0:0a05d691ce34 23 gpsState = StateStartGps;
pascalreygner 0:0a05d691ce34 24 gpsBufPos =0;
pascalreygner 0:0a05d691ce34 25
pascalreygner 0:0a05d691ce34 26 gps_uart.baud(9600);
pascalreygner 0:0a05d691ce34 27 gps_uart.attach(this,&GpsXbee::lecture,gps_uart.RxIrq);
pascalreygner 0:0a05d691ce34 28 }
pascalreygner 0:0a05d691ce34 29
pascalreygner 0:0a05d691ce34 30 GpsXbee::~GpsXbee()
pascalreygner 0:0a05d691ce34 31 {
pascalreygner 0:0a05d691ce34 32 gps_uart.attach(NULL);// bloque IRQ réception GPS
pascalreygner 0:0a05d691ce34 33
pascalreygner 0:0a05d691ce34 34 }
pascalreygner 0:0a05d691ce34 35
pascalreygner 0:0a05d691ce34 36 void GpsXbee::InitRMC(void)
pascalreygner 0:0a05d691ce34 37 {
pascalreygner 0:0a05d691ce34 38 rmc_hours =0;
pascalreygner 0:0a05d691ce34 39 rmc_minutes =0;
pascalreygner 0:0a05d691ce34 40 rmc_seconds =0;
pascalreygner 0:0a05d691ce34 41 rmc_milliseconds =0;
pascalreygner 0:0a05d691ce34 42 rmc_warning = 'V';
pascalreygner 0:0a05d691ce34 43 rmc_latitude =0;
pascalreygner 0:0a05d691ce34 44 rmc_longitude =0;
pascalreygner 0:0a05d691ce34 45 rmc_nsIndicator = 'N';
pascalreygner 0:0a05d691ce34 46 rmc_ewIndicator = 'W';
pascalreygner 0:0a05d691ce34 47 rmc_speedKnots =0;
pascalreygner 0:0a05d691ce34 48 rmc_jours =0 ;
pascalreygner 0:0a05d691ce34 49 rmc_mois =0 ;
pascalreygner 0:0a05d691ce34 50 rmc_ans =0 ;
pascalreygner 0:0a05d691ce34 51 }
pascalreygner 0:0a05d691ce34 52
pascalreygner 0:0a05d691ce34 53 void GpsXbee::InitGGA(void)
pascalreygner 0:0a05d691ce34 54 {
pascalreygner 0:0a05d691ce34 55 gga_hours = 0;
pascalreygner 0:0a05d691ce34 56 gga_minutes = 0;
pascalreygner 0:0a05d691ce34 57 gga_seconds = 0;
pascalreygner 0:0a05d691ce34 58 gga_milliseconds = 0;
pascalreygner 0:0a05d691ce34 59 gga_latitude = 0;
pascalreygner 0:0a05d691ce34 60 gga_longitude = 0;
pascalreygner 0:0a05d691ce34 61 gga_nsIndicator = 0;
pascalreygner 0:0a05d691ce34 62 gga_ewIndicator = 0;
pascalreygner 0:0a05d691ce34 63 gga_fix = 0;
pascalreygner 0:0a05d691ce34 64 gga_satellites = 0;
pascalreygner 0:0a05d691ce34 65 gga_hdop = 0;
pascalreygner 0:0a05d691ce34 66 gga_altitude = 0;
pascalreygner 0:0a05d691ce34 67 gga_geoidal = 0;
pascalreygner 0:0a05d691ce34 68 }
pascalreygner 0:0a05d691ce34 69
pascalreygner 0:0a05d691ce34 70 void GpsXbee::lecture(void) // réception d'un caractère - analyse trame
pascalreygner 0:0a05d691ce34 71 {
pascalreygner 0:0a05d691ce34 72 char car=0;
pascalreygner 0:0a05d691ce34 73 if((LPC_UART2->LSR & 0x01)==1) { // solution si getc fonctionne pas
pascalreygner 0:0a05d691ce34 74 car = LPC_UART2->RBR;
pascalreygner 0:0a05d691ce34 75 // if(gps_uart -> readable() == 1) {
pascalreygner 0:0a05d691ce34 76 // d = gps_uart -> getc(); // lecture caractère reçu
pascalreygner 0:0a05d691ce34 77 switch(gpsState) {
pascalreygner 0:0a05d691ce34 78 case StateStartGps:
pascalreygner 0:0a05d691ce34 79 if (car == '$') {
pascalreygner 0:0a05d691ce34 80 gpsBuf[0] = '$';
pascalreygner 0:0a05d691ce34 81 gpsBufPos = 1;
pascalreygner 0:0a05d691ce34 82 gpsState = StateDataGps;
pascalreygner 0:0a05d691ce34 83 }
pascalreygner 0:0a05d691ce34 84 break;
pascalreygner 0:0a05d691ce34 85 case StateDataGps:
pascalreygner 0:0a05d691ce34 86 if (gpsBufPos >= MTK3339_BUF_SZ) { // erreur trame
pascalreygner 0:0a05d691ce34 87 gpsState = StateStartGps;
pascalreygner 1:fba6b514d8d7 88 gpsTrameRMC = TRAME_ERR;
pascalreygner 1:fba6b514d8d7 89 gpsTrameGGA = TRAME_ERR;
pascalreygner 0:0a05d691ce34 90 } else if (car == '\r') { // fin de trame
pascalreygner 0:0a05d691ce34 91 gpsBuf[gpsBufPos] = 0;
pascalreygner 0:0a05d691ce34 92 gpsState = StateStartGps;
pascalreygner 0:0a05d691ce34 93 parseData(gpsBuf, gpsBufPos); // analyse trame
pascalreygner 0:0a05d691ce34 94
pascalreygner 0:0a05d691ce34 95 if (NmeaSentence == NmeaRmc ) { // décodage trame type "RMC"
pascalreygner 0:0a05d691ce34 96 if (rmc_warning == 'A') { // si données GPS valables : les afficher
pascalreygner 1:fba6b514d8d7 97 sprintf(gpsData,"%.2i/%.2i/%.2i:%.2iH%.2imn%.2is - Lat. = %f%c - Long. = %f%c",rmc_jours,rmc_mois,rmc_ans,rmc_hours,rmc_minutes,rmc_seconds,getLatitudeAsDegrees(rmc_latitude,rmc_nsIndicator),rmc_nsIndicator,getLongitudeAsDegrees(rmc_longitude,rmc_ewIndicator),rmc_ewIndicator);
pascalreygner 1:fba6b514d8d7 98 gpsTrameRMC = TRAME_OK; // Trame complète OK
pascalreygner 1:fba6b514d8d7 99
pascalreygner 0:0a05d691ce34 100 } else {
pascalreygner 0:0a05d691ce34 101 sprintf(gpsData,"NMEARMC : %.2i/%.2i/%.2i:%.2iH%.2imn%.2is --- Valeurs GPS incorrectes",rmc_jours,rmc_mois,rmc_ans,rmc_hours,rmc_minutes,rmc_seconds);
pascalreygner 0:0a05d691ce34 102 }
pascalreygner 0:0a05d691ce34 103 }
pascalreygner 0:0a05d691ce34 104 /* pour afficher les autres protocoles */
pascalreygner 1:fba6b514d8d7 105 else if (NmeaSentence == NmeaGga) { // décodage trame type "RMC"
pascalreygner 1:fba6b514d8d7 106 if (gga_fix == 1) {// si données GPS valables : les afficher
pascalreygner 1:fba6b514d8d7 107 sprintf(gpsData,"%.2iH%.2imn%.2is --- Latitude = %f%c --- Longitude = %f%c - Nb sat = %i",gga_hours,gga_minutes,gga_seconds,getLatitudeAsDegrees(gga_latitude,gga_nsIndicator),gga_nsIndicator,getLongitudeAsDegrees(gga_longitude,gga_ewIndicator),gga_ewIndicator,gga_satellites);
pascalreygner 1:fba6b514d8d7 108 gpsTrameGGA = TRAME_OK; // Trame complète OK
pascalreygner 1:fba6b514d8d7 109 } else
pascalreygner 1:fba6b514d8d7 110 sprintf(gpsData,"NMEAGGA : %.2iH%.2imn%.2is --- Valeurs GPS incorrectes",gga_hours,gga_minutes,gga_seconds);
pascalreygner 1:fba6b514d8d7 111 } // pour les autres types (VTG/GGA/GSV) affiche uniquement la trame reçue
pascalreygner 1:fba6b514d8d7 112 else memcpy(gpsData,gpsBuf,sizeof(gpsBuf));
pascalreygner 0:0a05d691ce34 113 } else {
pascalreygner 0:0a05d691ce34 114 gpsBuf[gpsBufPos++] = car; // enregistre caractère suivant de la trame
pascalreygner 0:0a05d691ce34 115 }
pascalreygner 0:0a05d691ce34 116 break;
pascalreygner 0:0a05d691ce34 117 }
pascalreygner 0:0a05d691ce34 118 }
pascalreygner 0:0a05d691ce34 119 }
pascalreygner 0:0a05d691ce34 120
pascalreygner 0:0a05d691ce34 121
pascalreygner 0:0a05d691ce34 122 /*
pascalreygner 0:0a05d691ce34 123 $GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh
pascalreygner 0:0a05d691ce34 124 1 = UTC of position fix
pascalreygner 0:0a05d691ce34 125 2 = Data status (V=navigation receiver warning)
pascalreygner 0:0a05d691ce34 126 3 = Latitude of fix
pascalreygner 0:0a05d691ce34 127 4 = N or S
pascalreygner 0:0a05d691ce34 128 5 = Longitude of fix
pascalreygner 0:0a05d691ce34 129 6 = E or W
pascalreygner 0:0a05d691ce34 130 7 = Speed over ground in knots
pascalreygner 0:0a05d691ce34 131 8 = Track made good in degrees True
pascalreygner 0:0a05d691ce34 132 9 = UT date
pascalreygner 0:0a05d691ce34 133 10 = Magnetic variation degrees (Easterly var. subtracts from true course)
pascalreygner 0:0a05d691ce34 134 11 = E or W
pascalreygner 0:0a05d691ce34 135 12 = Checksum
pascalreygner 0:0a05d691ce34 136 */
pascalreygner 0:0a05d691ce34 137 void GpsXbee::parseRMC(char* data, int dataLen)
pascalreygner 0:0a05d691ce34 138 {
pascalreygner 0:0a05d691ce34 139 double tm = 0;
pascalreygner 0:0a05d691ce34 140 char* p = data;
pascalreygner 0:0a05d691ce34 141 int pos = 0;
pascalreygner 0:0a05d691ce34 142
pascalreygner 0:0a05d691ce34 143 InitRMC();
pascalreygner 0:0a05d691ce34 144
pascalreygner 0:0a05d691ce34 145 p = strchr(p, ',');
pascalreygner 0:0a05d691ce34 146 while (p != NULL && *p != 0) {
pascalreygner 0:0a05d691ce34 147 p++;
pascalreygner 0:0a05d691ce34 148
pascalreygner 0:0a05d691ce34 149 switch(pos) {
pascalreygner 0:0a05d691ce34 150 case 0: // time: hhmmss.ss (heure GMT)
pascalreygner 0:0a05d691ce34 151 tm = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 152 rmc_hours = (int)(tm / 10000);
pascalreygner 0:0a05d691ce34 153 rmc_hours+=2; // remise à l'heure d'été Paris
pascalreygner 0:0a05d691ce34 154 if (rmc_hours == 24) rmc_hours = 0;
pascalreygner 0:0a05d691ce34 155 if (rmc_hours == 25) rmc_hours = 1;
pascalreygner 0:0a05d691ce34 156 rmc_minutes = ((int)tm % 10000) / 100;
pascalreygner 0:0a05d691ce34 157 rmc_seconds = ((int)tm % 100);
pascalreygner 0:0a05d691ce34 158 rmc_milliseconds = (int)(tm * 100) % 100;
pascalreygner 0:0a05d691ce34 159 break;
pascalreygner 0:0a05d691ce34 160 case 1: // V = warning
pascalreygner 0:0a05d691ce34 161 rmc_warning = *p;
pascalreygner 0:0a05d691ce34 162 break;
pascalreygner 0:0a05d691ce34 163 case 2: // latitude: ddmm.mmmm
pascalreygner 0:0a05d691ce34 164 rmc_latitude = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 165 break;
pascalreygner 0:0a05d691ce34 166 case 3: // N/S indicator (north or south)
pascalreygner 0:0a05d691ce34 167 if (*p == 'N' || *p == 'S') {
pascalreygner 0:0a05d691ce34 168 rmc_nsIndicator = *p;
pascalreygner 0:0a05d691ce34 169 } else rmc_nsIndicator = '?';
pascalreygner 0:0a05d691ce34 170 break;
pascalreygner 0:0a05d691ce34 171 case 4: // longitude: dddmm.mm
pascalreygner 0:0a05d691ce34 172 rmc_longitude = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 173 break;
pascalreygner 0:0a05d691ce34 174 case 5: // E/W indicator (east or west)
pascalreygner 0:0a05d691ce34 175 if (*p == 'E' || *p == 'W') {
pascalreygner 0:0a05d691ce34 176 rmc_ewIndicator = *p;
pascalreygner 0:0a05d691ce34 177 } else rmc_ewIndicator = '?';
pascalreygner 0:0a05d691ce34 178 break;
pascalreygner 0:0a05d691ce34 179 case 6: // speed in knots
pascalreygner 0:0a05d691ce34 180 rmc_speedKnots = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 181 break;
pascalreygner 0:0a05d691ce34 182 case 7: // ?
pascalreygner 0:0a05d691ce34 183 break;
pascalreygner 0:0a05d691ce34 184 case 8: // Date : ddmmyy
pascalreygner 0:0a05d691ce34 185 tm = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 186 rmc_jours = (int)(tm / 10000);
pascalreygner 0:0a05d691ce34 187 rmc_mois = ((int)tm % 10000) / 100;
pascalreygner 0:0a05d691ce34 188 rmc_ans = ((int)tm % 100);
pascalreygner 0:0a05d691ce34 189 break;
pascalreygner 0:0a05d691ce34 190 }
pascalreygner 0:0a05d691ce34 191 pos++;
pascalreygner 0:0a05d691ce34 192 p = strchr(p, ',');
pascalreygner 0:0a05d691ce34 193 }
pascalreygner 0:0a05d691ce34 194 }
pascalreygner 0:0a05d691ce34 195
pascalreygner 0:0a05d691ce34 196 void GpsXbee::parseGGA(char* data, int dataLen)
pascalreygner 0:0a05d691ce34 197 {
pascalreygner 0:0a05d691ce34 198 //http://aprs.gids.nl/nmea/#gga
pascalreygner 0:0a05d691ce34 199
pascalreygner 0:0a05d691ce34 200 double tm = 0;
pascalreygner 0:0a05d691ce34 201
pascalreygner 0:0a05d691ce34 202 InitGGA();
pascalreygner 0:0a05d691ce34 203
pascalreygner 0:0a05d691ce34 204 char* p = data;
pascalreygner 0:0a05d691ce34 205 int pos = 0;
pascalreygner 0:0a05d691ce34 206
pascalreygner 0:0a05d691ce34 207 p = strchr(p, ',');
pascalreygner 0:0a05d691ce34 208 while (p != NULL && *p != 0) {
pascalreygner 0:0a05d691ce34 209 p++;
pascalreygner 0:0a05d691ce34 210
pascalreygner 0:0a05d691ce34 211 switch(pos) {
pascalreygner 0:0a05d691ce34 212 case 0: // time: hhmmss.sss
pascalreygner 0:0a05d691ce34 213 tm = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 214 gga_hours = (int)(tm / 10000);
pascalreygner 0:0a05d691ce34 215 gga_minutes = ((int)tm % 10000) / 100;
pascalreygner 0:0a05d691ce34 216 gga_seconds = ((int)tm % 100);
pascalreygner 0:0a05d691ce34 217 gga_milliseconds = (int)(tm * 1000) % 1000;
pascalreygner 0:0a05d691ce34 218 break;
pascalreygner 0:0a05d691ce34 219 case 1: // latitude: ddmm.mmmm
pascalreygner 0:0a05d691ce34 220 gga_latitude = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 221 break;
pascalreygner 0:0a05d691ce34 222 case 2: // N/S indicator (north or south)
pascalreygner 0:0a05d691ce34 223 if (*p == 'N' || *p == 'S') {
pascalreygner 0:0a05d691ce34 224 gga_nsIndicator = *p;
pascalreygner 0:0a05d691ce34 225 }
pascalreygner 0:0a05d691ce34 226 break;
pascalreygner 0:0a05d691ce34 227 case 3: // longitude: dddmm.mmmm
pascalreygner 0:0a05d691ce34 228 gga_longitude = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 229 break;
pascalreygner 0:0a05d691ce34 230 case 4: // E/W indicator (east or west)
pascalreygner 0:0a05d691ce34 231 if (*p == 'E' || *p == 'W') {
pascalreygner 0:0a05d691ce34 232 gga_ewIndicator = *p;
pascalreygner 0:0a05d691ce34 233 }
pascalreygner 0:0a05d691ce34 234 break;
pascalreygner 0:0a05d691ce34 235 case 5: // position indicator (1=no fix, 2=GPS fix, 3=Differential)
pascalreygner 0:0a05d691ce34 236 gga_fix = strtol(p, NULL, 10);
pascalreygner 0:0a05d691ce34 237 break;
pascalreygner 0:0a05d691ce34 238 case 6: // num satellites
pascalreygner 0:0a05d691ce34 239 gga_satellites = strtol(p, NULL, 10);
pascalreygner 0:0a05d691ce34 240 break;
pascalreygner 0:0a05d691ce34 241 case 7: // hdop
pascalreygner 0:0a05d691ce34 242 gga_hdop = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 243 break;
pascalreygner 0:0a05d691ce34 244 case 8: // altitude
pascalreygner 0:0a05d691ce34 245 gga_altitude = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 246 break;
pascalreygner 0:0a05d691ce34 247 case 9: // units
pascalreygner 0:0a05d691ce34 248 // ignore units
pascalreygner 0:0a05d691ce34 249 break;
pascalreygner 0:0a05d691ce34 250 case 10: // geoidal separation
pascalreygner 0:0a05d691ce34 251 gga_geoidal = strtod(p, NULL);
pascalreygner 0:0a05d691ce34 252 break;
pascalreygner 0:0a05d691ce34 253 }
pascalreygner 0:0a05d691ce34 254 pos++;
pascalreygner 0:0a05d691ce34 255
pascalreygner 0:0a05d691ce34 256 p = strchr(p, ',');
pascalreygner 0:0a05d691ce34 257 }
pascalreygner 0:0a05d691ce34 258
pascalreygner 0:0a05d691ce34 259 }
pascalreygner 0:0a05d691ce34 260
pascalreygner 0:0a05d691ce34 261 int GpsXbee::parseData(char* data, int len)
pascalreygner 0:0a05d691ce34 262 {
pascalreygner 0:0a05d691ce34 263 // verify checksum
pascalreygner 0:0a05d691ce34 264 if (len < 3 || (len > 3 && data[len-3] != '*')) { // invalid data
pascalreygner 0:0a05d691ce34 265 return(-1);
pascalreygner 0:0a05d691ce34 266 }
pascalreygner 0:0a05d691ce34 267 int sum = strtol(&data[len-2], NULL, 16);
pascalreygner 0:0a05d691ce34 268 for(int i = 1; i < len-3; i++) {
pascalreygner 0:0a05d691ce34 269 sum ^= data[i];
pascalreygner 0:0a05d691ce34 270 }
pascalreygner 0:0a05d691ce34 271 if (sum != 0) {
pascalreygner 0:0a05d691ce34 272 return(-1);
pascalreygner 0:0a05d691ce34 273 }
pascalreygner 0:0a05d691ce34 274
pascalreygner 0:0a05d691ce34 275 NmeaSentence = NMEA_INVALID;
pascalreygner 0:0a05d691ce34 276 if (strncmp("$GPGGA", data, 6) == 0 ) {
pascalreygner 0:0a05d691ce34 277 parseGGA(data,len);
pascalreygner 0:0a05d691ce34 278 NmeaSentence = NmeaGga;
pascalreygner 0:0a05d691ce34 279 }
pascalreygner 0:0a05d691ce34 280
pascalreygner 0:0a05d691ce34 281 else if (strncmp("$GPRMC", data, 6) == 0) {
pascalreygner 0:0a05d691ce34 282 parseRMC(data, len);
pascalreygner 0:0a05d691ce34 283 NmeaSentence = NmeaRmc;
pascalreygner 0:0a05d691ce34 284 }
pascalreygner 0:0a05d691ce34 285
pascalreygner 0:0a05d691ce34 286 return(0);
pascalreygner 0:0a05d691ce34 287 }
pascalreygner 0:0a05d691ce34 288
pascalreygner 0:0a05d691ce34 289 double GpsXbee::getLatitudeAsDegrees(double l,char ns)
pascalreygner 0:0a05d691ce34 290 {
pascalreygner 0:0a05d691ce34 291 // convert from ddmm.mmmm to degrees only
pascalreygner 0:0a05d691ce34 292 // 60 minutes is 1 degree
pascalreygner 0:0a05d691ce34 293
pascalreygner 0:0a05d691ce34 294 int deg = (int)(l / 100);
pascalreygner 0:0a05d691ce34 295 l = (l - deg*100.0) / 60.0;
pascalreygner 0:0a05d691ce34 296 l = deg + l;
pascalreygner 0:0a05d691ce34 297 if (ns == 'S') l = -l;
pascalreygner 0:0a05d691ce34 298
pascalreygner 0:0a05d691ce34 299 return l;
pascalreygner 0:0a05d691ce34 300 }
pascalreygner 0:0a05d691ce34 301
pascalreygner 0:0a05d691ce34 302 double GpsXbee::getLongitudeAsDegrees(double l,char ew)
pascalreygner 0:0a05d691ce34 303 {
pascalreygner 0:0a05d691ce34 304 // convert from ddmm.mmmm to degrees only
pascalreygner 0:0a05d691ce34 305 // 60 minutes is 1 degree
pascalreygner 0:0a05d691ce34 306
pascalreygner 0:0a05d691ce34 307 int deg = (int)(l / 100);
pascalreygner 0:0a05d691ce34 308 l = (l - deg*100) / 60;
pascalreygner 0:0a05d691ce34 309 l = deg + l;
pascalreygner 0:0a05d691ce34 310 if (ew == 'W') l = -l;
pascalreygner 0:0a05d691ce34 311
pascalreygner 0:0a05d691ce34 312 return l;
pascalreygner 0:0a05d691ce34 313 }
pascalreygner 0:0a05d691ce34 314