probleme ecriture carte sd

Bonjour à tous,
je pense avoir un problème dans mon programme.
L’écriture sur la carte SD fonctionne 1 fois sur 5.
En moniteur série, aucun probléme.

Je séche totalement…

Voici mon programme:

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

File myfile;

int pinCS=10;
int OPB =2; // Capteur OPB connecté sur port 2
float value=0;
float rev=0;
int rpm;
int oldtime=0;
int time;
void isr() //service d'interruption de routine
{
rev++;
}
void setup() 
{
    Serial.begin(9600);
    pinMode (pinCS,OUTPUT);
    pinMode (OPB,INPUT);
    if (SD.begin())
    {
      Serial.println("Carte SD prete");
    }else
    { Serial.println(" Carte SD non prete");
return;
    }
myfile= SD.open("test.txt", FILE_WRITE);
if (myfile)  {
  Serial.println("pret a ecrire");
}
else  {
  Serial.println("erreur d ecriture");
}
myfile.close();
 }

void loop() {
  delay(500);
myfile= SD.open("test.txt", FILE_WRITE);  
  detachInterrupt(0);           
time=millis()-oldtime;         
rpm=(rev/time)*3600000;   // calcul revolution par seconde      
oldtime=millis();             
rev=0;

  Serial.println(rpm);

  
attachInterrupt(0,isr,RISING);

    myfile.println (rpm);
    
    
  myfile.close();

  // put your main code here, to run repeatedly:

}

Merci d’avance pour votre aide.

