Go Down

Topic: Créer un fichier nouveau dans la carte SD chaque jour. (Read 172 times) previous topic - next topic

beyam78

Bonjour!
J'ai à ma disposition une carte arduino UNO, une carte GPS LoRa GPS/Shield, un détecteur de particules PM laser dust sensor et un module SD MicroSD Card Adapter muni d'une carte SD de 1Giga.
J'ai écrit un code qui récupère les données de la carte GPS (latitude, longitude, date et heure) et celles du détecteur de particules (concentrations PM1.0, PM2.5 et PM10) dans un fichier de la carte SD.
Voilà le code:
Code: [Select]


/**
 * Exemple de code Arduino pour un datalogger basique avec stockage sur carte SD.
 */

/* Dépendances */
#include <SPI.h> // Pour la communication SPI
#include <SD.h>  // Pour la communication avec la carte SD
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <Arduino.h>
#define LENG 31   //0x42 + 31 bytes equal to 32 bytes
unsigned char buf[LENG];
float flat, flon;
char sz[32];
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
//Le PIN SS de la carte GPS est relié à D5 et le pin SS de la carte GPS au pin D2
int GPS_SS=5;
int SD_SS=6;

/** Broche CS de la carte SD */
const byte SDCARD_CS_PIN = 6; // A remplacer suivant votre shield SD

/** Nom du fichier de sortie */
const char* OUTPUT_FILENAME = "gpspm4.csv";

/** Delai entre deux prise de mesures */
const unsigned long DELAY_BETWEEN_MEASURES = 1000;

int PM01Value=0;          //define PM1.0 value of the air detector module
int PM2_5Value=0;         //define PM2.5 value of the air detector module
int PM10Value=0;         //define PM10 value of the air detector module

/** Fichier de sortie avec les mesures */
File file;

TinyGPS gps;
SoftwareSerial ss(3, 4); // Arduino TX, RX ,

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

/** Fonction setup() */
void setup() {
  Serial.setTimeout(1500);
  pinMode(SD_SS, OUTPUT);
  pinMode(GPS_SS,OUTPUT);
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  Serial.begin(9600);           // start serial for output
  ss.begin(9600); // SoftSerial port to get GPS data.
  while (!Serial) {
     ;
  };

    /* Initialisation du port SPI */
  //Le module SD écoute et le module GPS est comme sourd et muet 
  digitalWrite(SD_SS,LOW);
  digitalWrite(GPS_SS,HIGH);
  /* Initialisation de la carte SD */
  Serial.println(F("Initialisation de la carte SD ... "));
  if (!SD.begin(SDCARD_CS_PIN)) {
    Serial.println(F("Erreur : Impossible d'initialiser la carte SD"));
    Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
    for (;;); // Attend appui sur bouton RESET
  }

  /* Ouvre le fichier de sortie en ecriture */
  Serial.println(F("Ouverture du fichier de sortie ... "));
  file = SD.open(OUTPUT_FILENAME, FILE_WRITE);
  if (!file) {
    Serial.println(F("Erreur : Impossible d'ouvrir le fichier de sortie"));
    Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
    for (;;); // Attend appui sur bouton RESET
  }
 
  /* Ajoute l'entete CSV si le fichier est vide */
  if (file.size() == 0) {
    Serial.println(F("Ecriture de l'entete CSV ..."));
    file.println(F("PM1.0- PM2.5- PM10 "    "-Long - Lat -    Date et Heure  "));
    file.flush();
  }
}


/** Fonction loop() */
void loop() {
  /*Le module GPS écoute et le module SD est comme sourd et muet*/ 
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
 
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_date(gps);
  gps.stats(&chars, &sentences, &failed);
  Serial.println();
 
  smartdelay(1000);
  //delay(1000);
  digitalWrite(SD_SS,LOW);
  digitalWrite(GPS_SS,HIGH);
  // Temps de la precedente mesure et de la mesure actuelle
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();

  /* Realise une prise de mesure toutes les DELAY_BETWEEN_MEASURES millisecondes */
  if (currentMillis - previousMillis >= DELAY_BETWEEN_MEASURES) {
    previousMillis = currentMillis;
    measure();
  }
   if(Serial.find(0x42)){    //start to read when detect 0x42
    Serial.readBytes(buf,LENG);

   if(buf[0] == 0x4d){
      if(checkValue(buf,LENG)){
        PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
        PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
        PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
      }           
    }
  }
}


static void smartdelay(unsigned long ms)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  unsigned long start = millis();
  do
  {
    while (ss.available())
    {
      //ss.print(Serial.read());
      gps.encode(ss.read());
    }
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len-1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
   
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        day, month, year, hour, minute, second);
    //Serial.print(sz);
  }
  smartdelay(0);
}

static void print_str(const char *str, int len)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}

char checkValue(unsigned char *thebuf, char leng)

  char receiveflag=0;
  int receiveSum=0;

  for(int i=0; i<(leng-2); i++){
  receiveSum=receiveSum+thebuf[i];
  }
  receiveSum=receiveSum + 0x42;
 
  if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1]))  //check the serial data
  {
    receiveSum = 0;
    receiveflag = 1;
  }
  return receiveflag;
}

int transmitPM01(unsigned char *thebuf)
{
  int PM01Val;
  PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
  return PM01Val;
}

//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }

//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module 
  return PM10Val;
}
/** Fonction de recuperation des donnees du GPS */

void measure() {
  digitalWrite(SD_SS,LOW);
  digitalWrite(GPS_SS,HIGH);
  /* Recupere les valeurs */
  float lon=flon;
  float lat=flat;
  float PM01 = PM01Value;
  float PM25 = PM2_5Value;
  float PM10 = PM10Value;
 
 
  /* Affiche les donnees sur le port serie pour tester si les valeurs sont bien recuperees */
  Serial.print(PM01);
  Serial.print(F("-  "));
  Serial.print(PM25);
  Serial.print(F("-  "));
  Serial.print(PM10);
  Serial.print(lon);
  Serial.print(F("-  "));
  Serial.print(lat);
  Serial.print(F("-  "));
  Serial.println(sz);
   
  /* Enregistre les donnees sur la carte SD */
  file.print(PM01);
  file.print(F("- "));
  file.print(PM25);
  file.print(F("- "));
  file.print(PM10);
  file.flush();
  file.print(lon);
  file.print(F("- "));
  file.print(lat);
  file.print(F("- "));
  file.println(sz);
  file.flush();
}

La capture du résultat du moniteur est joint à ce message.
Maintenant je veux que chaque jour il soit créé un fichier ayant comme nom la date actuelle (par exemple 11/07/2018.csv). Je ne suis pas très forte en programmation, j'attends vos suggestions excusez moi pour la longueur.

beyam78

J'ai pensé à un ou 2 trucs. D'abord pour le nom du fichier (OUTPUT_FILENAME) j'écris le code suivant:
char OUTPUT_FILENAME[10]={day,"_",month,"_",year}; pour que ça prenne la date et l'heure actuelle.
Puisque je peux récupérer l'heure grâce au GPS je me demandais si j'écris un
if((hour==00)&&(minute==00)&&(second==0)){
instruction qui permet de retourner au débutdu programme et de le reexecuter
}

Maintenant est-ce que cette instruction(ou fonction) existe?

lesept

Lorsque l'Arduino exécute ton programme, il exécute la loop en boucle (d'où son nom), donc ce que tu cherches à faire se fait naturellement. A toi d'écrire ton programme pour tirer parti de ça et obtenir ce que tu veux.

Dans ton cas, tu peux faire un test sur l'heure comme tu le suggères, et si le test est bon, tu fermes le fichier dans lequel tu écris, tu changes le nom du fichier dans lequel tu vas écrire (comme tu l'as proposé avec char OUTPUT_FILENAME), tu ouvres le nouveau fichier pour pouvoir écrire dedans et c'est suffisant. Le programme continuera ensuite à écrire régulièrement les données dans ton (nouveau) fichier.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

beyam78

Merci bcp!! J'ai écrit ce code:
Code: [Select]


/**
 * Exemple de code Arduino pour un datalogger basique avec stockage sur carte SD.
 */

/* Dépendances */
#include <SPI.h> // Pour la communication SPI
#include <SD.h>  // Pour la communication avec la carte SD
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <Arduino.h>
#define LENG 31   //0x42 + 31 bytes equal to 32 bytes
unsigned char buf[LENG];
int year;
byte month, day, hour, minute, second, hundredths;
float flat, flon;
char sz[32];
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
//Le PIN SS de la carte GPS est relié à D5 et le pin SS de la carte GPS au pin D2
int GPS_SS=5;
int SD_SS=6;

/** Broche CS de la carte SD */
const byte SDCARD_CS_PIN = 6; // A remplacer suivant votre shield SD

/** Nom du fichier de sortie au format jour_mois_année */
char OUTPUT_FILENAME[10]={day,"_",month,"_",year};

/** Delai entre deux prise de mesures */
const unsigned long DELAY_BETWEEN_MEASURES = 1000;

int PM01Value=0;          //define PM1.0 value of the air detector module
int PM2_5Value=0;         //define PM2.5 value of the air detector module
int PM10Value=0;         //define PM10 value of the air detector module

/** Fichier de sortie avec les mesures */
File file;

TinyGPS gps;
SoftwareSerial ss(3, 4); // Arduino TX, RX ,

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

/** Fonction setup() */
void setup() {
  Serial.setTimeout(1500);
  pinMode(SD_SS, OUTPUT);
  pinMode(GPS_SS,OUTPUT);
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  Serial.begin(9600);           // start serial for output
  ss.begin(9600); // SoftSerial port to get GPS data.
  while (!Serial) {
     ;
  };
  //Création du premier fichier ayant comme nom la date actuelle
  creerFichier();
}


/** Fonction loop() */
void loop() {
  
  /*Le module GPS écoute et le module SD est comme sourd et muet*/  
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_date(gps);
  gps.stats(&chars, &sentences, &failed);
  Serial.println();
  
  smartdelay(1000);
  //delay(1000);
  digitalWrite(SD_SS,LOW);
  digitalWrite(GPS_SS,HIGH);
  // Temps de la precedente mesure et de la mesure actuelle
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();

  /* Realise une prise de mesure toutes les DELAY_BETWEEN_MEASURES millisecondes */
  if (currentMillis - previousMillis >= DELAY_BETWEEN_MEASURES) {
    previousMillis = currentMillis;
    //Appel de la fonction measure
    measure();
  }
   if(Serial.find(0x42)){    //start to read when detect 0x42
    Serial.readBytes(buf,LENG);

   if(buf[0] == 0x4d){
      if(checkValue(buf,LENG)){
        PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
        PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
        PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
      }          
    }
  }
}


static void smartdelay(unsigned long ms)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  unsigned long start = millis();
  do
  {
    while (ss.available())
    {
      //ss.print(Serial.read());
      gps.encode(ss.read());
    }
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len-1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
    
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        day, month, year, hour, minute, second);
    //Serial.print(sz);
  }
  smartdelay(0);
}

static void print_str(const char *str, int len)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}

char checkValue(unsigned char *thebuf, char leng)
{  
  char receiveflag=0;
  int receiveSum=0;

  for(int i=0; i<(leng-2); i++){
  receiveSum=receiveSum+thebuf[i];
  }
  receiveSum=receiveSum + 0x42;
 
  if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1]))  //check the serial data
  {
    receiveSum = 0;
    receiveflag = 1;
  }
  return receiveflag;
}

int transmitPM01(unsigned char *thebuf)
{
  int PM01Val;
  PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
  return PM01Val;
}

//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }

//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module  
  return PM10Val;
}

