[RÉSOLU] Trames d'erreurs séries GPS Beitian BN-220

Bonjour,
Je fabrique un compteur de vitesse, mais n'ayant pas de centrale inertielle sous la main j'ai pris un GPS - c'est un peu moins précis mais on a plus de possibilité ensuite :wink:

Ce GPS est un BN-220 de chez Beitian, c'est un modèle 5V assez simple qui n'utilise qu'une bête liaison série. On peut donc utiliser simplement SoftwareSerial par exemple pour recevoir des données.

J'ai suivi cet article : Using GPS Modules with Arduino & Raspberry Pi | DroneBot Workshop
Et avant de vraiment commencer à coder j'ai voulu tester le bon fonctionnement de mon module avec un programme très simple que voici :

#include <Arduino.h>
#include <SoftwareSerial.h>

SoftwareSerial uartGps(2, 3);

void setup()
{
    Serial.begin(115200);
    Serial.println("Démarrage!");
    //Serial.print("TinyGPS++ version "); Serial.println(_GPS_VERSION);
    uartGps.begin(9600);
}

void loop()
{
    while (uartGps.available() > 0)
    {
        Serial.write(uartGps.read());
    }
}

Et voici ce que j'obtiens au lieu des informations envoyées par le module par défaut :

Démarrage!
$GNRMC,,V,,,,,,,,,,N*4D
$GNVTG,,,,,,,,,N*2E
$GNGGA,,,,,,0,00,99.99,,,,,,*56
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GPGSV,1,1,00*79
$GLGSV,1,1,00*65
$GNGLL,,,,,,V,N*7A
$GNRMC,,V,,,,,,,,,,N*4D
$GNVTG,,,,,,,,,N*2E
$GNGGA,,,,,,0,00,99.99,,,,,,*56
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GPGSV,1,1,00*79
$GLGSV,1,1,00*65
$GNGLL,,,,,,V,N*7A
$GNRMC,,V,,,,,,,,,,N*4D
$GNVTG,,,,,,,,,N*2E
$GNGGA,,,,,,0,00,99.99,,,,,,*56
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GPGSV,1,1,00*79
$GLGSV,1,1,00*65
$GNGLL,,,,,,V,N*7A
$GNRMC,,V,,,,,,,,,,N*4D
$GNVTG,,,,,,,,,N*2E
$GNGGA,,,,,,0,00,99.99,,,,,,*56
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
$GPGSV,1,1,00*79
$GLGSV,1,1,00*65
$GNGLL,,,,,,V,N*7A

...à l'infini...

Clairement il y a une erreur quelque part, je ne pense pas que tous ces 9 et ces virgules soient des trames normales... J'ai effectué mes tests à l’extérieur en terrain dégagé, donc normalement le GPS est censé capter quelque chose, non ? (Après je ne connais pas cette technologie donc je tâtonne un peu...)

Avez-vous une idée de ce qui peut provoquer un tel comportement ? Ai-je fait une mauvaise manipulation ? Dites moi s'il manque des infos! Merci d'avance pour votre aide!
Cordialement,
Pandaroux007

Bonjour @pandaroux007,

Il faut que tu regardes ce fil de discussion, tu y trouveras toutes les réponses à tes questions :
GPS

C'était à mes débuts avec la contribution de @J-M-L à qui je dois tout ce que je sais aujourd'hui :wink: et qui m'a permis d'obtenir une forme d'autonomie à mon petit niveau.

Merci encore à lui.

Bonjour @philippe86220,
Merci pour ce lien! J'ai tout parcouru rapidement, c'est très intéressant sur bien des points mais je n'y vois pas d'allusions à des trames reçues comme celles que je reçois, mis à part le fait qu'elles apparaissent lorsque le GPS n'a pas de données à transmettre...

Dans ce cas pourquoi ?? Mon câblage est bon de ce que je vois, je l'alimente correctement et je fais mes tests en extérieur, donc normalement il devrait recevoir des données, non ?

(j'ai par ailleurs lu Horloge TRÈS précise pilotée par GPS avec Arduino Nano - #15 by rollmops67, ça confirme ce que j'ai pu voir dans votre topic)

On constate que même si à priori on ne capte pas encore de satellites (0 souligné en rouge) on a quand même déjà l'heure (soulignée en vert) et la date (soulignée en bleu)

Moi je n'ai même pas ces informations (même si on n'a pas le même GPS, normalement le mien aussi devrait afficher quelque chose non ?) - je ne comprends vraiment pas ce qui se passe :woozy_face: Je devrais pourtant capter quelques satellites...

Cordialement,
Pandaroux007

Essaye ce code en l'adaptant à ton matériel et en utilisant :

#include <SoftwareSerial.h>
Puisque apparemment tu en as besoin ...

const byte RXD2 = 16;
const byte TXD2 = 17;

const byte tailleMessageMax = 100;
char message[tailleMessageMax + 1]; // +1 car on doit avoir un caractère de fin de chaîne en C, le '\0'
const char marqueurDeFin = '\n';

void traiterMessage() {
  Serial.print("J'ai reçu: [");
  Serial.print(message);
  Serial.println(']');

  if (strncmp(message, "$GPRMC", 6) == 0) {
    Serial.println("Trame de type RMC");
  }
  else if (strncmp(message, "$GPGGA", 6) == 0) {
    Serial.println("Trame de type GGA");
  }
  else if (strncmp(message, "$GPGSA", 6) == 0) {
    Serial.println("Trame de type GSA");
  }
  else {
    Serial.println("Trame de type inconnu");
  }
}

bool messageRecu() {
  static byte indexMessage = 0;
  int r = Serial2.read();
  if (r != -1) { // on a reçu un caractère
    if (r == marqueurDeFin) {
      message[indexMessage] = '\0'; // on termine la c-string
      indexMessage = 0; // on se remet au début pour la prochaine fois
      return true;
    } else {
      if (indexMessage < tailleMessageMax) message[indexMessage++] = (char) r; // on stocke le caractère et on passe à la case suivante
    }
  }
  return false;
}

void setup() {
  Serial.begin(115200); Serial.println();
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); // initialise la liaison RX2-TX2 sur espressif WROOM 32
  delay(100);
}

void loop() {
  if (messageRecu()) traiterMessage();
}

tu es sûr de l'alimentation de ton module ?
le module semble marcher, mais les données vide, peut être que le GPS n'a pas assez de courant pour pouvoir capter les satellite correctement ?

essaye ça (je n'ai pas testé) :


#include <SoftwareSerial.h>


static const int RXPin = 2, TXPin = 3;
static const uint32_t GPSBaud = 9600;

SoftwareSerial uartGps(RXPin, TXPin);

const byte tailleMessageMax = 100;
char message[tailleMessageMax + 1]; // +1 car on doit avoir un caractère de fin de chaîne en C, le '\0'
const char marqueurDeFin = '\n';

void traiterMessage() {
  Serial.print("J'ai reçu: [");
  Serial.print(message);
  Serial.println(']');

  if (strncmp(message, "$GPRMC", 6) == 0) {
    Serial.println("Trame de type RMC");
  }
  else if (strncmp(message, "$GPGGA", 6) == 0) {
    Serial.println("Trame de type GGA");
  }
  else if (strncmp(message, "$GPGSA", 6) == 0) {
    Serial.println("Trame de type GSA");
  }
  else {
    Serial.println("Trame de type inconnu");
  }
}

bool messageRecu() {
  static byte indexMessage = 0;
  int r = uartGps.read();
  if (r != -1) { // on a reçu un caractère
    if (r == marqueurDeFin) {
      message[indexMessage] = '\0'; // on termine la c-string
      indexMessage = 0; // on se remet au début pour la prochaine fois
      return true;
    } else {
      if (indexMessage < tailleMessageMax) message[indexMessage++] = (char) r; // on stocke le caractère et on passe à la case suivante
    }
  }
  return false;
}

void setup() {
  Serial.begin(115200); Serial.println();
  uartGps.begin(9600);
  delay(100);
}

void loop() {
  if (messageRecu()) traiterMessage();
}

Il faut que TX soit sur RX et inversement ...
(branchements entre arduino et GPS)

Pour du basic, tu n'as que 4 fils à brancher :

  • VCC
  • GND
  • RX
  • TX

ça reste assez simple à utiliser.
A voir voltage de VCC ...

GPS pour CAP

Bonjour @terwal

Peut-être... J'ai regardé dans la datasheet - pas la officielle mais celle-ci semble avoir disparue ? - et d'après ce que je lis c'est 50mA, donc normalement supportable pour la pin 5V de ma NANO...


@philippe86220 Merci pour le code :slight_smile: Je l'ai adapté et le voici, je l'ai laissé tourner un petit moment (plus d'une minute) et voici ce qu'il me sort :

Programme de @philippe86220 adapté
#include <Arduino.h>
// -------------------------- libraries
#include <SoftwareSerial.h>
// #include <TinyGPS++.h>
// #include <SD.h>

SoftwareSerial uartGps(2, 3);
//TinyGPSPlus gps;

const byte tailleMessageMax = 100;
char message[tailleMessageMax + 1]; // +1 car on doit avoir un caractère de fin de chaîne en C, le '\0'
const char marqueurDeFin = '\n';

void traiterMessage() {
  Serial.print("J'ai reçu: [");
  Serial.print(message);
  Serial.println(']');

  if (strncmp(message, "$GPRMC", 6) == 0) {
    Serial.println("Trame de type RMC");
  }
  else if (strncmp(message, "$GPGGA", 6) == 0) {
    Serial.println("Trame de type GGA");
  }
  else if (strncmp(message, "$GPGSA", 6) == 0) {
    Serial.println("Trame de type GSA");
  }
  else {
    Serial.println("Trame de type inconnu");
  }
}

bool messageRecu() {
  static byte indexMessage = 0;
  int r = uartGps.read();
  if (r != -1) { // on a reçu un caractère
    if (r == marqueurDeFin) {
      message[indexMessage] = '\0'; // on termine la c-string
      indexMessage = 0; // on se remet au début pour la prochaine fois
      return true;
    } else {
      if (indexMessage < tailleMessageMax) message[indexMessage++] = (char) r; // on stocke le caractère et on passe à la case suivante
    }
  }
  return false;
}

void setup()
{
    Serial.begin(115200);
    Serial.println("Démarrage!");
    uartGps.begin(9600);
}

void loop()
{
    // while (uartGps.available() > 0)
    // {
    //     Serial.write(uartGps.read());
    // }
    if (messageRecu()) traiterMessage();
}
]'ai reçu: [$GNRMC,,V,,,,,,,,,,N*4D
Trame de type inconnu
]'ai reçu: [$GNVTG,,,,,,,,,N*2E
Trame de type inconnu
]'ai reçu: [$GNGGA,,,,,,0,00,99.99,,,,,,*56
Trame de type inconnu
]'ai reçu: [$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
Trame de type inconnu
]'ai reçu: [$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E
Trame de type inconnu
]'ai reçu: [$GPGSV,1,1,03,09,,,12,13,,,13,14,,,15*71
Trame de type inconnu
]'ai reçu: [$GLGSV,1,1,00*65
Trame de type inconnu
]'ai reçu: [$GNGLL,,,,,,V,N*7A
Trame de type inconnu

Oui, j'ai oublié de préciser désolé :woozy_face:, j'utilise une NANO chinoise, d'où la nécessité de SoftwareSerial pour pouvoir avoir les print dans le moniteur série en parallèle.


Vu que je reçois des données c'est censé être bon, j'ai quand même re-regardé et c'est normalement tout OK, j'ai bien RX et TX d'inversés entre la carte et le module, et j'ai même vérifié la tension disponible entre 5V et GND, je suis légèrement en dessous mais rien de significatif et le module fonctionne donc je ne pense pas que ce soit le problème...

Merci pour vos réponses!
Cordialement,
Pandaroux007

Essaye ça en installant la librairie TinyGPSPlus.h :

