Enregistrement sur SD qui s'arrête

Enregistrement sur SD qui s'arrête - C++ - Programmation

Marsh Posté le 31-08-2021 à 08:59:59    

Bonjour,
Sur une base Méga 2560, et uniquement en Grove, nous avons fait une station météo.
Il y a un anémomètre, girouette, anémomètre, pression et température, humidité et température. A cela a été ajouté une horloge et un enregistrement sur carte SD.
Les mesures s'effectuent toutes les 30 secondes et suivant les capteurs, la moyenne, le cumul, le maxi, etc est enregistré sur SD tous les quarts d'heure (ce qui représente 13 colonnes exploitables sous Excell)
Tout fonctionne très bien, sauf que, environ une heure après le début des enregistrements, cela s'arrête sans raison apparente. A l'écran, les mesures continuent normalement, c'est juste l'enregistrement sur SD qui présente un problème.
 
Cette station météo étant destinée à être mis en place dans un lieu difficile d'accès et sans réseau, elle sera alimentée par panneau solaire.
 
Merci à vous de nous proposer des idées de solutions.
Bonne journée.

Reply

Marsh Posté le 31-08-2021 à 08:59:59   

Reply

Marsh Posté le 31-08-2021 à 11:08:41    

Sans absolument aucun code ou autre information, ça vas être difficile d'aider, aucune log d'erreur, avez vous cherché au niveau d'un éventuelle fuite de mémoire qui rendrait l'écriture impossible ?
Je ne suis absolument pas spécialiste du domaine mais je suis presque sur que le manque d'info va rendre l'aide à partir d'un forum difficile...


---------------
D3
Reply

Marsh Posté le 31-08-2021 à 17:28:10    

+1 pour mechkurt. C'est un projet scolaire ou universitaire (quoique à cette période de l'année?)? Débugger est une compétence essentielle en programmation! Vu que c'est juste l'enregistrement qui déconne je regarderais de près le code qui s'en occupe (les différentes couches driver SPI - filesystem - ...) et je rajouterais des tests et des printf pour voir. Laisser tourner le truc pendant une heure branché sur un PC ne devrait pas trop poser de problèmes, 1h c'est pas énorme. Ensuite, une fois le problème plus isolé, on pourra eventuellement utiliser d'autres appareils, notamment un analyseur logique sur le bus SPI (je suppose) entre µC et carte SD voir un scope pour vérifier l'intégrité des signaux.

 

Ah et je suppose que vous avez déjà testés une autre carte SD?

 

PS: à déplacer dans la cat' Electronique?


Message édité par rat de combat le 31-08-2021 à 17:29:30
Reply

Marsh Posté le 31-08-2021 à 22:11:50    

Bonsoir,
Fournir le code de la station, aucun soucis, mais merci de m'indiquer la démarche (simple).
Ce n'est ni un projet scolaire ou universitaire. Juste une étude entre la météo et les précipitations et le temps de percolation et de réponse d'un lac situé à 80 mètre sous terre. Des sondes situées dans ce lac nous donnerons les variations de pression (donc de niveau) ainsi que les températures. le tout est horodaté. Je suis spéléo.
Oui, plusieurs cartes formatées en 32 ont été essayées.  
L'enregistrement est bon avec les bonnes données dans les bonnes colonnes, mais l'enregistrement coupe bêtement...
Quelque soit les configurations ou modifications actuelles, une coupure d'enregistrement se produit environ une heure après le début d'enregistrement, même en le laissant tourner 24 h....avec ou sans le solaire. Le maxi a été 1h30, mais coupure sans raison... c'est plus souvent une heure.
Si vous pensez qu'il est préférable de déplacer le sujet, pas de problèmes

Reply

Marsh Posté le 31-08-2021 à 22:49:26    

Vu la quantité de code le plus simple c'est probablement d'en faire une archive .zip et de la mettre sur un service de partage de fichiers, p.ex. https://www.cjoint.com/ ou un truc "Cloud" (évitons Google par contre). Après ça nous apportera probablement pas grand chose, à moins qu'il y ait une erreur grossière qui saute à l'oeil directement... Le mieux c'est encore de débugger sur le matériel réel.
 
Je suppose que ce n'est pas un problème de batterie qui se vide après 1h? Les cartes SD peuvent demander des pics d'intensité assez importantes en écriture, il y a du découplage etc? Eventuellement faire une photo du truc?

Reply

Marsh Posté le 01-09-2021 à 07:53:57    

