You are currently viewing Coordonnées GPS avec Arduino et la SIM808

Coordonnées GPS avec Arduino et la SIM808

Cet article a pour objectif l’acquisition des coordonnées GPS et la construction de liens Google Maps ou Waze en utilisant Arduino et la carte SIM808.

Le matériel nécessaire

Carte Arduino UNO Rev 3 Cordon USB de type A/B Module de développement SIM808
Carte Arduino UNO Câble USB 2.0 Type A/B Carte SIM808 EVB-V3.2
Transformateur d'alimentation 9V / 2A Antenne GPS Câbles Dupont Mâle / Femelle
Transformateur d’alimentation 5V à 26V Antenne GPS Câbles mâle/femelle

Prise en main de la carte SIM808

Présentation de la SIM808 EVB-V3.2

La carte de développement SIM808 EVB-V3.2 est une carte plutôt complète pour son prix abordable. Elle inclut en effet:

  • Un modem GSM / GPRS quadribande compatible avec les fréquences 850, 900, 1800 et 1900MHz
  • Un modem GPS
  • Un modem Bluetooth

La position des 3 connecteurs coaxiaux SMA des antennes sur la carte SIM808 est la suivante:

Emplacement des antennes sur la carte SIM808

Carte SIM

Pour ce projet, aucune carte téléphonique SIM n’est nécessaire. Seules les fonctionnalités GPS de la carte SIM808 seront utilisées.

Démarrage de la carte SIM808

La carte SIM808 EVB-V3.2 nécessite d’être démarrée après chaque mise sous tension afin d’être utilisable. Cette procédure de démarrage n’est pas intuitive, aussi je vous invite à lire attentivement le chapitre “Démarrage de la carte SIM808” de l’article “Réception de SMS avec Arduino et la SIM808”.

Câblage de la carte SIM808 avec Arduino

La carte de développement SIM808 requiert une puissance d’alimentation de l’ordre de 10 Watts. La puissance transmise à la carte Arduino par le PC à travers le câble USB n’est pas suffisante. Dans le cadre de ce projet, nous utilisons un transformateur 9V de 2A pour fournir la puissance nécessaire à la carte SIM808. Un transformateur délivrant une tension entre 5 à 26V de puissance équivalente peut également être utilisé.

La communication entre la carte Arduino et la carte SIM808, repose sur une liaison TTL. Dans ce tutoriel, nous choisissons les ports 8 et 9 de l’Arduino pour les données. Ne pas oublier de relier la masse des deux cartes afin que les signaux échangés aient la même référence :

  • La broche RXD de la SIM808 est reliée à la sortie 9 de l’Arduino.
  • La broche TXD de la SIM808 est reliée à l’entrée 8 de l’Arduino.
  • Les deux masses sont mises en commun (GND).
Branchement de la carte de développement SIM808 EVB avec Arduino Uno
Branchement de la carte de développement SIM808 EVB avec Arduino Uno

Bibliothèques utilisées

Deux bibliothèques Arduino sont utilisées dans ce programme, les bibliothèques “SIM808-EVB” et “AltSoftSerial”.

Pour la gestion du protocole de communication propre à la carte de développement SIM808 ce programme s’appuie sur une bibliothèque non-standard Arduino, la bibliothèque “SIM808-EVB” de “Tropratik”. La procédure à suivre pour son installation est décrite dans les trois paragraphes qui suivent.

Téléchargement de la bibliothèque “SIM808-EVB”

Cette bibliothèque n’est pas disponible dans le gestionnaire de bibliothèques de l’Arduino IDE. Il est nécessaire de la télécharger sur le site GitHub du projet : https://github.com/Tropratik/SIM808-EVB ou bien en utilisant ce lien.

Emplacement des bibliothèques Arduino sur votre PC

Pour savoir à quel endroit sont stockées les bibliothèques Arduino sur votre PC, il suffit de consulter le paramétrage de l’IDE Arduino. Pour cela, dans le menu “Fichier”, cliquez sur “Préférences”:

Emplacement des croquis Arduino

… dans la zone de saisie “Localisation du croquis” se trouve renseigné l’emplacement du répertoire racine “croquis”. Les bibliothèques Arduino installées sur le PC sont situés dans le sous-répertoire “libraries”.

Mise en place de la bibliothèque “SIM808-EVB”:

Après avoir décompressé votre fichier zippé, vous obtenez un dossier SIM808-EVB ou SIM808-EVB-main contenant deux dossiers “examples” et “test” ainsi que le code source de la bibliothèque.

