Programme Pluviométrie Bug

Bonjour, je suis en term sur un projet de réalisation d'un programme sur la pluviométrie: dès qu'il bascule l'impulsion est détecté par la carte arduino qu'il incrémente à sa variable Impulsions, il y a ensuite conversion des impulsions en mm de pluie (jusqu'à là aucun problème), il montre toutes les 10 sec la valeur (en vrai se sera 24h) sauf qu'au bout du 3ème ou 4ème affichage, le programme s'emballe et montre la dernière valeur indéfiniment et ne prend plus en compte les 10 sec (il compte toujours les impulsions. La simulation est faite sous ISIS et je sais que millis ne fonctionne pas pendant une interruption mais ce temps d'attente est négligeable. Merci de votre aide

volatile int Impulsion=0;
float Precipitation=0;
int interval = 10000;      //temps (86400000 ms pour 1 journée, 10000 ms pour 10 sec)
int currentMillis = 0;
int previousMillis = 0;

void setup()   
{
Serial.begin(19200);
attachInterrupt(0, gestionINT0, RISING);
}

void loop()
{
unsigned long currentMillis = millis();      

if(currentMillis - previousMillis > interval) 
{
  previousMillis = currentMillis;        //va déduire le temps écoulé au temps défini (24h) si inférieur à 86400000 ça attend avant envoie, si supérieur à 86400000 il envoie)
  Serial.print("Precipitation (mm)= "); 
  Serial.println(Precipitation);               
}
}

void gestionINT0()
{
Precipitation=0.307*Impulsion;  
++Impulsion;  //comptage  
}

Bonjour,

  1. Tu n'es pas dans la bonne rubrique, demande au modo de le changer.
  2. Il faut mettre ton code entre balises #, c'est illisible.
    @+

bonjour
meme remarque qu'icare

en passant tu stocke un long dans un int (currentmillis , previousmillis)

Re,
C'est déjà mieux pour la visibilité, mais tu peux faire mieux.
Au lieu d'utiliser "Quote" comme tu viens de le faire, utilise le "#" qui se trouve juste à gauche de "Quote"

Je stocke un long dans un int ? Faut que je remplace les int des Millis en long?

C'est mieux là? :stuck_out_tongue:

Re,

dmazoin:
Je stocke un long dans un int ? Faut que je remplace les int des Millis en long?

C'est mieux là? :stuck_out_tongue:

Déjà tu déclares en global

int currentMillis = 0;

Puis tu crées un variable locale dans loop()

unsigned long currentMillis = millis();

Tu pourrais également initialiser ta variable previousMillis dans le setup()

Alors , je vais vous demander de détailler car j'y connais pas grand chose (je me suis fait beaucoup aidé pour ce que je vous ai montré).

Vous pouvez me mettre directement les "truc" à leur place svp, je fait les truc que vous me dites et ça marche plus (j'ai du mettre au mauvais endroit) :disappointed_relieved:

Re,
Essaye cette version

volatile int Impulsion=0;
float Precipitation=0;
int interval = 10000;      //temps (86400000 ms pour 1 journée, 10000 ms pour 10 sec)
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;

void setup()   
{
Serial.begin(19200);
attachInterrupt(0, gestionINT0, RISING);
previousMillis = millis();
}

void loop()
{
currentMillis = millis();

if(currentMillis - previousMillis > interval) 
{
  previousMillis = currentMillis;        //va déduire le temps écoulé au temps défini (24h) si inférieur à 86400000 ça attend avant envoie, si supérieur à 86400000 il envoie)
  Serial.print("Precipitation (mm)= "); 
  Serial.println(Precipitation);            
}
}

void gestionINT0()
{
Precipitation=0.307*Impulsion;  
++Impulsion;  //comptage  
}

Après, il faut te poser la question, que se passe-il lorsque ta variable Impulsion "déborde".
Je pense qu'il faudra revoir le traitement de ton interruption, mais c'est toi qui voit.
Il faut fournir un minimum de réflexion et de travail
@+

Je pense que le programme tourne en boucle dans la "boucle" et qu'il ne prend plus en compte le reste du programme.

Je viens de test le programme, ça fonctionne , MERCI BEAUCOUP :stuck_out_tongue:

Bonne journée.

Re,

dmazoin:
Je pense que le programme tourne en boucle dans la "boucle" et qu'il ne prend plus en compte le reste du programme.

Dans loop() c'est normal que ça boucle :wink:
Que veux-tu dire avec ces propos ?

Que le programme ne sort plus de la boucle void loop()

La conversion d'impulsions en précipitation devrait se faire dans loop au moment de l'affichage et non pendant l'interruption.
Pour 2 raisons:

  • 1 - une multiplication en flottant c'est long et donc cela bloque les autre IT pendant tous ce temps là.
  • 2 - c'est inutile de calculer à chaque fois le niveau de précipitation s'il n'y en a pas besoin tout de suite.

En conséquence il est plus logique de faire la multiplication au moment d'afficher la valeur.

Re,

dmazoin:
Que le programme ne sort plus de la boucle void loop()

Je ne suis pas inquiet c'est le principe même du fonctionnement de la carte Arduino
Consulte le cours ci-dessous et tu feras de grand progres
http://forum.arduino.cc/index.php?topic=102618.msg1654827#msg1654827

Donc je déplace le Precipitation=0.049*Impulsion; dans le if juste avant Serial.print?

Sinon comment je peut faire pour reset Precipitation après l'affichage?

Autre truc pas logique

if(currentMillis - previousMillis > interval)

Ce test ne prend pas correctement en compte le débordement de millis().
Il faut l'écrire comme ça:

if(previousMillis + interval < currentMillis )

dmazoin:
Donc je déplace le Precipitation=0.049*Impulsion; dans le if juste avant Serial.print?

Sinon comment je peut faire pour reset Precipitation après l'affichage?

Exactement

Pourquoi veux-tu le remettre à zéro après l'affichage?
Si tu fais ça il sera mis à zéro toutes les 10s.

Le programme envoie toutes les 24h (on utilise 10 sec pour pouvoir le simuler), on envoie la valeur en mm à un autre camarade (lui se débrouille avec) et dès qu'il la lu , on la reset. Et ça toutes les 24h.

C'est bon , j'ai trouvé pour reset : y'a 15 jours j'avais essayé de mettre derrière serialprint : Precipitation=0 mais ça marchais pas et en faites faut mettre Impulsions. Pour ceux qui aurait pas suivit: si on prend a+b = c et qu'on reset c , ça sert à rien vu que b n'est toujours pas à 0 :sweat_smile:

Enfin bon , mon programme est finis :slight_smile: merci beaucoup pour votre aide (et j'ai déplacé le calcul pour qu'il se fasse juste avant l'envoie et c'est nickel ).

volatile int Impulsion=0;
float Precipitation=0;
int interval = 10000; //temps (86400000 ms pour 1 journée, 10000 ms pour 10 sec)
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;

void setup()
{
Serial.begin(19200);
attachInterrupt(0, gestionINT0, RISING);
previousMillis = millis();
}

'void loop()'
{
currentMillis = millis();

if(currentMillis - previousMillis > interval)
{
previousMillis = currentMillis; //va déduire le temps écoulé au temps défini (24h) si inférieur à 86400000 ça attend avant envoie, si supérieur à 86400000 il envoie)
Serial.print("Precipitation (mm)= ");
Serial.println(Precipitation);
}
}

void gestionINT0()
{
Precipitation=0.307*Impulsion;
++Impulsion; //comptage
}