#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPSPlus (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin =2, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPSPlus object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPSPlus with an attached GPS module"));
  Serial.print(F("Testing TinyGPSPlus library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

Tu ne reçois aucun satellite. Le sixième champs de GGA indique le statut de la réception
Voir ici

Je suis assez surpris de la doc du BN-220 qui indique une acquisition en 26s lors d'un démarrage à froid. Il faut plutôt tabler sur quelques minutes.


Hors sujet mais tu as un "conteur" au tout début de ton premier post qui pique les yeux :grin:.

Ouups corrigé merci (fichu clavier...) :woozy_face:


D'accord merci, je vais refaire un essai dehors pendant 10min, si au delà de ce temps je ne capte toujours rien, je vais commencer à avoir des doutes sur mon module... Sinon c'est juste qu'un démarrage de ce truc est très lent :wink:

Merci pour votre aide :slight_smile:
Cordialement,
Pandaroux007

Normalement si tu captes, une led doit clignoter :wink:

Re :slight_smile: Je viens de faire le test dehors...

Alors tout d'abord, je retire ce que j'ai dit sur les trames reçues, le code de @philippe86220 en #8 fonctionne bien et le GPS, dès le démarrage me fournit bien l'heure et la date (correcte).

Cependant j'ai dû attendre plus de 7 minutes pour avoir une position qui ne soit pas "INVALID"... La datasheet se trompe sur le temps nécessaire ?

EDIT : la réception de la date et de l'heure, est quasi instantanée après le démarrage du module, en voici la trace série :

Trace moniteur série
Testing TinyGPSPlus library v. 1.1.0
by Mikal Hart

Location: INVALID  Date/Time: INVALID INVALID
Location: INVALID  Date/Time: INVALID INVALID
Location: INVALID  Date/Time: INVALID INVALID
Location: INVALID  Date/Time: INVALID INVALID
Location: INVALID  Date/Time: INVALID INVALID
Location: INVALID  Date/Time: 3/13/2025 18:33:34.00
Location: INVALID  Date/Time: 3/13/2025 18:33:34.00
Location: INVALID  Date/Time: 3/13/2025 18:33:34.00
Location: INVALID  Date/Time: 3/13/2025 18:33:34.00
Location: INVALID  Date/Time: 3/13/2025 18:33:34.00

Il faut que je teste le temps de démarrage maintenant que le module est "chaud" de ce que j'ai compris, ça devrait aller plus vite normalement :slight_smile: Dès que j'ai le temps je fais ça.


Le GPS, même s'il n'envoie pas de données valides, cause quand même sur la ligne série, donc la led TX du module clignote un peu tout le temps :wink:
Je ne crois pas avoir vu bouger la led PPS par contre...


Merci en tout cas à tous pour votre aide!
Amitiés,
Pandaroux007

Étonnant :wink:
Bon ça fonctionne et tant mieux
Bonnes bidouilles jeune homme :wink:

Des explications ci-dessous sur les causes du temps de démarrage.

Au fait tu avais toujours des trames de type inconnu car tu ne recevais pas de :

  • $GPGSA
  • $GPGGA
  • $GPRMC

Je t’ai donné ce programme juste pour afficher les messages. C’était bien approximatif quand même.
@fdufnews a été droit à la solution.
Je crois que je n’interviendrai plus maintenant pour aider les autres :wink:
Je ne suis pas assez doué pour ça.

Bonne soirée @pandaroux007

Si maintenant tu as l'heure, c'est que au moins un GPS a été trouvé non et que le module a envoyé une trame GNGGA?
Donc ton programme d'origine devrais te renvoyer la trace GPGGA avec des données de l'heure et GPGGA avec le nombre de satellite accroché ?

le programme #8, ne fait rien de différent que les deux autres programmes proposé avant ?

+1 et comme son module d'après ce que je comprends utilise :

  • GPS
  • Glonass

Il devrait voir toutes les trames GP et GN je pense :wink:

PS : il peut même installer Galileo et du coup il travaillera avec les satellites Américains, Russes et Européens ...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.