Dossier SIM808-EVB de la bibliothèque Arduino de gestion de la carte de développement SIM808

La mise en place de la bibliothèque consiste simplement à déplacer ce dossier “SIM808-EVB” dans le sous-répertoire “libraries” identifié précédemment.

Installation de la bibliothèque “AltSoftSerial”:

La bibliothèque Arduino “AltSoftSerial” de “Paul Stoffregen” permet de remplacer l’interface série matérielle de communication TTL avec la carte de développement SIM808 par une interface logicielle. Ainsi, l’interface matérielle reste disponible pour l’affichage des messages d’exécution sur le moniteur série de l’Arduino IDE.

Je vous invite à installer cette bibliothèque standard Arduino. (Pour rappel, la procédure d’installation d’une bibliothèque standard Arduino est décrite au chapitre “Installation d’une bibliothèque pour l’écran OLED” de l’article “Température et humidité avec Arduino”.)

Le programme de calcul des coordonnées GPS

Comme d’habitude, nous démarrons l’écriture du logiciel par l’ossature de code Arduino suivante :

// Fonction de démarrage, s'exécute une seule fois:
void setup()
{
}
// Fonction principale du programme, s'exécute en boucle:
void loop()
{
}

Déclaration des bibliothèques

Les deux bibliothèques se déclarent par les lignes :

/* Bibliothèques Arduino utilisées */
#include <AltSoftSerial.h>
#include <Sim808_EVB.h>

Les objets associés à ces bibliothèques sont nommés “altSoftSerial_G” et “sim808EVB_G”:

// Déclarations globales
AltSoftSerial   altSoftSerial_G;
sim808          sim808EVB_G;

LED d’information de l’état du GPS

Nous allons utiliser la LED embarquée de la carte Arduino UNO pour connaitre l’état du modem GPS. La signification de la LED sera la suivante:

  • Éteinte : le modem GPS est éteint.
  • Clignotement : le modem GPS recherche sa position (les satellites).
  • Allumé en continu : le modem a trouvé une position.

Juste après avoir initialisé le port série pour les traces de notre programme, nous déclarons ce port en sortie et signalons que le modem GPS est éteint au démarrage :

// Fonction de démarrage, s'exécute une seule fois:
void setup()
{
  // Ouverture du port USB pour l'envoi des traces au PC
  Serial.begin(115200);

  // Positionnement en sortie du port de la diode interne
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);  // La diode éteinte signale que le GPS n'est pas disponible
}

Fonction d’initialisation de la carte SIM808

Afin de faciliter la lecture de notre code (et sa réutilisation pour de futurs projets), nous regroupons l’initialisation de la SIM808 dans une seule fonction “initialiser_sim808”. Voici le prototype de cette fonction :

// Prototypes de fonction
void initialiser_Sim808(void);

L’initialisation de la SIM808 s’effectue après avoir positionné les ports d’entrée/sortie :

void setup()
{
  // Ouverture du port USB pour l'envoi des traces au PC
  Serial.begin(115200);

  // Positionnement en sortie du port de la diode interne
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);  // La diode éteinte signale que le GPS n'est pas disponible

  // Initialisation de la communication avec la carte SIM808
  initialiser_sim808();  
}

Passons maintenant à l’écriture du contenu de la fonction “initialiser_sim808”.

Pour ouvrir la liaison série à l’aide de la bibliothèque “AltSoftSerial”, on utilise la méthode “begin” qui prend en paramètre la vitesse de communication exprimée en bauds. Étant donné que nous utilisons une interface série logicielle et non pas matérielle, il est nécessaire de choisir une vitesse pas trop élevée, ce sera 38400 dans notre cas.

De même, pour la bibliothèque “SIM808-EVB”, la méthode permettant d’initialiser la communication avec la carte SIM808 est la méthode “begin”. Elle demande en paramètre l’objet gérant le flux de communication série. 

En ajoutant l’affichage des caractéristiques de la carte SIM808 EVB sur la console série, nous arrivons au code suivant pour la fonction “initialiser_sim808” :

void initialiser_sim808(void)
{
  identification_t identification_L;
  
  Serial.println(F("Connexion avec la carte SIM808."));
  altSoftSerial_G.begin(38400);
  while(!sim808EVB_G.begin(altSoftSerial_G))
  {
    Serial.println(F("Echec de communication avec la carte SIM808. Nouvelle tentative..."));
    delay(1000);
  }
  Serial.println(F("La communication avec la carte SIM808 est établie."));

  identification_L = sim808EVB_G.getIdentification(); 
  Serial.print(F("Version logicielle: "));
  Serial.println(identification_L.softwareVersion);
  Serial.print(F(" - Fabricant: "));
  Serial.println(identification_L.manufacturerId);
  Serial.print(F(" - Identification de la carte: "));
  Serial.println(identification_L.productId);
  Serial.print(F(" - Numéro de série: "));
  Serial.println(identification_L.productSerialNumber);
}

