Comment Jongler entre des différentes communication UART

Salut tout le monde,

J'avance petit à petit sur mon compteur de piste pour ma moto et la je commence à jouer avec l'écran nextion. J'ai fais un petit truc simple avec l'écran pour comprendre le fonctionnement qui semblait simple en apparence mais qui me donne quelques difficultés.

L'idée, c'est qu'au démarrage de l'arduino et de l'écran, je fais un petit check des modules SD, DHT22 et GPS voir si tout est ok. J'ai une page sur le nextion "loading modules", c'est en rouge au départ et dès que les capteurs sont fonctionnelles, ça passe au vert sur l'écran nextion et c'est la que j'ai un problème :

  • Mon module SD passe au vert
  • Mon module DHT22 passe au vert
  • Mon module GPS reste au rouge car je n'arrive pas à jongler entre la communication UART de l'écran et du module GPS.

il y a t'il un moyen de :

  • Fermer la com avec l'écran
  • Ouvrir la com avec le GPS
  • Controler si GPS fonctionnel
  • Fermer la com avec le GPS
  • Ouvrir la com avec l'écran

voila le test que j'ai effectué qui est non concluant :

void initializeGPS() {

  gps.begin(9600);  // Sets up the GPS module to communicate with the Arduino over serial at 9600 baud
  gps.setUBXNav();  // Enable the UBX navigation messages to be sent from the GPS module
  statutGPS=true;

  if (statutGPS==true) {

    Serial1.end();
    delay(2000);
    myNex.begin(9600); // Liaison série avec l'écran Nextion définit à 9600 Bauds de vitesse.
    delay(2000);
    myNex.writeNum("CheckGPS.bco",7811); // Set button b0 background color to GREEN (color code: 2016)

  }

  else {

    myNex.writeNum("CheckGPS.bco",63651);

  }

}

Merci à ceux qui pourront m'aider :slight_smile:

c'est quoi déjà votre arduino ?

il faut un port matériel pour le GPS et un port matériel pour l'écran nextion.
SoftwareSerial ce n'est pas super robuste et ça se passe mal si vous avez les 2 liaisons capables d'envoyer des données en même temps.

je suis sur un arduino mega officiel avec un méga shield V2.0 posé dessus. LE GPS est sur TX1 et RX1 et l'écran sur TX0 et RX0

OK donc c'est bon pour la parie matérielle

postez tout le code, on ne sait pas comment est défini gps par exemple. d'autre part vous ne saurez que le GPS fonctionne que quand vous aurez reçu une position cohérente, donc ce ne sera pas au boot si vous ne voulez pas attendre

Le GPS Fonctionne très bien c'est plus un test au démarrage voir si il est bien connecté.

// INCLUSION DES BIBLIOTHEQUES ARDUINO POUR L'UTILISATION DES MODULES.

#include "EasyNextionLibrary.h" // Importation de la bibliothèque Nextion pour communiquer avec l'écran Nextion.
#include <SPI.h>             // Importation de la bibliothèque SPI pour traitement des données avec SDA et SCL.
#include <DHT.h>             // Importation de la bibliothèque DHT pour utilisation du capteur température/humidité DHT22.
#include <Wire.h>            // Importation de la bibliothèque Wire pour utilisation du protocole de liaison I2C.
#include <SD.h>              // Importation de la bibliothèque SD pour utilisation du module de carte micro SD (Penser à formater la carte micro SD en FAT32 avant utilisation).
#include <VMA430_GPS.h>      // Importation de la bibliothèque VMA430 pour l'utilisation du module GPS Neo 7M.
#include <SoftwareSerial.h>  // Importation de la bibliothèque Software Serial pour la gestion des ports série numériques.
#include <math.h>            // Importation de la bibliothèque math pour la réalisation de calcul comme pour la sonde de LDR.

// DÉFINITION DES CONSTANTES (VARIABLES QUI NE CHANGENT JAMAIS DE VALEUR).

const int brocheDeBranchementDHT=30;  // Le bus de communication du DHT22 sera branché sur la pin D30 de l'Arduino Méga 2560.
const int typeDeDHT=DHT22;            // Ici, le type de DHT utilisé est un DHT22.

const int boutonStart=24;             // PIN Digital où est relié le bouton START du chronomètre, à modifier sur la méga shield si besoin.
const int boutonStop=25;              // PIN Digital où est relié le bouton STOP du chronomètre, à modifier sur la méga shield si besoin.

const int sdCardPinChipSelect=53;   // Le lecteur de carte SD sera branché sur la pin 53 pour le CS (chip select), Bus SPI.

const float U=4.67; // U pour la tension sert au calcul de la température de liquide refroidissement.
const float I=0.00118; // I pour l'ampérage sert au calcul de la température de liquide refroidissement.

// LES CONSTANTES a b c SERVENT AU CALCUL DE LA TEMPÉRATURE DE LIQUIDE DE REFROIDISSEMENT VIA L'ÉQUATION DE STEIN HART.

const float a=0.0008694018333616047;
const float b=0.0003560428160151669;
const float c=-4.767988927196682e-7;

// DÉFINITION DES VARIABLES.

// VARIABLES POUR LA PARTIE CIRCUIT ET SESSION :

bool statutCircuit=false; // Booléen qui passe à TRUE lorsque le circuit a été choisi et ca permet de passer à la séléction de la session.
bool statutSession=false; // Booléen qui passe à TRUE lorsque la session a été choisie et ca permet par la suite de déclencher le chrono.
bool sdFile = false; // Booléen qui passe à TRUE lorsque les premières données ont été enregistrées sur la carte SD.
float longueurCircuit; // Variable qui va contenir la longueur du circuit choisi.
float LatLigneFinInit; // Variable qui va contenir la latitude de la ligne d'arrivée du circuit choisi.
float LongLigneFinInit; // Variable qui va contenir la longitude de la ligne d'arrivée du circuit choisi.
float LatMiniDeclenchementChrono;
float LatMaxiDeclenchementChrono;
float LongMiniDeclenchementChrono;
float LongMaxiDeclenchementChrono;
String selectCircuit; // Variable qui va contenir le nom du circuit choisi pour créer le fichier dans la carte SD.
String excelName;
int selectSession; // Variable qui va contenir la session choisie pour positioner dans le fichier excel au bon endroit.
long tpsMiniCircuit; // Variable qui va contenir le temps minimum obligatoire sur le circuit choisi pour éviter les rebonds du chrono au déclenchement du GPS.

// VARIABLES POUR LA PARTIE CHRONOMETRE :

int boutonStateStart=LOW; // Initialisation du bouton start à LOW.
int boutonStateStop=LOW;  // Initialisation du bouton stop à LOW.
bool chronoStatus=LOW;        // Pour mémoriser si on est en On ou Off.
bool startChrono;         // Permet de commencer le chronomètre.
bool stopChrono;          // Permet de stopper le chrono et afficher les temps.
unsigned long MS;         // Permet de stocker les MS sur 4 bytes soit de 0 à 4,294,967,295.
long bestLap = 300000;     // On définit le best lap à 300000ms comme ça dès le premier tour, celui-ci s'affiche comme meilleur temps actuel dans tous les cas.
unsigned long start;      // Même chose que pour le unsigned long MS ci-dessus.
int lap=0;                // Compteur de tour qu'on initialise à 0.
int x;                    // x est le retour de la fonction pour obtenir le temps minimum par tour.
long tpsMini;              // Permet d'indiquer à la fonction le temps mini du circuit sélectionné.
int minutes;              // Permettra d'indiquer les MS en minutes.
int secondes;             // Permettra d'indiquer les MS en secondes.
int milliemes;            // Permettra d'indiquer les MS en millièmes.

// DÉFINITION DU TABLEAU DES TEMPS. MAXIMUM 20 TOURS MAIS POSSIBILITÉ DE LE FAIRE PLUS GRAND :

int chronoSession[20] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

// DÉFINITION DES VARIABLES DES CAPTEURS

int capteurPM=0;
bool temoinPM=true;
int capteurReserve=0;
bool temoinReserve=false;

// DÉFINITION DES VARIABLES DE LA SONDE DE LDR

int rValue;
float tension=0;
float R=0;

// STATUTS DES INITIALISATIONS DES DIFFÉRENTS MODULES :

bool statutSD=false;
bool statutDHT22=false;
bool statutGPS=false;

// INITIALISATION DU MODULE DHT22 :

DHT dht(brocheDeBranchementDHT, typeDeDHT);  // On définit les pins utilisées par le module DHT ainsi que son type -> DHT22.
float tauxHumidite;
float temperature;

// INITIALISATION DU MODULE GPS

VMA430_GPS gps(&Serial1);  // Serial1 correspond aux broches TX1 et RX1 du méga shield arduino V2.0

// VARIABLES POUR MODULE GPS VMA430 NEO 7M

float latitude=0;
float longitude=0;

// CRÉATION OBJET myNex POUR ÉCRAN NEXTION

EasyNex myNex(Serial); // Create an object of EasyNex class with the name < myNex >

// ================================================================
// ===                   DÉBUT VOID SETUP                       ===
// ================================================================

void setup() {  // Début Void Setup

  // PARTIE QUI CONCERNE LA LIAISON SÉRIE.

  Serial.begin(9600);  // Liaison série définit à 9600 Bauds de vitesse.
  myNex.begin(9600); // Liaison série avec l'écran Nextion définit à 9600 Bauds de vitesse.

  delay(7000); // Petit delay avant d'arriver sur la page de chargement des modules sur l'écran Nextion.

  // DÉCLARATION DES PINS POUR BOUTON START ET STOP DU CHRONOMETRE.

  pinMode(boutonStart, INPUT_PULLUP);  // Résistance interne contre VCC. De ce fait, le bouton doit donner un GND
  pinMode(boutonStop, INPUT_PULLUP);   // Résistance interne contre VCC. De ce fait, le bouton doit donner un GND
  pinMode(A0, INPUT); // Brancher le fil bleu ciel/blanc de la cosse du compteur sur la broche A0 de l'arduino méga 2560 pour le contrôle du capteur de point mort
  pinMode(A1, INPUT); // Brancher le fil vert/blanc de la cosse du compteur sur la broche A1 de l'arduino méga 2560 pour le contrôle du capteur de réserve
  pinMode(A2, INPUT); // Sonde de LDR

  /*myNex.writeNum("CheckSD.bco", 7811);
  delay(500);
  myNex.writeNum("CheckDHT22.bco", 7811);
  delay(500);
  myNex.writeNum("CheckGPS.bco", 7811);

  myNex.writeNum("CheckSD.bco", 7811);
  delay(500);
  myNex.writeNum("CheckDHT22.bco", 7811);
  delay(500);
  myNex.writeNum("CheckGPS.bco", 7811);*/

  // OUVERTURE DES DIFFÉRENTS BUS DE COMMUNICATION.

  SPI.begin();      // Ouverture de la communication SPI.
  Wire.begin();     // Ouverture de la communication I2C.
  dht.begin();      // Initialisation du module DHT22

  // TEST DES DIFFÉRENTS MODULES AVEC MISE A JOUR DES STATUTS D'INITIALISATION

  /*initializeSD();
  initializeDHT22();
  initializeGPS();*/
  initializeSD();
  delay(1000);
  initializeDHT22();
  delay(1000);
  initializeGPS();

  if (statutSD==true && statutDHT22==true && statutGPS==true) {

  Serial.println();
  Serial.println("Choisissez votre circuit :"); // Faire que le nextion arrive sur la page d'accueil dès que tout est OK.

  }

}  // Fin Void Setup

// ================================================================
// ===                   DÉBUT VOID LOOP                        ===
// ================================================================

void loop() {  // Début Void Loop

static unsigned long controleCapteurspreviousMillis=0;  // Stocke le dernier temps d'exécution
  const long controleCapteursinterval=1017;  // Intervalle d'exécution en millisecondes (0.1 seconde)

  // Obtenez le temps actuel
  unsigned long controleCapteurscurrentMillis = millis();

  // Vérifiez si une seconde s'est écoulée

  if (controleCapteurscurrentMillis - controleCapteurspreviousMillis >= controleCapteursinterval) {

    // Sauvegardez le temps actuel

    controleCapteurspreviousMillis=controleCapteurscurrentMillis;

    controleCapteurs();
    
    }

  if (statutCircuit==false && statutSession==false) {

    //getCircuit();
    myNex.NextionListen();

  }

  else if (statutCircuit==true && statutSession==false) {

    //getSession();
    myNex.NextionListen();

  }

  else { // Si statutCircuit et statutSession valent TRUE alors on rentre obligatoirement dans cette boucle où on peut initialiser le fichier excel avec les données de base

    if (statutCircuit==true && statutSession==true && sdFile==false) {

    // Définir le nom du fichier excel (nomducircuit-J-M-A).
    // Update du fichier excel avec les données nécessaires.
    // Création du fichier si il n'existe pas avec la date et le circuit à rentrer dans le fichier excel et le fichier excel aura ce nom.
    // Penser à utiliser la variable de session pour mettre à jour la bonne colonne dans le tableau excel. Il faudra faire un switch case pour que les données aillent dans la bonne colonne du fichier excel.

    if (gps.getUBX_packet() && gps.parse_ubx_data()) { // Si on reçoit bien des données du GPS alors on récupère les infos des diiférents modules pour enregistrement sur carte SD.
   
    int day = gps.utc_time.day; // Récupération du jour
    int month = gps.utc_time.month; // Récupération du mois
    int year = gps.utc_time.year; // Récupération du mois

    float tauxHumidite = dht.readHumidity();        // Lecture du taux d'humidité, exprimé en %
    float temperature = dht.readTemperature();      // Lecture de la température ambiante, exprimée en degrés celsius

    String nomDuFichier=selectCircuit+day+"-"+month+".txt";  // Le nom du fichier est composé des initiales du circuit + le jour + le mois + l'extension .txt

    File monFichier;

    // Mise en forme de ces données (un seul chiffre après la virgule)

    String tauxHumiditeArrondi = String(tauxHumidite, 1);  // Affichage d'une seule décimale (car précision de 0,1 % ici)
    String temperatureArrondie = String(temperature, 1);   // Affichage d'une seule décimale (car précision de 0,1 °C ici)
    tauxHumiditeArrondi.replace(".", ",");                 // et on remplace les séparateurs de décimale, initialement en "." pour devenir ","
    temperatureArrondie.replace(".", ",");                 // (permet par exemple d'afficher 12,76 au lieu de 12.76 (ce qui facilite l'interprétation dans Excel ou tout autre tableur)

    monFichier = SD.open(nomDuFichier, FILE_WRITE);

    if (monFichier) {

      monFichier.println("Circuit : "+excelName+" le "+day+"/"+month+"/"+year);  // Le circuit sur lequel on roule. On passe ensuite à la ligne en dessous

      monFichier.print("Taux d'humidite : ");
      monFichier.print(tauxHumiditeArrondi);
      monFichier.println("%");

      monFichier.print("Temperature : ");
      monFichier.print(temperatureArrondie);
      monFichier.println("Degres");

      monFichier.close();  // L'enregistrement des données se fait au moment de la clôture du fichier

      // Rajouter un if qui dit que si l'enregistrement en carte SD s'est bien déroulé alors sdFile=TRUE

      sdFile = true;  // On veut faire l'update qu'une fois donc on passe à TRUE la variable pour ne pas update à chaque boucle le fichier excel

    }

    else {

      // Mettre un message sur le nextion qui dit que l'initialisation du fichier de data a échoué.

    }

    } 
    
  }

}

  

  while (statutCircuit==true && statutSession==true && sdFile==true) {  // Mettre dans cette boucle tout ce que je veux traiter à chaque tour de boucle et notamment toutes les données à enregistrer en carte SD.

  gestionChrono();

  static unsigned long previousMillis=0;  // Stocke le dernier temps d'exécution
  const long interval=1000;  // Intervalle d'exécution en millisecondes (0.1 seconde)

  // Obtenez le temps actuel
  unsigned long currentMillis = millis();

  // Vérifiez si une seconde s'est écoulée

  if (currentMillis - previousMillis >= interval) {

    // Sauvegardez le temps actuel

    previousMillis=currentMillis;

    myFunction();
    
    }

  }

}  // Fin Void Loop

