Go Down

Topic: probleme ecriture carte sd (Read 413 times) previous topic - next topic

carpoye

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:
Code: [Select]
#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.


J-M-L

#1
Apr 18, 2019, 01:54 pm Last Edit: Apr 18, 2019, 02:01 pm by J-M-L
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)


Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

carpoye

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.

carpoye

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

J-M-L

Que voulez vous dire par  "vous n'attachez pas l'interruption dans le setup."?
je ne vois pas
Code: [Select]
attachInterrupt(0,isr,RISING);donc on rentre dans la loop sans que les interruptions ne soient activées
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

dbrion06

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.

carpoye

#6
Apr 18, 2019, 02:51 pm Last Edit: Apr 18, 2019, 02:58 pm by carpoye
Voici le code modifié:
Code: [Select]
#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

J-M-L

#7
Apr 18, 2019, 02:58 pm Last Edit: Apr 18, 2019, 03:01 pm by J-M-L
mettez un
Code: [Select]
volatile unsigned int rev = 0;

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

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

carpoye

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

J-M-L

#9
Apr 18, 2019, 03:01 pm Last Edit: Apr 18, 2019, 03:02 pm by J-M-L
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)
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

dbrion06

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)

carpoye

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é:
Code: [Select]
#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);

}

J-M-L

#12
Apr 18, 2019, 03:22 pm Last Edit: Apr 18, 2019, 03:23 pm by J-M-L
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
Code: [Select]
    return;quand y'a un souci, faites plutôt un
Code: [Select]
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
Code: [Select]
if (myfile) {
  // ici tout OK
} else {
  // bug
}


Quote
Je pense que 1 seconde sépare chaque déflecteur.
alors pourquoi n'attendre que 1/2 seconde
Code: [Select]
  delay(500);entre 2 calculs?
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

carpoye

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.
 
Code: [Select]
#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);

}

carpoye

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.

Go Up