datalogger sdcard : duree de vie sdcard ?

Bonjour,

pour mes 3 sondes temperatures sur 1 emetteur 433mhz, le recepteur affiche sur lcd et enregistre sur sdcard : environ 7x/minute, affiche heure et temperature sur lcd 2x16
lors de mes essais avec une sd 1 gb, au bout d’un certain nombres d’essais : carte en fat16 non reconnue, et par le pc non plus, impossible de la formater : morte !!!
que se passe-t-il si il n’y a plus d’espace sur la sd ?
flush et close trop fréquents “use” la memoire de la carte ?
je voudrais parfois lire les temperatures sans la carte, donc eviter les erreurs qui s’affichent quand carte non présente
voilà le code recepteur avec beaucoup de commentaires et une copie ecran du fichier txt obtenu sur la carte sd, améliorations possibles bienvenues, c’est un amalgame d’extraits de code trouvés çà et là
les struct, les tableaux et autres ne me sont pas familiers, la pgmation en général non plus…

Merci

/*
combiner avec l'emetteur multi18b20tx.ino
ou lm75amultiTX.ino

ecrire sur la sd uniquement quand la temperature change de + ou - 20 degres
sur au moins 1 des 3 capteurs ca commence a devenir lourd pour mes capacités
 1 fichier txt different pour chaque capteur
58% flash
63% ram

*/
#include <Wire.h> 
#include <LiquidCrystal.h>  //https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/
#include <VirtualWire.h>   //https://github.com/manashmandal/VirtualWire
#include <SD.h>            //
#include <SPI.h>
#include <DS3232RTC.h>      // https://github.com/JChristensen/DS3232RTC
#include <TimeLib.h>      //https://github.com/PaulStoffregen/Time

// il faudra mettre une temporisation quelque part pour ne pas ecrire 10 fois/minute sur la sd

// Display pins  todo : utiliser un tft 2.4 pouces ou un 20x4 I2C !! ouille mon cerveau ....
//LiquidCrystal lcd(9, 8, 7, 6, 5, 4);// montage veroboard promini

LiquidCrystal lcd(4, 5, 6, 7, 8, 9); // test carte uno
//LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

//word HOUR,MINUT,SECOND,ANNEE, MOIS, JOUR; // variables pour utilisation dans 
// l'ecriture sur sdcard si besoin

const int receive_pin = 2;  // la 12 par defaut est utilisée par le spi sdcard
    File mesTemp;
/*
    File maT159;  // si 3 fichiers txt différents
    File maT160;
    File maT161;
*/
    const int chipSelect = 10;  // chipselect sd
    const byte bkl = 3; // pour bklight
    
struct package
{
  
  float temp159;   // pour gagner espace flash
  float temp160;  //  on peut declarer en int en faisant de meme sur 
  float temp161;   // l'emetteur on perd les décimales
  //byte probe1[8];  // adresses à mettre si besoin
  //byte probe2[8];
};


typedef struct package Package;
Package data;

// Array symbol degree
byte degree [8] = {B00001100,
 B00010010,
 B00010010,
 B00001100,
 B00000000,
 B00000000,
 B00000000,
 B00000000,
 };

// Affichage d'une valeur sur deux chiffres
// 1er essai fonction
/*
void print2digits(int val, Stream &sortie) {
  // si <10 alors on préfixe d'un 0
  sortie.print(val < 10 ? "0" : "");
  sortie.print(val, DEC);
}
*/

// 2eme essai autre fonction 
void printDigits(int digits)
{
// utility function for digital clock display: prints preceding colon and leading 0
    //lcd.print(':');
    if(digits < 10)
        lcd.print('0');
    lcd.print(digits);
}

    void printtosd(int digits)
{
// meme chose sur ecriture sd card
   
    if(digits < 10)
        mesTemp.print('0');
        mesTemp.print(digits);
}
void setup ()
{
    pinMode(bkl,OUTPUT);
    
     //Wire.begin();
   

        
    digitalWrite(bkl,0); //bklgiht eteint
 //  Create the custom character with the symbol of the degree
 lcd.createChar (0,degree);
 // toujours mettre le createChar avant begin si lcd en 4 bits
 // je connais la raison mais pas l'expliquer de maniere simple
 lcd.begin (16, 2);
 //lcd.clear (); suppose que lcd.begin fait clear
    delay(100);
     setSyncProvider(RTC.get);  // to get the time from the RTC
    if(timeStatus() != timeSet) 
        lcd.print(F("Unable get RTC"));
    else
        lcd.print(F("RTC ok"));  
        delay(600);
        lcd.clear();  
  if (SD.begin())
  {
    digitalWrite(bkl,0); //bklgiht allume
    lcd.print(F("SD card ready"));
    lcd.setCursor (2,1);
    lcd.print (F("attente data"));
    delay(1000);
  }
  /*else
  {
    lcd.print(F("SD card failed")); // pas nécessaire puisque sd.open
    // renverra une erreur si pas de carte
    delay(800); //  le pgme continuera apres le delay
  }*/
  
// creation du fichier sur sdcard
      mesTemp = SD.open("t75a.txt", FILE_WRITE);
       if (!mesTemp)  {
        lcd.clear();
        lcd.print(F("   Erreur"));
        lcd.setCursor (4,1);
        lcd.print(F("carte sd"));
         delay(2000);
                      }
    if (mesTemp.size() == 0) {
    // Ecriture de l'entete remplacer les virgules par point virgule pour csv
    mesTemp.println(F("    DATE  , H  M  S ,    N159,  N160,  N161"));
    // 
    mesTemp.flush(); // si je mets close ne veut plus ecrire les data 
           }
digitalWrite(bkl,1); //bklgiht eteint
                              
// init for rx433
    vw_set_rx_pin(receive_pin);
    vw_setup(1000);  // Bits per sec
    vw_rx_start();    // Start the receiver

 
      } //end setup

void loop ()
 {
  

 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(F("Time:"));
 lcd.setCursor(6,0);
 printDigits(hour()); // fonction met 0 si h < 10
 lcd.print(":");
 printDigits(minute());
 lcd.print(":");
 printDigits(second());
 lcd.setCursor(0,1);
 lcd.print(F("Date: "));
 printDigits(day());
 lcd.print("/");
 printDigits(month());
 lcd.print("/");
 lcd.print(year());
 // heure et date sur lcd 

 delay(1000);
 uint8_t buf[sizeof(data)];
    uint8_t buflen = sizeof(data);

if (vw_have_message())  // Is there a packet for us? 
  {
    vw_get_message(buf, &buflen);
    memcpy(&data,&buf,buflen);

    lcd.clear();
    digitalWrite(bkl,0); // bklight ON
    lcd.setCursor (0,0);
    lcd.print (F("N159 : "));
    lcd.setCursor (7,0);  
    lcd.print(data.temp159,1);
    lcd.setCursor (13,0);
 // Shows the symbol of the degree
    lcd.write (byte (0));
    lcd.print (F("C"));

    lcd.setCursor (0,1);
    lcd.print (F("N160 : "));
    lcd.setCursor (7,1);
    lcd.print(data.temp160,1); // 1 decimale
    lcd.setCursor (13,1);
    lcd.write (byte (0));
    lcd.print (F("C"));
     
// 3eme capteur : comme lcd 16x2 il faut effacer les data qui précédent
    delay(2000); // delay avant effacement
    lcd.clear();
    lcd.setCursor (0,0);
    lcd.print (F("N161 : "));
    lcd.setCursor (7,0);
  // lcd.print (temp161Char); 
    lcd.print(data.temp161,1);  //1 decimale
    lcd.setCursor (13,0);
 // Shows the symbol of the degree
     lcd.write (byte (0));
     lcd.print (F("C"));
     lcd.setCursor (2,1);
     lcd.print (F("ecriture SD"));
     
     delay(200); // augmenter le delay en cas de carte non presente
// mettre test logique A0 pour executer la fonction cartewrite ou pas
// et pour eviter les erreurs cartes qaund on choisit ne pas en mettre une
    /* if (!(A0)){
     *  goto loop(); // ah le goto 
     *   ou return; ????
     *  }
     *  sans mettre un test hardware 
     *  
     *  else {
    lcd.clear();
    lcd.print("error t75a.txt");
    // si pas de carte "goto loop();"  ????
     */
     
     cartewrite();
  }

         } // end loop



 // fonction ecriture data sur sd remplacer virgule par point virgule pour csv
 //  mettre l'heure sur la sdcarte 