rev n'a pas besoin d'être un float (unsigned int ou unsigned long devrait aller) et devrait être volatile...
time et oldtime devraient être des unsigned long
les N° de pins sont mieux en const byte
votre calcul est faux (débordement d'entier sans doute), vous n'attachez pas l'interruption dans le setup..

bref faut nettoyer...

indentez le code - c'est illisible (faites ctrl-T (PC) or cmd-T (Mac) dans l'IDE avant de copier le code pour qu'il soit indenté correctement)

Grand merci pour votre aide.
Je débute dans l’Arduino et la programmation en général.
Je vais essayer de "comprendre" ce que vous me dites et en prendre leçon.
Merci beaucoup.

Question bête, réponse bête..
Que voulez vous dire par "vous n'attachez pas l'interruption dans le setup."?

carpoye:
Que voulez vous dire par "vous n'attachez pas l'interruption dans le setup."?

je ne vois pas attachInterrupt(0,isr,RISING);donc on rentre dans la loop sans que les interruptions ne soient activées

Il faut, pour pouvoir compter les tours, que la routine d’interruption soit connue: au démarrage, elle ne l’est pas (l’est dans loop) et il faut rajoutre dans setup attachInterrupt (…), sinon la première valeur sera absurde.

Voici le code modifié:

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

File myfile;

const byte pinCS = 10;
const byte OPB = 2; // Capteur OPB connecté sur port 2
float value = 0;
unsigned int rev = 0;
int rpm;
unsigned long oldtime = 0;
unsigned long time;
void isr() //service d'interruption de routine
{
  rev++;
}
void setup()
{
  Serial.begin(9600);
  pinMode (pinCS, OUTPUT);
  pinMode (OPB, INPUT);
  if (SD.begin())
  {
    Serial.println("Carte SD prete");
  } else
  { Serial.println(" Carte SD non prete");
    return;
  }
  myfile = SD.open("test.txt", FILE_WRITE);
  if (myfile)  {
    Serial.println("pret a ecrire");
  }
  else  {
    Serial.println("erreur d ecriture");
  }
  myfile.close();
  attachInterrupt(0, isr, RISING);
}

void loop() {
  delay(500);
  myfile = SD.open("test.txt", FILE_WRITE);
  detachInterrupt(0);
  time = millis() - oldtime;
  rpm = (rev / time) * 3600000; // calcul revolution par seconde
  oldtime = millis();
  rev = 0;

  Serial.println(rpm);


  attachInterrupt(0, isr, RISING);

  myfile.println (rpm);


  myfile.close();

  // put your main code here, to run repeatedly:

}

Pour le calcul, je l’ai volontairement amplifié car ce n’est pas vraiment le tr/min qui m’intéresse mais les ralentissement du moteur.
Le capteur est situé sur un axe de 6cm de diamètre et a pour révolution: 1 révolution/10 seconde
avec 10 déflecteur dessus

mettez un volatile unsigned int rev = 0;

si vous ne faites qu'un tour en 10 secondes, qu'allez vous mesurer en O.5 seconde?

Désolé je viens de modifié mon précédent message pour explication.
Dix déflecteur sont sur l'axe.

détachez l'interruption avant d'aller jouer avec la SD
et attachez là de nouveau après avoir fermé le fichier à la toute fin de la loop

donc en 1/2 seconde, vous passez devant combien de détecteurs au max?

(ne modifiez pas les anciens posts sinon on ne s'y retrouve plus en lisant la conversation)

Est ce que le mode "append" (écrire à la fin du fichier) est la même chose que le mode "write" (souvent, c'est écraser ce qui existe, et écrire par dessus)
?
que se passe-t-il si SD.open ne marche pas (un message d'horreur pourrait être utile)

Grand merci pour vos réponse rapide.
Désolé pour la modification du message, je pensais que personne ne l’avais lu.

Je pense que 1 seconde sépare chaque déflecteur.

Code modifié:

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

File myfile;

const byte pinCS = 10;
const byte OPB = 2; // Capteur OPB connecté sur port 2
float value = 0;
unsigned int rev = 0;
int rpm;
unsigned long oldtime = 0;
unsigned long time;
void isr() //service d'interruption de routine
{
  rev++;
}
void setup()
{
  Serial.begin(9600);
  pinMode (pinCS, OUTPUT);
  pinMode (OPB, INPUT);
  if (SD.begin())
  {
    Serial.println("Carte SD prete");
  } else
  { Serial.println(" Carte SD non prete");
    return;
  }
  myfile = SD.open("test.txt", FILE_WRITE);
  if (myfile)  {
    Serial.println("pret a ecrire");
  }
  else  {
    Serial.println("erreur d ecriture");
  }
  myfile.close();
  attachInterrupt(0, isr, RISING);
}

void loop() {
  delay(500);
  myfile = SD.open("test.txt", FILE_WRITE);
  detachInterrupt(0);
  time = millis() - oldtime;
  rpm = (rev / time) * 3600000; // calcul revolution par seconde
  oldtime = millis();
  rev = 0;

  Serial.println(rpm);


  detachInterrupt(0, isr, RISING);

  myfile.println (rpm);


  myfile.close();

  attachInterrupt (0, isr, RISING);

}

et mon volatile.... et mes demandes du post 9... vous n'en tenez pas compte ? c'est pas la peine que je me fatigue alors....

au lieu de faire     return;quand y'a un souci, faites plutôt un while(true);pour bloquer le code. faire un return dans le setup() passe la main à la loop() ensuite.

vous pouvez tester si myfile =  SD.open(xxx) n'a pas marché avec un

if (myfile) { 
  // ici tout OK
} else {
  // bug
}

Je pense que 1 seconde sépare chaque déflecteur.

alors pourquoi n'attendre que 1/2 seconde  delay(500);entre 2 calculs?

Le problème c’est que dés que je test avec le pc tout ce passe bien.
Enfin j’ai des valeurs…
Mais dés que je le mets en “situation” (donc sans PC), aucune écriture sur la carte SD.

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

File myfile;

const byte pinCS = 10;
const byte OPB = 2; // Capteur OPB connecté sur port 2
float value = 0;
unsigned int rev = 0;
int rpm;
unsigned long oldtime = 0;
unsigned long time;
void isr() //service d'interruption de routine
{
  rev++;
}
void setup()
{
  Serial.begin(9600);
  pinMode (pinCS, OUTPUT);
  pinMode (OPB, INPUT);
  if (SD.begin())
  {
    Serial.println("Carte SD prete");
  } else
  { Serial.println(" Carte SD non prete");
    while(true);
  }
  myfile = SD.open("test.txt", FILE_WRITE);
  if (myfile)  {
    Serial.println("pret a ecrire");
  }
  else  {
    Serial.println("erreur d ecriture");
  }
  myfile.close();
  attachInterrupt(0, isr, RISING);

}

void loop() {
  delay(1000);
  myfile = SD.open("test.txt", FILE_WRITE);

  time = millis() - oldtime;
  rpm = (rev / time) * 3600000; // calcul revolution par seconde
  oldtime = millis();
  rev = 0;

  Serial.println(rpm);


 detachInterrupt(0);

  myfile.println (rpm);


  myfile.close();

  attachInterrupt (0, isr, RISING);

}

Après je me pose la question,
Existe t-il un capteur relié avec une courroie à l'axe pour mesurer la rotation.
Comme ce que je veux réellement c'est vérifié les ralentissements du moteur.
Ce serai peut être plus précis.

comme dit précédemment

détachez l'interruption avant d'aller jouer avec la SD (avant le SD.open)

carpoye:
Bonjour et désolé du retard de réponse.
Alors j’ai enfin écouté ce que vous m’avez répété >:( .
Cependant le rev j’ai du le laisser en float sinon plus rien ne fonctionner.
Malgré tout cela, l’écriture sur la carte SD fonctionne bien quand je suis branché au pc.
Mais dés que je le mets en fonctionnement sans le PC, aucune écriture sur la carte SD.
J’en perds mon latin de tout cela.
Merci d’avance pour vos futures réponses.

#include <Wire.h>

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

File myfile;

const byte pinCS = 10;
const byte OPB = 2; // Capteur OPB connecté sur port 2
float value = 0;
float rev = 0;
int rpm;
unsigned long oldtime = 0;
unsigned long time;
void isr() //service d’interruption de routine
{
  rev++;
}
void setup()
{
  Serial.begin(9600);
  pinMode (pinCS, OUTPUT);
  pinMode (OPB, INPUT);

if (SD.begin())
  {
    Serial.println(“Carte SD prete”);
  } else
  { Serial.println(" Carte SD non prete");
    while (true);
  }
  myfile = SD.open(“test.txt”, FILE_WRITE);
  if (myfile)  {
    Serial.println(“pret a ecrire”);
  }
  else  {
    Serial.println(“erreur d ecriture”);
  }
  myfile.close();
  attachInterrupt(0, isr, RISING);

}

void loop() {
  delay(1000);
  detachInterrupt(0);
  myfile = SD.open(“test.txt”, FILE_WRITE);

time = millis() - oldtime;
  rpm = (rev / time) * 3600000; // calcul revolution par seconde
  oldtime = millis();
  rev = 0;

Serial.println(rpm);

myfile.println (rpm);

myfile.close();
  attachInterrupt (0, isr, RISING);

}

volatile
volatile
volatile
volatile
volatile
volatile
volatile

Je viens d’essayer en volatile mais fonctionne toujours pas.

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

File myfile;

const byte pinCS = 10;
const byte OPB = 2; // Capteur OPB connecté sur port 2
float value = 0;
volatile float rev = 0;
int rpm;
unsigned long oldtime = 0;
unsigned long time;
void isr() //service d'interruption de routine
{
  rev++;
}
void setup()
{
  Serial.begin(9600);
  pinMode (pinCS, OUTPUT);
  pinMode (OPB, INPUT);

  if (SD.begin())
  {
    Serial.println("Carte SD prete");
  } else
  { Serial.println(" Carte SD non prete");
    while (true);
  }
  myfile = SD.open("test.txt", FILE_WRITE);
  if (myfile)  {
    Serial.println("pret a ecrire");
  }
  else  {
    Serial.println("erreur d ecriture");
  }
  myfile.close();
  attachInterrupt(0, isr, RISING);

}

void loop() {
  delay(1000);
  detachInterrupt(0);
  myfile = SD.open("test.txt", FILE_WRITE);

  time = millis() - oldtime;
  rpm = (rev / time) * 3600000; // calcul revolution par seconde
  oldtime = millis();
  rev = 0;

  Serial.println(rpm);

  myfile.println (rpm);

  myfile.close();
  attachInterrupt (0, isr, RISING);


}

testez ce que dit   myfile = SD.open("test.txt", FILE_WRITE); dans la loop() avant d’écrire dans le fichier