IniSat Modèle 1 Version 2 TP 5 : Station Sol Exo 1 : Enregistrement GPS sur carte SD Exo 2 : Mise en place d'un protocole de communication avec la station sol

Dependencies:   mbed

gps.h

Committer:
Giamarchi
Date:
2022-05-31
Revision:
1:5fcc88ae8ad4
Parent:
0:278eba15d90b

File content as of revision 1:5fcc88ae8ad4:

/*  L80 QUECTEL GPS Module
*   NMEA 0183 messages
*/
#include "mbed.h"
#include <math.h>
// Commandes pour paramétrer le taux par seconde depuis chaque seconde (1 Hz) jusqu'à 10 fois par seconde (10Hz)
#define PMTK_SET_NMEA_UPDATE_1HZ  "$PMTK220,1000*1F"
#define PMTK_SET_NMEA_UPDATE_5HZ  "$PMTK220,200*2C"
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"

// Code pour sélection de trame unique
#define TRAME_RMC   "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
#define TRAME_GGA   "$PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
#define TRAME_RMC_GGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
#define TRAME_ALL   "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"

#define Trame_TXT_On "$PQTXT,W,1,1*22"
#define Trame_TXT_Off "$PQTXT,W,0,1*23"

//  Selection de trames
void Select_Trame(char* trame) {
    printStr((char*) trame);
    printStr((char*)"\r\n");  
    }

//  Lecture des trames NMEA du GPS

char buffer[100];
uint8_t rx_ptr = 0;
uint8_t rx_ok = 0;

void Lect_GPS(void) {
    
    while(!rx_ok) {
    
        if (kbhit()) {
            buffer[rx_ptr] = _getchar();
            
            if((buffer[rx_ptr] == 0x0A) || (buffer[rx_ptr] == 0x0D))      // Test touche entrée en mode ASCII
            {
                buffer[rx_ptr] = 0;         // Transforme le tableau en chaine de caractères  
                rx_ptr = 0;
                rx_ok = 1;                      // Trame disponible pour décodage
//                pc.printf("%s\n\r",buffer);     // Echo  
            }
            else {
                rx_ptr++;
            }   
        }
    }
    rx_ok = 0;
}

void GPS_Init(void) {                   // Bloquer les tickers pour envoyer une commande
    rx_ok = 0;
    Select_Trame((char*)Trame_TXT_Off);
    Select_Trame((char*)TRAME_GGA);
}

struct gps {
    char *trame;                // $GPGGA
    char *horaire;              // 143512.000
    char *lat;
    char *ns;
    char *longi;
    char *ew;
    char *fix;               // 0 ou V -> pas de Fix         >1 ou A -> Fix
    char *nb_sat;
    char *prec;
    char *alt;
    float latitude;
    float longitude;
    uint16_t altitude;
    char fixe;
} gps;

//  Décodage Trame NMEA GGA
void GPS_Decodage (void) {

    if(buffer[0] == '$' && buffer[5] == 'A') {
//        pc.printf("GPS: %s\n\r",buffer);     // Echo  
        
        gps.trame = strtok(buffer, ",");
        gps.horaire = strtok(NULL, ",");
        
        gps.lat = strtok(NULL, ",");
        gps.latitude = atof(gps.lat);             
        gps.ns = strtok(NULL, ",");
//        if(gps.ns == "S")   {
//            gps.latitude  *= -1.0;
//        }
        gps.longi = strtok(NULL, ",");
        gps.longitude = atof(gps.longi);        
        gps.ew = strtok(NULL, ",");
//        if(gps.ew == "W")   {
//            gps.longitude *= -1.0;
//        }
        gps.fix = strtok(NULL, ",");
        gps.fixe = atoi(gps.fix);
        
        gps.nb_sat = strtok(NULL, ",");
        gps.prec = strtok(NULL, ",");
        gps.alt = strtok(NULL, ",");
        gps.altitude = atoi(gps.alt);

        if(gps.fixe) {
//  Conversion en degrée et minute pour Google Maps    
            float degrees = floor(gps.latitude / 100.0f);
            float minutes = gps.latitude - (degrees * 100.0f);
            gps.latitude = degrees + minutes / 60.0f;
        
            degrees = floor(gps.longitude / 100.0f);
            minutes = gps.longitude - (degrees * 100.0f);
            gps.longitude = degrees + minutes / 60.0f;
        } 
    }
}

void Envoi_GPS(void) {

    if(gps.fixe) {
        pc.printf("hms : %s\n",gps.horaire);
        pc.printf("lat : %f N\n",gps.latitude);
        pc.printf("long: %f E\n",gps.longitude);
        pc.printf("alt : %d m\n",gps.altitude);
    }
    else
        pc.printf("GPS: %s\n",buffer);
}

void XBee_Envoi_GPS(void) {
    
    if(gps.fixe) {
        xbee.printf("H%s\n",gps.horaire);
        xbee.printf("lat : %fN\n",gps.latitude);
        xbee.printf("long: %fE\n",gps.longitude);
        xbee.printf("#A%d\n",gps.altitude);
              
        FILE *fp = fopen("/sd/gps_data.txt", "a");
        fprintf(fp, "%.6f, %.6f, \n",gps.latitude,gps.longitude);   
        fclose(fp);
    }
    else
        xbee.printf("GPS: %s\n\r",buffer);
}
//==============================================================================
// Sélection de la trame GGA - Système de positionnement global des données fixées
// Exemple : $GPGGA,143512.000,4347.7852,N,00418.9704,E,1,7,1.29,28.9,M,49.4,M,,*60

//  UTC Position    143512.000      hhmmss.sss
//  Latitude        4347.7852       ddmm.mmmm
//  N/S Indicator   N               N=Nord - S=Sud
//  Longitude       00418.9704      ddmm.mmmm
//  W/E Indicator   E               W=Ouest - E=Est
//  Position Fix Indicator  1       0-invalid 1-Valid
//  Satellites Used 7               de 0 à 12
//  Précision       1.29            1-bon 9-mauvais
//  Altitude        28.9            valeur
//  Unité pour l'altitude   M       en mètre
//  Autres informations
//  Checksum        *60
//==============================================================================
// Sélection de la trame GLL - Géographic position - Latitude/Longitude
// Exemple : $GPGLL,3723.2475, N, 12158.3416, W, 161229.487, A*2C
//==============================================================================
// Sélection de la trame RMC - Utilisation pour les navires
// Exemple : $GPRMC,141147.000,A,4347.7885,N,00418.9737,E,0.00,350.58,280621,,,A*6D

//  UTC Position    141147.000      hhmmss.sss
//  Fix Indicator   A               A-valid V-invalid
//  Latitude        4347.7885       ddmm.mmmm
//  N/S Indicator   N               N=Nord - S=Sud
//  Longitude       00418.9737      ddmm.mmmm
//  W/E Indicator   E               W=Ouest - E=Est
//  Vitesse         0.00            en noeuds
//  Route sur le fond 350.58        en degrés
//  Date            280621          ddmmaa
//  Autres informations
//  Checksum        *6D
//==============================================================================