Ecriture de fichier sur carte SD

Bonjour,
J'ai un projet qui, pour faire court, devrait écrire une température dans un fichier. Cependant, même si l'Arduino (Uno) crée bien un fichier sur la carte SD (via un shield ethernet W5100), rien ne s'écrit dans le fichier. Ceci dit, ça arrive qu'un message d'erreur apparaisse sur la console.

#include <SPI.h>
#include <SD.h>

File fichier;
int sd = 4;
int ledVerte = 9;
int ledRouge = 8;
int alarme = 2;
int passage = 0;
int temperature;
int tension;
long attenteAlarme = 5*60*1000;

void setup() {
  pinMode(ledVerte, OUTPUT);
  pinMode(ledRouge, OUTPUT);
  pinMode(alarme, OUTPUT);
  pinMode(sd, OUTPUT);

  digitalWrite(ledVerte, 1);

  tension = analogRead(A0)*(5000/1024);
  temperature = (tension - 500)/ 100;

  Serial.begin(9600);
  
  if (!SD.begin()) {
    Serial.println("Erreur de demarrage!");
    return;
  }
  Serial.println("Carte SD prête.");

  fichier = SD.open("temperature.txt", FILE_WRITE);
  fichier.print("Température au démarrage = ");
  fichier.print(temperature);
  fichier.println("° C");
  fichier.close();
}

void loop() {
  
  if(analogRead(A5) > 900 && passage == 0) {
    
    digitalWrite(ledVerte, 0);
    digitalWrite(ledRouge, 1);
    digitalWrite(alarme, 1);
    
    delay (2000);

    digitalWrite(alarme, 0);
    passage = 1;
  }

  if (analogRead(A5) < 900) {
    digitalWrite(ledVerte, 1);
    digitalWrite(ledRouge, 0);
    passage = 0;
  }

  if (analogRead(A3) > 1000) {
    fichier.close();
    Serial.println(analogRead(A3));
  }
}

La partie intéressante ici se trouve dans le setup.
Et oui, la carte est bien formatée en FAT32.

J'espère que vous pourrez trouver une solution à mon problème,
Merci

avec les exemples de la librairie SD, tu arrives à écrire sur ta carte ?

  • ce calcul ne va faire ce que vous voulez long attenteAlarme = 5*60*1000; car les maths sont fait en entiers sur 16 bits puis stockė dans votre long. Mettez unsigned long attenteAlarme = 5*60*1000[b][color=red]ul[/color][/b];

  • il faut faire SD.begin([b]4[/b]) pour préciser la Pin SS (ou mieux - sd au lieu de 4 puisque vous lui avez donné un petit nom)

  • vaut mieux utiliser la librairie SDFat

  • Prenez un nom au format 8.3 pour le nom de fichier

  • n'utilisez pas la Pin 10 en input (pas un pb pour le code posté mais au cas où vous auriez simplifié le code posté)

Bon... j'ai essayé tout ce que vous m'avez dit :

  • oui, les exemples marchent
  • j'ai ajouté le "ul"
  • j'ai bien mis SD.begin(4)
  • j'ai essayé de télécharger la librairie mais ça me dit qu'il y a une erreur
  • j'ai changé le nom de mon fichier
  • je confirme que le Pin 10 n'est pas en input

Malheureusement, ça ne marche toujours pas. Dans la voie série, je voie que l'initialisation est impossible...

Ben... si l'exemple fonctionne, compares l'exemple avec ton code pour voir ce qui change dans la manière d'initialiser la carte

Postez votre code

#include <SD.h>
#include <SPI.h>

File fichier;
int sd = 4;
int ledVerte = 9;
int ledRouge = 8;
int alarme = 2;
int passage = 0;
int temperature;
int tension;
long attenteAlarme = 5*60*1000ul;

void setup() {
  pinMode(ledVerte, OUTPUT);
  pinMode(ledRouge, OUTPUT);
  pinMode(alarme, OUTPUT);
  pinMode(sd, OUTPUT);

  digitalWrite(ledVerte, 1);

  tension = analogRead(A0)*(5000/1024);
  temperature = (tension - 500)/ 100;

  Serial.begin(9600);
  SD.begin(sd);
  
  if (!SD.begin()) {
    Serial.println("Erreur de demarrage!");
    return;
  }
  Serial.println("Carte SD prête.");

  fichier = SD.open("temp.txt", FILE_WRITE);
  fichier.print("Température au démarrage = ");
  fichier.print(temperature);
  fichier.println("° C");
  fichier.close();
}