/** Fonction de recuperation des donnees du GPS tant que la journée n'est pas finie, c'est à dire avant minuit */
void measure() {
  if((hour!=00)&&(minute!=00)&&(second!=00)){
  digitalWrite(SD_SS,LOW);
  digitalWrite(GPS_SS,HIGH);
  /* Recupere les valeurs */
  float lon=flon;
  float lat=flat;
  float PM01 = PM01Value;
  float PM25 = PM2_5Value;
  float PM10 = PM10Value;
  
 
  /* Affiche les donnees sur le port serie pour tester si les valeurs sont bien recuperees */
  Serial.print(PM01);
  Serial.print(F("-  "));
  Serial.print(PM25);
  Serial.print(F("-  "));
  Serial.print(PM10);
  Serial.print(lon);
  Serial.print(F("-  "));
  Serial.print(lat);
  Serial.print(F("-  "));
  Serial.println(sz);
                
  
  /* Enregistre les donnees sur la carte SD */
  file.print(PM01);
  file.print(F("- "));
  file.print(PM25);
  file.print(F("- "));
  file.print(PM10);
  file.flush();
  file.print(lon);
  file.print(F("- "));
  file.print(lat);
  file.print(F("- "));
  file.println(sz);
  file.flush();
  }
  /* S'il est minuit, on ferme le fichier actuel et on en crée un autre*/
  if((hour==00)&&(minute==00)&&(second==00)){
      file.close();
      creerFichier();  
  }
}
  /**Fonction pour créer un fichier*/
void creerFichier(){
    /* Initialisation du port SPI */
    //Le module SD écoute et le module GPS est comme sourd et muet
    digitalWrite(SD_SS,LOW);
    digitalWrite(GPS_SS,HIGH);
    /* Initialisation de la carte SD */
    Serial.println(F("Initialisation de la carte SD ... "));
    if (!SD.begin(SDCARD_CS_PIN)) {
      Serial.println(F("Erreur : Impossible d'initialiser la carte SD"));
      Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
      for (;;); // Attend appui sur bouton RESET
    }

    /* Ouvre le fichier de sortie en ecriture */
    Serial.println(F("Ouverture du fichier de sortie ... "));
    file = SD.open(OUTPUT_FILENAME, FILE_WRITE);
    if (!file) {
    Serial.println(F("Erreur : Impossible d'ouvrir le fichier de sortie"));
    Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
    for (;;); // Attend appui sur bouton RESET
  }
  
  /* Ajoute l'entete CSV si le fichier est vide */
    if (file.size() == 0) {
    Serial.println(F("Ecriture de l'entete CSV ..."));
    file.println(F("PM1.0- PM2.5- PM10 "    "-Long - Lat -    Date et Heure  "));
    file.flush();
  }
}

lesept

Je n'aurais pas fait comme ça, mais ça devrait fonctionner (j'ai lu rapidement...)
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Christian_R

if((hour==00)&&(minute==00)&&(second==0)){
instruction qui permet de retourner au débutdu programme et de le reexecuter
}


Cette condition est valide pendant 1 seconde complète, donc le programme va se relancer plusieurs fois si le temps d'exécution de la boucle est inférieur à la seconde.

Si le temps d'exécution dépasse 1 seconde, c'est le contraire, la condition de test risque de ne jamais être atteinte (si on saute de 23h59min59sec  à 00h00min02sec par ex.).

Il vaut mieux utiliser une inégalité dans le test, et un flag qui compte les relances.
Christian

fdufnews

Avec la librairies SD, les noms de fichiers doivent être de la forme 8.3.
8 caractères pour le nom + 3 caractères pour l'extension.

Le nom du fichier n'est jamais initialisé.

beyam78

fdufnews donc je ne peux pas créer une fichier ayant comme nom 12/07/2018.csv car c'est égal à 10 au lieu de 8. Est-ce que je peux créer un fichier ayant comme nom 12/07.csv avec la ligne de code
Code: [Select]
char OUTPUT_FILENAME[10]={hour,"_",minute,".csv"}; ou bien ce n'est pas possible? Je n'ai pas compris ce que vous voulez dire par ''le nom du fichier n'est jamais initialisé"?

beyam78

J'ai essayé de tester le code en modifiant quelques trucs pour le tester maintenant puisqu'il n'est pas encore minuit:
Code: [Select]