Démarrage du modem GPS

Comme pour l’initialisation de la carte SIM808, nous regroupons les fonctions de démarrage du modem GPS au sein d’une unique fonction nommée “demarrer_gps”. Voici sa déclaration :

void demarrer_gps(void);

Le démarrage du modem GPS s’effectue après l’initialisation de la carte SIM808:

// Fonction de démarrage, s'exécute une seule fois:
void setup()
{
  // Ouverture du port USB pour l'envoi des traces au PC
  Serial.begin(115200);

  // Positionnement en sortie du port de la diode interne
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);  // La diode éteinte signale que le GPS n'est pas disponible

  // Initialisation de la communication avec la carte SIM808
  initialiser_sim808();  

  // Initialisation du modem GPS
  demarrer_gps();
}

Passons maintenant à l’écriture du contenu de la fonction “demarrer_gps”.

La commande proposée par la bibliothèque “Sim808_EVB” pour connaitre l’état d’alimentation du module GPS est la méthode “getGnssPower” de notre objet “sim808EVB_G”. Pour le mettre sous tension, on utilise “gnssPowerOn”.

Une fois alimenté, “getGnssRunStatus” permet de connaitre l’état de démarrage du module. Et c’est une fois démarré qu’il commence à discuter avec les satellites pour déterminer sa position.

Comme indiqué dans les caractéristiques de la carte SIM808, entre 30 secondes et 2 minutes sont nécessaires au module GPS pour pouvoir réaliser son premier positionnement. Aussi, nous resterons dans une boucle d’attente tant que la méthode  “getGnssFixStatus” n’aura pas retournée un résultat positif.

En ajoutant la mise à jour de la LED interne pour refléter l’état du modem GPS, je vous propose la fonction  “demarrer_gps” suivante:

void demarrer_gps(void)
{
  bool etat_L = false;

  etat_L = sim808EVB_G.getGnssPower();
  if(etat_L)
  {
    Serial.println(F("GPS allumé."));
  }
  else
  {
    Serial.println(F("GPS éteint. On l'allume"));
    sim808EVB_G.gnssPowerOn(); 
    Serial.println(F("Initialisation du GPS."));
    etat_L = sim808EVB_G.getGnssRunStatus();
    do
    {
      digitalWrite(LED_BUILTIN, HIGH);  // Clignotement de la diode pour signaler la recherche GPS
      etat_L = sim808EVB_G.getGnssRunStatus();
      Serial.print(F("."));
      delay(500);
      digitalWrite(LED_BUILTIN, LOW);  // Clignotement de la diode pour signaler la recherche GPS
      delay(500);
    }
    while(!etat_L);
    Serial.println(F("\nGPS en recherche de satellites."));
    etat_L = sim808EVB_G.getGnssFixStatus();
    do
    {
      digitalWrite(LED_BUILTIN, HIGH);  // Clignotement de la diode pour signaler la recherche GPS
      etat_L = sim808EVB_G.getGnssFixStatus();
      Serial.print(F("."));
      delay(500);
      digitalWrite(LED_BUILTIN, LOW);  // Clignotement de la diode pour signaler la recherche GPS
      delay(500);
    }
    while(!etat_L);
    Serial.println(F("\nGPS initialisé."));
  }
}

Extinction du modem GPS

L’extinction du modem GPS permet de diminuer le courant consommé par le montage. Cela n’a pas une grande importance pour le projet en cours, puisque nous utilisons un transformateur pour alimenter notre carte SIM808, mais ce sera primordial pour un projet de balise GPS avec alimentation autonome qui sera détaillé plus tard sur ce site tropratik.fr.

Pour rester prévisible, nous le baptisons “arreter_gps”. Voici sa déclaration :

void arreter_gps(void);

La commande d’extinction du modem GPS est la méthode “gnssPowerOff” de notre objet “sim808EVB_G”.

Nous en déduisons la fonction “arreter_gps” suivante :

void arreter_gps(void)
{   
  bool etat_L;

  etat_L = sim808EVB_G.getGnssPower();
  if(!etat_L)
  {
    Serial.println(F("GPS éteint."));
  }
  else
  {
    Serial.println(F("GPS allumé. On l'éteint"));
    sim808EVB_G.gnssPowerOff();
  }
}

