Problem opening SD file (SD.h)

Bonjour,

Je souhaite réaliser des mesures de température, d'humidité (ATH20) et de taux de eCO2 (ENS160), puis récupérer la date et l'heure via une RTC (DS3231) pour enregistrer ces données sur une micro carte SD.

La lecture des valeurs des capteurs et de la date/heure sur le bus I2C se déroule correctement. Cependant, l'ouverture du fichier sur la carte SD (SPI) échoue 9 fois sur 10. J'ai testé en commentant les lignes de code qui interrogent le bus I2C ( get_Date_Time(); & get_sensors_values(); ), et dans ce cas, le fichier sur la carte SD s'ouvre correctement à chaque fois.

Je ne comprends donc pas d'où peut venir le problème, car le bus I2C et SPI n'utilisent pas les mêmes broches.

Arduino Nano 328P
bus i2c : SDA => A4 | SCL => A5
bus SPI : CS => D10 | MOSI => D11 | MISO => D12 | CLK => D13

Merci d'avance pour vos conseilles,
Mr Smits

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <DS3231.h>
#include "Date_Time.h"
#include <AHT20.h>
#include <ScioSense_ENS160.h>

File SD_File;

DS3231 myRTC;
RTClib Date;
bool h12Flag, pmFlag, century = false;
DateTime now;
char Date_Time_STR[21]; //eg : "25/12/2024,00:00:00," = 20 caratéres + \0

AHT20 aht20;
float Temperature;
char Temp_STR[6];
float Humidity;
char Hum_STR[6];

ScioSense_ENS160 ens160(ENS160_I2CADDR_1);
uint16_t eCO2;

char Sensors_Values_STR[17];  //eg : "25.00,55.00,550," = 16 caractères + \0

void setup() {
  Serial.begin(9600);

  Serial.println("Connectiong to SD Card...");
  while(SD.begin(10) == false){
    Serial.println("Fail ! Retrying...");
    delay(500);
  }
  Serial.println("SD Card acknowledged");

  Wire.begin();

  init_Date_Time();

  Serial.println("Connectiong to AHT20...");
  while(aht20.begin() == false){
    Serial.println("Fail ! Retrying...");
    delay(500);
  }
  Serial.println("AHT20 acknowledged");

  Serial.println("Connectiong to ENS160...");
  while(ens160.begin() == false){
    Serial.println("Fail ! Retrying...");
    delay(500);
  }
  Serial.println("ENS160 acknowledged");
  Serial.print("Standard mode ");
  Serial.println(ens160.setMode(ENS160_OPMODE_STD) ? "done." : "failed!");
}

void loop() {
  get_Date_Time();
  get_sensors_values();
  Serial.print(Date_Time_STR);Serial.println(Sensors_Values_STR);
  save_to_SD();
  delay(5000);
}

void init_Date_Time(void){
  myRTC.setClockMode(false);  // set to 24h
  
  myRTC.setDoW(init_DoW);
  myRTC.setDate(init_date);
  myRTC.setMonth(init_month);
  myRTC.setYear(init_year);  
  myRTC.setHour(init_hour);
  myRTC.setMinute(init_minute);
  myRTC.setSecond(init_second);
}

void get_Date_Time(void){
  DateTime now = Date.now();
  sprintf(Date_Time_STR,"%02d/%02d/%02d,%02d:%02d:%02d,", now.day(), now.month(), now.year(), now.hour(), now.minute(), now.second());
}

void get_sensors_values(void){
  if(aht20.available()){
    Temperature = aht20.getTemperature();
    Humidity = aht20.getHumidity();
  }
  
  if(ens160.available()){
    ens160.set_envdata(Temperature, Humidity);
    ens160.measure(true);
    ens160.measureRaw(true);
    eCO2 = ens160.geteCO2();
  }

  dtostrf(Temperature, 5, 2, Temp_STR);
  dtostrf(Humidity, 5, 2, Hum_STR);
  sprintf(Sensors_Values_STR,"%s,%s,%03d",Temp_STR, Hum_STR, eCO2);
}

void save_to_SD(void){
  if(SD.exists("DATA.CSV"))
    {
      SD_File = SD.open("DATA.CSV", FILE_WRITE);
      if (SD_File)
      {
        SD_File.print(Date_Time_STR);
        SD_File.println(Sensors_Values_STR);
        SD_File.close();
        Serial.println("Data writed to file !");
      }
      else Serial.println("Fail opening file !");
    }
    else Serial.println("File doesn't exist !");
}

quel arduino ? combien de mémoire reste-il à la compilation?

un Arduino Nano328P.

lors du téléversement vers le µC :
Sketch uses 24006 bytes (78%) of program storage space. Maximum is 30720 bytes.
Global variables use 1801 bytes (87%) of dynamic memory, leaving 247 bytes for local variables. Maximum is 2048 bytes.

donc en soit la mémoire il reste de l'espace mémoire programme et dynamique :man_shrugging:

247 c’est peu…

Essayez de gagner de la ram ou testez le code sur une mega si vous en avez une

les serial.print (F( font gagner de la ram au détriment de la flash
pour la flash le boot nano occupe 2k, alors que l'optiboot d'un uno occupe 512 bytes

le "nouveau boot" du nano est optiboot ? , je n'ai jamais utilisé de nano donc ils sont effacés de ma liste boards.txt , quand le programme est au point sur un uno, aucune de mes applis n'ont besoin de l'uart ni des serial.print sur promini , on peut meme effacer le boot et flasher iscp

bref quand on veut gagner des octets ram/flash

Non pas au détriment - si vous n'utilisez pas serial.print(F("coucou")); mais juste serial.print("coucou");", vous avez "coucou" à la fois en RAM et en flash sur les AVR (sur ESP32 un const char * est mis automatiquement en flash)

j'ai testé avec une arduino ONU mais elle n'as pas plus de RAM donc je ne sais pas si le problème viens de l'espace disponible.

"
"Sketch uses 24006 bytes (74%) of program storage space. Maximum is 32256 bytes.
Global variables use 1801 bytes (87%) of dynamic memory, leaving 247 bytes for local variables. Maximum is 2048 bytes.
"

le UNO a le même processeur que la Nano, donc non ça ne change rien. c'est pour cela que tester sur une MEGA aurait pu être intéressant

Bonjour à tous,

Je vous remercie pour vos pistes de recherche, c'était effectivement un manque d'espace mémoire dynamique.

J'ai réduit le code de setup au minimum, (sans Serial.print pour les acknowledge des différents excslaves, ce qui peut compliquer le début s'il y a un problème mais il faut faire des choix ^^)

Cela a réduit l'utilisation de la mémoire dynamique de 87% à 80% et l'ouverture de la carte SD s'opère sans problèmes maintenant.

Je vous remercie pour votre aide.

Tu dois pouvoir conserver les print en utilisant des F-string comme proposé par @chrislemire
Remplacer les

Serial.println("Connectiong to SD Card...");

par

Serial.println(F("Connectiong to SD Card..."));

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