Voilà ci dessous le code entier.
Je ne pense pas que cela soit un problème d'alimentation car pour les essais l'alimentation est celle du bureau par usb. Avec le panneau solaire, c'est sur le jack d'alimentation. Le résultat est identique.
Pour les essais également le compteur était de 5, toutes les 2 minutes et demie (et non 30 comme actuellement soit le quart d'heure) Il y avait donc plus d'enregistrements sur la carte au lieu de 4 maintenant, mais coupure après 1 heure.
Merci  
 
#include <PCF85063TP.h>
 
#include <Wire.h>
 
//Baromètre Humidité et Température //
 
#include <HP20x_dev.h>
#include <Arduino.h>
/*#include "Wire.h"*/
#include <KalmanFilter.h>
/*#include "PCF85063TP.h"*/
#include <DFRobot_SHT3x.h>
#include <SD.h>
#include <SPI.h>
 
PCD85063TP clock;//define a object of PCD85063TP class
//DFRobot_SHT3x sht3x(&Wire,/*address=*/0x45,/*RST=*/4);
DFRobot_SHT3x   sht3x;
unsigned char ret = 0;
File monFichier;
 
/*
 * Variables statiques
 */
#define PLUVIOMETRE 1   //pin D3, interruption n°1
#define VALEUR_PLUVIOMETRE 0.2794 //valeur en mm d'eau à chaque bascule d'auget
#define GIROUETTE   A1  //port analogique A1
#define ANEMOMETRE 0   //pin D2, interruption n°0
 
#define PI        3.1415
#define RAYON     0.07  //rayon en mètre de l'anémomètre en mètre
 
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;
unsigned long delaiAnemometre = 3000L;    //3 secondes
unsigned long delaiProgramme = 60000L;   //60 sec
 
float vitesseVent(0); //vent moyen cumulé sur 1 min
float gust(0);        //vent max cumulé sur 1 min
int nbAnemo = 0;      //nb d'occurence de mesure Anemo
int nbGir = 0;        //nb d'occurence de mesure Girouette
float pluvio1min(0);  //pluie sur 1 min
float gir(0);         //direction moyenne de la girouette sur 1 min (en degrés)
 
/*
 * Variables globales
 */
volatile unsigned int countPluviometre = 0; //variable pour l'interruption du pluviometre pour compter les impulsions
volatile unsigned int countAnemometre = 0;  //variable pour l'interruption de l'anémomètre pour compter les impulsions
char direct[] = "";
String Azimut, Lejour;
int LAnnee = 2021, Ljour, Lmois, Lheure, Lminute, Lseconde, compteur = 0;
float TempB, TempC, TempF, Humid, PressA, Vent, MoyenB, MoyenC, MoyenF, MoyenH, MoyenP, MoyenV, VentMax(0);
/*  
 *  Fonction d'interruption du pluviomètre qui incrémente un compteur à chaque impulsion
 */
void interruptPluviometre()
{
  countPluviometre++;
}
 
/*  
 *  Fonction d'interruption de l'anémomètre qui incrémente un compteur à chaque impulsion
 */
void interruptAnemometre(){
  countAnemometre++;
}
 
 
void setup()  
{
    Serial.begin(9600);        // série de démarrage pour la sortie
 
    /* Mise sous tension, délai de 150 ms, jusqu’à ce que la tension soit stable */
    delay(150);
    /* Reset HP20x_dev */
    HP20x.begin();
    delay(100);
        //Initialize the chip
  while (sht3x.begin() != 0)  
  {
    Serial.println("Échec de l’initialisation de la puce, vérifier la connexion du fil" );
    delay(3000);
    Serial.begin(9600);
  clock.begin();
 
  clock.stopClock();
  clock.fillByYMD(2021,8,17);//Année,Mois,Jour
  clock.fillByHMS(7,5,00);//15:28 30"
  clock.fillDayOfWeek(TUE);//Saturday
  clock.setTime();//write time to the RTC chip
  clock.startClock();
 
 
  //clock.setcalibration(1, 32767.2);  // Réglage du décalage par fréquence d’horloge
  uint8_t ret = clock.calibratBySeconds(0, -0.000041);
  Serial.print("offset value: " );
  Serial.print("0x" );
  Serial.println(ret, HEX);
  }
  /**
   * readSerialNumber Lire le numéro de série de la puce.
   * Renvoie le numéro de série à 32 chiffres.
   */
  Serial.print("Numéro de série de la puce : " );
  Serial.println(sht3x.readSerialNumber());
  if(!sht3x.softReset())
  {
  Serial.println("Échec de l’initialisation de la puce...." );
  }
  Serial.print("Initialisation de la carte SD..." );
   pinMode(10, OUTPUT);
   
  if (!SD.begin(4))  
  {
  Serial.println("échec d’initialisation!" );
    return;
  }
  monFichier = SD.open("Combe.txt", FILE_WRITE);
  if (monFichier)  
  {
  Serial.print("\nÉcriture dans Grande Combe.txt..." );
    monFichier.println("Date;Heure;Temp_BaroC;Temp_C;Temp_F;Humidite%;Pression;Vent max m/s;Vent moyen m/s;Azimut vent;Direction vent;Vent dominant;Pluie mm;" ); // titres colonnes sur sd mod avec sonde
  Serial.println("" );
    monFichier.close();    
  }
  Serial.println("initialisation effectuée." );
   
  Serial.println("------------------Lecture en mode de mesure unique-----------------------" );
   
  pinMode(PLUVIOMETRE, INPUT_PULLUP);
  attachInterrupt(PLUVIOMETRE,interruptPluviometre,RISING) ;
   
  pinMode(ANEMOMETRE, INPUT_PULLUP);
  attachInterrupt(ANEMOMETRE,interruptAnemometre,RISING) ;
}
 
/*  
 *  Fonction qui converti en angle la valeur analogique renvoyée par l'arduino (valeurs fixes)
 *  RETURN : angle en degré
 */
float getGirouetteAngle(int value)
{
  float angle = 0;
  if (value > 280 && value < 290)  
 {angle = 180; Azimut = "Sud";} // Sud
  if (value > 240 && value < 250)  
 {angle = 202.5; Azimut = "SSO";} // SSO
  if (value > 628 && value < 636)  
 {angle = 225; Azimut = "SO";}  // SO
  if (value > 598 && value < 606)  
 {angle = 247.5; Azimut = "OSO";} // OSO
  if (value > 940 && value < 950)  
 {angle = 270; Azimut = "Ouest";}   // Ouest
  if (value > 824 && value < 832)  
 {angle = 292.5; Azimut = "ONO";}// ONO
  if (value > 884 && value < 892)  
 {angle = 315; Azimut = "NO";}  // NO
  if (value > 700 && value < 710)  
 {angle = 337.5; Azimut = "NNO";} // NNO
  if (value > 784 && value < 792)  
 {angle = 0; Azimut = "Nord";}    // Nord
  if (value > 402 && value < 412)  
 {angle = 22.5; Azimut = "NNE";} // NNE
  if (value > 458 && value < 468)  
 {angle = 45; Azimut = "NE";}   // NE
  if (value > 78 && value < 85)    
 {angle = 67.5; Azimut = "ENE";} // ENE
  if (value > 88 && value < 98)    
 {angle = 90; Azimut = "Est";}   // Est
  if (value > 60 && value < 70)    
 {angle = 112.5; Azimut = "ESE";} // ESE
  if (value > 180 && value < 190)  
 {angle = 135; Azimut = "SE";}   // SE
  if (value > 122 && value < 132)  
 {angle = 157.5; Azimut = "SSE";}// SSE
  return angle;
}
 
void printTime()
{
  clock.getTime();
  Lheure = clock.hour;
  Serial.print("\n " );Serial.print(Lheure);
  Serial.print(":" );
  Lminute = clock.minute;
  Serial.print(Lminute);
  Serial.print(":" );
  Lseconde = clock.second;
  Serial.print(Lseconde);
  Serial.print("  " );
  Serial.print(" " );
  switch (clock.dayOfWeek)
  {
    case MON:
      Lejour = "Lundi";
      break;
    case TUE:
      Lejour = "Mardi";
      break;
    case WED:
      Lejour = "Mercredi";
      break;
    case THU:
      Lejour = "Jeudi";
      break;
    case FRI:
      Lejour = "Vendredi";
      break;
    case SAT:
      Lejour = "Samedi";
      break;
    case SUN:
      Lejour = "Dimanche";
      break;
  }
  Serial.print(Lejour);
  Serial.print(" " );
  Ljour = clock.dayOfMonth;
  Serial.print(Ljour);
  Serial.print("/" );
  Lmois = clock.month;
  Serial.print(Lmois);
  Serial.print("/" );
  if (Lmois == 12 and Ljour == 31)
  LAnnee ++;
  Serial.print(LAnnee);
}
 
void loop()
{
  printTime();
  delay(30000);
 
  monFichier = SD.open("Combe.txt", FILE_WRITE);
  if (monFichier)    
  Serial.println("\n Données en cours :" );
  compteur++;
  TempB = HP20x.ReadTemperature() / 100.0;  
  TempC = sht3x.getTemperatureC();
  TempF = sht3x.getTemperatureF();
  Humid = sht3x.getHumidityRH();
  PressA = HP20x.ReadPressure() / 100.0;
  vitesseVent = (PI * RAYON * 2 * countAnemometre)/3*3.6; //3 = durée de prise de mesure (3sec) m/s
  if(vitesseVent > VentMax)  
    VentMax = vitesseVent;
  MoyenB += TempB;
  MoyenC += TempC;
  MoyenF += TempF;
  MoyenH += Humid;
  MoyenP += PressA;
  MoyenV += vitesseVent;
  Serial.print("\n Compteur                   : " ); Serial.print(compteur);
  Serial.print("\n T° Baromètre C°            : " );Serial.print(TempB);
  Serial.print("\n Température en Celsius     : " ); Serial.print(TempC);
  Serial.print("\n Température en Farhenheit  : " ); Serial.print(TempF);
  Serial.print("\n Humidite Relative(%RH)     : " ); Serial.print(Humid);
  Serial.print("\n Pression actuelle en hPa   : " ); Serial.print(PressA);
 
  unsigned long currentMillis = millis(); // read time passed
 
    //Récupération des infos de l'anémomètre et girouette toutes les 3 sec
    //Enregistrement cumulé des valeurs
  if (currentMillis - previousMillis > delaiAnemometre)
  {
    previousMillis = millis();
    nbAnemo++;
    countAnemometre = 0;
    int gdir = analogRead(GIROUETTE);
    gir = getGirouetteAngle(gdir);
    nbGir++;
    Serial.print("\n Vent actuel en m/s         : " );Serial.println(vitesseVent);
    Serial.print(" Vitesse vent cumulée       : " );Serial.println(MoyenV);
    Serial.print(" N bascules du Pluviomètre  : " );Serial.println(countPluviometre);
    Serial.print(" Direction vent actuel      : " );Serial.print(gir); Serial.print("° " ); Serial.println(Azimut);
    pluvio1min += countPluviometre*VALEUR_PLUVIOMETRE;
    countPluviometre = 0;
    Serial.print(" Pluviométrie en mm         : " );Serial.println(pluvio1min);
  }  
  if (compteur == 30)
  {
    MoyenB = MoyenB / compteur;
    MoyenC = MoyenC / compteur;
    MoyenF = MoyenF / compteur;
    MoyenH = MoyenH / compteur;
    MoyenP = MoyenP / compteur;
    MoyenV = MoyenV / compteur;
  Serial.print("\n Écriture dans Grande Combe.txt..." );
  Serial.print("\n température moyenne        : " ); Serial.print(MoyenB);
  Serial.print("\n température moyenne C°     : " ); Serial.print(MoyenC);
  Serial.print("\n température moyenne F      : " ); Serial.print(MoyenF);
  Serial.print("\n Humidité moyenne           : " ); Serial.print(MoyenH);
  Serial.print("\n Pression moyenne           : " ); Serial.print(MoyenP);
  Serial.print("\n Vent moyen en m/s          : " ); Serial.print(MoyenV);
  Serial.print("\n Vent Max en m/s            : " ); Serial.print(VentMax);
  Serial.print("\n Pluviométrie en mm         : " );Serial.println(pluvio1min);
    String DateNomJour = String(Lejour);
    String DateNumJour = String(Ljour);
    String DateMois = String(Lmois);
    String DateHeure = String(Lheure);
    String DateMinute = String(Lminute);
    String DateSeconde = String(Lseconde);
    String TempBaro = String(MoyenB);
    String TemperatureC = String(MoyenC);
    String TemperatureF = String(MoyenF);
    String Humidite  = String(MoyenH);
    String Pression = String(MoyenP);
    String VMoyen = String(MoyenV);
    String VMax = String(VentMax);  
    String Pluviometrie = String(pluvio1min);
    String Girouette = String(gir);
    DateNomJour += " " + DateNumJour + "/" + DateMois + "/" + LAnnee;
    DateHeure += ":" + DateMinute + ":" + DateSeconde;
    String Combe =  DateNomJour + ";" + DateHeure + ";" + TempBaro + ";" + TemperatureC + ";" + TemperatureF + ";" + Humidite + ";" + Pression + ";" + VMax + ";" + VMoyen + ";" + Azimut + ";" + gir + ";" + " " + ";" + Pluviometrie ;    
    monFichier = SD.open("Combe.txt", FILE_WRITE); //Maximum 8 caractères avant le .txt  
    if (monFichier)
    {    
      monFichier.println(Combe);      
  Serial.println("\n terminée." );
      monFichier.close();  
  /*  }
 /*   else  
    {
  Serial.println("erreur d’ouverture de Grande Combe.txt" ); */      
    }  
    delay(5000);
    MoyenB = 0;
    MoyenC = 0;
    MoyenF = 0;
    MoyenH = 0;
    MoyenP = 0;
    MoyenV = 0;
    VentMax = 0;
    pluvio1min = 0;
    compteur = 0;
 }
 
    // On enregistre la donnée
}
 

Reply

Marsh Posté le 01-09-2021 à 10:12:49    

Salut,
 
Je n'y connais pas grand chose en Arduino, mais, concernant cette partie :
 

Code :
  1. monFichier = SD.open("Combe.txt", FILE_WRITE);
  2.   if (monFichier)


 
1/ Je ne comprends pas trop ce "if (monFichier)" sans rien derrière.
2/ Pour moi tu ne referme jamais ce "open" et tu refais ensuite des open/close plus bas dans le code.  
3/ Pourquoi d'ailleurs ce "SD.open" alors que tu n'écris a priori rien dans le fichier avant de le ré-ouvrir plus tard.
 

Code :
  1. monFichier = SD.open("Combe.txt", FILE_WRITE); //Maximum 8 caractères avant le .txt   
  2.     if (monFichier)
  3.     {   
  4.       monFichier.println(Combe);     
  5.   Serial.println("\n terminée." );
  6.       monFichier.close(); 
  7.   /*  }
  8. /*   else   
  9.     {
  10.   Serial.println("erreur d’ouverture de Grande Combe.txt" ); */     
  11.     } 
  12.     delay(5000);
  13.     MoyenB = 0;
  14.     MoyenC = 0;


 
J'ai également du mal à comprendre pourquoi tu as commenté le "else". La syntaxe du commentaire semble également erronée.
 
Ce n'est probablement pas indispensable mais j'aurais pour ma part tendance à segmenter les données dans plusieurs fichiers plutôt que de les écrire dans un seul ... Un par jour, par semaine, par mois ... à voir selon les données et la façon de les exploiter derrière.  
 
 
Plus globalement le code me semble assez "approximatif" : il manque par exemple pour moi plusieurs "else" et/ou de tests de retour de fonction avec les remontés d'erreurs qui vont avec.
 
A+


Message édité par eusebius le 01-09-2021 à 10:31:36
Reply

Marsh Posté le 01-09-2021 à 17:16:57    

Bon, après un bref regard je suis d'accord avec eusebius, le code n'est pas top. Ne le prend pas mal surtout, j'ai bien conscience que tu n'es (probablement) pas dév.

 

Quelque exemples pour illustrer ce que je dis:
-du code mis en commentaire de partout
-mélange de char[] et de String
-les "variables statiques" sont des directives préprocesseur (et des variables globales il y en a aussi dans le tas)
-Serial.beginn appellé possiblement x fois dans une boucle
-Je pense une mauvaise compréhension de comment fonctionnent les chaînes de caractères
-utilisation d'interruption sur des signaux possiblement "bruités" (->debounce)
-…

 

J'ai aussi pensé à autre chose, il consomme combien de RAM ton code? Je ne sais pas si Serial.println utilise la FLASH ou recopie tout dans la RAM. Il faudrait vérifier, le logiciel Arduino devrait l'afficher après la compilation.

 

Si j'ai le temps je vais essayer de nettoyer un peu tout ça ce soir, mais comme je n'ai pas le hardware je ne peux pas tester donc exercice difficile...

 

edit: eusebius:

Citation :

1/ Je ne comprends pas trop ce "if (monFichier)" sans rien derrière.

Je ne pense pas que ce soit ça ta difficulté, mais au pif: if(bidule) est équivalent à if(bidule!=0).


Message édité par rat de combat le 01-09-2021 à 17:19:01
Reply

Marsh Posté le 01-09-2021 à 18:32:08    

Bon, je peux pas tout faire mais voici une version un peu meilleure de la fonction setup(). En gros plein de texte sur l'interface série pour savoir ce qui se passe, vérifier les valeurs returnées par les appels de fonctions. Attention, en cas d'échec le µC va s'arrêter (tourner en boucle infinie while(1); ), il faut éteindre et rallumer pour une nouvelle tentative (après avoir vérifié les connections etc). Pour l'initialisation du SHT3x j'ai mis une boucle do {} while(); pour essayer 10 fois avant d'abandonner, mais c'est plus pour montrer cette technique, ça devrait fonctionner du premier coup. Attention aussi aux "nombres magiques", autrement dit des constantes qui traînent sans aucune explication. Il vaut mieux utiliser des #define, surtout si la même valeur est utilisée à plusieurs endroits différents (car sinon gare au changement à un endroit mais pas à l'autre...). Le fichier sur la carte SD je l'ouvre une fois et je le laisse ouvert, il faudra prévoir un bouton poussoir ou autre pour dire à l'Arduino de fermer le fichier et d'"éjecter" la carte SD pour pouvoir l'éteindre et récupérer la carte avec les infos.
 
Bref, c'est un début. Je te conseille de reprendre tout le code petit par petit et essayer de nettoyer en suivant ces quelque conseils. Des conseils tu peux aussi en trouver d'autres sur internet et puis dans la cat' Électronique il y a un loooong sujet dédié Arduino.

Code :
  1. void setup()
  2. {
  3.     delay(500);
  4.    
  5.     Serial.begin(9600);
  6.    
  7.     Serial.println("START SETUP" );
  8.    
  9.     HP20x.begin(); //init baromètre - ne retourne rien
  10.    
  11.     Serial.println("initialisation SHT3x..." );
  12.    
  13.     unsigned char tries;
  14.     int ret;
  15.    
  16.     do
  17.     {
  18.         ret=sht3x.begin();
  19.        
  20.         if(ret!=0)
  21.         {
  22.             Serial.println("échec initialisation SHT3x, je retente..." );
  23.             delay(300);
  24.         }
  25.            
  26.     } while(ret!=0 && ++tries<10);
  27.        
  28.     if(ret!=0)
  29.     {
  30.         Serial.println("échec initialisation SHT3x, STOP!" );
  31.         while(1); //faudrait faire clignoter une LED ou quelque chose ici
  32.     }
  33.    
  34.     Serial.print("Numéro de série de la puce SHT3x: " );
  35.     Serial.println(sht3x.readSerialNumber());
  36.    
  37.     if(sht3x.softReset()==0)
  38.     {
  39.         Serial.println("échec reset SHT3x, STOP!" );
  40.         while(1); //idem
  41.     }
  42.    
  43.     Serial.println("SHT3x initialisation OK" );
  44.     Serial.println("initialisation horloge" );
  45.     //faudrait vérifier les valeurs que retournent les fonctions si il n'y a pas eu de problème
  46.     clock.stopClock();
  47.     clock.fillByYMD(2021,8,17);//Année,Mois,Jour
  48.     clock.fillByHMS(7,5,00);//15:28 30"
  49.     clock.fillDayOfWeek(TUE);//Saturday
  50.     clock.setTime();//write time to the RTC chip
  51.     clock.startClock();
  52.    
  53.     unsigned char offset=clock.calibratBySeconds(0, -0.000041); //d'où vient cette valeur? "magic number"
  54.     Serial.print("offset value: " );
  55.     Serial.print("0x" );
  56.     Serial.println(offset, HEX);
  57.    
  58.     Serial.println("Initialisation de la carte SD..." );
  59.     pinMode(10, OUTPUT);
  60.     if(SD.begin(4)==0) //"magic number"
  61.     {
  62.         Serial.println("échec d’initialisation, STOP!" );
  63.         while(1);
  64.     }
  65.    
  66.     Serial.println("init SD ok" );
  67.    
  68.     monFichier = SD.open("Combe.txt", FILE_WRITE);
  69.     if(monFichier==0)
  70.     {
  71.         Serial.println("échec ouverture fichier, STOP!" );
  72.         while(1);
  73.     }
  74.        
  75.     Serial.print("Écriture dans Grande Combe.txt..." );
  76.     monFichier.println("Date;Heure;Temp_BaroC;Temp_C;Temp_F;Humidite%;Pression;Vent max m/s;Vent moyen m/s;Azimut vent;Direction vent;Vent dominant;Pluie mm;" ); // titres colonnes sur sd mod avec sonde
  77.     Serial.println("ok" );
  78.    
  79.     Serial.println("initialisation effectuée." );
  80.     Serial.println("------------------Lecture en mode de mesure unique-----------------------" );
  81.     pinMode(PLUVIOMETRE, INPUT_PULLUP);
  82.     attachInterrupt(PLUVIOMETRE,interruptPluviometre,RISING);
  83.     pinMode(ANEMOMETRE, INPUT_PULLUP);
  84.     attachInterrupt(ANEMOMETRE,interruptAnemometre,RISING);
  85. }

