Traitement de données NMEA avec spéarateur

Bonjour à tous,

Cela fait toute l'après-midi que je cherche, essaie différente technique mais rien ne fonctionne et je ne trouve pas de tuto sauf un site qui semble très bien décrire la manip... mais qui à un bug d'affichage au moment le plus intéressant! :slight_smile:

www.redohm.fr... et leur mail me retourne un undelivered!

Voilà mon code:

gps.begin(9600); // Confirmer l'écriture sur 9600 pour le GPS
   delay(5000);
    if (gps.available())                     // if date is coming from software serial port ==> data is coming from SoftSerial shield
    {  

        while(gps.available())               // reading data into char array
        {
            buffer[count++]=gps.read();      // writing data into array
            if(count == 64)break;
        }
       Serial.write(buffer,count);                 // if no data transmission ends, write buffer to hardware serial port
        clearBufferArray();                         // call clearBufferArray function to clear the stored data from the array
        count = 0;                                  // set counter of while loop to zero     

    }
   delay(3000);

Il m'affiche parfaitement la donnée que j'ai besoin après "Serial.write(buffer,count);" soit:

$GPGGA,172945.000,xxxx.2000,N,00xxx.1458,E,2,7,1.22,476.5,M,48.

Jusque là c'est bon... C'est la suite qui me pose problème... Comment décomposer chaque valeur entre les virgules pour en créer des variables séparées? J'ai vu que Serial.Println(buffer[23]) par exemple me sortait des données en bytes.
J'ai donc essayé les fonction Serial.ReadBytesUntil(), j'ai essayé d'écrire simplement dans un variable char, j'ai essayé d'utiliser String... j'ai bien lu et relu : Serial Input Basics thread

Mais rien n'y fait pour le moment! :frowning:

Si vous avez un tutoriel qui me permettrait de comprendre un peu plus sur le sujet, je serai heureux de pouvoir apprendre sans m'arracher les cheveux!

Merci d'avance et à bientôt!

strtok est ton ami

:frowning:

J’y comprends vraiment rien… j’ai essayé à nouveau avec StringIndexOf() et avec strtok() mais rien n’y fait…

Si je charge ma variable avec la donnée:

$GPGGA,172945.000,xxxx.2000,N,00xxx.1458,E,2,7,1.22,476.5,M,48.

J’arrive bien a la décomposer… mais d’une fois que j’essaie de récupérer depuis les données qui sorte de gps.read ou gps.write, j’ai rien qui se passe mis à part des bugs…

Voici mon dernier test:

// Soft Cédric Rey pour Technofox Compact //

/*ajouter les libraries
#include <Servo.h>; // Fonctionnement du servomoteur
Servo MonServo; //nommer mon servo
#include <SoftwareSerial.h>; // Lecture des sondes et capteurs
SoftwareSerial sim(10, 11); //Indiquer le port de RX / TX de la carte SIM
SoftwareSerial gps(8, 9); //Indiquer les port de RX / TX de la puce GPS*/
#include <SoftwareSerial.h>;
#include <string.h>;
#define MAX_STRING_LEN  20
SoftwareSerial gps(8, 9); //Indiquer les port de RX / TX de la puce GPS
int count=0;
char *record1 = "$GPGGA,143820.000,46xx.1893,N,00xx1.1485,E,2,7,1.26,477.9,M,48.$";
char *p, *i;

void setup() {

  Serial.begin(9600);
  gps.begin(9600); // Confirmer l'écriture sur 9600 pour le GPS

  Serial.println("Split record1: ");
  Serial.println(subStr(record1, ",", 1));
  Serial.println(subStr(record1, ",", 2));
  Serial.println(subStr(record1, ",", 3));
  Serial.println(subStr(record1, ",", 4));
  Serial.println(subStr(record1, ",", 5));
  Serial.println(subStr(record1, ",", 6));
  Serial.println(subStr(record1, ",", 7));
  Serial.println(subStr(record1, ",", 8));
  Serial.println(subStr(record1, ",", 9));
  Serial.println(subStr(record1, ",", 10));
  Serial.println(subStr(record1, ",", 11));
  Serial.println(subStr(record1, ",", 12));

}

void loop () {

gps.begin(9600); // Confirmer l'écriture sur 9600 pour le GPS
   delay(5000);
    if (gps.available())                     // if date is coming from software serial port ==> data is coming from SoftSerial shield
    {  

        while(gps.available())               // reading data into char array
        {
            record1[count++]=gps.read();      // writing data into array
            if(count == 64)break;
        }
       Serial.write(record1,count);                 // if no data transmission ends, write buffer to hardware serial port
        clearBufferArray();                         // call clearBufferArray function to clear the stored data from the array
        count = 0;                                  // set counter of while loop to zero     

    }
  
}

// Function to return a substring defined by a delimiter at an index
char* subStr (char* str, char *delim, int index) {
  char *act, *sub, *ptr;
  static char copy[MAX_STRING_LEN];
  int i;

  // Since strtok consumes the first arg, make a copy
  strcpy(copy, str);

  for (i = 1, act = copy; i <= index; i++, act = NULL) {
     //Serial.print(".");
     sub = strtok_r(act, delim, &ptr);
     if (sub == NULL) break;
  }
  return sub;

}