/**
 * Exemple de code Arduino pour un datalogger basique avec stockage sur carte SD.
 */

/* Dépendances */
#include <SPI.h> // Pour la communication SPI
#include <SD.h>  // Pour la communication avec la carte SD
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <Arduino.h>
#define LENG 31   //0x42 + 31 bytes equal to 32 bytes
unsigned char buf[LENG];
int year;
byte month, day, hour, minute, second, hundredths;
float flat, flon;
char sz[32];
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
//Le PIN SS de la carte GPS est relié à D5 et le pin SS de la carte GPS au pin D2
int GPS_SS=5;
int SD_SS=6;

/** Broche CS de la carte SD */
const byte SDCARD_CS_PIN = 6; // A remplacer suivant votre shield SD

/** Nom du fichier de sortie au format jour_mois_année */
char OUTPUT_FILENAME[10]={hour,"_",minute,".csv"};

/** Delai entre deux prise de mesures */
const unsigned long DELAY_BETWEEN_MEASURES = 1000;

int PM01Value=0;          //define PM1.0 value of the air detector module
int PM2_5Value=0;         //define PM2.5 value of the air detector module
int PM10Value=0;         //define PM10 value of the air detector module

/** Fichier de sortie avec les mesures */
File file;

TinyGPS gps;
SoftwareSerial ss(3, 4); // Arduino TX, RX ,

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

/** Fonction setup() */
void setup() {
  Serial.setTimeout(1500);
  pinMode(SD_SS, OUTPUT);
  pinMode(GPS_SS,OUTPUT);
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  Serial.begin(9600);           // start serial for output
  ss.begin(9600); // SoftSerial port to get GPS data.
  while (!Serial) {
     ;
  };
  //Création du premier fichier ayant comme nom la date actuelle
  creerFichier();
}


/** Fonction loop() */
void loop() {
  
  /*Le module GPS écoute et le module SD est comme sourd et muet*/  
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_date(gps);
  gps.stats(&chars, &sentences, &failed);
  Serial.println();
  
  smartdelay(1000);
  //delay(1000);
  digitalWrite(SD_SS,LOW);
  digitalWrite(GPS_SS,HIGH);
  // Temps de la precedente mesure et de la mesure actuelle
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();

  /* Realise une prise de mesure toutes les DELAY_BETWEEN_MEASURES millisecondes */
  if (currentMillis - previousMillis >= DELAY_BETWEEN_MEASURES) {
    previousMillis = currentMillis;
    //Appel de la fonction measure
    measure();
  }
   if(Serial.find(0x42)){    //start to read when detect 0x42
    Serial.readBytes(buf,LENG);

   if(buf[0] == 0x4d){
      if(checkValue(buf,LENG)){
        PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
        PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
        PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
      }          
    }
  }
}


static void smartdelay(unsigned long ms)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  unsigned long start = millis();
  do
  {
    while (ss.available())
    {
      //ss.print(Serial.read());
      gps.encode(ss.read());
    }
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len-1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
    
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        day, month, year, hour, minute, second);
    //Serial.print(sz);
  }
  smartdelay(0);
}

static void print_str(const char *str, int len)
{
  digitalWrite(SD_SS,HIGH);
  digitalWrite(GPS_SS,LOW);
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}

char checkValue(unsigned char *thebuf, char leng)
{  
  char receiveflag=0;
  int receiveSum=0;

  for(int i=0; i<(leng-2); i++){
  receiveSum=receiveSum+thebuf[i];
  }
  receiveSum=receiveSum + 0x42;
 
  if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1]))  //check the serial data
  {
    receiveSum = 0;
    receiveflag = 1;
  }
  return receiveflag;
}

int transmitPM01(unsigned char *thebuf)
{
  int PM01Val;
  PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
  return PM01Val;
}

//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }

//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module  
  return PM10Val;
}

