Writing on SD Card

hi,

I just did a lil bit of cleaning in the code .... except that I had to spend a lil too strong brush stroke ...

Indeed, writing on the SD card information is no longer .. The file is created when you call the function ecritureSD ()
against by any of the requested data is written to the SD card while it worked well before my little helping household ...
Have you any idea what's wrong?

#include <SD.h>
#include <SPI.h>         
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
#include <avr/pgmspace.h>
// --- Déclaration des constantes utiles ---
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield

// cosm
#define APIKEY         "oQ9B9XdFdGdIYmJPRT0g" // replace your Cosm api key here
#define FEEDID         56809 // replace your feed ID
#define USERAGENT      "Vera" // user agent is the project name
//
// variables globales :
#define PERIOD_WRITE_DATA    120000
unsigned long last_write_data;

byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

unsigned int localPort = 8888;      // local port to listen for UDP packets

IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server

IPAddress timeServer2(129, 6, 15, 28); //  time-a.nist.gov NTP server

IPAddress srvphp(192, 168, 0, 135); // Adresse IP serveur perso PHP

const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 

int Jour = day();  // variable d'initialisation pour la mise à zero de la production à minuit
volatile long comptageImpulsion=0; // variable accessible dans la routine interruption externe 0
int test; // Variable utilisée pour tester valeur renvoyée par fonctions SD Card

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

// cosm
// initialize the library instance:
EthernetClient client;
char server[] = "api.cosm.com";   // name address for cosm API

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
// const unsigned long postingInterval = 10*1000; //delay between updates to cosm.com
//

time_t prevDisplay = 0; // when the digital clock was displayed
const  int timeZoneOffset = +1; // GMT zone;
// --- Déclaration des constantes des broches E/S numériques ---

const int brocheSDCardSelect=4;

// --- Déclaration des constantes des broches analogiques ---


// --- Déclaration des objets utiles pour les fonctionnalités utilisées ---
File file; // objet file 
File root; // objet root pour le répertoire racine

// ////////////////////////// 2. FONCTION SETUP = Code d'initialisation ////////////////////////// 
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { // debut de la fonction setup()

  // --- ici instructions à exécuter 1 seule fois au démarrage du programme --- 

  // ------- Initialisation fonctionnalités utilisées -------  
  // ------- Initialisation des variables utilisées -------  
  last_write_data = millis() - PERIOD_WRITE_DATA;
  comptageImpulsion = 0;


  Serial.begin(115200); // initialise connexion série à 115200 bauds
  // IMPORTANT : régler le terminal côté PC avec la même valeur de transmission 

  //---- initialise l'utilisation de la carte mémoire SD en mode SPI  
  pinMode(10, OUTPUT); // met la broche 10 (SS) en sortie (nécessaire avec module ethernet)
  digitalWrite(10, HIGH); // mais désactive le  circuit intégré W5100 du module ethernet!

  //----- initialisation de la carte SD ----- 
  Serial.println( (__FlashStringHelper *)PSTR("Initialisation de la SD card..."));

  pinMode(10, OUTPUT); // laisser la broche SS en sortie - obligatoire avec librairie SD

  test=SD.begin(brocheSDCardSelect); // initialisation de la carte SD avec broche 4 en tant que CS - renvoie true/false

  if (test!=true) { // si initialisation n'est pas réussie
    Serial.println( (__FlashStringHelper *)PSTR("Echec init SD")); // message port Série
  }
  else { // si nitialisation réussie
    Serial.println( (__FlashStringHelper *)PSTR("Init SD reussie !")); // message port Série

    //----- affiche le contenu du répertoire 

    root = SD.open("/"); // ouvre la SD Card à la racine

    Serial.println( (__FlashStringHelper *)PSTR("Rep racine ouvert"));
  }

  attachInterrupt(0, gestionINT0, RISING); // attache l'interruption externe n°0 à la fonction gestionINT0()
  // mode déclenchement possibles = LOW, CHANGE, RISING, FALLING


    // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println( (__FlashStringHelper *)PSTR("Echec Ethernet DHCP"));
    // no point in carrying on, so do nothing forevermore:
    //  for(;;)
    //    ;
  }

  Udp.begin(localPort);
  setSyncProvider(getNtpTime);
  while(timeStatus()== timeNotSet); // wait until the time is set by the sync provider
  //---- crée fichier en écriture --- 
 // file = SD.open("data.txt", FILE_WRITE); // ouvre le fichier en écriture
  // NB : le fichier est créé si il n'existe pas !

  //---- test si fichier dispo en écriture 
 // if (!file) { // si fichier pas dispo 

   // Serial.println( (__FlashStringHelper *)PSTR("Erreur ouverture fichier !"));

  } // fin if

  // else { // si le fichier existe et est ouvert 

   // Serial.println( (__FlashStringHelper *)PSTR("Fichier pret pour ecriture !"));

    //----- Ecriture dans le fichier au format CSV ----- 

    // premiere ligne du fichier CSV - entete avec liste des champs
    // showStringfileln(PSTR("Nbreimpulsion;Millis;Heure;Minute;Seconde;Jour;Mois;Annee"));
  //  file.println( (__FlashStringHelper *)PSTR("Nbreimpulsion;Millis;Heure;Minute;Seconde;Jour;Mois;Annee") );

  //  file.close(); // ferme le fichier
  //  Serial.println( (__FlashStringHelper *)PSTR("Fin enregistrement !"));  
  //  Serial.println( (__FlashStringHelper *)PSTR("Fermeture fichier !"));
