Go Down

Topic: Récupérer une trame NMEA ($gprmc). (Read 753 times) previous topic - next topic

Insomnie

Feb 07, 2018, 10:20 am Last Edit: Feb 07, 2018, 10:32 am by Insomnie
   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.

infobarquee

AUCUNE AIDE PAR MP

Insomnie

#2
Feb 12, 2018, 11:27 am Last Edit: Feb 12, 2018, 12:08 pm by Insomnie
Non je ne l'avais pas essayer, j'obtiens les trames mais ca me donne un affichage comme ca :
https://i.gyazo.com/c02408478fc2db6c613b437bb7c39292.png

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 ?

bricoleau

#3
Feb 12, 2018, 01:33 pm Last Edit: Feb 12, 2018, 01:34 pm by bricoleau
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à:D
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Insomnie

NB juste en passant : donc tu es là ?  :D
c'est effectivement la ou je me trouve.

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

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

Code: [Select]
#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)

https://gyazo.com/e4461b8dc90f5d706af6e7792c284d1b


bricoleau

#5
Feb 13, 2018, 01:37 pm Last Edit: Feb 13, 2018, 01:38 pm by bricoleau
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.
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

bricoleau

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.
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Insomnie

#7
Feb 19, 2018, 11:18 am Last Edit: Feb 19, 2018, 12:15 pm by Insomnie
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

Code: [Select]
#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 = "";
  
}

Code: [Select]
$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
Code: [Select]

$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,,

Code: [Select]
$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,




Insomnie

#8
Feb 19, 2018, 12:15 pm Last Edit: Feb 19, 2018, 02:14 pm by Insomnie
Edit 2 :

Avancé du programme
Code: [Select]
#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 = "";
 
}

Code: [Select]
$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.

bricoleau

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.
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Insomnie

#10
Feb 19, 2018, 02:19 pm Last Edit: Feb 19, 2018, 02:26 pm by Insomnie
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)

Go Up