/** Fonction de recuperation des donnees du GPS tant que la journée n'est pas finie, c'est à dire avant minuit */
void measure() {
  if((hour==12)&&(minute==11)){
  digitalWrite(SD_SS,LOW);
  digitalWrite(GPS_SS,HIGH);
  /* Recupere les valeurs */
  float lon=flon;
  float lat=flat;
  float PM01 = PM01Value;
  float PM25 = PM2_5Value;
  float PM10 = PM10Value;
  
 
  /* Affiche les donnees sur le port serie pour tester si les valeurs sont bien recuperees */
  Serial.print(PM01);
  Serial.print(F("-  "));
  Serial.print(PM25);
  Serial.print(F("-  "));
  Serial.print(PM10);
  Serial.print(lon);
  Serial.print(F("-  "));
  Serial.print(lat);
  Serial.print(F("-  "));
  Serial.println(sz);
                
  
  /* Enregistre les donnees sur la carte SD */
  file.print(PM01);
  file.print(F("- "));
  file.print(PM25);
  file.print(F("- "));
  file.print(PM10);
  file.flush();
  file.print(lon);
  file.print(F("- "));
  file.print(lat);
  file.print(F("- "));
  file.println(sz);
  file.flush();
  }
  /* S'il est minuit, on ferme le fichier actuel et on en crée un autre*/
  else {
      file.close();
      creerFichier();  
  }
}
  /**Fonction pour créer un fichier*/
void creerFichier(){
    /* Initialisation du port SPI */
    //Le module SD écoute et le module GPS est comme sourd et muet
    digitalWrite(SD_SS,LOW);
    digitalWrite(GPS_SS,HIGH);
    /* Initialisation de la carte SD */
    Serial.println(F("Initialisation de la carte SD ... "));
    if (!SD.begin(SDCARD_CS_PIN)) {
      Serial.println(F("Erreur : Impossible d'initialiser la carte SD"));
      Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
      for (;;); // Attend appui sur bouton RESET
    }

    /* Ouvre le fichier de sortie en ecriture */
    Serial.println(F("Ouverture du fichier de sortie ... "));
    file = SD.open(OUTPUT_FILENAME, FILE_WRITE);
    if (!file) {
    Serial.println(F("Erreur : Impossible d'ouvrir le fichier de sortie"));
    Serial.println(F("Verifiez la carte SD et appuyez sur le bouton RESET"));
    for (;;); // Attend appui sur bouton RESET
  }
  
  /* Ajoute l'entete CSV si le fichier est vide */
    if (file.size() == 0) {
    Serial.println(F("Ecriture de l'entete CSV ..."));
    file.println(F("PM1.0- PM2.5- PM10 "    "-Long - Lat -    Date et Heure  "));
    file.flush();
  }
}



beyam78

La compilation ne donne aucune erreur et j'ai joint la capture du moniteur à ce message.
Aussi aucun fichier n'est créé dans la carte mémoire. Je ne vois aucun fichier quand j'execute ListFile. Je ne comprends pas d'où vient le problème.

fdufnews

Après chaque accès au fichier il faut penser à le fermer. Sinon tu vas le perdre lors d'un reset ou d'un plantage du logiciel.

fdufnews donc je ne peux pas créer une fichier ayant comme nom 12/07/2018.csv car c'est égal à 10 au lieu de 8. Est-ce que je peux créer un fichier ayant comme nom 12/07.csv avec la ligne de code
Code: [Select]
char OUTPUT_FILENAME[10]={hour,"_",minute,".csv"}; ou bien ce n'est pas possible? Je n'ai pas compris ce que vous voulez dire par ''le nom du fichier n'est jamais initialisé"?
Le séparateur / a un sens particulier lorsqu'on parle de système de fichier. Un conseil, si tu veux trier tes fichiers facilement plus tard il vaut mieux coder leur nom sous la forme année,mois, jour comme ça par exemple:
20180712.CSV. Lorsque tu liras la carte un tri sur le nom correspondra aussi à la chronologie des fichiers. Ne pas oublier que la librairie SD ne gère pas le champ date des fichiers.
Concernant l'initialisation du nom de fichier à aucun endroit de ton code tu ne places une chaine de caractères avec la date dans la variable OUTPUT_FILENAME. Fais un print de cette variable et tu comprendras.

Go Up