// ================================================================
// ===                  DÉBUT SECTION FONCTION                  ===
// ================================================================

void initializeSD() {

  /*Serial.println();
  Serial.println();
  Serial.println(F("Initialisation de la carte SD..."));*/

  if (!SD.begin(sdCardPinChipSelect)) {

    /*Serial.println();
    Serial.println();
    Serial.println(F("Échec de l'initialisation du lecteur de SD card. Vérifiez :"));
    Serial.println(F("1. que la carte SD soit bien insérée"));
    Serial.println(F("2. que votre câblage soit bon"));
    Serial.println(F("3. que la variable 'sdCardPinChipSelect' corresponde bien au branchement de la pin CS de votre carte SD sur l'Arduino"));
    Serial.println(F("Et appuyez sur le bouton RESET de votre Arduino une fois le pb résolu, pour redémarrer ce programme !"));*/
    statutSD=false;
    return;

    while (true);

  }

    statutSD=true;

      if (statutSD==true) {

        myNex.writeNum("CheckSD.bco",7811); // Set button b0 background color to GREEN (color code: 2016)

      }

      else {

        myNex.writeNum("CheckSD.bco",31);

      }

}

void initializeDHT22() {

  // Lecture des données

  float tauxHumidite=dht.readHumidity();    // Lecture du taux d'humidité, exprimé en %
  float temperature=dht.readTemperature();  // Lecture de la température ambiante, exprimée en degrés celsius

  // Vérification si données bien reçues

  if (isnan(tauxHumidite) || isnan(temperature)) {

    //Serial.println(F("Aucune valeur retournée par le DHT22. Est-il bien branché ?"));
    statutDHT22=false;
    return;  // Si aucune valeur n'a été reçue par l'Arduino, on attend 2 secondes.

  }

  else {

    statutDHT22=true;
    /*Serial.println();
    Serial.println();
    Serial.println("Initialisation du module DHT22 réussi !");
    Serial.println();
    Serial.println();*/

  }

  if (statutDHT22==true) {

    myNex.writeNum("CheckDHT22.bco",7811); // Set button b0 background color to GREEN (color code: 2016)

  }

  else {

    myNex.writeNum("CheckDHT22.bco",63651);

  }

}

void initializeGPS() {

  gps.begin(9600);  // Sets up the GPS module to communicate with the Arduino over serial at 9600 baud
  gps.setUBXNav();  // Enable the UBX navigation messages to be sent from the GPS module
  statutGPS=true;

  if (statutGPS==true) {

    Serial1.end();
    delay(2000);
    myNex.begin(9600); // Liaison série avec l'écran Nextion définit à 9600 Bauds de vitesse.
    delay(2000);
    myNex.writeNum("CheckGPS.bco",7811); // Set button b0 background color to GREEN (color code: 2016)

  }

  else {

    myNex.writeNum("CheckGPS.bco",63651);

  }

}

void controleCapteurs() {

  controlePM();
  controleReserve();
  controleLDR();

}

void controlePM() {

  capteurPM = analogRead(A0); // Lecture de l'entrée sur la PIN A0
  float tension=capteurPM*5/1024; // Conversion des octets reçus en tension sur 5V

  if (tension<=1.90) { // Si la tension est inférieur ou égale à 1.90V alors on est au point mort

    temoinPM=true;
    // Allumer le témoin de point mort sur l'écran nextion

  }

  if (tension>=1.91) { // Si la tension est supérieur ou égale à 1.91V alors on a une vitesse enclenché

    temoinPM=false;
    // Éteindre le témoin de point mort sur l'écran nextion

  }

}

void rpm() {




}

void vitesse() {




}

void controleReserve() {

  capteurReserve = analogRead(A1); // Lecture de l'entrée sur la PIN A1
  float tension=capteurReserve*5/1024; // Conversion des octets reçus en tension sur 5V

  if (tension<=1.00) { // Si la tension est inférieur ou égale à 1.00V alors on est pas dans la réserve

    temoinReserve=false;
    // Éteindre le témoin de réserve sur l'écran nextion

  }

  if (tension==2.00) { // Si la tension est égale à 2.00V alors on est dans la réserve

    temoinReserve=true;
    // Allumer le témoin de réserve sur l'écran nextion

  }

}

int controleLDR() {

  rValue=analogRead(A0);
  tension=rValue*U/1024; // Calcul pour obtenir la valeur en volts d'une résistance
  //Serial.print(rValue);Serial.println(" Octets");
  //Serial.print(tension);Serial.println(" Volts");
  R=(tension-0.38)/I;
  //Serial.print(R);Serial.println(" Ohms");
  
  float logR=log(R); 
  
  float temperature=(1/(a+b*logR+c*logR*logR*logR)-273.15)/1.065;
  //temperature=temperature/1.065;

  return temperature;

}

void gestionChrono() {

  lectureBoutons();

    if (boutonStateStart==HIGH && boutonStateStop==LOW) {  // Si bouton start appuyé et bouton stop relaché  

      appuiStart();

      if (MS>tpsMiniCircuit) {

        lap = lap + 1;                      // Compteur de tour qui s'incrémentera dès que le gps passera par la ligne d'arrivée et que le temps au tour est supérieur au temps minimum définit. Ca évite de passer au tour suivant à cause d'un rebond du GPS notamment.
        chronoSession[lap - 1] = MS;

        if (MS < bestLap) {

          bestLap = MS;

        }

      }

    }

    if (startChrono==true && stopChrono==false && chronoStatus==true) {

      startSession();

    }

    if (boutonStateStop == HIGH && boutonStateStart == LOW) {

      appuiStop();

    }

    if (startChrono==false && stopChrono==true) {

      endSession();

    }

    if (boutonStateStart == HIGH && boutonStateStop == HIGH) { // On repasse le circuit et la session à false et ça va nous redemander de nouveau le circuit et la session. Sur le nextion, renvoyer à la page d'accueil.

      statutCircuit=false;
      statutSession=false;
      sdFile=false;

    }
    
}

void myFunction() { // Fonction qui s'éxécutera toutes les secondes pour l'enregistrement en carte SD des coordonées GPS, le déclenchement via GPS du tour suivant etc...
  
  

}

float get_latitude() {

  float latitude = gps.location.latitude;
  return latitude;
}

float get_longitude() {

  float longitude = gps.location.longitude;
  return longitude;
}

int get_heures() {

  // Récupérer grâce à la variable du GPS les heures
  
  int heures = gps.utc_time.hour;  // H=date_time du GPS (heures)
  return heures;
}

int get_minutes() {

  // Récupérer grâce à la variable du GPS les minutes
  int minutes = gps.utc_time.minute;  // M=date_time du GPS (minutes)
  return minutes;
}

void trigger1() {

  if (Serial.available() > 0) {

    int circuit = Serial.read();

    switch (circuit) {

      case 'a':

        Serial.println("Vous avez choisi le circuit du Vigeant. Longueur : 3.768kms");
        selectCircuit = "LV-";
        excelName="Le Vigeant";
        statutCircuit = true;
        longueurCircuit = 3.768;
        LatLigneFinInit = 46.19720690;
        LongLigneFinInit = 0.63580155;
        LatMiniDeclenchementChrono = 46.19695720;
        LatMaxiDeclenchementChrono = 46.19745660;
        LongMiniDeclenchementChrono = 0.63578009;
        LongMaxiDeclenchementChrono = 0.63582301;
        tpsMiniCircuit = 90000;

        break;

      case 'b':

        Serial.println("Vous avez choisi le circuit de Fontenay. Longueur : 2.400kms");
        selectCircuit = "FC-";
        excelName="Fontenay Le Comte";
        statutCircuit = true;
        longueurCircuit = 2.400;
        LatLigneFinInit = 46.43826724;
        LongLigneFinInit = -0.79176127;
        tpsMiniCircuit = 70000;

        break;

      case 'c':

        Serial.println("Vous avez choisi le circuit de Saintonge. Longueur : 2.200kms");
        selectCircuit = "HS-";
        excelName="Haut De Saintonge";
        statutCircuit = true;
        longueurCircuit = 2.200;
        LatLigneFinInit = 46.43826724;
        LongLigneFinInit = -0.79176127;
        tpsMiniCircuit = 60000;

        break;

      case 'd':

        Serial.println("Vous avez choisi le circuit de Dijon Prenois. Longueur : 3.800kms");
        selectCircuit = "DP-";
        excelName="Dijon Prenois";
        statutCircuit = true;
        longueurCircuit = 3.800;
        LatLigneFinInit = 46.43826724;
        LongLigneFinInit = -0.79176127;
        tpsMiniCircuit = 80000;

        break;

      case 'e':

        Serial.println("Vous avez choisi le circuit de Pau Arnos. Longueur : 3.030kms");
        selectCircuit = "PA-";
        excelName="Pau Arnos";
        statutCircuit = true;
        longueurCircuit = 3.030;
        LatLigneFinInit = 46.43826724;
        LongLigneFinInit = -0.79176127;
        tpsMiniCircuit = 70000;

        break;

      case 'f':

        Serial.println("Vous avez choisi le circuit de Nogaro. Longueur : 3.640kms");
        selectCircuit = "N-";
        excelName="Nogaro";
        statutCircuit = true;
        longueurCircuit = 3.640;
        LatLigneFinInit = 46.43826724;
        LongLigneFinInit = -0.79176127;
        tpsMiniCircuit = 60000;

        break;

      case 'g':

        Serial.println("Vous avez choisi le circuit de Test. Longueur : X kms");
        selectCircuit = "TT-";
        excelName="Test";
        statutCircuit = true;
        longueurCircuit = 4.53;
        LatLigneFinInit = 45.72760705;
        LongLigneFinInit = 0.38614690;
        tpsMiniCircuit = 1000;

        break;

      default:

        Serial.println("Choisissez votre circuit");

    }
  }
}

void trigger2() {

  if (Serial.available() > 0) {

    int sessionByte = Serial.read();

    switch (sessionByte) {

      case '1':

        Serial.println("Session 1");
        selectSession = 1;
        statutSession = true;

        break;

      case '2':

        Serial.println("Session 2");
        selectSession = 2;
        statutSession = true;

        break;


      case '3':

        Serial.println("Session 3");
        selectSession = 3;
        statutSession = true;

        break;

      case '4':

        Serial.println("Session 4");
        selectSession = 4;
        statutSession = true;

        break;

      case '5':

        Serial.println("Session 5");
        selectSession = 5;
        statutSession = true;

        break;

      case '6':

        Serial.println("Session 6");
        selectSession = 6;
        statutSession = true;

        break;

      case '7':

        Serial.println("Session 7");
        selectSession = 7;
        statutSession = true;

        break;

      case '8':

        Serial.println("Session 8");
        selectSession = 8;
        statutSession = true;

        break;

      default:

        Serial.println("Choisissez votre session");
    }
  }
}

void lectureBoutons() {

  boutonStateStart = digitalRead(boutonStart);
  boutonStateStop = digitalRead(boutonStop);
  delay(100);  // Pour couvrir les rebonds
}


void appuiStart() {

  start=millis();    // On commence le chrono mais sans l'afficher
  startChrono=true;  // On passe la variable à true pour que la loop continu le chrono meme quand on relache le bouton
  stopChrono=false;  // On passe la variable à false car on veut que le chrono tourne
  chronoStatus=true;
}

void startSession() {  // Appeler cette fonction à chaque passage de la ligne d'arrivé après avoir enregistrer le temps au tour  

  MS = millis() - start;

  // Ci dessous, affichage des minutes / secondes / millièmes. A envoyer vers le nextion

  myNex.writeNum("LapChrono.val", MS);
  Serial.print((MS / 1000) / 60);  // minutes
  Serial.print("'");
  Serial.print((MS / 1000) % 60);  // secondes
  Serial.print("''");
  Serial.println(MS % 1000);  // millièmes

}

void appuiStop() {

  start = ' ';
  startChrono=false;
  stopChrono=true;
  chronoStatus=false;

  // Une fois le bouton stop appuyé, envoyer sur une page du nextion pour lire les data de la session.
}

