Récupérer une trame NMEA ($gprmc).

Bonjour a tous, je me présente, Insomnie, un novice en arduino.

Pour un projet d'un pluviomètre connecté, je dois récupérer une trame (GPRMC) venant d'un module "PmodGPS" afin de l'envoyer sur ordinateur mais pour ça je dois d'abord la recevoir et la stocker.

Mon problème ici est la réception de cette trame sur arduino. J'ai déjà essayer en vain de faire des programmes mais je n'ai pas trouver de résultats concluants en utilisant des programmes venant de droite et gauche.

Le matériel que possède est une carte arduino MEGA 2560 et un module PmodGPS.

Merci d'avoir lu.

bonjour,
as tu essayé CECI ?

Non je ne l'avais pas essayer, j'obtiens les trames mais ca me donne un affichage comme ca :

Ps : Je suis sur arduino uno avec ce test

Autre question, en ce basant sur ce programme, comment on peux passer a la ligne a chaque trame $GP reçu ?

Bonjour

Pour poster ici le contenu de ton terminal arduino, un copier/coller serait plus simple pour tout le monde (avec des balises [code] et [/code] de part et d'autre).

Donc, comme tu peux le constater, tu as des caractères qui arrivent à ton arduino par la liaison série avec ton module GPS. C'est déjà un bon début.

Ensuite, si tu veux récupérer uniquement les informations de la trame GPRMC, tu auras un bout de code à faire tourner sur l'arduino, pour analyser les caractères reçus et alimenter des variables (latitude, longitude, etc.)

Mais une fois que tes variables sont chargées, tu veux faire quoi précisément avec cette information?
"L'envoyer au PC" ce n'est pas assez précis.

NB juste en passant : donc tu es là ? :smiley:

bricoleau:
NB juste en passant : donc tu es là ? :smiley:

c'est effectivement la ou je me trouve.

bricoleau:
Ensuite, si tu veux récupérer uniquement les informations de la trame GPRMC, tu auras un bout de code à faire tourner sur l'arduino, pour analyser les caractères reçus et alimenter des variables (latitude, longitude, etc.)

Je souhaite récupérer seulement la trame RMC mais avec tout mes essais soit les données sont fausses, soit ca ne m'isole pas la trame RMC

bricoleau:
Mais une fois que tes variables sont chargées, tu veux faire quoi précisément avec cette information?
"L'envoyer au PC" ce n'est pas assez précis.

J'ai parlé brièvement de cette partie car je ne l'ai pas encore abordée, je veux créer une IHM qui montrera les informations récolté par une trame créée de moi même, et l'envoie des données se fera par modules Xbee.

Sinon, voila un code que l'on m'as passer, que j'ai un peu modifier, qui est celui sur lequel je bosse actuellement

#define RX 0; 

String message = "";

void setup()
{
  Serial.begin(9600);  
}

void loop()
{
 // message= analogRead(0);
  //Serial.println("Trame gps :");
  Serial.print(message);
  char carac = 0;
  // boucle qui attends un \n pour valider la trame et la décoder (/!\ Passer l'option en bas à droite du moniteur série en "Nouvelle ligne")
  while (carac != '\n')

  {
    // si un caractère est présent sur la liaison
    if(Serial.available())
    {
      // lecture d'un caractère
      carac = Serial.read();
      // concaténation du caractère au message
      message = message + carac; 
    }
  }
  
  Serial.print (message);
  
  //Serial.println("Message Recu !"); 
  
  if (message.substring(0,6) == "$GPRMC")
  {
    Serial.println("Trame GPRMC Recue");
    Serial.println(message);
    
    // Décodage de la trame

    // latitude
    String latitude;
    latitude = latitude + message.substring(20,29);
    if(message[30] == 'N')
      latitude = latitude + " Nord";
    else
      latitude = latitude + " Sud";
    Serial.println ("Latitude: " + latitude);

    
    // longitude
    String longitude;
    longitude = longitude + message.substring(32,42);
    if(message[43] == 'W')
      longitude = longitude + " Ouest";
    else
      longitude = longitude + " Est";
    Serial.println ("Longitude: " + longitude);
    
    // Heure
    String heure;
    String heures;
    heure = heures + message[7] + message[8] + "H " + message[9] + message[10] + "Min " + message[11] + message[12] + "Sec ";
      Serial.println("heure: " + heure);
//note : Heure utc, donc mettre heure +1             message.substring(8,17)
    //Date
    String date;
    date = date + message[56] + message[57] + "/" + message[58] + message[59] + "/20" + message[60] + message[61] ;
      Serial.println("date: " + date);
        
    
  }
   if (message.substring(0,6) != "$GPRMC"){ Serial.println(""); }
    
  else 
    Serial.println("Message inconnu ou incomplet ou autre type de trame");
 
  message = ""; 
}

Et voici la console, j'ai du mal a comprendre le problème.
(par probleme je ne peux entrer la trame dans la balise code)

Ce code est basé sur le principe que chaque information se trouve en position fixe, dans la ligne GPRMC reçue.
Il suffit qu'une zone soit plus ou moins longue et cela décale les positions.

Le plus fiable serait de compter les virgules pour savoir dans quelle zone on est, puis de la décoder spécifiquement, caractère par caractère.

J'ai bien une lib sous la main, que j'ai écrite et qui assure le décodage caractère par caractère d'une trame GPRMC, mais ce n'est pas super compliqué à coder.

Si c'est pour un projet scolaire (les coordonnées gps de la première pièce jointe, situent le test dans un lycée), je préfère te donner les indications pour t'aider à faire par toi-même. Cela te sera plus profitable.

En fait, je ne comprend pas vraiment comment fonctionne les fonctions d'arduino, rien ne me parle pour detecter une serie de caractère dans une trame.

Et j'aimerais donc savoir quelle partie de mon programme je dois changer et quelle fonction utiliser

Edit : J'ai reussi a faire fonctionner mon code, j'ai réussi a obtenir les infos dont j'avais besoin

#define RX 0; 

String message = "";

void setup()
{
  Serial.begin(9600);  
}

void loop()
{
  //Serial.print("Trame gps :");
  Serial.print(message);
  char carac = 0;
  // boucle qui attends un \n pour valider la trame et la décoder (/!\ Passer l'option en bas à droite du moniteur série en "Nouvelle ligne")
  while (carac != '\n')

  {
    // si un caractère est présent sur la liaison
    if(Serial.available())
    {
      // lecture d'un caractère
      carac = Serial.read();
      // concaténation du caractère au message
      message = message + carac; 
    }
  }
  
  Serial.print (message);
  
  if (message.substring(0,6) == "$GPRMC")
  {
    //Serial.print("Trame GPRMC Recue : "); 
    //Serial.println(message);
    
    // Décodage de la trame

    // latitude
    String latitude;   latitude = latitude + message.substring(20,29);   if(message[30] == 'N')  latitude = latitude + " Nord";   else      latitude = latitude + " Sud";    Serial.println ("Latitude: " + latitude);  
 
    // longitude
    String longitude;   longitude = longitude + message.substring(32,42); if(message[43] == 'W')  longitude = longitude + " Ouest";   else longitude = longitude + " Est"; Serial.println ("Longitude: " + longitude);
       
    // Heure
    String heure;  heure = heure + message[7] + message[8] + "H " + message[9] + message[10] + "Min " + message[11] + message[12] + "Sec "; Serial.println("heure: " + heure);
    
    //Date
    String date; date = date + message[57] + message[58] + "/" + message[59] + message[60] + "/20" + message[61] + message[62] ;  Serial.println("date: " + date);
        
  }
  if (message.substring(0,6) != "$GPRMC"){ Serial.println(""); }
    
  else 
  Serial.println("");
  
 
  message = ""; 
  
}
$GPGGA,103822.000,4804.1441,N,00045.5744,W,1,4,2.01,97.5,M,47.7,M,,*77

$GPGSA,A,3,07,30,05,28,,,,,,,,,2.24,2.01,0.99*0E

$GPGSV,3,1,12,05,72,231,31,30,64,069,29,13,48,282,20,07,39,055,28*7C

$GPGSV,3,2,12,28,31,130,11,20,26,309,,15,16,282,,02,10,214,*72

$GPGSV,3,3,12,09,09,094,18,21,08,330,,27,01,022,,49,,,*4C

$GPRMC,103822.000,A,4804.1441,N,00045.5744,W,0.39,337.53,190218,,,A*75
Latitude: 4804.1441 Nord
Longitude: 00045.5744 Ouest
heure: 10H 38Min 22Sec 
date: 19/02/2018

$GPVTG,337.53,T,,M,0.39,N,0.72,K,A*33

$GPGGA,103823.000,4804.1442,N,00045.5745,W,1,4⸮$GPGGA,103824.000,4804.1443,N,00045.5745,W,1,4,2.01,97.5,M,47.7,M,,*72

$GPGSA,A,3,07,30,05,28,,,,,,,,,2.24,2.01,0.99*0E

$GPRMC,103824.000,A,4804.1443,N,00045.5745,W,0.33,324.54,190218,,,A*7F
Latitude: 4804.1443 Nord
Longitude: 00045.5745 Ouest
heure: 10H 38Min 24Sec 
date: 19/02/2018

$GPVTG,324.54,T,,M,0.33,N,0.60,K,A*3F

$GPGGA,103825.000,4804.1444,N,00045.5746,W,1,4,2.01,97.5,M,47.7,M,,*77

$GPGSA,A,3,07,30,05,28,,,,,,,,,2.24,2.01,0.99*0E

$GPRMC,103825.000,A,4804.1444,N,00045.5746,W,0.29,344.31,190218,,,A*74
Latitude: 4804.1444 Nord
Longitude: 00045.5746 Ouest
heure: 10H 38Min 25Sec 
date: 19/02/2018

$GPVTG,344.31,T,,M,0.29,N,0.53,K,A*31

$GPGGA,103826.000,4804.1445,N,00045.5746,W,1,4,2.01,97.5,M,47.7,M,,*75

$GPGSA,A,3,07,30,05,28,,,,,,,,,2.24,2.01,0.99*0E

$GPRMC,103826.000,A,4804.1445,N,00045.5746,W,0.33,7.02,190218,,,A*79
Latitude: 4804.1445 Nord
Longitude: 00045.5746 Ouest
heure: 10H 38Min 26Sec 
date: 02/18/20,,

$GPVTG,7.02,T,,M,0.33,N,0.60,K,A*3E

$GPGGA,103827.000,4804.1446,N,00045.5746,W,1,4,3.51,97.5,M,47.7,M,,*73

$GPGSA,A,3,07,30,05,28,,,,,,,,,7.13,3.51,6.20*0F

$GPGSV,3,1,12,05,72,231,32,30,64,069,30,13,48,282,20,07,39,055,25*7A

$GPGSV,3,2,12,33,32,199,,28,31,130,17,20,26,309,,15,16,282,*70

$GPGSV,3,3,12,02,10,214,,09,09,094,17,21,08,330,,27,01,022,*7A

$GPRMC,103827.000,A,4804.1446,N,00045.5746,W,0.32,358.38,190218,,,A*7A
Latitude: 4804.1446 Nord
Longitude: 00045.5746 Ouest
heure: 10H 38Min 27Sec 
date: 19/02/2018

$GPVTG,358.38,T,,M,0.32,N,0.59,K,A*35

$GPGGA,103828.000,4804.1446,N,00045.5746,W,1,4,3.51,97.5,M,47.7,M,,*7C

$GPGSA,A,3,07,30,05,28,,,,,,,,,7.12,3.51,6.20*0E

$GPRMC,103828.000,A,4804.1446,N,00045.5746,W,0.27,356.50,190218,,,A*71
Latitude: 4804.1446 Nord
Longitude: 00045.5746 Ouest
heure: 10H 38Min 28Sec 
date: 19/02/2018

Mais maintenant j'obtient parfois des résultats incomplèt durant l'affichage (ici la date) et je ne comprend pas pourquoi c'est comme ca, alors que j'ai une trame complète.
Voila un exemple pour illustrer

$GPRMC,103826.000,A,4804.1445,N,00045.5746,W,0.33,7.02,190218,,,A*79
Latitude: 4804.1445 Nord
Longitude: 00045.5746 Ouest
heure: 10H 38Min 26Sec 
date: 02/18/20,,
$GPRMC,104617.000,A,4804.1430,N,00045.5561,W,0.11,55.57,190218,,,A*40
Latitude: 4804.1430 Nord
Longitude: 00045.5561 Ouest
heure: 10H 46Min 17Sec 
date: 90/21/208,

Edit 2 :

Avancé du programme

#define RX 0; 

String message = "";

void setup()
{
  Serial.begin(9600);  
}

void loop()
{

  Serial.print(message);
  char carac = 0;
  // boucle qui attends un \n pour valider la trame et la décoder (/!\ Passer l'option en bas à droite du moniteur série en "Nouvelle ligne")
  while (carac != '\n')

  {
    // si un caractère est présent sur la liaison
    if(Serial.available())
    {
      // lecture d'un caractère
      carac = Serial.read();
      // concaténation du caractère au message
      message = message + carac; 
    }
  }
  
  Serial.print (message);
  
  if (message.substring(0,6) == "$GPRMC")
  {
    
    // Décodage de la trame

    // latitude
    String latitude;   latitude = latitude + message.substring(20,29);   if(message[30] == 'N')  latitude = latitude + " Nord";   else      latitude = latitude + " Sud";    Serial.println ("Latitude: " + latitude);  
    String latitude2;  latitude2 = message.substring(20,29);if(message[30] == 'N')  latitude2 = "" + latitude2;   else      latitude2 =  " Sud" + latitude2 ; Serial.println ("Latitude2: " + latitude2); 

 
    // longitude
    String longitude;   longitude = longitude + message.substring(32,42); if(message[43] == 'W')  longitude = longitude + " Ouest";   else longitude = longitude + " Est"; Serial.println ("Longitude: " + longitude);
    String longitude2;  longitude2 = message.substring(32,42); if(message[43] == 'W')  longitude2 = "-" + longitude2;   else longitude2 = "" + longitude2; Serial.println ("Longitude2: " + longitude2);

       
    // Heure
    String heure;  heure = heure + message[7] + message[8] + "H " + message[9] + message[10] + "Min " + message[11] + message[12] + "Sec "; Serial.println("heure: " + heure);
    String heure2; heure2 = heure2 + message.substring(7,13);Serial.println("heure2: " + heure2);
    
    //Date
    String date;  date = date + message[57] + message[58] + "/" + message[59] + message[60] + "/20" + message[61] + message[62] ;  Serial.println("date: " + date);
    String date2; date2 = date2 + message.substring(57,61) + "20" + message[61] + message[62] ; Serial.println("date2: " + date2);
    
    //trame
    String trame; trame = latitude2 +","+ longitude2 +","+ heure2 +","+ date2; Serial.println(trame); 
    
  }
  if (message.substring(0,6) != "$GPRMC"){ Serial.println(""); }
    
  else 
  Serial.println("");
  
 
  message = ""; 
  
}
$GPGSV,3,2,11,20,39,301,,15,29,289,19,07,25,056,19,21,12,318,*77

$GPGSV,3,3,11,08,05,045,,27,01,009,,46,,,*7A

$GPRMC,111227.000,A,4804.1390,N,00045.$GPGGA,111235.000,4804.1388,N,00045.5734,W,1,5,1.61,74.3,M,47.7,M,,*72

$GPGSA,A,3,07,30,05,13,28,,,,,,,,1.89,1.61,0.98*0C

$GPRMC,111235.000,A,4804.1388,N,00045.5734,W,0.28,165.33,190218,,,A*7C
Latitude: 4804.1388 Nord
Latitude2: 4804.1388
Longitude: 00045.5734 Ouest
Longitude2: -00045.5734
heure: 11H 12Min 35Sec 
heure2: 111235
date: 19/02/2018
date2: 19022018
4804.1388,-00045.5734,111235,19022018

$GPVTG,165.33,T,,M,0.28,N,0.51,K,A*31

$GPGGA,111236.000,4804.1387,N,00045.5733,W,1,5,1.61,74.3,M,47.7,M,,*79

$GPGSA,A,3,07,30,05,13,28,,,,,,,,1.89,1.61,0.98*0C

$GPRMC,111236.000,A,4804.1387,N,00045.5733,W,0.22,156.32,190218,,,A*7C
Latitude: 4804.1387 Nord
Latitude2: 4804.1387
Longitude: 00045.5733 Ouest
Longitude2: -00045.5733
heure: 11H 12Min 36Sec 
heure2: 111236
date: 19/02/2018
date2: 19022018
4804.1387,-00045.5733,111236,19022018

$GPVTG,156.32,T,,M,0.22,N,0.41,K,A*3B

$GPGGA,111237.000,4804.1386,N,00045.5733,W,1,5,1.61,74.3,M,47.7,M,,*79

$GPGSA,A,3,07,30,05,13,28,,,,,,,,1.89,1.61,0.98*0C

$GPGSV,3,1,11,05,61,199,32,13,61,295,24,30,50,060,33,28,43,115,25*7B

$GPGSV,3,2,11,20,39,301,,15,29,289,22,07,25,056,22,21,12,318,*77

$GPGSV,3,3,11,08,05,045,,27,01,009,,47,,,*7B

$GPRMC,111237.000,A,4804.1386,N,00045.5733,W,0.17,157.52,190218,,,A*7D
Latitude: 4804.1386 Nord
Latitude2: 4804.1386
Longitude: 00045.5733 Ouest
Longitude2: -00045.5733
heure: 11H 12Min 37Sec 
heure2: 111237
date: 19/02/2018
date2: 19022018
4804.1386,-00045.5733,111237,19022018

Edit 3 : Dans mon code, j'ai l'heure UTC, mais je n'arrive pas a modifier la valeur que j'obtient pour mettre l'heure francaise.

J'ai déjà expliqué pourquoi ce programme ne convient pas, et maintenant nous en avons l'illustration.

La date se trouve dans les dernières données de la ligne.
Juste avant la date, il y a d'autres données dont la longueur varie d'une ligne à l'autre.
Il est donc illusoire de chercher à récupérer jour/mois/année en position fixe.

La date est après la neuvième virgule, sur la ligne gprmc.
Le seul moyen fiable pour la récupérer est de compter les virgules.

Et comment je compte les virgules ? En créant des variables ?
(quand je dis que je suis un novice je suis VRAIMENT un novice, j'ai beaucoup de mal avec arduino)