Problème création fichiers sur micro sd

Bonjour
j ai besoin de stocker des infos sur une carte sd et je souhaiterais créer un fichier . txt avec comme non la date, le mois et l'année a chaque début de mois.
je dois dire que je suis pas un pro en c et deja quand j ai commencer a ecrire un code avec mes idées j etais tres loin de ce code que j'ai trouvé sur les forums mais chez moi ca fonctionne pas le fichiers ne se créer pas du tout sur la carte et quand je fais un dir j ai un ce message d erreur [3945051][E][vfs_api.cpp:27] open(): 17052022.txt does not start with /

j'ai pu créer des fichiers et les nommés comme je le souhaite en suivant les commande de la biblio sd.card mais des que je veux utilise le code du dessous rien ne se crée sur ma carte.

c est sur une esp 32 lecteur de carte azdelivry sous visual studio code

merci de votre aide

File fichier;
char datafile[13];
int jour=now.day();
int mois = now.month();
int annee= now.year(); 
sprintf(datafile,"%02d%02d%04d.txt",jour,mois,annee);  //  %d pour un int 
datafile[13]='\0';
fichier = SD.open(datafile, FILE_WRITE);
listDir(SD, "/",0);

cette case mémoire n'existe pas, les indices vont de 0 à 12 (13 caractères) ➜ vous écrasez quelque chose en mémoire, c'est un bug

sprintf rajoutera pour vous le caractère nul de toutes façons donc pas la peine de faire ça

On suppose, puisqu'on a pas tout le code, que l'initialisation de la carte s'est bien déroulée.
Et il faudrait sans doute fermer le fichier à la fin pour qu'il soit physiquement écrit sur la carte.

j ai corriger comme ca mais ca marche pas mieux ,en fait j ai du mal a comprendre le fonctionnement de tout ca c est bien fichier que je dois fermer?

et oui l initialisation s'est bien passé, j ai pu crée de fichiers en traditionnelle mais la je comprends pas

File fichier;
char datafile[13];
int jour=now.day();
int mois = now.month();
int annee= now.year(); 
sprintf(datafile,"%02d%02d%04d.txt",jour,mois,annee);  //  %d pour un int 
datafile[13];
fichier = SD.open(datafile, FILE_WRITE);
fichier.close();
listDir(SD, "/",0);

c'est quoi ça ??

postez TOUT le code qui compile. ensuite on pourra discuter

comme je l' ai dit plus haut j ai récupéré ce code sur un autre post.

je n ai rien de plus en code que ca j ai juste chercher sur google " creer un fichier.txt sur une carte sd avec comme nom la date du jours" et je suis tombe sur ce code, c est sur le forum arduino il me semble mais je sais plus ou.
datafile [13] j ai cru comprendre que c'était pour la fonction sprintf pour ne pas prendre plus de 13 caractères

Le code que vous avez posté ne compile pas s’il n’est pas dans un sketch complet avec setup et loop… postez le code complet.

Je parle du datafile [13] qui traine au milieu du code pas de la définition en en tête

oui moi aussi je parlais du meme au depart il y avait datafile[13]='\0' vous m avez dit que le \0 servait a rien et la fonction le faisait automatiquement donc j ai retire le \0.

j ai virer le "datafile 13" du coup mais ca fonctionne pas mieux mon fichier.txt a la date du jours ne se créer pas sur ma carte

enfin voila le code complet

#include <Arduino.h>

#include <esp_now.h>// https://github.com/espressif/esp-idf/blob/master/components/esp_wifi/include/esp_now.h
#include <WiFi.h>
#include <Wire.h>
#include "RTClib.h"
#include "FS.h"
#include "SPIFFS.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h> 
#include <SD.h>

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);



/****************************/
/*****config RCTime**********/
/****************************/
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {
"Dimanche",
"Lundi",
"Mardi", 
"Mercredi",
"Jeudi",
"Vendredi",
"Samedi"
};

///////fin config RTC


/**********************************/
/************config ecran***********/
/**********************************/


const unsigned char Logo [] PROGMEM =

 {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
	
 


////////fin config ecran

/*****************************************/
/*****config Capteur_Temperature**********/
/*****************************************/

const byte BROCHE_ONEWIRE = 32; // Broche du signal capteur bus 1-Wire 
float temperature; // declaration d'une variable à virgule pour lecture temperature

/* Code de retour de la fonction getTemperature() */
enum DS18B20_RCODES
 {
  READ_OK,  // Lecture ok
  NO_SENSOR_FOUND,  // Pas de capteur
  INVALID_ADDRESS,  // Adresse reçue invalide
  INVALID_SENSOR  // Capteur invalide (pas un DS18B20)
 };

OneWire ds(BROCHE_ONEWIRE);// Création de l'objet OneWire pour manipuler le bus 1-Wire 
 
/*****************************************************************************************************************/ 
/******************Fonction de lecture de la température via un capteur DS18B20.**********************************/
/*****************************************************************************************************************/

byte getTemperature(float *temperature, byte reset_search) 
{
  byte data[9], addr[8];  // data[] : Données lues depuis le scratchpad   addr[] : Adresse du module 1-Wire détecté
    
  if (reset_search)   // Reset le bus 1-Wire ci nécessaire (requis pour la lecture du premier capteur) 
     {
      ds.reset_search();
     }
 
  if (!ds.search(addr)) // Recherche le prochain capteur 1-Wire disponible 
     {
       return NO_SENSOR_FOUND;// Pas de capteur
     }
    
  if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue 
     {
       return INVALID_ADDRESS; // Adresse invalide si differend de 7
     }
 
  if (addr[0] != 0x28)    // Vérifie qu'il s'agit bien d'un DS18B20 
     {
       return INVALID_SENSOR; // Mauvais type de capteur si differend de 0x28
     }
 
  /* Reset le bus 1-Wire et sélectionne le capteur */
     ds.reset();
     ds.select(addr);
  
  /* Lance une prise de mesure de température et attend la fin de la mesure */
     ds.write(0x44, 1);
     delay(800);
  
  /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
     ds.reset();
     ds.select(addr);
     ds.write(0xBE);
 
 /* Lecture du scratchpad */
  for (byte i = 0; i < 9; i++) 
      {
      data[i] = ds.read();
      }
      *temperature = (int16_t) ((data[1] << 8) | data[0]) * 0.0625; // Calcul de la température en degré Celsius 
  
  return READ_OK; // Pas d'erreur
}

/***********fin config Capteur_temperature**************/

/**********************************************************************/
/*****************Config SDcard****************************************/
/**********************************************************************/
/****Cablage de la carte comme suit determiné par la librairie SD.H****/
/*    MOSI - pin 23                                                 */
/*    MISO - pin 19                                                   */
/*    SCK - pin 18                                                    */
/*    CS - pin 5 (for MKRZero SD: SDCARD_SS_PIN)                      */
/**********************************************************************/
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
  Serial.printf("Listing directory: %s\n", dirname);

  File root = fs.open(dirname);
  if(!root){
    Serial.println("Failed to open directory");
    return;
  }
  if(!root.isDirectory()){
    Serial.println("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while(file){
    if(file.isDirectory()){
      Serial.print("  DIR : ");
      Serial.println(file.name());
      if(levels){
        listDir(fs, file.name(), levels -1);
      }
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}

void createDir(fs::FS &fs, const char * path){
  Serial.printf("Creating Dir: %s\n", path);
  if(fs.mkdir(path)){
    Serial.println("Dir created");
  } else {
    Serial.println("mkdir failed");
  }
}

void removeDir(fs::FS &fs, const char * path){
  Serial.printf("Removing Dir: %s\n", path);
  if(fs.rmdir(path)){
    Serial.println("Dir removed");
  } else {
    Serial.println("rmdir failed");
  }
}

void readFile(fs::FS &fs, const char * path){
  Serial.printf("Reading file: %s\n", path);

  File file = fs.open(path);
  if(!file){
    Serial.println("Failed to open file for reading");
    return;
  }

  Serial.print("Read from file: ");
  while(file.available()){
    Serial.write(file.read());
  }
  file.close();
}

void writeFile(fs::FS &fs, const char * path, const char * message){
  Serial.printf("Writing file: %s\n", path);

  File file = fs.open(path, FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file for writing");
    return;
  }
  if(file.print(message)){
    Serial.println("File written");
  } else {
    Serial.println("Write failed");
  }
  file.close();
}

void appendFile(fs::FS &fs, const char * path, const char * message){
  Serial.printf("Appending to file: %s\n", path);

  File file = fs.open(path, FILE_APPEND);
  if(!file){
    Serial.println("Failed to open file for appending");
    return;
  }
  if(file.print(message)){
      Serial.println("Message appended");
  } else {
    Serial.println("Append failed");
  }
  file.close();
}

void renameFile(fs::FS &fs, const char * path1, const char * path2){
  Serial.printf("Renaming file %s to %s\n", path1, path2);
  if (fs.rename(path1, path2)) {
    Serial.println("File renamed");
  } else {
    Serial.println("Rename failed");
  }
}

void deleteFile(fs::FS &fs, const char * path){
  Serial.printf("Deleting file: %s\n", path);
  if(fs.remove(path)){
    Serial.println("File deleted");
  } else {
    Serial.println("Delete failed");
  }
}

void testFileIO(fs::FS &fs, const char * path){
  File file = fs.open(path);
  static uint8_t buf[512];
  size_t len = 0;
  uint32_t start = millis();
  uint32_t end = start;
  if(file){
    len = file.size();
    size_t flen = len;
    start = millis();
    while(len){
      size_t toRead = len;
      if(toRead > 512){
        toRead = 512;
      }
      file.read(buf, toRead);
      len -= toRead;
    }
    end = millis() - start;
    Serial.printf("%u bytes read for %u ms\n", flen, end);
    file.close();
  } else {
    Serial.println("Failed to open file for reading");
  }


  file = fs.open(path, FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file for writing");
    return;
  }

  size_t i;
  start = millis();
  for(i=0; i<2048; i++){
    file.write(buf, 512);
  }
  end = millis() - start;
  Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
  file.close();
}



/*********************fin config sd_Card****************************/





/******************************************************/
/**************Variables_Globales**********************/
/******************************************************/
  



/**********Fin déclaration variables globales*********/


void setup() {
  
  
  // Init Serial Monitor
  Serial.begin(115200);

  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  

/************************************************/
/************setup_RCTime_module_clock***********/
/************************************************/
rtc.begin();
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); prends la date et l'heure du pc au moment de la compilation
/* pour mettre la date et l'heure manuellement decommenter la ligne suivante ,mettre les bonnes dates et heure compilé et uploader 
en manuel: année, mois, jour, heure, minute et secondes.Attention 20 a 30sec d'avance peuvent etre necessaires pour compiler et transferer. une fois transferé,
remettre la ligne de reglage date en commentaire, stoper l esp 32, retirer l horloge, rallumer, recompiler et transfere le programme avec les ligne en commentaire
afin que le programme n'ajuste pas l heure a chaque demarrage*/
//rtc.adjust(DateTime(2022, 3, 2, 10, 46, 0));


/**************fin setup RCTime**************************/

/*********************************************************/
/************setup_ecran_Oled_monochrome_128*64***********/
/*********************************************************/
Serial.println("OLED FeatherWing test");
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x64

  Serial.println("OLED begun");

  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(1000);

  // Clear the buffer.
  display.clearDisplay();
  display.display();

  // text display tests
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.print("Connecting to SSID\n'adafruit':");
  display.print("connected!");
  display.println("IP: 10.0.1.23");
  display.println("Sending val #0");
  display.setCursor(0,0);
  display.display(); // actually display all of the above

/*****************Affichage_logo**************/
display.clearDisplay();
display.fillScreen(SSD1306_BLACK);
int16_t positionImageAxeHorizontal = 0;     // Position de la gauche de l’image à 0 pixels du bord gauche de l’écran
int16_t positionImageAxeVertical = 22;       // Position du haut de l’image à 22 pixels du bord haut de l’écran OLED
int16_t largeurDeLimage = 126;                // Largeur de l’image à afficher : 126 pixels
int16_t hauteurDeLimage = 19;                // Hauteur de l’image à afficher : 19 pixels
display.drawBitmap(positionImageAxeHorizontal, positionImageAxeVertical, Logo, largeurDeLimage, hauteurDeLimage, WHITE);
display.display();
delay(5000);
/*************************fin setup ecran**************************/


/**********************************/
/************setup SD_Card***********/
/**********************************/
 if(!SD.begin(5)){
    Serial.println("Card Mount Failed");
    return;
  }
  
  // afficher le type de carte 
  uint8_t cardType = SD.cardType();

  if(cardType == CARD_NONE){
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if(cardType == CARD_MMC){
    Serial.println("MMC");
  } else if(cardType == CARD_SD){
    Serial.println("SDSC");
  } else if(cardType == CARD_SDHC){
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }
// afficher la taille de carte 
  uint64_t cardSize = SD.cardSize() / (1024 * 1024); 
  Serial.printf("SD Card Size: %lluMB\n", cardSize);

  listDir(SD, "/", 0);
  createDir(SD, "/mydir");
  listDir(SD, "/", 0);
  removeDir(SD, "/mydir");
  listDir(SD, "/", 2);
  writeFile(SD, "/hello.txt", "Hello ");
  appendFile(SD, "/hello.txt", "World!\n");
  readFile(SD, "/hello.txt");
  deleteFile(SD, "/foo.txt");
  renameFile(SD, "/hello.txt", "/foo.txt");
  readFile(SD, "/foo.txt");
  //testFileIO(SD, "/foo.txt"); trop de temps pour tester l'ecriture sur la carte
  Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));


////////fin setup SD_card


}

void loop() {


DateTime now = rtc.now();

// text display tests
  display.clearDisplay();
  display.fillScreen(SSD1306_BLACK);
  delay(200);
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  
  
  
        display.print(daysOfTheWeek[now.dayOfTheWeek()]);// affichage du jour de la semaine
        display.print(" ");
  
     /* Affichage de la date du jour */
     if (now.day() < 10) 
     {
        display.print("0");
        display.print(now.day());
     }
     else 
     {
        display.print(now.day(), DEC);
     }
        display.print('/');
     
     /*Affichage du mois*/    
     
     if (now.month() < 10) 
     {
        display.print("0");
        display.print(now.month());
     }
     else 
     {
        display.print(now.month(), DEC);
     }
        display.print('/');
        display.print(now.year(), DEC);
        display.println(" ");

      /*Affichage de l'heure */ 
         display.setCursor(40,10);
     if (now.hour() < 10) 
     {
         display.print("0");
     }
         display.print(now.hour(),DEC);
         display.print(":");
     
     /* Affichage des minutes*/
     if (now.minute() < 10) 
     {
         display.print("0");
     }
         display.print(now.minute(),DEC);
         display.print(":");
  
      /* Affichage des secondes*/
     if (now.second() < 10)
     {
        display.print("0");
     }
        display.println(now.second(),DEC);
        //display.setCursor(0,0);
        //display.display(); // actually display all of the above



 /* Lit la température ambiante à ~1Hz */
  if (getTemperature(&temperature, true) != READ_OK) 
  {
    Serial.println(F("Erreur de lecture du capteur"));
    return;
  }

  /* Affiche la température */
    display.setCursor(30,25);
    display.println(F("Temperature"));
    display.setCursor(40,35);
    display.print(temperature, 2);
    display.print((char)247);
    display.print("C");
    display.display();
    


  if ((now.minute()==00)&&(now.second()==00))
  {
  Serial.println(now.timestamp(DateTime::TIMESTAMP_DATE)+String(";")+now.timestamp(DateTime::TIMESTAMP_TIME)+String(";")+temperature);
  }

  /*essais creation fichiers.txt date du jours sur la carte sd*/

   File fichier;
   char datafile[13];
   int jour=now.day();
   int mois = now.month();
   int annee= now.year(); 
   sprintf(datafile,"%02d%02d%04d.txt",jour,mois,annee);  //  %d pour un int 
   fichier = SD.open(datafile, FILE_WRITE);
   fichier.close();
   listDir(SD, "/",0);
 
/****************************************************************************/
  
 
 delay(10);


}

essayez de mettre quelque chose dedans avant de le fermer

justement comment je mets quelque chose dedans ?
car c est ma deuxième problématique lorsque je crée un fichier avec comme nom la dates comment je le rappel pour écrire dedans puisque la fonction appendFile utilise le nom exact du fichier créer?

cdt

essayez de faire

File fichier;
char datafile[] = "18052020.txt";
fichier = SD.open(datafile, FILE_WRITE);
fichier.println("coucou");
fichier.close();

voici le message d'erreur qui m est donnée et le fichier n est pas sur la carte sd
Listing directory: /
DIR : System Volume Information
FILE: test.txt SIZE: 0
FILE: foo.txt SIZE: 13
FILE: Curent_File.txt SIZE: 5
[ 39554][E][vfs_api.cpp:27] open(): 18052020.txt does not start with /

voici la modif prog

File fichier;
char datafile[] = "18052020.txt";
int jour=now.day();
int mois = now.month();
int annee= now.year(); 

fichier = SD.open(datafile, FILE_WRITE);
fichier.println("coucou");
fichier.close();
listDir(SD, "/",0);

essayez avec un / au début alors

File fichier;
char datafile[] = "/18052020.txt";
fichier = SD.open(datafile, FILE_WRITE);
if (fichier) {
  fichier.println("coucou");
  fichier.close();
} else {
  Serial.println("Erreur");
}

listDir(SD, "/",0);

ca fonctionne avec le slash comme vous m avez dit du coup j ai teste le slash avec mon ancien bout de prog dans le sprintf et c est ok le fichier est bien crée sur la carte
par contre ma deuxieme question je vais crée un fichier en debut de mois et enregistré des données tous le mois dois je fermé le fichier et ouvrir a chaque enregistrement de données et est ce que utiliser la fonction est fonctionnel

 fichier = SD.open(datafile, FILE_WRITE); 
 fichier.println("mesdonnées")
File fichier;
char datafile[13];
int jour=now.day();
int mois = now.month();
int annee= now.year(); 
sprintf(datafile,"/%02d%02d%04d.txt",jour,mois,annee);  //  %d pour un int 
fichier = SD.open(datafile, FILE_WRITE);
fichier.println("coucou");
fichier.close();
listDir(SD, "/",0);

je fais la reponse parceque je viens de tester

ouvrir , fermer et enregistrer plusieurs fois fonctionne mais faut que je travaille sur l'ecriture des données car je réécris sur la même ligne donc j'efface mes anciennes données.
je prends note de la modif avec le message d'erreur et modifie mon programme

cdt

Salut.
Quelle est la version de la librairie SD ?

En version 1.2.4 :
#define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

Versions précédentes :
#define FILE_WRITE (O_READ | O_WRITE | O_CREAT)

mais attention dans ce cas il vous faut 14 caractères dans le tableau datafile

ce n'est pas obligatoire, mais c'est mieux si l'arduino plante car les données ne sont pas forcément écrites immédiatement sur la SD (il y a un buffer de 512 octets en mémoire)

Bonjour c est la version 1.2.4

cdt

Bonjour a tous

j ai deux problèmes que je n'arrive pas a comprendre.

je crée un fichier en début de mois nommé jour mois année avec la fonction sprintf. cette partie la est fonctionnelle.

ensuite je veux ouvrir mon fichier a seconde précise ici j ai essayé lorsque les secondes sont égales a 10 soit une fois par minute, (fonctionnel en partie)

au départ pour ouvrir mon fichier j ai utilisé cette commande écrit comme ceci : fichier = SD.open(datafile, FILE_WRITE); je me suis dit que je pouvais réutilisé la variable "datafile" pour réouvrir le fichier, mais ca ne marche pas. j ai ce message d'erreur

[ 32458][E][vfs_api.cpp:27] open(): does not start with /

si je veux ouvrir mon fichier pour enregistrer dedans je le dois le nommer tel que ceci fichier = SD.open("/23052022.txt", FILE_WRITE); comment faire pour utilisé "datafile" pour l ouverture qui est la variable de création du fichier?

et le deuxième point chaque fois que j ouvre mon fichier pour écrire je pense que j'efface ce qu'il y a d'écrit pour réécrire sur les mêmes lignes, hors il me semblait que la fonction Write continuait d'écrire les données a la suite?

merci de votre aide

File fichier;
char datafile[13];
int jour=now.day();
int mois = now.month();
int annee= now.year(); 
int heure = now.hour();
int secondes =now.second();
int minute =now.minute();

if (now.month() != Curent_month) {
    
sprintf(datafile,"/%02d%02d%04d.txt",jour,mois,annee);  //  %d pour un int 
fichier = SD.open(datafile, FILE_WRITE);

if (fichier) {
    Serial.println("Writing to file..."); // message de boucle sur le serial pour debug
    fichier.println(mois);// ecriture des données
    fichier.close();
    Serial.println("Done.");//ecriture faite
  }
  // si le fichier ne s'ouvre pas:''erreur ouverture fichier sd"
  else {
    Serial.println("error opening fichier sd");
  }
Curent_month = now.month();

}

if (now.second()==10)
{
fichier = SD.open("/23052022.txt", FILE_WRITE);

 if (fichier) {
    Serial.println("Writing to file..."); // message de boucle sur le serial pour debug
    // ecriture des données
   
    fichier.println(";");
    fichier.println("ok");
  
      fichier.close();
    Serial.println("Done.");//ecriture faite
  }
  // si le fichier ne s'ouvre pas:''erreur ouverture fichier sd"
  else {
    Serial.println("error opening fichier sd");
  }

listDir(SD, "/",0);}

dans une autre discussion on avait dit qu'il fallait 14 octets
1 pour le /
12 pour le nom
1 pour le caractère null de fin de chaîne

le sprintf() déborde et écrase un truc en mémoire