void endSession() {

  startChrono = ' ';
  stopChrono = ' ';
  start=0;

  minutes = (MS / 1000) / 60;
  secondes = (MS / 1000) % 60;
  milliemes = MS % 1000;

  //Si lap11==0, on affiche les tours de 0 à 9 et si lap11!=0 alors on affiche les tours de 10 à 19

  if (chronoSession[10] == 0) {

    Serial.print("Lap 1 : ");
    Serial.println(chronoSession[0]);
    Serial.print("Lap 2 : ");
    Serial.println(chronoSession[1]);
    Serial.print("Lap 3 : ");
    Serial.println(chronoSession[2]);
    Serial.print("Lap 4 : ");
    Serial.println(chronoSession[3]);
    Serial.print("Lap 5 : ");
    Serial.println(chronoSession[4]);
    Serial.print("Lap 6 : ");
    Serial.println(chronoSession[5]);
    Serial.print("Lap 7 : ");
    Serial.println(chronoSession[6]);
    Serial.print("Lap 8 : ");
    Serial.println(chronoSession[7]);
    Serial.print("Lap 9 : ");
    Serial.println(chronoSession[8]);
    Serial.print("Lap 10 : ");
    Serial.println(chronoSession[9]);

  }

  else {

    Serial.print("Lap 11 : ");
    Serial.println(chronoSession[10]);
    Serial.print("Lap 12 : ");
    Serial.println(chronoSession[11]);
    Serial.print("Lap 13 : ");
    Serial.println(chronoSession[12]);
    Serial.print("Lap 14 : ");
    Serial.println(chronoSession[13]);
    Serial.print("Lap 15 : ");
    Serial.println(chronoSession[14]);
    Serial.print("Lap 16 : ");
    Serial.println(chronoSession[15]);
    Serial.print("Lap 17 : ");
    Serial.println(chronoSession[16]);
    Serial.print("Lap 18 : ");
    Serial.println(chronoSession[17]);
    Serial.print("Lap 19 : ");
    Serial.println(chronoSession[18]);
    Serial.print("Lap 20 : ");
    Serial.println(chronoSession[19]);
  }

}

/*void trigger1(){
   Create a button on Nextion
   * Write in the Touch Release Event of the button
   * this command:    printh 23 02 54 01
   * Every time the button is pressed, the trigger1() function will run
   * and the code inside will be executed once
   
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // If LED_BUILTIN is ON, turn it OFF, or the opposite
  if(digitalRead(LED_BUILTIN) == HIGH){
    myNex.writeNum("b0.bco", 2016); // Set button b0 background color to GREEN (color code: 2016)
    myNex.writeStr("b0.txt", "ON"); // Set button b0 text to "ON"
    
  }else if(digitalRead(LED_BUILTIN) == LOW){
    myNex.writeNum("b0.bco", 63488); // Set button b0 background color to RED (color code: 63488)
    myNex.writeStr("b0.txt", "OFF"); // Set button b0 text to "ON"
  }
}
*/

il n'y a pas moyen de savoir si sur une ligne série quelque chose est connecté de l'autre côté avant que ce machin ne se mette à parler :slight_smile:

je ne connais pas la classe VMA430_GPS (souvent ici c'est TinyGPS+ qui est utilisé), il faudrait voir s'il y a une fonction capable d'aller lire la config du GPS par exemple ➜ on l'interroge, si on a une réponse cohérente alors c'est qu'il est bien là

Il est là le problème, c'est que je ne pipe pas grand chose à ce module GPS et sa librairie, j'ai pu récupérer la date et la position GPS et c'est déjà pas mal, il y a très peu de docs sur ce module donc je ne sais pas si il existe une fonction pour lire la config du GPS. Truc bête par exemple, je n'arrive pas à récupérer ma vitesse avec ce GPS mais bon c'est pas nécessaire sur piste donc je m'en passerais.

il faut faire un code asynchrone, vous ne restez pas coincé en attente du GPS, quand vous récupérez la première trame, vous activez l'indicateur. Si vous ne recevez pas de trame pendant 5s, vous désactivez l'indicateur

TinyGPS+ le fait, si votre modèle envoie les trames normalisées habituelles sur port série, vous pourriez passer sur TinyGPS.

j'avais essayer tinyGPS et je n'arrivais à le faire fonctionner mais peut être qu'avec les quelques connaissances que j'ai acquis ces derniers temps, je pourrais y arriver mais pour l'instant je suis sur l'écran nextion et le jonglage entre les com UART donc j'aurais besoin sur piste pour jongler entre le GPS et l'écran

je ne comprends pas quel "jonglage" vous souhaitez faire (je n'utilise pas les nextions)

On ne ferme jamais la communication avec l'écran, il est juste là et vous utilisez Serial1 pour le GPS (ou votre variable gps plutôt) et Serial pour l'écran (ou la variable myNex plutôt) puisque ce sont les ports sur lesquels ils sont branchés

ma recommandation serait de ne pas utiliser Serial pour l'écran mais de prendre Serial2 ou Serial3, ce qui vous permettrait de conserver Serial pour le debug et le chargement du code sur la MEGA.

Ce que j'ai remarqué hier en faisant mes test au démarrage de l'écran, c'est que si je force le passage au vert sur l'écran dans le setup, ça marche niquel mais dès que je fais un appel au GPS puis à l'écran, il y a un conflit tout comme avec le moniteur série d'ailleurs, je n'arrive pas utiliser les 2 UART TX1 et TX0 en même temps

Bonjour vincent_16

Tu pourrais le faire, "en même temps" en passant pas serialEvent qui travail en mode interruption. Ainsi, la réception se fait "en tâche de fond", pas besoin d'appeler la fonction, il te suffit de positionner un flag lorsque un serial a reçu une chaine complète.

Cordialement
jpbbricole

C'est un peu du chinois pour moi tout ça :sweat_smile:

je peux faire un truc dans le genre ?

void serialEvent() {

  while (Serial.available()) {

    // Ici je peux lancer une fonction par exemple en fonction de ce que je reçois de l'écran ?

  }

while (Serial1.available()) {

    // En mettant Serial1, ça communiquerais avec mon GPS quand j'en ai besoin ?

  }

}
  1. Serial.event() n'est pas portable. Ce n'est pas supporté sur les nouvelles plateformes, ce qui peut rendre un code caduc si, plus tard, on veut évoluer vers un processeur plus puissant.
  2. Serial.event() ne fait qu'un if (Serial.available()) pour appeler une fonction utilisateur. Alors autant le faire sois-même dans loop()

La librairie VM430_GPS force l'usage de softwareSerial lorsqu'on développe pour les familles __AVR__ sans distinction de type de CPU.
Le module GPS en question utilise un module u-blox NEO-7 qui est supporté par tiny-GPS.

Le GPS peut prendre à certain temps pour démarrer donc peut-être que le test dans le setup() arrive un peu trop tot pour qu'il soit en état de répondre.

L'idée dans le setup, c'est juste de voir si il reçoit bien les infos notamment avec une ligne qui mets ACK received. Dés que j'ai cette ligne j'aimerais bien dire à mon écran : "C'est OK passe au vert" mais comme je communique avec le GPS, je n'arrive pas dans la foulée à envoyer la commande au nextion même en mettant un petit delay avant d'envoyer au nextion la commande

C'est vraiment cette partie la qui me pose problème

void initializeGPS() { // Fonction que j'appel depuis mon setup

  gps.begin(9600);  // Sets up the GPS module to communicate with the Arduino over serial at 9600 baud // Connection au GPS
  gps.setUBXNav();  // Enable the UBX navigation messages to be sent from the GPS module
  statutGPS=true; la j'ai simplifié pour juste dire c'est ok passe au vert

  if (statutGPS==true) {

    Serial1.end(); // Je ferme la com avec le GPS
    delay(2000);
    myNex.begin(9600); // J'ouvre la liaison série avec l'écran Nextion
    delay(2000);
    myNex.writeNum("CheckGPS.bco",7811); // Set button b0 background color to GREEN (color code: 2016) // Je dis à une checkbox de l'écran nextion de passer au vert

  }

  else {

    myNex.writeNum("CheckGPS.bco",63651); // Sinon la check box reste au rouge

  }

}

Il n'y a aucune raison de couper la communication avec le GPS cela n'apporte rien. Les 2 périphériques n'utilisent pas la même liaison matérielle, elles peuvent rester à l'écoute en permanence et cela évite de perdre des messages.

Mais quand je laisse les deux à l'écoute, la commande que j'envoie au nextion ne s'exécute pas alors que pour le module SD et le DHT22, l'envoie de cette même commande fonctionne parfaitement, c'est comme si j'avais un conflit entre l'écran et le GPS et que la commande que j'envoie au nextion est enfaite envoyer au module GPS

est ce que le fait d'avoir #include <SoftwareSerial.h> au début du code peut mettre la pagaille ?

Déjà, ce n'est pas une bonne idée d'utiliser Serial pour le Nextion car cela entre en conflit lors des téléchargement et cela t'empêche d'utiliser Serial pour envoyer des messages pour le debug.

La librairie VMA340_GPS est codée avec les pieds.

  • Elle force l'usage de SoftwareSerial si on développe pour la famille AVR le constructeur est modifié. Je ne crois pas que cela est une réelle influence (à confirmer) car les 2 librairies héritent de Stream
 #ifdef __AVR__
  VMA430_GPS(SoftwareSerial *);
#endif
  VMA430_GPS(HardwareSerial *);
  • Elle écrit des messages sur Serial même lorsque GPS_DEBUG est inactif. Ça c'est un problème car cela parasite la liaison vers le Nextion c'est une bonne raison pour passer le Nextion sur Serial2 ou 3.

Je ne le pense pas.