Reply

Marsh Posté le 01-09-2021 à 23:22:40    

Bonsoir,  
Merci de vos réflexions. Je suis plus à l'aise avec beaucoup de vide sous les pieds et la biologie souterraine qu'avec la programmation.
 
C'est vrai que certaine fonctions ont été mises en commentaires pour "essayer" d'améliorer sans toutefois perde la ligne au cas ou!. Par exemple, plutôt que d'ouvrir et fermer la carte SD, l'idée était de la laisser ouverte....pas concluant!.
Pour l'horloge, c'est la bibliothèque et exemple du module d'origine. Il fonctionne très bien et l'horloge est réglée à une minute de décalage, ce qui n'est pas grave du tout car le décalage est constant et sur le temps, pas d'importance.
 
Merci pour ces premières idées.
 

Reply

Marsh Posté le 01-09-2021 à 23:22:40   

Reply

Marsh Posté le 02-09-2021 à 15:59:07    

fpaude a écrit :

Je suis plus à l'aise avec beaucoup de vide sous les pieds et la biologie souterraine qu'avec la programmation.

Oui, j'en doute pas. Malheureusement perso je ne connais pas bien le monde Arduino et puis sans le matériel difficile voire impossible d'améliorer / de débugger le code. :(  
Une autre idée quand même: Tu pourrais virer tout les capteurs et ne garder que l'enregistrement (d'une valeur qui s'incrémente tout le temps, genre millis() )voir si ça fonctionne ou pas. Il faut essayer de créer un code le plus court possible qui présente le bug pour pouvoir débugger plus facilement. Si le code "minimaliste" fonctionne on pourra rajouter capteur par capteur en prenant soin de tester après chaque grosse modification.

Reply

Marsh Posté le 02-09-2021 à 22:54:00    

Bonsoir,
J'ai téléversé les lignes de code proposée, Résultat: l'horloge est totalement déréglée et se réinitialise à chaque démarrage (mais ce n'est pas à priori trop grave actuellement), le libellé de chaque colonne dans l'enregistrement SD a disparu, toutes les données restent bonnes, mais coupure de l'enregistrement au bout d'une heure.
Nous allons essayer de désactiver toutes les mesures sauf une en gardant l'heure.
 
A suivre donc. Merci

Reply

Marsh Posté le 03-09-2021 à 12:45:32    

Pour la fonction getGirouetteAngle, j'ai l'impression que tout le monde a pompé sur https://www.sla99.fr/2019/09/12/pro [...] urs-meteo/ or sa méthode me semble plus que douteuse :
Manifestement il a positionné sa girouette aux 16 angles qu'il voulait repérer, il a pris les mesures du capteur, il a tapé une fourchette de 10 (9 en fait au vu de son code, et en fait parfois moins)  autour de ce qu'il a mesuré et basta.

Citation :

Pour la girouette, c’est un peu plus compliqué. Il faut associer un tableau de valeur à la valeur analogique retournée, puis définir l’angle associé. Concrètement, le nord (N) = 0°, le nord-nord-est = 22,5°, etc … Il faut donc mesurer à la main les 16 valeurs analogiques et faire une fonction de correspondance.


Mais ça, ça laisse plein de trous dans la raquette, pour lesquels il va renvoyer 0, alors que ça n'a aucune raison d'être la bonne valeur.
 
En supposant que la capteur envoie une mesure localement continue par morceaux ce que laisse supposer sa remarque

Citation :

les valeurs bougent de 1 ou 2

Je vois que capteur n'a pas l'air de varier de manière simple : si je prends les valeurs d'orientation successives on a (en prenant la valeur moyenne de la fonction pour déterminer l'angle :
E :     93
ESE : 65
SE :   184.5
SSE : 127
S :     285
SSO : 245
SO :   632
OSO : 602
O :     945
ONO : 828
C'est pas du tout linéaire, donc un vrai ré-étalonnage s'impose, en particulier pour voir a quel moment on a des sautes de plage de valeurs.
Il y a peut être un mix de valeurs de plusieurs capteurs pour une valeur finale composite, repérable dans le pattern des bits de l'entier retourné par le capteur.
(Et penser a faire un étalonnage en faisant tourner dans un sens, et dans l'autre).

Ah en fait c'est tout con, le capteur n'envoie que 16 valeurs d'après la page d'un revendeur :

Citation :

Faite tourner la girouette pour repérer les 16 valeurs de tensions différentes relatives à ses différentes positions.


Dans ce cas la, sa méthode va marcher. Mais j'éviterais de renvoyer 0 si on lit une valeur pas prévue, je renverrais plutôt -1, pour détecter ce cas de figure dans le code appelant et agir en fonction.
Seulement 16 valeurs c'est un poil riquiqui comme plage de valeurs pour le capteur, je ne m'y attendais pas. Mais manifestement, au vu d'un rapide googlage, c'est le standard des capteurs bas de gamme valant dans les 15 €, manifestement c'est avec une techno à aimants.  
 
A+,


Message édité par gilou le 03-09-2021 à 14:25:34

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 03-09-2021 à 16:43:58    

Le code que j'avais posté c'était plus un exemple de comment organiser/écrire ça plus proprement, pas un truc à copier 1:1. Comme je disais, sans avoir le hardware impossible de t'aider. :(  
 
Par contre je voudrais insister sur un point: Si tu laisses le fichier ouvert il faut impérativement prévoir un mécanisme pour le fermer avant de mettre le système hors tension pour retirer la carte, sinon tu vas perdre des données (->buffer etc).

Reply

Marsh Posté le 03-09-2021 à 23:18:00    

Bonsoir, et merci de toutes vos idées d'améliorations.
Pour le moment, tout le programme écrit semble fonctionner correctement. Chaque sonde ou module a été testé seul avant d'être associé avec un autre pour former le tout. Nous sommes tout a fait conscient qu'il peut-être simplifié ou améliorer, mais nous avons laissé tourner l'ensemble pendant 24 h. les données s'affichent et sont cohérentes dans la fenêtre Sérial. une mesure toutes les 30 secondes, moyennes ou cumuls... tous les quart d'heures.
 
C'est l'enregistrement qui pose problème.
 
L'idée de n'utiliser qu'un seul capteur était une bonne idée pour voir le résultat. Le choix a été fait au hasard avec la Pression et Température. Toutes les lignes qui n'étaient pas en relation avec le baromètre et sa température associé ont été désactivée.
L'horloge a été conservée en l'état. La pile est neuve et a été changée.
Résultat: bons enregistrements avec moyennes, mais coupure après 1 heure. A noter toutefois qu'après la coupure, l'affichage du Sérial est différent avec des sauts de lignes en moins, cela reste lisible, mais plus condensé.
L'idée est davantage tournée vers un problème matériel que de programmation, ou un peu des deux!!!
 
Le choix des connections Grove a été fait pour limiter les faux contacts et la solidité de l'ensemble.
 
Dernier point, si le téléversement est à nouveau réalisé, tout repart correctement en enregistrement pour se couper 1 h après. La carte a été formaté spécialement (Fat32)et ne sert qu'aux enregistrements.

Reply

Marsh Posté le 04-09-2021 à 00:26:15    

fpaude a écrit :

Bonsoir,
J'ai téléversé les lignes de code proposée, Résultat: l'horloge est totalement déréglée et se réinitialise à chaque démarrage (mais ce n'est pas à priori trop grave actuellement), le libellé de chaque colonne dans l'enregistrement SD a disparu, toutes les données restent bonnes, mais coupure de l'enregistrement au bout d'une heure.
Nous allons essayer de désactiver toutes les mesures sauf une en gardant l'heure.
 
A suivre donc. Merci


> le libellé de chaque colonne dans l'enregistrement SD a disparu
C'est normal : RdC n'a pas fait un  monFichier.close(); après la ligne 80, donc le premier SD.open de la première execution de loop()  va écraser la ligne de libellé avec sa première écriture.
 
J'ai regardé le code que tu as posté initialement, il est assez compréhensible, et a première vue, la seule chose que je vois qui me choque, c'est ceci :
void loop()
{
  printTime();
  delay(30000);
 
  monFichier = SD.open("Combe.txt", FILE_WRITE);
  if (monFichier)   {  
    Serial.println("\n Données en cours :" );
  }
  ...
 
tu fais un monFichier = SD.open, tu écris pas dans le fichier, tu ne fermes pas le fichier, et tu le rouvres ensuite. (eusebius te signalait justement ce point)
Il se peut que chaque fois que tu ouvres ton fichier sans le refermer, tu consomme un descripteur de fichier, et que tu les épuises au bout d'un certain temps, puisque c'est fait une fois par appel à loop donc deux fois par minute. Et si tu n'as plus de descripteur de fichier disponible, tu ne peux plus écrire dans le fichier, ce qui collerait bien avec le comportement décrit, surtout que si ça coupe au bout de 1h, ça correspondrait a 120 appels a loop, ce qui est pas loin de 128, un chiffre d'informaticien, qui pourrait bien être le nb total de descripteurs disponibles dans ton système.
 
A mon avis, tu devrais juste faire ici
void loop()
{
  printTime();
  delay(30000);
 
   Serial.println("\n Données en cours :" );
 
et laisser le reste du code initialement posté tel quel (dans un premier temps, car il est améliorable, mais déjà, ça laisserait voir si c'est la source du problème).
 
EDIT : Ah si, il y a une autre erreur :
 Combe =  DateNomJour + ";" + DateHeure + ";" + TempBaro + ";" + TemperatureC + ";" + TemperatureF + ";" + Humidite + ";"
   + Pression + ";" + VMax + ";" + VMoyen + ";" + Azimut + ";" + gir + ";" + " " + ";" + Pluviometrie ;
 
     ça devrait être  
       Combe =  DateNomJour + ";" + DateHeure + ";" + TempBaro + ";" + TemperatureC + ";" + TemperatureF + ";" + Humidite + ";"
   + Pression + ";" + VMax + ";" + VMoyen + ";" + Azimut + ";" + Girouette + ";" + " " + ";" + Pluviometrie ;
 
et une autre :
if (Lmois == 12 and Ljour == 31) {
    LAnnee++;
  }
ce qui fait que le 21 décembre, tu vas incrémenter l'année toute les 30s...
 
A+,

Message cité 1 fois
Message édité par gilou le 04-09-2021 à 02:17:27

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-09-2021 à 00:38:01    

gilou a écrit :


> le libellé de chaque colonne dans l'enregistrement SD a disparu
C'est normal : RdC n'a pas fait un  monFichier.close(); après la ligne 80, donc le premier SD.open de la première execution de loop()  va écraser la ligne de libellé avec sa première écriture.

En effet, j'étais parti sur l'idée d'ouvrir le fichier dans setup() et de le laisser ouvert tout le temps jusqu'à un appui sur un bouton poussoir pour signaler au µC "c'est terminé, ferme le fichier". Sauf que je n'ai pas posté de code complet et en mélangeant ma version de setup avec le reste, bref...
 
Je plussoie ton analyse concernant les descripteurs de fichiers (ou alors un problème de mémoire vive si il y a du malloc caché quelque part au fin-fond de la lib'?). :jap:

Reply

Marsh Posté le 04-09-2021 à 02:56:04    

Bon, j'ai reformaté le code pour le rendre plus lisible, et ai corrigé les erreurs signalées.
J'ai pas d'environnement pour le tester.
A mes fautes de frappes près, ça devrait être meilleur  
 

Code :
  1. // Bus
  2. #include <Wire.h>
  3. // chip
  4. #include <Arduino.h>
  5. // RTC
  6. #include <PCF85063TP.h>
  7. // senseur baromètre
  8. #include <HP20x_dev.h>
  9. // senseur température et humidité
  10. #include <DFRobot_SHT3x.h>
  11. // carte SD
  12. #include <SD.h>
  13. //port série
  14. #include <SPI.h>
  15. #include <KalmanFilter.h>
  16. PCD85063TP clock; //define a object of PCD85063TP class
  17. //DFRobot_SHT3x sht3x(&Wire,/*address=*/0x45,/*RST=*/4);
  18. DFRobot_SHT3x sht3x;
  19. unsigned char ret = 0;
  20. File monFichier;
  21. /*
  22. * Variables statiques
  23. */
  24. #define PLUVIOMETRE 1 //pin D3, interruption n°1
  25. #define VALEUR_PLUVIOMETRE 0.2794 //valeur en mm d'eau à chaque bascule d'auget
  26. #define GIROUETTE A1 //port analogique A1
  27. #define ANEMOMETRE 0 //pin D2, interruption n°0
  28. #define PI 3.1415
  29. #define RAYON 0.07 //rayon en mètre de l'anémomètre en mètre
  30. unsigned long previousMillis = 0;
  31. unsigned long previousMillis2 = 0;
  32. unsigned long delaiAnemometre = 3000 L; //3 secondes
  33. unsigned long delaiProgramme = 60000 L; //60 sec
  34. float vitesseVent(0); //vent moyen cumulé sur 1 min
  35. float gust(0); //vent max cumulé sur 1 min
  36. int nbAnemo = 0; //nb d'occurence de mesure Anemo
  37. int nbGir = 0; //nb d'occurence de mesure Girouette
  38. float pluvio1min(0); //pluie sur 1 min
  39. float gir(0); //direction moyenne de la girouette sur 1 min (en degrés)
  40. /*
  41. * Variables globales
  42. */
  43. volatile unsigned int countPluviometre = 0; //variable pour l'interruption du pluviometre pour compter les impulsions
  44. volatile unsigned int countAnemometre = 0; //variable pour l'interruption de l'anémomètre pour compter les impulsions
  45. char direct[] = "";
  46. String Azimut, Lejour;
  47. // Tant que tu n'as pas un moyen de faire une mise a jour de la date autre que l'initialisation, c'est ici qu'il faut le faire
  48. int LAnnee = 2021;
  49. int Lmois = 8;
  50. int Ljour = 17;
  51. int Ljoursemaine = TUE;
  52. int Lheure = 7;
  53. int Lminute = 5;
  54. int Lseconde = 0;
  55. int compteur = 0;
  56. int SMois = 0;
  57. float TempB, TempC, TempF, Humid, PressA, Vent, MoyenB, MoyenC, MoyenF, MoyenH, MoyenP, MoyenV, VentMax(0);
  58. /*   
  59. *  Fonction d'interruption du pluviomètre qui incrémente un compteur à chaque impulsion
  60. */
  61. void interruptPluviometre() {
  62.   countPluviometre++;
  63. }
  64. /*   
  65. *  Fonction d'interruption de l'anémomètre qui incrémente un compteur à chaque impulsion
  66. */
  67. void interruptAnemometre() {
  68.   countAnemometre++;
  69. }
  70. void setup() {
  71.   Serial.begin(9600); // série de démarrage pour la sortie
  72.   /* Mise sous tension, délai de 150 ms, jusqu’à ce que la tension soit stable */
  73.   delay(150);
  74.   /* Reset HP20x_dev */
  75.   HP20x.begin();
  76.   delay(100);
  77.   //Initialize the chip
  78.   while (sht3x.begin() != 0) {
  79.     Serial.println("Échec de l’initialisation de la puce, vérifier la connexion du fil" );
  80.     delay(3000);
  81.     Serial.begin(9600);
  82.     clock.begin();
  83.     // toute cette partie la devra figurer dans un code de mise a jour de la clock
  84.     // par donnée de synchronisation externe, si tu en écris un plus tard
  85.     clock.stopClock();
  86.     clock.fillByYMD(LAnnee, Lmois, Ljour);
  87.     clock.fillByHMS(Lheure, Lminute, Lseconde);
  88.     clock.fillDayOfWeek(Ljoursemaine);
  89.     clock.setTime(); // write time to the RTC chip
  90.     clock.startClock();
  91.     SMois = Lmois;
  92.     //clock.setcalibration(1, 32767.2);  // Réglage du décalage par fréquence d’horloge
  93.     uint8_t ret = clock.calibratBySeconds(0, -0.000041);
  94.     Serial.print("offset value: " );
  95.     Serial.print("0x" );
  96.     Serial.println(ret, HEX);
  97.   }
  98.   /**
  99.    * readSerialNumber Lire le numéro de série de la puce.
  100.    * Renvoie le numéro de série à 32 chiffres.
  101.    */
  102.   Serial.print("Numéro de série de la puce : " );
  103.   Serial.println(sht3x.readSerialNumber());
  104.   if (!sht3x.softReset()) {
  105.     Serial.println("Échec de l’initialisation de la puce...." );
  106.   }
  107.   Serial.print("Initialisation de la carte SD..." );
  108.   pinMode(10, OUTPUT);
  109.   if (!SD.begin(4)) {
  110.     Serial.println("échec d’initialisation!" );
  111.     return;
  112.   }
  113.   monFichier = SD.open("Combe.txt", FILE_WRITE);
  114.   if (monFichier) {
  115.     Serial.print("\nÉcriture dans Combe.txt..." );
  116.     // en têtes
  117.     monFichier.println("Date;Heure;Temp_BaroC;Temp_C;Temp_F;Humidite%;Pression;Vent max m/s;Vent moyen m/s;Azimut vent;Direction vent;Vent dominant;Pluie mm;" );
  118.     Serial.println("" );
  119.     monFichier.close();
  120.   }
  121.   Serial.println("initialisation effectuée." );
  122.   Serial.println("------------------Lecture en mode de mesure unique-----------------------" );
  123.   pinMode(PLUVIOMETRE, INPUT_PULLUP);
  124.   attachInterrupt(PLUVIOMETRE, interruptPluviometre, RISING);
  125.   pinMode(ANEMOMETRE, INPUT_PULLUP);
  126.   attachInterrupt(ANEMOMETRE, interruptAnemometre, RISING);
  127. }
  128. /*   
  129. *  Fonction qui converti en angle la valeur analogique renvoyée par l'arduino (valeurs fixes)
  130. *  RETURN : angle en degré
  131. */
  132. float getGirouetteAngle(int value) {
  133.   float angle = 0;
  134.   if (value > 280 && value < 290) {
  135.     angle = 180;
  136.     Azimut = "Sud";
  137.   } // Sud
  138.   if (value > 240 && value < 250) {
  139.     angle = 202.5;
  140.     Azimut = "SSO";
  141.   } // SSO
  142.   if (value > 628 && value < 636) {
  143.     angle = 225;
  144.     Azimut = "SO";
  145.   } // SO
  146.   if (value > 598 && value < 606) {
  147.     angle = 247.5;
  148.     Azimut = "OSO";
  149.   } // OSO
  150.   if (value > 940 && value < 950) {
  151.     angle = 270;
  152.     Azimut = "Ouest";
  153.   } // Ouest
  154.   if (value > 824 && value < 832) {
  155.     angle = 292.5;
  156.     Azimut = "ONO";
  157.   } // ONO
  158.   if (value > 884 && value < 892) {
  159.     angle = 315;
  160.     Azimut = "NO";
  161.   } // NO
  162.   if (value > 700 && value < 710) {
  163.     angle = 337.5;
  164.     Azimut = "NNO";
  165.   } // NNO
  166.   if (value > 784 && value < 792) {
  167.     angle = 0;
  168.     Azimut = "Nord";
  169.   } // Nord
  170.   if (value > 402 && value < 412) {
  171.     angle = 22.5;
  172.     Azimut = "NNE";
  173.   } // NNE
  174.   if (value > 458 && value < 468) {
  175.     angle = 45;
  176.     Azimut = "NE";
  177.   } // NE
  178.   if (value > 78 && value < 85) {
  179.     angle = 67.5;
  180.     Azimut = "ENE";
  181.   } // ENE
  182.   if (value > 88 && value < 98) {
  183.     angle = 90;
  184.     Azimut = "Est";
  185.   } // Est
  186.   if (value > 60 && value < 70) {
  187.     angle = 112.5;
  188.     Azimut = "ESE";
  189.   } // ESE
  190.   if (value > 180 && value < 190) {
  191.     angle = 135;
  192.     Azimut = "SE";
  193.   } // SE
  194.   if (value > 122 && value < 132) {
  195.     angle = 157.5;
  196.     Azimut = "SSE";
  197.   } // SSE
  198.   return angle;
  199. }
  200. void printTime() {
  201.   clock.getTime();
  202.   Lheure = clock.hour;
  203.   Lminute = clock.minute;
  204.   Lseconde = clock.second;
  205.   Ljour = clock.dayOfMonth;
  206.   Lmois = clock.month;
  207.   switch (clock.dayOfWeek) {
  208.   case MON:
  209.     Lejour = "Lundi";
  210.     break;
  211.   case TUE:
  212.     Lejour = "Mardi";
  213.     break;
  214.   case WED:
  215.     Lejour = "Mercredi";
  216.     break;
  217.   case THU:
  218.     Lejour = "Jeudi";
  219.     break;
  220.   case FRI:
  221.     Lejour = "Vendredi";
  222.     break;
  223.   case SAT:
  224.     Lejour = "Samedi";
  225.     break;
  226.   case SUN:
  227.     Lejour = "Dimanche";
  228.     break;
  229.   default:
  230.     Lejour = "*Erreur*";
  231.     break;
  232.   }
  233.   if (Smois == 12 && Smois != Lmois) {
  234.     // on était en décembre et on a changé de mois, donc on change d'année
  235.     LAnnee++;
  236.   }
  237.   Serial.print("\n " );
  238.   Serial.print(Lheure);
  239.   Serial.print(":" );
  240.   Serial.print(Lminute);
  241.   Serial.print(":" );
  242.   Serial.print(Lseconde);
  243.   Serial.print("  " );
  244.   Serial.print(" " );
  245.   Serial.print(Lejour);
  246.   Serial.print(" " );
  247.   Serial.print(Ljour);
  248.   Serial.print("/" );
  249.   Serial.print(Lmois);
  250.   Serial.print("/" );
  251.   Serial.print(LAnnee);
  252. }
  253. void loop() {
  254.   printTime();
  255.   delay(30000);
  256.   compteur++;
  257.   Serial.println("\n Données en cours :" );
  258.   // lecture des données
  259.   TempB = HP20x.ReadTemperature() / 100.0;
  260.   TempC = sht3x.getTemperatureC();
  261.   TempF = sht3x.getTemperatureF();
  262.   Humid = sht3x.getHumidityRH();
  263.   PressA = HP20x.ReadPressure() / 100.0;
  264.   vitesseVent = (PI * RAYON * 2 * countAnemometre) / 3 * 3.6; //3 = durée de prise de mesure (3sec) m/s
  265.   if (vitesseVent > VentMax) {
  266.     VentMax = vitesseVent;
  267.   }
  268.   // cumul dans les variables d'accumulation de mesures
  269.   MoyenB += TempB;
  270.   MoyenC += TempC;
  271.   MoyenF += TempF;
  272.   MoyenH += Humid;
  273.   MoyenP += PressA;
  274.   MoyenV += vitesseVent;
  275.   Serial.print("\n Compteur                   : " );
  276.   Serial.print(compteur);
  277.   Serial.print("\n T° Baromètre C°            : " );
  278.   Serial.print(TempB);
  279.   Serial.print("\n Température en Celsius     : " );
  280.   Serial.print(TempC);
  281.   Serial.print("\n Température en Farhenheit  : " );
  282.   Serial.print(TempF);
  283.   Serial.print("\n Humidite Relative(%RH)     : " );
  284.   Serial.print(Humid);
  285.   Serial.print("\n Pression actuelle en hPa   : " );
  286.   Serial.print(PressA);
  287.   //Récupération des infos de l'anémomètre et girouette toutes les 3 sec
  288.   unsigned long currentMillis = millis(); // read time passed
  289.   if (currentMillis - previousMillis > delaiAnemometre) {
  290.     previousMillis = millis();
  291.     nbAnemo++;
  292.     countAnemometre = 0;
  293.     int gdir = analogRead(GIROUETTE);
  294.     gir = getGirouetteAngle(gdir);
  295.     nbGir++;
  296.     pluvio1min += countPluviometre * VALEUR_PLUVIOMETRE;
  297.     countPluviometre = 0;
  298.     Serial.print("\n Vent actuel en m/s         : " );
  299.     Serial.println(vitesseVent);
  300.     Serial.print(" Vitesse vent cumulée       : " );
  301.     Serial.println(MoyenV);
  302.     Serial.print(" N bascules du Pluviomètre  : " );
  303.     Serial.println(countPluviometre);
  304.     Serial.print(" Direction vent actuel      : " );
  305.     Serial.print(gir);
  306.     Serial.print("° " );
  307.     Serial.println(Azimut);
  308.     Serial.print(" Pluviométrie en mm         : " );
  309.     Serial.println(pluvio1min);
  310.   }
  311.   //Enregistrement cumulé des valeurs
  312.   if (compteur == 30) {
  313.     // Calcul des valeurs moyennes pour les 30 mesures
  314.     MoyenB /= compteur;
  315.     MoyenC /= compteur;
  316.     MoyenF /= compteur;
  317.     MoyenH /= compteur;
  318.     MoyenP /= compteur;
  319.     MoyenV /= compteur;
  320.     Serial.print("\n Écriture dans Grande Combe.txt..." );
  321.     Serial.print("\n température moyenne        : " );
  322.     Serial.print(MoyenB);
  323.     Serial.print("\n température moyenne C°     : " );
  324.     Serial.print(MoyenC);
  325.     Serial.print("\n température moyenne F      : " );
  326.     Serial.print(MoyenF);
  327.     Serial.print("\n Humidité moyenne           : " );
  328.     Serial.print(MoyenH);
  329.     Serial.print("\n Pression moyenne           : " );
  330.     Serial.print(MoyenP);
  331.     Serial.print("\n Vent moyen en m/s          : " );
  332.     Serial.print(MoyenV);
  333.     Serial.print("\n Vent Max en m/s            : " );
  334.     Serial.print(VentMax);
  335.     Serial.print("\n Pluviométrie en mm         : " );
  336.     Serial.println(pluvio1min);
  337.     monFichier = SD.open("Combe.txt", FILE_WRITE); //Maximum 8 caractères avant le .txt   
  338.     if (monFichier) {
  339.       String DateNomJour = String(Lejour);
  340.       String DateNumJour = String(Ljour);
  341.       String DateMois = String(Lmois);
  342.       String DateHeure = String(Lheure);
  343.       String DateMinute = String(Lminute);
  344.       String DateSeconde = String(Lseconde);
  345.       String TempBaro = String(MoyenB);
  346.       String TemperatureC = String(MoyenC);
  347.       String TemperatureF = String(MoyenF);
  348.       String Humidite = String(MoyenH);
  349.       String Pression = String(MoyenP);
  350.       String VMoyen = String(MoyenV);
  351.       String VMax = String(VentMax);
  352.       String Pluviometrie = String(pluvio1min);
  353.       String Girouette = String(gir);
  354.       String Combe =
  355.         DateNomJour + " " + DateNumJour + "/" + DateMois + "/" + LAnnee + ";" +
  356.         DateHeure + ":" + DateMinute + ":" + DateSeconde + ";" +
  357.         TempBaro + ";" +
  358.         TemperatureC + ";" +
  359.         TemperatureF + ";" +
  360.         Humidite + ";" +
  361.         Pression + ";" +
  362.         VMax + ";" +
  363.         VMoyen + ";" +
  364.         Azimut + ";" +
  365.         Girouette + ";" +
  366.         " " + ";" +
  367.         Pluviometrie;
  368.       monFichier.println(Combe);
  369.       Serial.println("\n terminée." );
  370.       monFichier.close();
  371.     } else {
  372.       Serial.println("erreur d’ouverture du fichier Combe.txt" );
  373.     }
  374.     delay(5000);
  375.     // raz des variables d'accumulation de mesures
  376.     MoyenB = 0;
  377.     MoyenC = 0;
  378.     MoyenF = 0;
  379.     MoyenH = 0;
  380.     MoyenP = 0;
  381.     MoyenV = 0;
  382.     VentMax = 0;
  383.     pluvio1min = 0;
  384.     compteur = 0;
  385.   }
  386. }


 
A+,


Message édité par gilou le 04-09-2021 à 04:23:22

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-09-2021 à 08:21:11    

Merci, c'est effectivement plus clair.
 
Après essai, voici les corrections et questions en relation:
A la ligne 37 et 38, j'ai enlevé l'espace avant le L
A la ligne 260, cela ne passe pas tel quel. J'ai donc remplacé les deux Smois par Lmois. C'est accepté dans la compilation. A quoi sert le ! avant le = Lmois ?
J'ai fait un copier-coller. J'ai 423 ligne dans le copier et dans le coller, seulement 386. A priori, toutes les lignes vides ne sont pas prises en compte.
Lors de l'affichage Sérial, tous les caractères accentués sont remplacer par un ? inversé, alors que les textes n'ont pas changés par rapport aux versions précédentes par exemple : T° Baromètre C° devient Tʔ Baromʔtre Cʔ
 
Pour le moment cela tourne bien, je vais le laissé toute la journée. Je vais au forum des assos pour recruter de jeunes spéléos en devenir!!!

Reply

Marsh Posté le 04-09-2021 à 08:48:11    

Complément d'information, le pluviomètre compte bien la hauteur d'eau, mais le nombre de bascules d'auget reste à zéro dans le Sérial

Reply

Marsh Posté le 04-09-2021 à 11:25:09    

fpaude a écrit :

Merci, c'est effectivement plus clair.
 
Après essai, voici les corrections et questions en relation:
A la ligne 37 et 38, j'ai enlevé l'espace avant le L
A la ligne 260, cela ne passe pas tel quel. J'ai donc remplacé les deux Smois par Lmois. C'est accepté dans la compilation. A quoi sert le ! avant le = Lmois ?
J'ai fait un copier-coller. J'ai 423 ligne dans le copier et dans le coller, seulement 386. A priori, toutes les lignes vides ne sont pas prises en compte.
Lors de l'affichage Sérial, tous les caractères accentués sont remplacer par un ? inversé, alors que les textes n'ont pas changés par rapport aux versions précédentes par exemple : T° Baromètre C° devient Tʔ Baromʔtre Cʔ
 
Pour le moment cela tourne bien, je vais le laissé toute la journée. Je vais au forum des assos pour recruter de jeunes spéléos en devenir!!!


Si, les textes ont probablement changé d'encodage suite a mon édition sous emacs (ou a leur passage via un formateur en ligne), ça explique les ? en sortie.
Si ça se trouve, ils ont été tranformés en isolatin
 
> A la ligne 37 et 38, j'ai enlevé l'espace avant le L
C'est ce foutu formateur en ligne qui l'a mis  :fou: (j'utilise un formateur, car le forum n'a pas les mêmes idées sur l'indentation que mon emacs)  
 
Pour la ligne 260, si si, c'est tout a fait du bon C, != signifie pas égal, différent, c'est le contraire de ==
Bon, j'ai simplifié le code, et en plus j'ai vu que j'avais oublié de taper la ligne qui fait la sauvegarde :o et qui est essentielle au bon fonctionnement de l'algo
 
Bon, en te remettant tout dans le bon encodage (manifestement, la console ou tu affiches ton texte est en isolatin-1) ça donne ceci :

Code :
  1. // Bus
  2. #include <Wire.h>
  3. // chip
  4. #include <Arduino.h>
  5. // RTC
  6. #include <PCF85063TP.h>
  7. // senseur baromètre
  8. #include <HP20x_dev.h>
  9. // senseur température et humidité
  10. #include <DFRobot_SHT3x.h>
  11. // carte SD
  12. #include <SD.h>
  13. //port série
  14. #include <SPI.h>
  15. #include <KalmanFilter.h>
  16. PCD85063TP clock; //define a object of PCD85063TP class
  17. //DFRobot_SHT3x sht3x(&Wire,/*address=*/0x45,/*RST=*/4);
  18. DFRobot_SHT3x   sht3x;
  19. unsigned char ret = 0;
  20. File monFichier;
  21. /*
  22. * Variables statiques
  23. */
  24. #define PLUVIOMETRE 1   //pin D3, interruption n°1
  25. #define VALEUR_PLUVIOMETRE 0.2794 //valeur en mm d'eau à chaque bascule d'auget
  26. #define GIROUETTE   A1  //port analogique A1
  27. #define ANEMOMETRE 0   //pin D2, interruption n°0
  28. #define PI        3.1415
  29. #define RAYON     0.07  //rayon en mètre de l'anémomètre en mètre  
  30. unsigned long previousMillis = 0;
  31. unsigned long previousMillis2 = 0;
  32. unsigned long delaiAnemometre = 3000L;    //3 secondes
  33. unsigned long delaiProgramme = 60000L;   //60 sec
  34. float vitesseVent(0); //vent moyen cumulé sur 1 min
  35. float gust(0);        //vent max cumulé sur 1 min
  36. int nbAnemo = 0;      //nb d'occurence de mesure Anemo
  37. int nbGir = 0;        //nb d'occurence de mesure Girouette
  38. float pluvio1min(0);  //pluie sur 1 min
  39. float gir(0);         //direction moyenne de la girouette sur 1 min (en degrés)
  40. /*
  41. * Variables globales
  42. */
  43. volatile unsigned int countPluviometre = 0; //variable pour l'interruption du pluviometre pour compter les impulsions
  44. volatile unsigned int countAnemometre = 0;  //variable pour l'interruption de l'anémomètre pour compter les impulsions
  45. char direct[] = "";
  46. String Azimut, Lejour;
  47. // Tant que tu n'as pas un moyen de faire une mise a jour de la date autre que l'initialisation, c'est ici qu'il faut le faire
  48. int LAnnee = 2021;
  49. int Lmois = 8;
  50. int Ljour = 17;
  51. int Ljoursemaine = TUE;
  52. int Lheure = 7;
  53. int Lminute = 5;
  54. int Lseconde = 0;
  55. int compteur = 0;
  56. int SMois = 0;
  57. float TempB, TempC, TempF, Humid, PressA, Vent, MoyenB, MoyenC, MoyenF, MoyenH, MoyenP, MoyenV, VentMax(0);
  58. /*   
  59. *  Fonction d'interruption du pluviomètre qui incrémente un compteur à chaque impulsion
  60. */
  61. void interruptPluviometre() {
  62.   countPluviometre++;
  63. }
  64. /*   
  65. *  Fonction d'interruption de l'anémomètre qui incrémente un compteur à chaque impulsion
  66. */
  67. void interruptAnemometre() {
  68.   countAnemometre++;
  69. }
  70. void setup() {
  71.   Serial.begin(9600);        // série de démarrage pour la sortie
  72.   /* Mise sous tension, délai de 150 ms, jusqu'à  ce que la tension soit stable */
  73.   delay(150);
  74.  
  75.   /* Reset HP20x_dev */
  76.   HP20x.begin();
  77.   delay(100);
  78.  
  79.   //Initialize the chip
  80.   while (sht3x.begin() != 0) {
  81.     Serial.println("Échec de l'initialisation de la puce, vérifier la connexion du fil" );
  82.     delay(3000);
  83.     Serial.begin(9600);
  84.     clock.begin();
  85.     // toute cette partie la devra figurer dans un code de mise a jour de la clock
  86.     // par donnée de synchronisation externe, si tu en écris un plus tard
  87.     clock.stopClock();
  88.     clock.fillByYMD(LAnnee, Lmois,   Ljour);
  89.     clock.fillByHMS(Lheure, Lminute, Lseconde);
  90.     clock.fillDayOfWeek(Ljoursemaine);
  91.     clock.setTime();             // write time to the RTC chip
  92.     clock.startClock();
  93.     SMois = Lmois;
  94.     //clock.setcalibration(1, 32767.2);  // Réglage du décalage par fréquence d'horloge
  95.    
  96.     uint8_t ret = clock.calibratBySeconds(0, -0.000041);
  97.     Serial.print("offset value: " );
  98.     Serial.print("0x" );
  99.     Serial.println(ret, HEX);
  100.   }
  101.  
  102.   /**
  103.    * readSerialNumber Lire le numéro de série de la puce.
  104.    * Renvoie le numéro de série à 32 chiffres.
  105.    */
  106.   Serial.print("Numéro de série de la puce : " );
  107.   Serial.println(sht3x.readSerialNumber());
  108.   if (!sht3x.softReset()) {
  109.     Serial.println("Échec de l'initialisation de la puce...." );
  110.   }
  111.  
  112.   Serial.print("Initialisation de la carte SD..." );
  113.   pinMode(10, OUTPUT);
  114.   if (!SD.begin(4)) {
  115.     Serial.println("échec d'initialisation!" );
  116.     return;
  117.   }
  118.  
  119.   monFichier = SD.open("Combe.txt", FILE_WRITE);
  120.   if (monFichier) {
  121.     Serial.print("\nÉcriture dans Combe.txt..." );
  122.     // ligne d'en-têtes
  123.     monFichier.println("Date;Heure;Temp_BaroC;Temp_C;Temp_F;Humidite%;Pression;Vent max m/s;Vent moyen m/s;Azimut vent;Direction vent;Vent dominant;Pluie mm;" );
  124.     Serial.println("" );
  125.     monFichier.close();   
  126.   }
  127.  
  128.   Serial.println("initialisation effectuée." );
  129.   Serial.println("------------------Lecture en mode de mesure unique-----------------------" );
  130.  
  131.   pinMode(PLUVIOMETRE, INPUT_PULLUP);
  132.   attachInterrupt(PLUVIOMETRE, interruptPluviometre, RISING);
  133.  
  134.   pinMode(ANEMOMETRE, INPUT_PULLUP);
  135.   attachInterrupt(ANEMOMETRE, interruptAnemometre, RISING);
  136. }
  137. /*   
  138. *  Fonction qui converti en angle la valeur analogique renvoyée par l'arduino (valeurs fixes)
  139. *  RETURN : angle en degré
  140. */
  141. float getGirouetteAngle(int value) {
  142.   float angle = 0;
  143.   if (value > 280 && value < 290) {
  144.     angle = 180;
  145.     Azimut = "Sud";
  146.   } // Sud
  147.   if (value > 240 && value < 250) {
  148.     angle = 202.5;
  149.     Azimut = "SSO";
  150.   } // SSO
  151.   if (value > 628 && value < 636) {
  152.     angle = 225;
  153.     Azimut = "SO";
  154.   } // SO
  155.   if (value > 598 && value < 606) {
  156.     angle = 247.5;
  157.     Azimut = "OSO";
  158.   } // OSO
  159.   if (value > 940 && value < 950) {
  160.     angle = 270;
  161.     Azimut = "Ouest";
  162.   } // Ouest
  163.   if (value > 824 && value < 832) {
  164.     angle = 292.5;
  165.     Azimut = "ONO";
  166.   } // ONO
  167.   if (value > 884 && value < 892) {
  168.     angle = 315;
  169.     Azimut = "NO";
  170.   } // NO
  171.   if (value > 700 && value < 710) {
  172.     angle = 337.5;
  173.     Azimut = "NNO";
  174.   } // NNO
  175.   if (value > 784 && value < 792) {
  176.     angle = 0;
  177.     Azimut = "Nord";
  178.   } // Nord
  179.   if (value > 402 && value < 412) {
  180.     angle = 22.5;
  181.     Azimut = "NNE";
  182.   } // NNE
  183.   if (value > 458 && value < 468) {
  184.     angle = 45;
  185.     Azimut = "NE";
  186.   } // NE
  187.   if (value > 78 && value < 85) {
  188.     angle = 67.5;
  189.     Azimut = "ENE";
  190.   } // ENE
  191.   if (value > 88 && value < 98) {
  192.     angle = 90;
  193.     Azimut = "Est";
  194.   } // Est
  195.   if (value > 60 && value < 70) {
  196.     angle = 112.5;
  197.     Azimut = "ESE";
  198.   } // ESE
  199.   if (value > 180 && value < 190) {
  200.     angle = 135;
  201.     Azimut = "SE";
  202.   } // SE
  203.   if (value > 122 && value < 132) {
  204.     angle = 157.5;
  205.     Azimut = "SSE";
  206.   } // SSE
  207.   return angle;
  208. }
  209. void printTime() {
  210.   clock.getTime();
  211.   Lheure =   clock.hour;
  212.   Lminute =  clock.minute;
  213.   Lseconde = clock.second;
  214.   Ljour =    clock.dayOfMonth;
  215.   Lmois =    clock.month;
  216.  
  217.   switch (clock.dayOfWeek) {
  218.   case MON:
  219.     Lejour = "Lundi";
  220.     break;
  221.   case TUE:
  222.     Lejour = "Mardi";
  223.     break;
  224.   case WED:
  225.     Lejour = "Mercredi";
  226.     break;
  227.   case THU:
  228.     Lejour = "Jeudi";
  229.     break;
  230.   case FRI:
  231.     Lejour = "Vendredi";
  232.     break;
  233.   case SAT:
  234.     Lejour = "Samedi";
  235.     break;
  236.   case SUN:
  237.     Lejour = "Dimanche";
  238.     break;
  239.   default:
  240.     Lejour = "*Erreur*";
  241.     break;
  242.   }
  243.  
  244.   // Si on était en décembre et qu'on a changé de mois, donc on change d'année
  245.   if ((Smois == 12) && (Lmois == 1)) {
  246.     LAnnee++;
  247.   }
  248.   // et j'avais oublié de taper cette ligne essentielle, la sauvegarde du mois  
  249.   // pour détecter quand il a changé au le prochain appel a printTime
  250.   // Smois c'est Sauvegarde du mois (courant).   
  251.   Smois = Lmois;
  252.  
  253.   Serial.print("\n " );
  254.   Serial.print(Lheure);
  255.   Serial.print(":" );
  256.   Serial.print(Lminute);
  257.   Serial.print(":" );
  258.   Serial.print(Lseconde);
  259.   Serial.print("  " );
  260.   Serial.print(" " );
  261.   Serial.print(Lejour);
  262.   Serial.print(" " );
  263.   Serial.print(Ljour);
  264.   Serial.print("/" );
  265.   Serial.print(Lmois);
  266.   Serial.print("/" );
  267.   Serial.print(LAnnee);
  268. }
  269. void loop() {
  270.   printTime();
  271.   delay(30000);
  272.   compteur++;
  273.  
  274.   Serial.println("\n Données en cours :" );
  275.   // lecture des données
  276.   TempB = HP20x.ReadTemperature() / 100.0; 
  277.   TempC = sht3x.getTemperatureC();
  278.   TempF = sht3x.getTemperatureF();
  279.   Humid = sht3x.getHumidityRH();
  280.   PressA = HP20x.ReadPressure() / 100.0;
  281.   vitesseVent = (PI * RAYON * 2 * countAnemometre) / 3 * 3.6; //3 = durée de prise de mesure (3sec) m/s
  282.   if (vitesseVent > VentMax) {
  283.     VentMax = vitesseVent;
  284.   }
  285.   // cumul dans les variables d'accumulation de mesures
  286.   MoyenB += TempB;
  287.   MoyenC += TempC;
  288.   MoyenF += TempF;
  289.   MoyenH += Humid;
  290.   MoyenP += PressA;
  291.   MoyenV += vitesseVent;
  292.  
  293.   Serial.print("\n Compteur                   : " );
  294.   Serial.print(compteur);
  295.   Serial.print("\n T° Baromètre C°            : " );
  296.   Serial.print(TempB);
  297.   Serial.print("\n Température en Celsius     : " );
  298.   Serial.print(TempC);
  299.   Serial.print("\n Température en Farhenheit  : " );
  300.   Serial.print(TempF);
  301.   Serial.print("\n Humidite Relative(%RH)     : " );
  302.   Serial.print(Humid);
  303.   Serial.print("\n Pression actuelle en hPa   : " );
  304.   Serial.print(PressA);
  305.   //Récupération des infos de l'anémomètre et girouette toutes les 3 sec
  306.   unsigned long currentMillis = millis(); // read time passed
  307.   if (currentMillis - previousMillis > delaiAnemometre) {
  308.     previousMillis = millis();
  309.     nbAnemo++;
  310.     countAnemometre = 0;
  311.     int gdir = analogRead(GIROUETTE);
  312.     gir = getGirouetteAngle(gdir);
  313.     nbGir++;
  314. pluvio1min += countPluviometre * VALEUR_PLUVIOMETRE;
  315.     countPluviometre = 0;
  316.     Serial.print("\n Vent actuel en m/s         : " );
  317.     Serial.println(vitesseVent);
  318.     Serial.print(" Vitesse vent cumulée       : " );
  319.     Serial.println(MoyenV);
  320.     Serial.print(" N bascules du Pluviomètre  : " );
  321.     Serial.println(countPluviometre);
  322.     Serial.print(" Direction vent actuel      : " );
  323.     Serial.print(gir);
  324.     Serial.print("° " );
  325.     Serial.println(Azimut);
  326.     Serial.print(" Pluviométrie en mm         : " );
  327.     Serial.println(pluvio1min);
  328.     }
  329.  
  330.   //Enregistrement cumulé des valeurs
  331.   if (compteur == 30) {
  332.     // Calcul des valeurs moyennes pour les 30 mesures
  333.     MoyenB /= compteur;
  334.     MoyenC /= compteur;
  335.     MoyenF /= compteur;
  336.     MoyenH /= compteur;
  337.     MoyenP /= compteur;
  338.     MoyenV /= compteur;
  339.      
  340.     Serial.print("\n Écriture dans Grande Combe.txt..." );
  341.     Serial.print("\n température moyenne        : " );
  342.     Serial.print(MoyenB);
  343.     Serial.print("\n température moyenne C°     : " );
  344.     Serial.print(MoyenC);
  345.     Serial.print("\n température moyenne F      : " );
  346.     Serial.print(MoyenF);
  347.     Serial.print("\n Humidité moyenne           : " );
  348.     Serial.print(MoyenH);
  349.     Serial.print("\n Pression moyenne           : " );
  350.     Serial.print(MoyenP);
  351.     Serial.print("\n Vent moyen en m/s          : " );
  352.     Serial.print(MoyenV);
  353.     Serial.print("\n Vent Max en m/s            : " );
  354.     Serial.print(VentMax);
  355.     Serial.print("\n Pluviométrie en mm         : " );
  356.     Serial.println(pluvio1min);
  357.     monFichier = SD.open("Combe.txt", FILE_WRITE); //Maximum 8 caractères avant le .txt   
  358.     if (monFichier) {
  359.   String DateNomJour  = String(Lejour);
  360.   String DateNumJour  = String(Ljour);
  361.   String DateMois     = String(Lmois);
  362.   String DateHeure    = String(Lheure);
  363.   String DateMinute   = String(Lminute);
  364.   String DateSeconde  = String(Lseconde);
  365.   String TempBaro     = String(MoyenB);
  366.   String TemperatureC = String(MoyenC);
  367.   String TemperatureF = String(MoyenF);
  368.   String Humidite     = String(MoyenH);
  369.   String Pression     = String(MoyenP);
  370.   String VMoyen       = String(MoyenV);
  371.   String VMax         = String(VentMax); 
  372.   String Pluviometrie = String(pluvio1min);
  373.   String Girouette    = String(gir);
  374.   String Combe =
  375.         DateNomJour + " " + DateNumJour + "/" + DateMois + "/" + LAnnee + ";" +
  376.         DateHeure + ":" + DateMinute + ":" + DateSeconde + ";" +
  377.         TempBaro + ";" +
  378.         TemperatureC + ";" +
  379.         TemperatureF + ";" +
  380.         Humidite + ";" +
  381.         Pression + ";" +
  382.         VMax + ";" +
  383.         VMoyen + ";" +
  384.         Azimut + ";" +
  385.         Girouette + ";" +
  386.         " " + ";" +
  387.         Pluviometrie;
  388.   monFichier.println(Combe);
  389.       Serial.println("\n terminée." );
  390.   monFichier.close();
  391.     }
  392.     else {
  393.   Serial.println("erreur d'ouverture du fichier Combe.txt" );
  394.     }
  395.     delay(5000);
  396.     // raz des variables d'accumulation de mesures
  397.     MoyenB = 0;
  398.     MoyenC = 0;
  399.     MoyenF = 0;
  400.     MoyenH = 0;
  401.     MoyenP = 0;
  402.     MoyenV = 0;
  403.     VentMax = 0;
  404.     pluvio1min = 0;
  405.     compteur = 0;
  406.   }
  407. }


En y réfléchissant, c'est probablement le copier-coller depuis le forum qui fait le souk. Copies le dans un fichier texte que tu auras au préalable créé avec l'encodage ANSI dans le bloc-note et ça sera OK, je viens de vérifier.
A+,


Message édité par gilou le 04-09-2021 à 12:55:09

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-09-2021 à 15:51:58    

Dernier point :
 
Le début de setup devrait ressembler a ceci :

Code :
  1. void setup() {
  2. delay(150);    // Mise sous tension, délai de 150 ms, jusqu'à  ce que la tension soit stable  
  3. /* initialisation de l'interface de communication série */
  4. Serial.begin(9600);    // initialise la communication sur le port série en 9600 bauds, retour aux années 80...
  5.  
  6. Serial.println("** Instrumentation à la Grande Combe **" );
  7. Serial.println("Initialisation des capteurs" );
  8. /* initialisation de la RTC */
  9. clock.begin();
  10.     // toute cette partie la devra figurer dans un code de mise a jour de la clock
  11.     // par donnée de synchronisation externe, si tu en écris un plus tard
  12.     clock.stopClock();
  13.     clock.fillByYMD(LAnnee, Lmois,   Ljour);
  14.     clock.fillByHMS(Lheure, Lminute, Lseconde);
  15.     clock.fillDayOfWeek(Ljoursemaine);
  16.     clock.setTime();             // write time to the RTC chip
  17.     clock.startClock();
  18.     SMois = Lmois;
  19.     //clock.setcalibration(1, 32767.2);  // Réglage du décalage par fréquence d'horloge
  20.     uint8_t ret = clock.calibratBySeconds(0, -0.000041);
  21.     Serial.print("offset value: " );
  22.     Serial.print("0x" );
  23.     Serial.println(ret, HEX);
  24. /* initialisation du capteur de température/pression/altitude */
  25. HP20x.begin(); // l'interface est optimiste et n'envisage pas d'échec...
  26. delay(100);
  27.  
  28.   /* initialisation du capteur de température/humidité */
  29.   while (sht3x.begin()) { // Note : écrire une fonction qui renvoie 0 quand c'est bon, en C, ça mérite presque la lapidation au silex...
  30.     Serial.println("Échec de l'initialisation de la puce, vérifier la connexion du fil" );
  31.     delay(3000);
  32.   }
  33. ....


avec ce que tu as actuellement qui suit le test while (!sht3x.begin()) { , tu réinitalises la RTC a chaque tentative d'initialisation du capteur d'humidité, et il n'y a a priori aucune raison
 
Au fait, il y a une raison d'utiliser les deux capteurs de température ?
 
A+,


Message édité par gilou le 04-09-2021 à 21:47:02

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 05-09-2021 à 09:08:39    

Bonjour,
Voici les dernières nouvelles:
Sans savoir comment et pourquoi, les caractères accentués sont revenus.
La compilation ne passe toujours pas avec les deux Smois, mais accepte les Lmois.
L'ensemble a tourné hier toute le journée, arrêt pour lire les résultats, relance toute la nuit et lecture ce matin.
Les capteurs Pression et Humidité ont chacun également la température. Il y a une très légère différence environ 2/10 de degrés sur les moyennes, pourtant ils sont côte à côte. enregistrer les deux, c'est juste parce qu'ils sont là. Le baromètre a uniquement la température en Celsius, l'Humidité en Celsius et Fahrenheit. l'humidité est automatiquement donnée en % RH.
Tout cela va dans le bon sens, et encore un grand merci. Nous allons pouvoir envisager la mise en place dans la garrigue de la station, et les sondes destinées à aller sous terre à -80 mètres dans un lac (sondes autonomes et prévues pour cela)

Reply

Marsh Posté le 05-09-2021 à 11:17:37    

C'est ma faute pour les Smois, je viens de le voir.
Remplacer la déclaration  
int SMois = 0;
par
int Smois = 0;
avec un m minuscule
et idem dans les utilisations, et ça ira.
Ce qui donne :
 

Code :
  1. // Bus
  2. #include <Wire.h>
  3. // chip
  4. #include <Arduino.h>
  5. // RTC
  6. #include <PCF85063TP.h>
  7. // senseur baromètre
  8. #include <HP20x_dev.h>
  9. // senseur température et humidité
  10. #include <DFRobot_SHT3x.h>
  11. // carte SD
  12. #include <SD.h>
  13. //port série
  14. #include <SPI.h>
  15. #include <KalmanFilter.h>
  16. PCD85063TP clock; //define a object of PCD85063TP class
  17. //DFRobot_SHT3x sht3x(&Wire,/*address=*/0x45,/*RST=*/4);
  18. DFRobot_SHT3x   sht3x;
  19. unsigned char ret = 0;
  20. File monFichier;
  21. /*
  22. * Variables statiques
  23. */
  24. #define PLUVIOMETRE 1   //pin D3, interruption n°1
  25. #define VALEUR_PLUVIOMETRE 0.2794 //valeur en mm d'eau à chaque bascule d'auget
  26. #define GIROUETTE   A1  //port analogique A1
  27. #define ANEMOMETRE 0   //pin D2, interruption n°0
  28. #define PI        3.1415
  29. #define RAYON     0.07  //rayon en mètre de l'anémomètre en mètre  
  30. unsigned long previousMillis = 0;
  31. unsigned long previousMillis2 = 0;
  32. unsigned long delaiAnemometre = 3000L;    //3 secondes
  33. unsigned long delaiProgramme = 60000L;   //60 sec
  34. float vitesseVent(0); //vent moyen cumulé sur 1 min
  35. float gust(0);        //vent max cumulé sur 1 min
  36. int nbAnemo = 0;      //nb d'occurence de mesure Anemo
  37. int nbGir = 0;        //nb d'occurence de mesure Girouette
  38. float pluvio1min(0);  //pluie sur 1 min
  39. float gir(0);         //direction moyenne de la girouette sur 1 min (en degrés)
  40. /*
  41. * Variables globales
  42. */
  43. volatile unsigned int countPluviometre = 0; //variable pour l'interruption du pluviometre pour compter les impulsions
  44. volatile unsigned int countAnemometre = 0;  //variable pour l'interruption de l'anémomètre pour compter les impulsions
  45. char direct[] = "";
  46. String Azimut, Lejour;
  47. // Tant que tu n'as pas un moyen de faire une mise a jour de la date autre que l'initialisation, c'est ici qu'il faut le faire
  48. int LAnnee = 2021;
  49. int Lmois = 8;
  50. int Ljour = 17;
  51. int Ljoursemaine = TUE;
  52. int Lheure = 7;
  53. int Lminute = 5;
  54. int Lseconde = 0;
  55. int compteur = 0;
  56. int Smois = 0;
  57. float TempB, TempC, TempF, Humid, PressA, Vent, MoyenB, MoyenC, MoyenF, MoyenH, MoyenP, MoyenV, VentMax(0);
  58. /*   
  59. *  Fonction d'interruption du pluviomètre qui incrémente un compteur à chaque impulsion
  60. */
  61. void interruptPluviometre() {
  62.   countPluviometre++;
  63. }
  64. /*   
  65. *  Fonction d'interruption de l'anémomètre qui incrémente un compteur à chaque impulsion
  66. */
  67. void interruptAnemometre() {
  68.   countAnemometre++;
  69. }
  70. void setup() {
  71.     delay(150);    // Mise sous tension, délai de 150 ms, jusqu'à  ce que la tension soit stable  
  72.     /* initialisation de l'interface de communication série */
  73.     Serial.begin(9600);    // initialise la communication sur le port série en 9600 bauds, retour aux années 80...
  74.  
  75.     Serial.println("** Instrumentation à la Grande Combe **" );
  76.     Serial.println("Initialisation des capteurs" );
  77.     /* initialisation de la RTC */
  78.     clock.begin();
  79.     // toute cette partie la devra figurer dans un code de mise a jour de la clock
  80.     // par donnée de synchronisation externe, si tu en écris un plus tard
  81.     clock.stopClock();
  82.     clock.fillByYMD(LAnnee, Lmois,   Ljour);
  83.     clock.fillByHMS(Lheure, Lminute, Lseconde);
  84.     clock.fillDayOfWeek(Ljoursemaine);
  85.     clock.setTime();             // write time to the RTC chip
  86.     clock.startClock();
  87.     Smois = Lmois;
  88.     //clock.setcalibration(1, 32767.2);  // Réglage du décalage par fréquence d'horloge
  89.     uint8_t ret = clock.calibratBySeconds(0, -0.000041);
  90.     Serial.print("offset value: " );
  91.     Serial.print("0x" );
  92.     Serial.println(ret, HEX);
  93. /* initialisation du capteur de température/pression/altitude */
  94. HP20x.begin(); // l'interface est optimiste et n'envisage pas d'échec...
  95. delay(100);
  96.  
  97.   /* initialisation du capteur de température/humidité */
  98.   while (sht3x.begin()) { // Note : écrire une fonction qui renvoie 0 quand c'est bon, en C, ça mérite presque la lapidation au silex...
  99.     Serial.println("Échec de l'initialisation de la puce, vérifier la connexion du fil" );
  100.     delay(3000);
  101.   }
  102.  
  103.   /**
  104.    * readSerialNumber Lire le numéro de série de la puce.
  105.    * Renvoie le numéro de série à 32 chiffres.
  106.    */
  107.   Serial.print("Numéro de série de la puce : " );
  108.   Serial.println(sht3x.readSerialNumber());
  109.   if (!sht3x.softReset()) {
  110.     Serial.println("Échec de l'initialisation de la puce...." );
  111.   }
  112.  
  113.   Serial.print("Initialisation de la carte SD..." );
  114.   pinMode(10, OUTPUT);
  115.   if (!SD.begin(4)) {
  116.     Serial.println("échec d'initialisation!" );
  117.     return;
  118.   }
  119.  
  120.   monFichier = SD.open("Combe.txt", FILE_WRITE);
  121.   if (monFichier) {
  122.     Serial.print("\nÉcriture dans Combe.txt..." );
  123.     // ligne d'en-têtes
  124.     monFichier.println("Date;Heure;Temp_BaroC;Temp_C;Temp_F;Humidite%;Pression;Vent max m/s;Vent moyen m/s;Azimut vent;Direction vent;Vent dominant;Pluie mm;" );
  125.     Serial.println("" );
  126.     monFichier.close();   
  127.   }
  128.  
  129.   Serial.println("initialisation effectuée." );
  130.   Serial.println("------------------Lecture en mode de mesure unique-----------------------" );
  131.  
  132.   pinMode(PLUVIOMETRE, INPUT_PULLUP);
  133.   attachInterrupt(PLUVIOMETRE, interruptPluviometre, RISING);
  134.  
  135.   pinMode(ANEMOMETRE, INPUT_PULLUP);
  136.   attachInterrupt(ANEMOMETRE, interruptAnemometre, RISING);
  137. }
  138. /*   
  139. *  Fonction qui converti en angle la valeur analogique renvoyée par l'arduino (valeurs fixes)
  140. *  RETURN : angle en degré
  141. */
  142. float getGirouetteAngle(int value) {
  143.   float angle = 0;
  144.   if (value > 280 && value < 290) {
  145.     angle = 180;
  146.     Azimut = "Sud";
  147.   } // Sud
  148.   if (value > 240 && value < 250) {
  149.     angle = 202.5;
  150.     Azimut = "SSO";
  151.   } // SSO
  152.   if (value > 628 && value < 636) {
  153.     angle = 225;
  154.     Azimut = "SO";
  155.   } // SO
  156.   if (value > 598 && value < 606) {
  157.     angle = 247.5;
  158.     Azimut = "OSO";
  159.   } // OSO
  160.   if (value > 940 && value < 950) {
  161.     angle = 270;
  162.     Azimut = "Ouest";
  163.   } // Ouest
  164.   if (value > 824 && value < 832) {
  165.     angle = 292.5;
  166.     Azimut = "ONO";
  167.   } // ONO
  168.   if (value > 884 && value < 892) {
  169.     angle = 315;
  170.     Azimut = "NO";
  171.   } // NO
  172.   if (value > 700 && value < 710) {
  173.     angle = 337.5;
  174.     Azimut = "NNO";
  175.   } // NNO
  176.   if (value > 784 && value < 792) {
  177.     angle = 0;
  178.     Azimut = "Nord";
  179.   } // Nord
  180.   if (value > 402 && value < 412) {
  181.     angle = 22.5;
  182.     Azimut = "NNE";
  183.   } // NNE
  184.   if (value > 458 && value < 468) {
  185.     angle = 45;
  186.     Azimut = "NE";
  187.   } // NE
  188.   if (value > 78 && value < 85) {
  189.     angle = 67.5;
  190.     Azimut = "ENE";
  191.   } // ENE
  192.   if (value > 88 && value < 98) {
  193.     angle = 90;
  194.     Azimut = "Est";
  195.   } // Est
  196.   if (value > 60 && value < 70) {
  197.     angle = 112.5;
  198.     Azimut = "ESE";
  199.   } // ESE
  200.   if (value > 180 && value < 190) {
  201.     angle = 135;
  202.     Azimut = "SE";
  203.   } // SE
  204.   if (value > 122 && value < 132) {
  205.     angle = 157.5;
  206.     Azimut = "SSE";
  207.   } // SSE
  208.   return angle;
  209. }
  210. void printTime() {
  211.   clock.getTime();
  212.   Lheure =   clock.hour;
  213.   Lminute =  clock.minute;
  214.   Lseconde = clock.second;
  215.   Ljour =    clock.dayOfMonth;
  216.   Lmois =    clock.month;
  217.  
  218.   switch (clock.dayOfWeek) {
  219.   case MON:
  220.     Lejour = "Lundi";
  221.     break;
  222.   case TUE:
  223.     Lejour = "Mardi";
  224.     break;
  225.   case WED:
  226.     Lejour = "Mercredi";
  227.     break;
  228.   case THU:
  229.     Lejour = "Jeudi";
  230.     break;
  231.   case FRI:
  232.     Lejour = "Vendredi";
  233.     break;
  234.   case SAT:
  235.     Lejour = "Samedi";
  236.     break;
  237.   case SUN:
  238.     Lejour = "Dimanche";
  239.     break;
  240.   default:
  241.     Lejour = "*Erreur*";
  242.     break;
  243.   }
  244.  
  245.   // Si on était en décembre et qu'on a changé de mois, donc on change d'année
  246.   if ((Smois == 12) && (Lmois == 1)) {
  247.     LAnnee++;
  248.   }
  249.   // et j'avais oublié de taper cette ligne essentielle, la sauvegarde du mois  
  250.   // pour détecter quand il a changé au le prochain appel a printTime
  251.   // Smois c'est Sauvegarde du mois (courant).   
  252.   Smois = Lmois;
  253.  
  254.   Serial.print("\n " );
  255.   Serial.print(Lheure);
  256.   Serial.print(":" );
  257.   Serial.print(Lminute);
  258.   Serial.print(":" );
  259.   Serial.print(Lseconde);
  260.   Serial.print("  " );
  261.   Serial.print(" " );
  262.   Serial.print(Lejour);
  263.   Serial.print(" " );
  264.   Serial.print(Ljour);
  265.   Serial.print("/" );
  266.   Serial.print(Lmois);
  267.   Serial.print("/" );
  268.   Serial.print(LAnnee);
  269. }
  270. void loop() {
  271.   printTime();
  272.   delay(30000);
  273.   compteur++;
  274.  
  275.   Serial.println("\n Données en cours :" );
  276.   // lecture des données
  277.   TempB = HP20x.ReadTemperature() / 100.0; 
  278.   TempC = sht3x.getTemperatureC();
  279.   TempF = sht3x.getTemperatureF();
  280.   Humid = sht3x.getHumidityRH();
  281.   PressA = HP20x.ReadPressure() / 100.0;
  282.   vitesseVent = (PI * RAYON * 2 * countAnemometre) / 3 * 3.6; //3 = durée de prise de mesure (3sec) m/s
  283.   if (vitesseVent > VentMax) {
  284.     VentMax = vitesseVent;
  285.   }
  286.   // cumul dans les variables d'accumulation de mesures
  287.   MoyenB += TempB;
  288.   MoyenC += TempC;
  289.   MoyenF += TempF;
  290.   MoyenH += Humid;
  291.   MoyenP += PressA;
  292.   MoyenV += vitesseVent;
  293.  
  294.   Serial.print("\n Compteur                   : " );
  295.   Serial.print(compteur);
  296.   Serial.print("\n T° Baromètre C°            : " );
  297.   Serial.print(TempB);
  298.   Serial.print("\n Température en Celsius     : " );
  299.   Serial.print(TempC);
  300.   Serial.print("\n Température en Farhenheit  : " );
  301.   Serial.print(TempF);
  302.   Serial.print("\n Humidite Relative(%RH)     : " );
  303.   Serial.print(Humid);
  304.   Serial.print("\n Pression actuelle en hPa   : " );
  305.   Serial.print(PressA);
  306.   //Récupération des infos de l'anémomètre et girouette toutes les 3 sec
  307.   unsigned long currentMillis = millis(); // read time passed
  308.   if (currentMillis - previousMillis > delaiAnemometre) {
  309.     previousMillis = millis();
  310.     nbAnemo++;
  311.     countAnemometre = 0;
  312.     int gdir = analogRead(GIROUETTE);
  313.     gir = getGirouetteAngle(gdir);
  314.     nbGir++;
  315.    pluvio1min += countPluviometre * VALEUR_PLUVIOMETRE;
  316.     countPluviometre = 0;
  317.     Serial.print("\n Vent actuel en m/s         : " );
  318.     Serial.println(vitesseVent);
  319.     Serial.print(" Vitesse vent cumulée       : " );
  320.     Serial.println(MoyenV);
  321.     Serial.print(" N bascules du Pluviomètre  : " );
  322.     Serial.println(countPluviometre);
  323.     Serial.print(" Direction vent actuel      : " );
  324.     Serial.print(gir);
  325.     Serial.print("° " );
  326.     Serial.println(Azimut);
  327.     Serial.print(" Pluviométrie en mm         : " );
  328.     Serial.println(pluvio1min);
  329.     }
  330.  
  331.   //Enregistrement cumulé des valeurs
  332.   if (compteur == 30) {
  333.     // Calcul des valeurs moyennes pour les 30 mesures
  334.     MoyenB /= compteur;
  335.     MoyenC /= compteur;
  336.     MoyenF /= compteur;
  337.     MoyenH /= compteur;
  338.     MoyenP /= compteur;
  339.     MoyenV /= compteur;
  340.      
  341.     Serial.print("\n Écriture dans Grande Combe.txt..." );
  342.     Serial.print("\n température moyenne        : " );
  343.     Serial.print(MoyenB);
  344.     Serial.print("\n température moyenne C°     : " );
  345.     Serial.print(MoyenC);
  346.     Serial.print("\n température moyenne F      : " );
  347.     Serial.print(MoyenF);
  348.     Serial.print("\n Humidité moyenne           : " );
  349.     Serial.print(MoyenH);
  350.     Serial.print("\n Pression moyenne           : " );
  351.     Serial.print(MoyenP);
  352.     Serial.print("\n Vent moyen en m/s          : " );
  353.     Serial.print(MoyenV);
  354.     Serial.print("\n Vent Max en m/s            : " );
  355.     Serial.print(VentMax);
  356.     Serial.print("\n Pluviométrie en mm         : " );
  357.     Serial.println(pluvio1min);
  358.     monFichier = SD.open("Combe.txt", FILE_WRITE); //Maximum 8 caractères avant le .txt   
  359.     if (monFichier) {
  360. String DateNomJour  = String(Lejour);
  361. String DateNumJour  = String(Ljour);
  362. String DateMois     = String(Lmois);
  363. String DateHeure    = String(Lheure);
  364. String DateMinute   = String(Lminute);
  365. String DateSeconde  = String(Lseconde);
  366. String TempBaro     = String(MoyenB);
  367. String TemperatureC = String(MoyenC);
  368. String TemperatureF = String(MoyenF);
  369. String Humidite     = String(MoyenH);
  370. String Pression     = String(MoyenP);
  371. String VMoyen       = String(MoyenV);
  372. String VMax         = String(VentMax); 
  373. String Pluviometrie = String(pluvio1min);
  374. String Girouette    = String(gir);
  375. String Combe =
  376.         DateNomJour + " " + DateNumJour + "/" + DateMois + "/" + LAnnee + ";" +
  377.         DateHeure + ":" + DateMinute + ":" + DateSeconde + ";" +
  378.         TempBaro + ";" +
  379.         TemperatureC + ";" +
  380.         TemperatureF + ";" +
  381.         Humidite + ";" +
  382.         Pression + ";" +
  383.         VMax + ";" +
  384.         VMoyen + ";" +
  385.         Azimut + ";" +
  386.         Girouette + ";" +
  387.         " " + ";" +
  388.         Pluviometrie;
  389. monFichier.println(Combe);
  390.         Serial.println("\n terminée." );
  391. monFichier.close();
  392.     }
  393.     else {
  394. Serial.println("erreur d'ouverture du fichier Combe.txt" );
  395.     }
  396.     delay(5000);
  397.     // raz des variables d'accumulation de mesures
  398.     MoyenB = 0;
  399.     MoyenC = 0;
  400.     MoyenF = 0;
  401.     MoyenH = 0;
  402.     MoyenP = 0;
  403.     MoyenV = 0;
  404.     VentMax = 0;
  405.     pluvio1min = 0;
  406.     compteur = 0;
  407.   }
  408. }


 
Il reste quelques trucs dont je ne suis pas sur :

  • J'ai mis le premier delay(150) du setup avant le Serial.begin(9600) parce que ça me semblait plus logique, mais si tu constates un pb, remets les dans l'ordre inverse.
  • #include <KalmanFilter.h> : je pense que c'est pas utilisé ici. Retire la ligne, recompiles, et si ça passe, c'est bien que c'était inutile.


En tout cas, content de voir que mon diagnostic était le bon (maximum de descripteur de fichiers ouverts atteint).
 
A+,


Message édité par gilou le 05-09-2021 à 11:34:29

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 08-09-2021 à 22:34:43    

Bonsoir,
L'ensemble du code a été compilé sans soucis et mis en marche devant la clim (dans l'Aude, il fait chaud!) puis débranché et mis en place avec le panneau solaire sur le toit. Tout cela a été réalisé depuis lundi minuit jusqu'à aujourd'hui 22 h avec deux arrêt pour vérifier.
Tout semble correct dans les mesures.
Je ne pense pas que le "KalmanFilter.h" soit inutile car c'est lui qui convertit les angles de la girouette (valeur des résistances internes.)
Pour l'horloge, j'ai réussi à la régler à 30 secondes près, mais en utilisant le croquis du fournisseur. Les lignes de codes actuelles restent inopérantes sans raisons. A supprimer ou modifier?
L'Aude étant dès ce soir en alerte inondation, l'ensemble a été remis en place pour valider au mieux cet épisode Cévenol.
Je vous tiens au courant des dernières mesures, et d'ores et déjà un grand merci pour vos solutions.
Si vos pas vous approchent de l'Aude, c'est avec plaisir que je vous ferais découvrir la Spéléologie. :) ))

Reply

Marsh Posté le 08-09-2021 à 23:56:45    

> Si vos pas vous approchent de l'Aude, c'est avec plaisir que je vous ferais découvrir la Spéléologie.  
Merci pour l'invitation :) , mais ce n'est plus de mon age (j'ai passé la 60-aine, et ma condition physique n'est plus suffisante).
 
> Je ne pense pas que le "KalmanFilter.h" soit inutile car c'est lui qui convertit les angles de la girouette (valeur des résistances internes.)
 
A aucun moment n'est instancié de filtre, donc ce qui est dans KalmanFilter.h n'est pas utilisé.
Pour un exemple d'utilisation, voir ici : https://github.com/Seeed-Studio/Gro [...] x_demo.ino
Il y a instanciation du filtre :
 
KalmanFilter t_filter;    //temperature filter
 
Puis une utilisation dudit filtre sur la mesure renvoyée par le capteur
 
long Temper = HP20x.ReadTemperature();
    Serial.println("Temper:" );
    float t = Temper / 100.0;
    Serial.print(t);
    Serial.println("C.\n" );
    Serial.println("Filter:" );
    Serial.print(t_filter.Filter(t));
    Serial.println("C.\n" );
 
Cela est inexistant dans le code posté ici.
 
A+,


Message édité par gilou le 08-09-2021 à 23:57:32

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed