Ecriture sur une carte SD via esp8266

Bonjour à tous !

J'ai pour projet de me faire une balance connectée avec des load cells pour pouvoir sortir de belles courbes de poids !
Néanmoins, je me heurte à un problème : Je n'arrive pas à créer de fichiers sur une carte SD (formatée en fat32). Et même si le fichier existe déjà, rien n'est écrit dedans après le script.
J'utilise un Wemos D1 mini pro / D1 mini R2 sur lequel j'ai branché un lecteur de carte SD (ici) aux pins MISO (12) , MOSI (13), SCLK (14) et CS (0 ou 8).

Voici le code :

#include "HX711.h"
#include <SD.h>

//

#define DOUT  0
#define CLK   14

HX711 scale;
File myFile;

float calibration_factor = -4500;
void setup() {
  Serial.begin(9600);
  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor);
  scale.set_offset();
  scale.tare();

  long zero_factor = scale.read_average(); //Get a baseline reading
  Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
  Serial.println(zero_factor);

  myFile = SD.open("valeurs.csv", FILE_WRITE);
  myFile.println("temps;poids");
  myFile.close();
}

String virgule = ";";
float valeur;

void loop() {
  valeur = scale.get_units(5);
  Serial.print(valeur);
  Serial.print(" kg");
  Serial.println();

  myFile = SD.open("valeurs.csv", FILE_WRITE);
  myFile.println(millis() + virgule + valeur);
  myFile.close();
  delay(50);
}

J'avais un ancien code qui marchait sur un arduino qui utilisait la bibliotheque SPI mais mes ESP8266 la détestent puisqu'ils n'arretent pas de reboot quand je l'incorpore au projet donc j'ai fait une croix dessus (je ne sais plus à quoi elle servait)

Bonne après midi !

les exemples qui utilisent la bibliothèque SD commencent dans le setup par activer le lecteur

  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

(perso je préfère la bibliothèque SDFat)

Marc_Bresson:

  myFile.println(millis() + virgule + valeur);

}

millis() est un unsigned long
virgule est une String
valeur est un float.

Tu ne peux pas les ajouter comme ça, il faut d'abord convertir les numériques en Strings, ensuite concaténer les Strings.
Ou, plus simple, utiliser 3 print() à la suite.

biggil:
Tu ne peux pas les ajouter comme ça, il faut d'abord convertir les numériques en Strings, ensuite concaténer les Strings.

hum - c'est un peu plus sioux que ça

Le bug qui apparaissait suivant quel était le type du premier argument dans la concaténation a été réglé et cette partie là fonctionne. (c'est lié à un truc un peu pointu sur les "Overload resolution" et la classe StringSumHelper sait faire).

Essayez ce code pour vous en convaincre:

String virgule = ";";
float valeur = 12.33;

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println(millis() + virgule + valeur);
  valeur += 1;
  delay(1000);
}

le moniteur série (à 115200 bauds) affichera

[color=purple]
0;12.33
999;13.33
1999;14.33
3000;15.33
4000;16.33
5001;17.33
6001;18.33
...
[/color]

mais ça fonctionne un peu par chance car la String est au milieu

Le compilo voit un entier non signé (millis()) pour lequel on veut faire l'opérateur addition avec une instance d'une classe (virgule) et donc il sait dans ce cas grace aux règles qu'il faut appeler l'opérateur surchargé de la classe avec (une promotion) de l'entier. le résultat est aussi un String (en fait une StringSumHelper) et la concaténation peut continuer avec valeur (ce coup ci on a une string en partie gauche).

Si vous aviez à imprimer   Serial.println(virgule + valeur + millis());et espérez avoir une concaténation de la représentation ASCII de valeur puis de millis(), là ça ne va pas marcher. Le compilateur va fabriquer une "expression à droite" en faisant l'addition du float valeur avec l'entier millis() (donc des maths entre les deux) puis ensuite combiner la représentation ASCII de cette somme avec la String.

il faudrait écrire Serial.println(virgule + String(valeur) + String(millis()));si on voulait concatènera toutes les représentation ASCII.

Ou, plus simple, utiliser 3 print() à la suite.

ça c'est 100% la bonne idée :slight_smile: !!!

oups :confused: cette portion de code marchait plutôt bien il y a 8 mois sur mon arduino ^^

Le soucis vient plus du fichier qui n'est pas créé lorceque je l'ouvre et rien n'est écrit dedans pendant l'initialisation. J'ai un peu regarder SDfat mais ça m'a l'air d'utiliser SPI qui ne marche pas du tout sur mes cartes (reboot en permanence)

Vous avez essayé en rajoutant le SD.begin() ?

Bonjour,

Alors je suis passé sur SdFat et je n'arrive toujours pas à écrire des fichiers sur ma carte SD ... Je n'ai plus le problème de reboot. Avez-vous d'autres idées ?
voici le code de l'exemple que j'utilise :

#include <SPI.h>
#include "SdFat.h"
SdFat SD;

#define SD_CS_PIN SS // 15 sur mon wemos d1 mini pro
File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  pinMode(SS, OUTPUT);
  digitalWrite(SS,HIGH);
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  
  Serial.print("Initializing SD card...");

  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop() {
  // nothing happens after setup
}

Ça plante ou ? Il n’arrive pas à ouvrir le fichier ?
Comment est branché le module SD ? Lequel est-ce ? Vous avez un module 3.3V ?
La carte est formatée comment ? Quelle taille ?
Que dit la console série ?
Vous êtes vraiment sur un wemos d1 mini pro ? Le SS c’est GPIO15 donc D8. C’est bien connecté au bon endroit ? (D5 D6 D7 pour SCK MISO MOSI).

Bonsoir :slight_smile:

Aucun fichier n'est créé sur la carte SD et la console dit "initialisation failed ...".

La carte est formatée en FAT32 et fait 8Go. J'ai essayé avec une autre carte, mais ça n'a pas marché non plus. J'ai refait le formatage de la carte, pour être sûr, j'ai changé de lecteur de carte, de Wemos D1 mini pro etc., mais rien n'y fait.

le lecteur de carte est celui-ci : https://fr.aliexpress.com/item/32816126771.html?spm=a2g0s.9042311.0.0.77836c37vfZpvm. J'ai essayé en 5v, puis en 3.3v sur un autre (pour être sur de pas l'avoir grillé).

voici les connexions (désolé pour les liens gdrive) sur sur le wemos d1 ici et sur le lecteur de carte ici.

Je ne questionne pas trop mon code, puisqu'aux dernières nouvelles, il marchait sur un arduino nano, mais il est possible que je me sois planté sur la configuration de l'IDE.
En allant dans ArduinoData\packages\esp8266\hardware\esp8266\2.7.2\variants\d1_mini, on retrouve les valeurs dont vous parlez, mais sur la carte, il n'y a aucune mention des D7, D8 etc., on a que 15,12,14,13.

Bonne soirée !

Essayez le formatage avec l’exemple de sdfat

Bonjour

et comme ça ?

if (!SD.begin()) 
  {
    Serial.println("initialization failed!");
    return;
  }

Serial.println("initialization done.");

@+

Bonjour !

Merci pour vos réponses super rapides ahah.

J'ai trouvé et c'est grâce à vous ! La vitesse de l'horloge SPI par défaut était trop élevée ahah. Je l'ai baissée à 20MHz (au lieu de 50) et tout fonctionne parfaitement !

C'est un énorme soulagement.

Passez une excellente journée.