void clearBufferArray()                     // function to clear buffer array
{
    for (int i=0; i<count;i++)
    {
        record1[i]=NULL;
       gps.end();
 
    }                      // clear all index of array with command NULL
}

Es-ce que quelqu’un arriverait à me dépatouiller? J’arrive pas à comprendre sur quel point je bloque.

Merci d’avance.

Re-boujour… j’avance!

J’ai réussi grâce à un script de lesept sur un autre feed à comprendre un peu plus le fonctionnement!
Voici mon code:

#include <SoftwareSerial.h>

char frame[128];
char GPGGA[2];
char Date[1];
char latitude[1];
char lat[1];
char longitude[1];
char lon[1];
char positionnement[1];
char sat[2];
char precision[3];
char altitude[1];
char autre[6];
char somme[3];
char verification = "$GPGGA";

const char s[2] = ",";
char *token;

boolean state;
double serialnr;

SoftwareSerial gps(8, 9);
char buffer[64];                   // buffer array for data receive over serial port
int count=0;                                // counter for buffer array
void setup()
{
    gps.begin(9600);                 // the SoftSerial baud rate
    Serial.begin(9600);                     // the Serial port of Arduino baud rate.
}
 
void loop()
{
delay(2000);
    if (gps.available())                     // if date is coming from software serial port ==> data is coming from SoftSerial shield
    {  

        while(gps.available())               // reading data into char array
        {
            buffer[count++]=gps.read();      // writing data into array
            if(count == 64)break;
        }

      //buffer[count] = '\0';

        Serial.write(buffer,count);
        Serial.println();
        Serial.println();
        
  token = strtok(buffer, s);
  Serial.println("Recherche du premier mot de la série:");
   Serial.println(token);
        Serial.println();
        Serial.println();
   
  if(token == verification) {
  Serial.println(token);
  Serial.println("2ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("3ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("4ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("5ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("6ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("7ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("8ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("9ème boucle");
  token = strtok(NULL, s); 
  Serial.println(token);
  Serial.println("10ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("11ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
   Serial.println("12ème boucle");
  token = strtok(NULL, s);
  Serial.println(token);
  } else {
    Serial.println("restart");
    }
  
/*
  while(token != NULL) {
    Serial.println(token);
    token = strtok(NULL, s);
     }
*/
     clearBufferArray();
     count=0;
 
  
  /*strcpy(GPGGA, strtok(NULL, ",")); // type de trame
  strcpy(Date, strtok(NULL, ",")); // Gets Fix status
  strcpy(latitude, strtok(NULL, ",")); // Gets UTC date & time
  strcpy(lat, strtok(NULL, ",")); // Gets longitude
  strcpy(longitude, strtok(NULL, ",")); // Gets MSL altitude
  strcpy(lon, strtok(NULL, ",")); // Gets speed over ground
  strcpy(positionnement, strtok(NULL, ",")); // Gets course over ground
  strcpy(sat, strtok(NULL, ",")); // Gets Fix Mode
  strcpy(precision, strtok(NULL, ",")); // Gets Fix Mode
  strcpy(altitude, strtok(NULL, ",")); // Gets Fix Mode
  strcpy(autre, strtok(NULL, ",")); // Gets Fix Mode
  strcpy(somme, strtok(NULL, ",")); // Gets Fix Mode
      
       

          
  Serial.println("Type de trame:");
  Serial.println(GPGGA);
  Serial.println("Date et heure");
  Serial.println(Date);
  Serial.println("Latitude:");  
  Serial.println(latitude);
  Serial.println("Lat:");
  Serial.println(lat);
  Serial.println("Longitude:");
  Serial.println(longitude);
  Serial.println("Lon:");
  Serial.println(lon);
  Serial.println("Possitionnement:");
  Serial.println(positionnement);
  Serial.println("Nombre de satelite:");
  Serial.println(sat);
  Serial.println("Précision:");
  Serial.println(precision);
  Serial.println("altitude:");
  Serial.println(altitude);
      
      // if no data transmission ends, write buffer to hardware serial port
        clearBufferArray();                         // call clearBufferArray function to clear the stored data from the array
        count = 0;                                  // set counter of while loop to zero 
    }
  /*  if (Serial.available())                 // if data is available on hardware serial port ==> data is coming from PC or notebook
    gps.write(Serial.read());        // write it to the SoftSerial shield
*/}
}

void GPS() {

  int8_t counter, answer;
  long previous;

  
  
  
  
  
  
  }
 
 
void clearBufferArray()                     // function to clear buffer array
{
    for (int i=0; i<count;i++)
    {
        buffer[i]=NULL;
    }                      // clear all index of array with command NULL
}

J’ai seulement un petit problème… parfois la chaîne qui passe dans le buffer ne commence pas par “$GPGGA” donc je souhaite ignorer et relire une fois la sortie avant de pouvoir la séparer dans différentes variable.

Cependant,

if(token == “$GPGGA”)

ne réussi pas à faire la vérification… même via une variable char.

Es-ce que vous savez pourquoi?

Merci d’avance!

Tu trouveras dans ce lien l'ensemble des fonctions de manipulation des chaines de caractères, avec les explications et des exemples d'utilisation.

Pour vérifier si ta chaîne contient GPGGA, tu peux utiliser strstr

  char * pch;
  pch = strstr (buffer,"GPGGA");
  if (pch == NULL) {  // On n'a pas trouvé GPGGA

  }

... A tester ...