//  }  
  // ------- Broches en sorties numériques -------  

  // ------- Broches en entrées numériques -------  

  // ------- Activation si besoin du rappel au + (pullup) des broches en entrées numériques -------  


//} // fin de la fonction setup()
// ********************************************************************************

////////////////////////////////// 3. FONCTION LOOP = Boucle sans fin = coeur du programme //////////////////
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()

  // On purge l'arrivée de caractères, retour de COSM (pour debug)
// if (client.available()) {
//   while( client.available() )
 //    Serial.print(client.read() );
 // }

  // Si la communication a été coupée, on ferme le client et on indique lastConnected = false;
//  if (!client.connected() && lastConnected) {
 //   Serial.println();
 //   Serial.println( (__FlashStringHelper *)PSTR("disconnecting."));
  //  client.stop();
//    lastConnected = false;
 // }
  // Initialisation du compteur au changement de jour

  if (Jour != day()) {
    comptageImpulsion = 0;
    Jour = day();
    Serial.println( (__FlashStringHelper *)PSTR("Init compteur changement de jour"));
    file.println( (__FlashStringHelper *)PSTR("Init compteur changement de jour") );
  }

  // Si et seulement si PERIOD_WRITE_DATA s'est écoulé depuis la dernière fois, on exécute la fonction d'écriture SD et l'envoi sur COSM

  // Sinon, on recommence loop
  if ( (millis()-last_write_data) > PERIOD_WRITE_DATA )
  {
    // Initialisation de la variale permettant la réinitialisation du compteur au changement de jour
    Jour = day(); // Gestion de l'initialisation du compreur de changement de jour

    last_write_data = millis(); // variable de gestion de la boucle if

    // cosm
    // read the analog sensor:
    long sensorReading = comptageImpulsion ;   

    // A chaque fois qu'on écrit dans le fichier, on envoi aussi sur COSM.
    // La gestion du délai est déjà fait plus haut
    sendData(sensorReading);
    // store the state of the connection for next time through
    // the loop:
  //  lastConnected = client.connected();
  } // fin else
}

// fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
void sendData(int thisData) {
  // if there's a successful connection:
  if (client.connect(srvphp, 80)) {
    char reqhttp[100];
    int annee = year();
    int sec = second();
    int jour=day();
    int mois = month();
    int heure= hour();
    int minut= minute();
    
    Serial.println("connected srvphp");
    // Make a HTTP request:
    sprintf( reqhttp, "GET /solaire/txp2.php?nom_inst=Dupont&date_prod=%04d%02d%02d%02d%02d%02d&prod=%05d&commentaires=arduino HTTP/1.0",annee,mois,jour,heure,minut,sec,comptageImpulsion);
    client.println(reqhttp);
    client.println();
    Serial.println(F("Fin envoie srvphp"));
    client.stop();
    } 
  else {
    if (client.connect(server, 80)) {
    Serial.println( (__FlashStringHelper *)PSTR("connecting COSM..."));
    // send the HTTP PUT request:
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.cosm.com");
    client.print("X-ApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");

    // calculate the length of the sensor reading in bytes:
    // 8 bytes for "sensor1," + number of digits of the data:
    int thisLength = 8 + getLength(thisData);
    client.println(thisLength);

    // last pieces of the HTTP PUT request:
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();

    // here's the actual content of the PUT request:
    client.print("sensor2,");
    client.println(thisData);
    Serial.println(F("Fin envoie COSM"));
    client.stop();
  } 
   else {
     ecritureSD();
  }
   
    }
}


int getLength(int someValue) {
  // there's at least one byte:
  int digits = 1;

  int dividend = someValue /10;
  while (dividend > 0) {
    dividend = dividend /10;
    digits++;
  }
  // return the number of digits:
  return digits;
}

void gestionINT0() {// la fonction appelée par l'interruption externe n°0

    comptageImpulsion=comptageImpulsion+1; // Incrémente la variable de comptage

  //---- affiche le nombre d'impulsions sur le port série
  Serial.print("Nombre impulsions = "); 
  Serial.println(comptageImpulsion); 

  // tout se passe dans la fonction de gestion de l'interruption externe

}


// ////////////////////////// AUTRES FONCTIONS DU PROGRAMME //////////////////// 

void digitalClockDisplay(){
  // digital clock display of the time
 Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" -- ");
  Serial.print(day());
  Serial.print("/");
  Serial.print(month());
  Serial.print("/");
  Serial.print(year()); 
  Serial.println();
  file.print(hour()), file.print(';');
  printDigitsSD(minute()), file.print(';');
  printDigitsSD(second()), file.print(';');
  file.print(day()), file.print(';');
  file.print(month()), file.print(';');
  file.print(year()), file.print(';'); 
  file.println();  
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}
void printDigitsSD(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  if(digits < 10)
    file.print('0');
  file.print(digits);
}
/*-------- NTP code ----------*/

unsigned long getNtpTime()
{
  sendNTPpacket(timeServer); // send an NTP packet to a time server
  delay(1000);
  if ( Udp.parsePacket() ) {  
    // We've received a packet, read the data from it
    Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord; 
    const unsigned long seventyYears = 2208988800UL;     
    // subtract seventy years and add the time zone:
    unsigned long epoch = secsSince1900 - seventyYears + (timeZoneOffset * 3600L);
    Serial.println( (__FlashStringHelper *)PSTR("Heure sur serveur ntp 1"));
    return epoch;
  } 
  else {
    sendNTPpacket(timeServer2); // send an NTP packet to a time server
    delay(1000);
    if ( Udp.parsePacket() ) {  
      // We've received a packet, read the data from it
      Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer

      //the timestamp starts at byte 40 of the received packet and is four bytes,
      // or two words, long. First, esxtract the two words:

      unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
      unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
      // combine the four bytes (two words) into a long integer
      // this is NTP time (seconds since Jan 1 1900):
      unsigned long secsSince1900 = highWord << 16 | lowWord; 
      const unsigned long seventyYears = 2208988800UL;     
      // subtract seventy years and add the time zone:
      unsigned long epoch = secsSince1900 - seventyYears + (timeZoneOffset * 3600L);
      Serial.println( (__FlashStringHelper *)PSTR("Heure sur serveur ntp 2"));
      return epoch;
    }

  }
  return 0;

}
// send an NTP request to the time server at the given address 
unsigned long sendNTPpacket(IPAddress& address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp: 		   
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 
}




void ecritureSD() {

    // if you couldn't make a connection:

    // Mise en forme du nom du fichier .txt  
    char datafile[13];
    int jour=day();
    int mois = month();
    int heure= hour();
    int minut= minute();

    sprintf(datafile,"%02d%02d%02d%02d.txt",mois,jour,heure,minut);  //  %d pour un int 

      //----- initialisation de la carte SD ----- 
    Serial.println( (__FlashStringHelper *)PSTR("Initialisation de la SD card..."));

    SD.begin(brocheSDCardSelect); // initialisation de la carte SD avec broche 4 en tant que CS - renvoie true/false

    root = SD.open("/"); // ouvre la SD Card à la racine

    Serial.println( (__FlashStringHelper *)PSTR("Rep racine ouvert"));

    Serial.println(datafile);
    //---- crée fichier en écriture --- 
    file = SD.open(datafile, FILE_WRITE); // ouvre le fichier en écriture
    // NB : le fichier est créé si il n'existe pas !

    //---- test si fichier dispo en écriture 
    if (!file) { // si fichier pas dispo 
      Serial.println( (__FlashStringHelper *)PSTR("Erreur ouverture fichier"));
    } // fin if
    else { // si le fichier existe et est ouvert 
      Serial.println( (__FlashStringHelper *)PSTR("Fichier pret pour ecriture"));
      //----- Ecriture dans le fichier au format CSV ----- 
      Serial.println( (__FlashStringHelper *)PSTR("Enregistrement en cours"));
      file.print("test");

      // valeur deuxieme champ
      file.print(comptageImpulsion);
      file.print(';'); 
      // valeur quatrieme champ
      file.print(millis()), file.print(';');
      // le dernier champ doit se terminer par un saut de ligne +++
      if( now() != prevDisplay) //update the display only if the time has changed
      {
        prevDisplay = now();
        digitalClockDisplay(); 
      }  
      Serial.println( (__FlashStringHelper *)PSTR("connection failed"));
      Serial.println();
      Serial.println( (__FlashStringHelper *)PSTR("disconnecting"));

      file.close(); // ferme le fichier
      Serial.println( (__FlashStringHelper *)PSTR("Fin enregistrement"));  
      Serial.println( (__FlashStringHelper *)PSTR("Fermeture fichier")); 


    }
    // note the time that the connection was made or attempted:
    // lastConnectionTime = millis();

}
// ////////////////////////// Fin du programme ////////////////////