Lecture des informations GPS

Pour la lecture des informations GPS du modem, nous allons utiliser la méthode “getGnssCoordinates” qui retourne une structure de type “gnssCoordinates_t”.

Voici le détail de cette structure :

  • status (bool) : indique la disponibilité des informations de localisation.
  • latitude (sexagesimale_t) : latitude en coordonnées sexagésimales.
  • longitude (sexagesimale_t) : longitude en coordonnées sexagésimales.
  • altitude (float) : altitude en mètres.
  • speed (float) : vitesse de déplacement en km/h.

La latitude et la longitude sont elles-mêmes stockées dans une structure sexagésimale (sexagesimale_t) composée comme suit:

  • positive (bool) : Coordonnée positive (true) ou négative (false). Une latitude positive donne la direction Nord et une latitude négative le Sud. Une longitude positive donne la direction Est et une longitude négative l’Ouest.
  • degree (uint8_t) : La latitude varie de [-90° à +90°], la longitude de [-180° à +180°].
  • minute (uint8_t) : La minute est une division d’un degré (60 minutes = 1 degré).
  • second (float) : La seconde est une division d’une minute (60 secondes = 1 minute).

Avant de lire ces paramètres, nous testerons la valeur de “status” qui est attendue à “true” si tout s’est bien déroulé.

Coordonnées géographiques sexagésimales

Les coordonnées géographiques que nous avons l’habitude d’utiliser sur une carte sont au format
xx° xx’ xx” N/S, xx° xx’ xx” E/O. Ainsi, la Tour Eiffel possède les coordonnées 48° 51′ 30″ N, 2° 17′ 40″ E et le Machu Picchu les coordonnées 13° 09′ 50″ S, 72° 32′ 45″ O.

Pour les afficher sous ce format, nous créons une fonction de mise en forme des cordonnées sexagésimales. (Celles que nous avons obtenues au paragraphe précédent). Le nom de cette fonction de mise en forme est “donner_coordonees_en_texte”.

  • Le premier paramètre de cette fonction est un paramètre de sortie, plus précisément l’adresse de la chaine de caractères dans laquelle sera écrit le résultat obtenu.
  • Les 2ème et 3ème paramètres de la fonction servent à transmettre les coordonnées sexagésimales à convertir.

La conversion d’un nombre flottant en texte n’est pas immédiate en langage Arduino, aussi dans cette fonction et dans la suite de cet article, nous utiliserons la fonction “modff” qui permet de séparer la partie entière d’un nombre flottant de sa partie décimale .

void donner_coordonees_en_texte(char* position_texte, sexagesimale_t latitude, sexagesimale_t longitude)
{
  char signe_latitude;
  char signe_longitude;
  float partie_entiere;

  if(latitude.positif)
  {
    signe_latitude = 'N';
  }
  else
  {
    signe_latitude = 'S';
  }
  if(longitude.positif)
  {
    signe_longitude = 'E';
  }
  else
  {
    signe_longitude = 'O';
  }
  sprintf(position_texte, "%d°%d'%02d.%02d"%c, %d°%d'%02d.%02d"%c", latitude.degree, latitude.minute , int(latitude.seconde),  int(modff(latitude.seconde, &partie_entiere)*100), signe_latitude,
                                                                     longitude.degree, longitude.minute , int(longitude.seconde),  int(modff(longitude.seconde, &partie_entiere)*100), signe_longitude);    
}

Lien Google Maps

Un acteur majeur de la localisation GPS aujourd’hui est “Google Maps”. Les liens Google Map qui permettent d’afficher une carte en vue cartographique sur un navigateur Internet sont très pratiques. Dans la suite de ce paragraphe, nous allons écrire les fonctions qui vont nous permettre de générer ces liens à partir des coordonnées sexagésimales que nous avons obtenues précédemment.

Google met à disposition la documentation complète pour la création des liens Google Maps à l’adresse suivante: https://developers.google.com/maps/documentation/urls/get-started.

À la lecture de cette documentation, on remarque que Google Maps utilise des coordonnées GPS écrites au format degrés décimaux. Pour notre fonction  de conversion de coordonnées sexagésimales en coordonnées à degrés décimaux, nous nous appuyons sur l’algorithme de conversion fourni par Wikipédia au lien suivant et obtenons la fonction “sexagesimale_vers_degres_decimaux suivante” :

float sexagesimale_vers_degres_decimaux(sexagesimale_t coordonnee)
{
  float valeur;
  
  valeur = float(coordonnee.degree) + float(coordonnee.minute) / 60.0 + float(coordonnee.seconde) / 3600.0 ;
  if(!coordonnee.positif)
  {
    valeur = valeur * -1;
  }
  return(valeur);
}

Comme évoqué précédemment, la conversion d’un nombre flottant en texte n’est pas immédiate en langage Arduino, aussi nous créons une fonction “flottant_vers_texte” pour la conversion en texte de nos coordonnées en degrés décimaux.

void flottant_vers_texte(char* texte, float valeur)
{
  float partie_entiere, partie_fractionnaire;

  partie_fractionnaire = modff(valeur, &partie_entiere);
  sprintf(texte,"%d.%ld", (int)partie_entiere, (long)abs(partie_fractionnaire*pow(10, 7)));
}

Revenons maintenant à la documentation des liens Google Maps. Il est possible de générer 4 types de liens:

Type de lien Première parti du lien:
Lien de recherche d’un emplacement https://www.google.com/maps/search/?api=1&
Lien de navigation GPS (pour se rendre à l’endroit choisi) https://www.google.com/maps/dir/?api=1&
Lien d’affichage d’une carte en vue cartographique centrée sur l’emplacement choisi https://www.google.com/maps/@?api=1&map_action=map&
Lien de navigation dans une rue en mode “Google Street” (affichage en vue réelle). https://www.google.com/maps/@?api=1&map_action=pano&

 

Dans cet article, nous choisissons l’affichage en vue cartographique pour Google Maps libre à vous de choisir l’affichage d’un autre type de carte pour ce programme. Notre lien web débute donc par “https://www.google.com/maps/@?api=1&map_action=map&”.

Un dernier point important dans les liens Google Maps, est le choix du zoom d’affichage. Cela s’effectue en ajoutant le paramètre “&zoom=” en fin de lien dynamique. Dans la fonction ci-dessous, le zoom est à la valeur 18.

void donner_lien_google_map(char* lien, sexagesimale_t latitude, sexagesimale_t longitude)
{
  char texte_latitude[15], texte_longitude[15];

  flottant_vers_texte(texte_latitude, sexagesimale_vers_degres_decimaux(latitude));
  flottant_vers_texte(texte_longitude, sexagesimale_vers_degres_decimaux(longitude)); 
  sprintf(lien, "https://www.google.com/maps/@?api=1&map_action=map&center=%s%s%s&zoom=18", texte_latitude, ",", texte_longitude);
}

Lien Waze

L’application de navigation que j’utilise lorsque je veux me rendre dans un lieu inconnu est l’application “Waze” que je trouve plutôt bien faite. L’idée est de construire un lien qui, lorsqu’il sera ouvert sur notre smartphone ou notre tablette Android, va directement lancer l’application Waze et lui demander de calculer l’itinéraire qui nous permettra de nous rendre à la position GPS fournie par la carte SIM808

La documentation pour la construction des liens Waze est disponible à l’adresse suivante: https://developers.google.com/waze/deeplinks?hl=fr.

À la lecture de cette documentation, on constate rapidement que la construction d’un lien Waze est proche de la construction d’un lien “Google Maps”. Cela s’explique par le fait que Waze appartient également à Google (rachat de la société en 2013).

Pour lancer la navigation Waze vers un lieu, le lien web doit débuter par “https://waze.com/ul?”

Et comme pour Google Maps, cette documentation nous indique que le paramètre “&zoom=” en fin de lien dynamique permet de définir le zoom d’affichage. 

void donner_lien_waze(char* lien, sexagesimale_t latitude, sexagesimale_t longitude)
{
  char texte_latitude[15], texte_longitude[15];
  
  flottant_vers_texte(texte_latitude, sexagesimale_vers_degres_decimaux(latitude));
  flottant_vers_texte(texte_longitude, sexagesimale_vers_degres_decimaux(longitude));
  sprintf(lien, "https://www.waze.com/ul?ll=%s%s%s&navigate=yes&zoom=18", texte_latitude, "%2C", texte_longitude);        
}

Affichage des coordonnées et des liens GPS

Maintenant que nous avons écrit notre boite à outils de fonction GPS, nous allons pouvoir les tester.

Le choix est fait d’appeler les fonctions créées précédemment en boucle et d’afficher leur résultat sur le port série selon les étapes suivantes :

  1. Lecture des coordonnées GPS à partir du modem de la carte SIM808
  2. Coordonnées géographiques au format cartographique.
  3. Lien Google Maps.
  4. Lien Waze

Nous aboutissons à la fonction “loop” du programme Arduino :

// Fonction principale du programme, s'exécute en boucle:
void loop()
{
  gnssCoordinates_t gnssCoordinates_L;
  char tampon_message[90];

  Serial.print('\n'); // Saut d'une ligne pour une meilleur visibilité
  gnssCoordinates_L = sim808EVB_G.getGnssCoordinates();
  if(gnssCoordinates_L.status)
  {
    // Calcul des coordonnées géographiques:
    donner_coordonees_en_texte(tampon_message, gnssCoordinates_L.latitude, gnssCoordinates_L.longitude);
    Serial.print(F("\nCoordonnées géographiques: "));    
    Serial.println(tampon_message);

    // Calcul du lien Google Map:
    donner_lien_google_map(tampon_message, gnssCoordinates_L.latitude, gnssCoordinates_L.longitude);
    Serial.print(F("Lien google Map: "));    
    Serial.println(tampon_message);

    // Calcul du lien Waze:
    donner_lien_waze(tampon_message, gnssCoordinates_L.latitude, gnssCoordinates_L.longitude);
    Serial.print(F("Lien Waze: "));    
    Serial.println(tampon_message);

    // Pause de  10 secondes
    delay(5000);
  }
  else
  {
    Serial.println(F("Erreur de lecture GPS"));  
  }
}

Le programme complet :

Voici le moment de la synthèse !

Si l’on assemble toutes les pièces du puzzle, on obtient le programme complet suivant:

/* Bibliothèques Arduino utilisées */
#include <AltSoftSerial.h>
#include <Sim808_EVB.h>

// Prototypes de fonction
void initialiser_sim808(void);
void demarrer_gps(void);
void arreter_gps(void);
void donner_coordonees_en_texte(char* position_texte, sexagesimale_t latitude, sexagesimale_t longitude);
float sexagesimale_vers_degres_decimaux(sexagesimale_t coordonnee);
void flottant_vers_texte(char* texte, float valeur);
void donner_lien_google_map(char* lien, sexagesimale_t latitude, sexagesimale_t longitude);
void donner_lien_waze(char* lien, sexagesimale_t latitude, sexagesimale_t longitude);

// Déclarations globales
AltSoftSerial   altSoftSerial_G;
sim808          sim808EVB_G;

// Fonction de démarrage, s'exécute une seule fois:
void setup()
{
  // Ouverture du port USB pour l'envoi des traces au PC
  Serial.begin(115200);

  // Positionnement en sortie du port de la diode interne
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);  // La diode éteinte signale que le GPS n'est pas disponible

  // Initialisation de la communication avec la carte SIM808
  initialiser_sim808();  

  // Initialisation du modem GPS
  demarrer_gps();
}

// Fonction principale du programme, s'exécute en boucle:
void loop()
{
  gnssCoordinates_t gnssCoordinates_L;
  char tampon_message[90];

  Serial.print('\n'); // Saut d'une ligne pour une meilleur visibilité
  gnssCoordinates_L = sim808EVB_G.getGnssCoordinates();
  if(gnssCoordinates_L.status)
  {
    // Calcul des coordonnées géographiques:
    donner_coordonees_en_texte(tampon_message, gnssCoordinates_L.latitude, gnssCoordinates_L.longitude);
    Serial.print(F("\nCoordonnées géographiques: "));    
    Serial.println(tampon_message);

    // Calcul du lien Google Map:
    donner_lien_google_map(tampon_message, gnssCoordinates_L.latitude, gnssCoordinates_L.longitude);
    Serial.print(F("Lien google Map: "));    
    Serial.println(tampon_message);

    // Calcul du lien Waze:
    donner_lien_waze(tampon_message, gnssCoordinates_L.latitude, gnssCoordinates_L.longitude);
    Serial.print(F("Lien Waze: "));    
    Serial.println(tampon_message);

    // Pause de  10 secondes
    delay(5000);
  }
  else
  {
    Serial.println(F("Erreur de lecture GPS"));  
  }
}