void  cartewrite() {
  
  if (mesTemp) { 
     mesTemp.print(day());
     mesTemp.print("/");  
      mesTemp.print(month()); 
      mesTemp.print("/"); 
      mesTemp.print(year());
      mesTemp.print(", ");  
      
      printtosd(hour()); // 
      mesTemp.print(":"); 
      printtosd(minute());
      mesTemp.print(":");  
      printtosd(second()); 
      mesTemp.print(",    "); 
    mesTemp.print(data.temp159,1);
    mesTemp.print(" , ");    
    mesTemp.print(data.temp160,1);
    mesTemp.print(" , ");    
    mesTemp.println(data.temp161,1);
    mesTemp.flush(); // flush ou close ?
  }
  
  // if the file didn't open, print an error:
  else {
    lcd.clear(); // un peu trop de lcd.clear 
    digitalWrite(bkl,0); //bklgiht allume
    lcd.print("error t75a.txt");  
    // si pas de carte "goto loop();"  ????
    // non çà retourne au loop tout seul apres le delay qui suit
    // çà réaffiche l'heure courante et les temperatures
    // un peu trop de clignotement du lcd
    // un lcd 20x4 pour afficher heure+3 temperatures sur meme ecran 
    // ou tft 2 pouces 4 avec lecteur sd intégré
  }
  
  delay(2000);
  digitalWrite(bkl,1); // eteint bklight
}

j'oubliais : le lcdcreatorchar doit se trouver avant le lcd.begin, sinon çà bloque, j'ai cherché pour trouver l'erreur, non signalée par le compilateur forcément

elektrax:
j'oubliais : le lcdcreatorchar doit se trouver avant le lcd.begin, sinon çà bloque, j'ai cherché pour trouver l'erreur, non signalée par le compilateur forcément

Bonjour,

J'ai constaté ça aussi avec la librairie LiquidCrystal alors que quand on utilise un afficheur I2C et la librairie LiquidCrystal_I2C il n'y a pas ce problème et les caractères doivent être créés après le begin().

C'est très étrange et je n'ai pas trouvé la solution du problème.
C'est gênant car on ne peut pas changer dynamiquement les caractères.

flush et close trop fréquents "use" la memoire de la carte ?

Tout dépend de la SD utilisée.
Je n'utilise que des SD de marque Sandisk pour ma RASPBERRY PI.
Sur ARDUINO même les Kingston m'ont posé problème.

pour mes 3 sondes temperatures sur 1 emetteur 433mhz, le recepteur affiche sur lcd et enregistre sur sdcard : environ 7x/minute, affiche heure et temperature sur lcd 2x16

Il serait plus intéressant de remplacer le récepteur par un serveur domotique sur RASPBERRY PI, avec une SD de qualité bien sûr, tout en conservant le récepteur 433MHz ARDUINO (le transformer en passerelle USB).

pour le creatorChar, c'est pcque le begin configure le processeur hd4480 en 4 bits, pour ecrire dans la cgrom il faut qu'il soit en 8 bits, explication sommaire
si on utilise et initialise le lcd en 8 bits, ce que fait l' interface i2c, pas de problemes

pour les sdcard datalogger, j'utilise des vieilles sd récup..donc les marques/fabricants sont aleatoires