void loop() {
  
  if(analogRead(A5) > 900 && passage == 0) {
    
    digitalWrite(ledVerte, 0);
    digitalWrite(ledRouge, 1);
    digitalWrite(alarme, 1);
    
    delay (attenteAlarme);

    digitalWrite(alarme, 0);
    passage = 1;
  }

  if (analogRead(A5) < 900) {
    digitalWrite(ledVerte, 1);
    digitalWrite(ledRouge, 0);
    passage = 0;
  }

  if (analogRead(A3) > 1000) {
    fichier.close();
    Serial.println(analogRead(A3));
  }
}

Désolé de ma réponse tardive.
Et oui j'ai bien comparé toutes les lignes mais je n'ai rien remarqué d'anormal.

je ne pense pas que vous avez cela dans les exemples....

  SD.begin(sd);
  if (!SD.begin()) {

(on n'appelle pas 2 fois SD.begin())

sinon vous effectuez des calculs en nombre entiers tronqués

  tension = analogRead(A0)*(5000/1024);// --> c'est pareil que multiplier par 4
  temperature = (tension - 500)/ 100;

vaudrait mieux faire

  tension = analogRead(A0)*(5000.0/1024); 
  temperature = (tension - 500)/ 100.0;

histoire de faire les calculs en flottant en ensuite tronquer pour faire un nombre entier

J'ai fait les modifications :

tension = analogRead(A0)*(5000,0/1024,0);
  temperature = (tension - 500)/ 100,0;

Et je n'ai laissé que

if (!SD.begin()) {
    Serial.println("Erreur de demarrage!");
    return;
  }
  Serial.println("Carte SD prête.");

Mais ça m'affiche toujours "Erreur de démarrage !". J'avoue que je ne comprends absolument pas ce qui coince.

Bonjour,

Si tu mets des virgules comme séparateur décimal, cela m'étonnerais que ça compile.

Si vous ne passez pas de paramètre à SD begin la librairie utilisera le SS par défaut et ce ne sera pas le bon....

if (!SD.begin(sd)) {...}

(Avec des virgules ça va compiler car la virgule à un sens en C++ mais ça ne va pas faire du tout ce qui est attendu)

Merci ! J'ai changé tout ce que vous m'avez dit et ça marche !
J'ai juste un petit problème : deux lignes s'écrivent dans le fichier, au lieu d'une ("Température au démarrage =").

cool :wink:

postez votre code. il se peut que la seconde ligne soit celle d'une exécution précédente.

#include <SPI.h>
#include <SD.h>

File fichier;
int sd = 4;
int ledVerte = 9;
int ledRouge = 8;
int alarme = 2;
int passage = 0;
float tempDemarrage;
float tempEvent;
long attenteAlarme = 5*60*1000ul;

void setup() {
  pinMode(ledVerte, OUTPUT);
  pinMode(ledRouge, OUTPUT);
  pinMode(alarme, OUTPUT);
  pinMode(sd, OUTPUT);

  digitalWrite(ledVerte, 1);

  tempDemarrage = (analogRead(A0) - 500)/10;

  Serial.begin(9600);
  
  if (!SD.begin(sd)) {
    Serial.println("Erreur de demarrage!");
    return;
  }
  Serial.println("Carte SD prête.");

  fichier = SD.open("temp.txt", FILE_WRITE);
  fichier.print("Température au démarrage = ");
  fichier.print(tempDemarrage);
  fichier.println("° C");
  fichier.close();
}

void loop() {
  
  if(analogRead(A5) > 900 && passage == 0) {

    tempEvent = (analogRead(A0) - 500)/10;
    fichier.println("");
    fichier.print("Temperature au moment de l'arrêt =");
    fichier.print(tempEvent);
    fichier.println("° C");
    fichier.close();
    
    digitalWrite(ledVerte, 0);
    digitalWrite(ledRouge, 1);
    digitalWrite(alarme, 1);
    
    delay (attenteAlarme);

    digitalWrite(alarme, 0);
    passage = 1;
  }

  if (analogRead(A5) < 900) {
    digitalWrite(ledVerte, 1);
    digitalWrite(ledRouge, 0);
    passage = 0;
  }

  if (analogRead(A3) > 1000) {
    fichier.close();
    Serial.println(analogRead(A3));
  }
}

Le problème vient (pour l'instant) de ce que j'ai écrit dans le setup

pourquoi vous faites un   fichier.close(); dans le setup() et ensuite dans la boucle vous essayez d'écrire dans le fichier ?

il faut ouvrir le fichier, écrire et le fermer quand vous avez fini.

sinon pour que ce soit un peu plus "propre" vous pourriez modifier vos déclarations comme cela:

#include <SPI.h>
#include <SD.h>

File fichier;

const byte sd = 4;
const byte ledVerte = 9;
const byte ledRouge = 8;
const byte alarme = 2;

int passage = 0;
float tempDemarrage;
float tempEvent;

const unsigned long attenteAlarme = 5 * 60 * 1000ul;