void initialiser_sim808(void)
{
  identification_t identification_L;
  
  Serial.println(F("Connexion avec la carte SIM808."));
  altSoftSerial_G.begin(38400);
  while(!sim808EVB_G.begin(altSoftSerial_G))
  {
    Serial.println(F("Echec de communication avec la carte SIM808. Nouvelle tentative..."));
    delay(1000);
  }
  Serial.println(F("La communication avec la carte SIM808 est établie."));

  identification_L = sim808EVB_G.getIdentification(); 
  Serial.print(F("Version logicielle: "));
  Serial.println(identification_L.softwareVersion);
  Serial.print(F(" - Fabricant: "));
  Serial.println(identification_L.manufacturerId);
  Serial.print(F(" - Identification de la carte: "));
  Serial.println(identification_L.productId);
  Serial.print(F(" - Numéro de série: "));
  Serial.println(identification_L.productSerialNumber);
}

void demarrer_gps(void)
{
  bool etat_L = false;

  etat_L = sim808EVB_G.getGnssPower();
  if(etat_L)
  {
    Serial.println(F("GPS allumé."));
  }
  else
  {
    Serial.println(F("GPS éteint. On l'allume"));
    sim808EVB_G.gnssPowerOn(); 
    Serial.println(F("Initialisation du GPS."));
    etat_L = sim808EVB_G.getGnssRunStatus();
    do
    {
      digitalWrite(LED_BUILTIN, HIGH);  // Clignotement de la diode pour signaler la recherche GPS
      etat_L = sim808EVB_G.getGnssRunStatus();
      Serial.print(F("."));
      delay(500);
      digitalWrite(LED_BUILTIN, LOW);  // Clignotement de la diode pour signaler la recherche GPS
      delay(500);
    }
    while(!etat_L);
    Serial.println(F("\nGPS en recherche de satellites."));
    etat_L = sim808EVB_G.getGnssFixStatus();
    do
    {
      digitalWrite(LED_BUILTIN, HIGH);  // Clignotement de la diode pour signaler la recherche GPS
      etat_L = sim808EVB_G.getGnssFixStatus();
      Serial.print(F("."));
      delay(500);
      digitalWrite(LED_BUILTIN, LOW);  // Clignotement de la diode pour signaler la recherche GPS
      delay(500);
    }
    while(!etat_L);
    Serial.println(F("\nGPS initialisé."));
  }
}

void arreter_gps(void)
{   
  bool etat_L;

  etat_L = sim808EVB_G.getGnssPower();
  if(!etat_L)
  {
    Serial.println(F("GPS éteint."));
  }
  else
  {
    Serial.println(F("GPS allumé. On l'éteint"));
    sim808EVB_G.gnssPowerOff();
  }
}


void donner_coordonees_en_texte(char* position_texte, sexagesimale_t latitude, sexagesimale_t longitude)
{
  char signe_latitude;
  char signe_longitude;
  float partie_entiere;

  if(latitude.positive)
  {
    signe_latitude = 'N';
  }
  else
  {
    signe_latitude = 'S';
  }
  if(longitude.positive)
  {
    signe_longitude = 'E';
  }
  else
  {
    signe_longitude = 'O';
  }
  sprintf(position_texte, "%d°%d'%02d.%02d\"%c, %d°%d'%02d.%02d\"%c", latitude.degree, latitude.minute , int(latitude.second),  int(modff(latitude.second, &partie_entiere)*100), signe_latitude,
                                                                     longitude.degree, longitude.minute , int(longitude.second),  int(modff(longitude.second, &partie_entiere)*100), signe_longitude);    
}

float sexagesimale_vers_degres_decimaux(sexagesimale_t coordonnee)
{
  float valeur;
  
  valeur = float(coordonnee.degree) + float(coordonnee.minute) / 60.0 + float(coordonnee.second) / 3600.0 ;
  if(!coordonnee.positive)
  {
    valeur = valeur * -1;
  }
  return(valeur);
}

void flottant_vers_texte(char* texte, float valeur)
{
  float partie_entiere, partie_fractionnaire;

  partie_fractionnaire = modff(valeur, &partie_entiere);
  sprintf(texte,"%d.%ld", (int)partie_entiere, (long)abs(partie_fractionnaire*pow(10, 7)));
}

void donner_lien_google_map(char* lien, sexagesimale_t latitude, sexagesimale_t longitude)
{
  char texte_latitude[15], texte_longitude[15];

  flottant_vers_texte(texte_latitude, sexagesimale_vers_degres_decimaux(latitude));
  flottant_vers_texte(texte_longitude, sexagesimale_vers_degres_decimaux(longitude)); 
  sprintf(lien, "https://www.google.com/maps/@?api=1&map_action=map&center=%s%s%s&zoom=18", texte_latitude, ",", texte_longitude);
}

void donner_lien_waze(char* lien, sexagesimale_t latitude, sexagesimale_t longitude)
{
  char texte_latitude[15], texte_longitude[15];
  
  flottant_vers_texte(texte_latitude, sexagesimale_vers_degres_decimaux(latitude));
  flottant_vers_texte(texte_longitude, sexagesimale_vers_degres_decimaux(longitude));
  sprintf(lien, "https://www.waze.com/ul?ll=%s%s%s&navigate=yes&zoom=18", texte_latitude, "%2C", texte_longitude);        
}

Compilation et test:

Pour tester notre programme, nous réalisons les opérations suivantes :

  1. Compiler puis transférer ce programme dans le microcontrôleur Arduino
  2. Démarrer la carte SIM808
  3. Effectuer un redémarrage de votre Arduino Uno en appuyant sur le bouton “Reset”.
  4. Ouvrir une console série à 115200 bauds.

Qu’observons-nous ?

Dans un premier temps, va s’afficher la ligne:

Connexion avec la carte SIM808.

puis au bout de quelques secondes:

La communication avec la carte SIM808 est établie.
Version logicielle: 1418B01SIM808M32
– Fabricant: SIMCOM_Ltd
– Identification de la carte: SIMCOM_SIM808
– Numéro de série: 865067020990670

Si vous n’arrivez pas à obtenir cette dernière ligne, je vous invite à vérifier :

  • Le câblage entre votre carte Arduino Uno et votre carte SIM808.
  • L’alimentation de votre carte SIM808

Ensuite, la carte Arduino demande à la SIM808 de démarrer son modem GPS:

GPS éteint. On l’allume
Initialisation du GPS
. . . . .
GPS en recherche de satellites.
. . . . . . . . . . . . . . . . . . . . . .

La LED embarquée de la carte Arduino se met à clignoter. Cela peut prendre jusqu’à 2 minutes avant d’obtenir la confirmation :

GPS initialisé.

Si vous n’obtenez pas cette confirmation, je vous invite à vérifier:

  • Que l’antenne GPS est bien vissée sur le connecteur SMA correspondant.
  • Que l’antenne GPS est correctement positionnée (face plate en direction du sol) dans un lieu perméable aux ondes GPS.

Une fois initialisée, la LED embarquée s’allume en continue et la console série affiche les coordonnées GPS calculées par Arduino. Par exemple:

Coordonnées géographiques: 47°28’55.59″N, 1°6’22.50″O
Lien google Map: https://www.google.com/maps/@?api=1&map_action=map&center=47.4821129,-1.1062500&zoom=18
Lien Waze: https://www.waze.com/ul?ll=47.4821129%2C-1.1062500&navigate=yes&zoom=18

Un copié / collé du lien Google Maps dans un navigateur Internet ouvre une carte Google Maps centrée sur cette position:

Ouverture du lien Google Maps généré par Arduino

Quant au lien Waze, si vous l’envoyez par mail sur un smartphone possédant l’application, ce lien va directement lancer une recherche de navigation Waze vers cette position. 

Ouverture du lienWaze généré par Arduino

Voici un résumé du fonctionnement de notre application en vidéo:

Voilà, maintenant nous somme capble d’utiliser le modem GPS de la carte SIM808 avec Arduino.

J’espère que cet article vous a plu et qu’il vous donnera plein d’idées pour vos projets personnels. Pour ma part, le but est d’intégrer ces fonctionnalités de localisation dans un futur projet de “balise GPS autonome”. N’hésitez pas à me partager vos propres idées de réalisation.

Pour continuer:

Pour continuer, voici 2 autres projets qui pourraient vous intéresser:

S’abonner
Notification pour
guest
9 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
Dési
Dési
1 année il y a

bjr. pour ce projet sans la carte sim comment on peut recevoir le message indiquant la position si on utilise dans le cas de la localisation de véhicule volé par exemple ?

Sèb
Sèb
1 année il y a

Bonjour,
cet article est très intéressant. merci beaucoup pour le code de l’ino. Existe-t’il un ino exemple pour faire fonctionner les fonctions appel téléphonique de la sim808 ?

avel
avel
9 mois il y a

Super merci pour votre partage de code. J’ai une erreur sur la latitude. En effet sur la console j’ai: Lien google Map: https://www.google.com/maps/@?api=1&map_action=map&center=43.807457 pour la latitude. Mais en réalité la position est 43.080….
il semblerait que le dixieme soit supprimé.
Bien cordialement

avel
avel
9 mois il y a

Autre question… 🙂 Il faut appuyer sur le BP pour initialiser le GPS. Peut on s’en passer ? Pour un tracker GPs se serait plus pratique. Merci