Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Arduino, C++] Problème d'écriture sur carte SD

    11 janvier 2018 à 19:20:14

    Bonjour à tous !!

    Je bosse actuellement sur un projet Arduino dans lequel je récupère sur une carte SD les données fournies par 3 capteurs. Le problème est qu'une fois compilé et téléversé sur la carte arduino, le programme s'arrête au bout de 24 prises de mesure (avant c'était 21, parfois c'est 22 ... bizarre !) . J'ai essayer pas mal de truc, mais rien y fait :colere2:

    Je vous joins le code. D'ailleurs si vous trouvez des trucs à redire ou à améliorer je suis preneur ;)
    /**** PROGRAMME PRINCIPAL *****/
    
    #include <SPI.h>  // Pour la communication SPI
    #include <SD.h>   // Pour la communication avec la carte SD
    
    int CS_PIN = 10;
    
    int NbTopsFan; //mesurer le front de montée du signal
    float Debit;                               
    int debitmetre = 3;    //Où placer le capteur
    int R = 16000;  // résistance "fixe" du pont diviseur de tension
    int Vcc = 5;    // tension d'entrée  
    
    void rpm () {     //Voici la fonction que l'interruption déclenche
      NbTopsFan++;  //Cette fonction mesure les fronts de montée et de descente du signal envoyé par les capteurs à effet Hall
    }
    
    void setup() {
      /* Initialisation du port série */
      Serial.begin(9600);
      pinMode(debitmetre, INPUT); //initializes digital pin 3 as an input
      attachInterrupt(0, rpm, RISING); //and the interrupt is attached
      
      /* Initialisation du port SPI */
      pinMode(10, OUTPUT); 
      
      /* Initialisation de la carte SD */
      Serial.print("Init SD card... ");
      if (!SD.begin(CS_PIN)) { // gestion du cas d'erreur
        Serial.println("FAIL");
        for(;;); } // Attend l'appui sur bouton RESET
      Serial.println("OK");
    
    }
    
    void loop() {
    
      /* calcul de température */
      int valeur0 = analogRead(A0); //tension mesurée aux bornes de la thermistance
      float Ut0 = valeur0 * (Vcc / 1024.0); //conversion de la valeur analogique en volt
      float Rt = (Ut0*R/(Vcc-Ut0))/1000; // calcul de la valeur de la thermistance (pont diviseur de tension)
      float Temperature = 450.57*pow(Rt,-0.619); // température mesurée
      Serial.println(" ");Serial.print("Temperature = ");Serial.println(Temperature);
    
      /* calcul du débit */
      NbTopsFan = 0;   //Set NbTops to 0 ready for calculations
      sei();      //Enables interrupts
      delay (1000);  
      cli();      //Disable interrupts
      Debit = NbTopsFan / 7.5; //fonction de calcul du débit
      Serial.print("Débit = "); Serial.println(Debit);
    
      /* calcul de la pression */
      int valeur1 = analogRead(A1); //tension mesurée aux bornes du capteur de pression
      float Ut1 = valeur1 * (Vcc / 1024.0); //conversion de la valeur analogique en volt
      float Pression = 2.55*Ut1 - 1.37; // pression mesurée
      Serial.print("Pression = "); Serial.println(Pression);
    
      /* Ecriture des données dans le fichier*/
      File fichier = SD.open("donnees", FILE_WRITE); // Ouverture d'un fichier en écriture{
      if(!SD.open ("donnees", FILE_WRITE)) { // gestion du cas d'erreur
        Serial.println("Erreur ouverture fichier");
        for(;;);} // Attend appui sur bouton RESET
      Serial.print("écriture des données sur la carte SD...");
      fichier.print("(");fichier.print(Temperature);fichier.print(", ");fichier.print(Debit);fichier.print(", ");fichier.print(Pression);fichier.println(")");
      Serial.println("OK");
      fichier.close();
    
    }

    Merci d'avance pour votre aide !!
    P.S. : si ça peut vous aider je joins le screen du moniteur série au moment ou ça bug :
    • Partager sur Facebook
    • Partager sur Twitter
      12 janvier 2018 à 21:49:02

      Désactiver les interruptions, ce n'est pas une très bonne idée.

      Surtout quand on sait que les dernières version du logiciel arduino utilise les interruptions dans la gestion du Serial.

      Si le buffer du Serial devient plein quand les interruptions sont désactivées, ça peut conduire à un freeze du programme.

      Donc je te conseille de laisser les interruptions actives et de ne les désactiver que lorsque c'est nécessaire.

      Ton code ligne 45 à 51 devrait être :

        /* calcul du débit */
      
        // Désactivation des interruptions le temps de remettre le compteur à 0
        // Eh oui, mieux vaut ne pas avoir une incrémentation le temps de la remise à 0
        cli();      //Disable interrupts
        NbTopsFan = 0;   //Set NbTops to 0 ready for calculations
      
        // Réactivation des interruptions pour le comptage pendant 1000ms
        // Eh oui, c'est le but, avoir un certain nombre d'incrémentation pendant un laps de temps précis de 1000ms
        
        sei();      //Enables interrupts
        delay (1000);
        
        // Désactivation des interruptions le temps de faire le calcul
        // Eh oui, le laps de temps est écoulée et mieux vaut ne pas avoir une incrémentation le temps de la division
        cli();      //Disable interrupts
        Debit = NbTopsFan / 7.5; //fonction de calcul du débit
        
        // Réactivation des interruptions pour le reste du programme
        sei();      //Enables interrupts
        
        Serial.print("Débit = "); Serial.println(Debit);



      • Partager sur Facebook
      • Partager sur Twitter
        13 janvier 2018 à 21:44:11

        Merci de ta réponse !! 

        Cependant cette solution ne fonctionne pas car elle ne m'écrit qu'une seule fois les données sur la carte SD, avant de me retourner "Erreur ouverture fichier". En revanche elle rend les mesures du débit plus précises, car après vérification je me suis rendu compte que l'incrémentation se faisait encore pendant le temps de remise à 0 et le temps de calcul.

        Du coup j'ai trouvé une solution (peut être pas la meilleure), c'est de carrément supprimer la condition qui gère le cas d'erreur lors de l'ouverture du fichier :

          File fichier = SD.open("donnees", FILE_WRITE); // Ouverture d'un fichier en écriture
          Serial.print("écriture des données sur la carte SD...");



        • Partager sur Facebook
        • Partager sur Twitter
          16 janvier 2018 à 8:19:05

          Dans ton code, tu as :

            /* Ecriture des données dans le fichier*/
            File fichier = SD.open("donnees", FILE_WRITE); // Ouverture d'un fichier en écriture{
            if(!SD.open ("donnees", FILE_WRITE)) { // gestion du cas d'erreur
              Serial.println("Erreur ouverture fichier");

          Au final, tu fais 2 fois l'appel à SD.open donc tu ouvres 2 fois le fichier.

          Pas étonnant que tu ai une erreur ;)

          Tu devrait plutôt avoir :

            /* Ecriture des données dans le fichier*/
            File fichier = SD.open("donnees", FILE_WRITE); // Ouverture d'un fichier en écriture{
            if(!fichier) { // gestion du cas d'erreur
              Serial.println("Erreur ouverture fichier");




          • Partager sur Facebook
          • Partager sur Twitter

          [Arduino, C++] Problème d'écriture sur carte SD

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown