BMP280 detecter changement de pression ... par rapport au temps

Bonjour :slight_smile:

j'ai récupéré un code (capteur de pression atmosphérique ...)
que j'ai modifié pour pouvoir afficher la pression sur 11 leds entre haute et basse pression
une sorte de barregraphe ... cela marche ...

mais j'aurais aimé aussi pouvoir détecter un changement de pression ...
si pendant un interval de temps si la pression diminue ou augmente ...
sur 2 autres leds ...
j'ai mis 30 min comme période (eventime1) et en utilisant millis()
mais cela ne marche pas a priori ...

en modifiant ma valeur (evenTime1) j'ai pu voir que les valeurs
previousTime1 et currentTime etait toujours identiques ...
en principe cela ne devrait pas

y a un bug mais je ne vois pas ou :slight_smile:
ah j'ai peut être trouvé quelque chose ^^
c'est que j'utilise 4 if a la suite en repetant 4 fois previousTime1 = currentTime;

mon code était trop long
j'ai mis uniquement la fonction concernée par le problème et non tout le code
je réutilise la variable "pression" gérée par une autre fonction.

pouvez vous m'aiguiller ? :slight_smile:
merci :slight_smile:

void changmtPression ()
         {
            // variables pour hausse ou baisse de pression, en fonction du temps 
            unsigned long currentTime;
            unsigned long previousTime1 = 0;
            float previousPression;
            const long eventTime1 = 5000;    //   30 minutes
            float eventPression1 = 0.4;
            float eventPression2 = 0.1;
             
             currentTime = millis();
             previousPression = pression;
                  
             if(currentTime - previousTime1 >= eventTime1) 
                   {
                   
                     if ((pression - previousPression >= eventPression2) || (pression - previousPression >= eventPression1))
                      {
                          previousTime1 = currentTime;
                          digitalWrite(ledDpression, HIGH );
                          previousPression = pression;
                      }
                   }
    
            if( currentTime - previousTime1 >= eventTime1)
                  { 
                    
                    if(pression - previousPression <= eventPression2)
                      {
                          previousTime1 = currentTime;
                          digitalWrite(ledDpression, LOW );
                          previousPression = pression;
                      }
                   }
    
             if(currentTime - previousTime1 >= eventTime1) 
                   {
                     
                     if ((pression - previousPression >= eventPression2) || (pression + previousPression >= eventPression1))
                      {
                          previousTime1 = currentTime;
                          digitalWrite(ledPpression, HIGH );
                          previousPression = pression;
                      }
                   }
    
            if(currentTime - previousTime1 >= eventTime1)
                  previousTime1 = currentTime;
                  { 
                    if(pression + previousPression <= eventPression2)
                      {
                          digitalWrite(ledPpression, LOW );
                          previousPression = pression;
                          previousTime1 = currentTime;
                      }
                   }

                      
            Serial.print("currentTime: ");
            Serial.print(currentTime, DEC);
            Serial.print(" ms");
            Serial.print("\t");
            Serial.print("previousTime1: ");
            Serial.print(previousTime1, DEC);
            Serial.print(" ms");
            Serial.print("\t");
            Serial.print("Leds :");
            Serial.print("\t");
            // affichage des sorties led a la queue leuleu
            Serial.print(digitalRead(ledPb5));
            Serial.print(digitalRead(ledPb4));
            Serial.print(digitalRead(ledPb3));
            Serial.print(digitalRead(ledPb2));
            Serial.print(digitalRead(ledPb1));
            Serial.print(digitalRead(ledPm));
            Serial.print(digitalRead(ledPh1));
            Serial.print(digitalRead(ledPh2));
            Serial.print(digitalRead(ledPh3));
            Serial.print(digitalRead(ledPh4));
            Serial.print(digitalRead(ledPh5));
            Serial.print("\t");
            Serial.print(digitalRead(ledDpression));
            Serial.print(digitalRead(ledPpression));
            Serial.println();
            Serial.println();
            delay(2000); //Update every 1 sec
         }

Bonjour, si je comprend bien tu es dans une fonction qui est appelée depuis la loop. En fait en plus d'avoir plusieurs fois le même if (ce qui n'est pas un bug mais inutile) ça sera toujours vrai car a l'appel de cette fonction previous time est initialisé a 0 et currenttime le temps en millisecondes depuis le démarrage du programme, avec un delay de 2000 ça sera certainement toujours > a 5000.
Pour attendre 30min, il faut que eventtime soit égal a 30601000 millisecondes.
Deux corrections donc :

  • initialiser previoustime dans la loop, passer par reference dans la fonction, mettre a jour la valeur
  • modifier la valeur d'eventtime

oui j'ai oublié de remettre Currenttime a la valeur que je lui avait mise (1800000)

je l'avais modifié pour tester ... je suis en train de remodifier mon code ...

"passer par reference dans la fonction" j'ai essayé d'integrer a la fin de la fonction "void lecturecapteur()"

return pression;

mais il m'a dis un truc du genre ...

warning: return-statement with a value, in function returning 'void' [-fpermissive]

return pression;

il faut que je change "void lecturecapteur()" par exempble "int lecturecapteur()"

"passer par reference dans la fonction" ......... ? je ne vois pas trop comment faire ...

merci

Bonjour,

Il faudrait voir comment est appelé changmtPression(), on peut supposer qu'il est appelé périodiquement.
Il faut donc que previousTime1 soit déclaré static si on veut que sa valeur persiste entre les différents appels idem pour previousPression.

oui disons ....

c'est un type void et est appelé periodiquement justement dans mon loop

void loop() 

{
  lectureCapteur();
  affichPression ();  // affichage barregraph sur 11 leds ...
  changmtPression ();  
}
int lectureCapteur ()
  {
  
  //Read values from the sensor:
  pressure = bmp.readPressure();
  temperature = bmp.readTemperature();
  pressionCap = ((((pressure)/pow((1-((float)(ELEVATION))/44330), 5.255))/100.0))/1.001862;
  //Print values to serial monitor:
  //Serial.print("Pressure: ");
  //Serial.print(pressure, 2);
  //Serial.print(" Pa");
  //Serial.print("\t");
    Serial.print(("Temp: "));
    Serial.print(temperature/1.05);
    Serial.print(" oC");
    Serial.print("\t");
    Serial.print("Sea Level Pressure ~ ");
    Serial.print(pressionCap, 2);
    Serial.println(" hPa");
    // delay(2000); //Update every 5 sec
    return pressionCap;
   
  }

dans mon code void changmtPression ()
au debut, apres déclaration des variables je mets
currentTime = millis();
previousPression = pressionCap;

donc si je retourne pressionCap et que je la mémorise dans previousPression
si je ne me trompe pas a chaque tour de boucle loop () ...
previous pression et pressionCap sera toujours identique ...
je ne vois pas comment faire concrètement pour la memeoriser

void changmtPression ()
         {
            // variables pour hausse ou baisse de pression, en fonction du temps 
            unsigned long currentTime;
            unsigned long previousTime1 = 0;
            float previousPression;
            const long eventTime1 = 1800000;    //   30 minutes
            float eventPression1 = 0.8;
            float eventPression2 = 0.2;
            int ledStateDp = LOW;
            int ledStatePp = LOW;
             
             currentTime = millis();
             previousPression = pressionCap;

                     // code pour allumer une led si la pression descend trop rapidement en fonction du temps
                     if((currentTime - previousTime1 >= eventTime1) || (currentTime < eventTime1))
                        // si temps compris entre previousTime et eventTime
                           {
                             if (pressionCap > previousPression - eventPression2)
                             // si pression mesurée > a pression memorisée - eventpression2 --> 0.2
                                {
                                    if(ledStateDp == HIGH)
                                      {
                                       ledStateDp = LOW;
                                       digitalWrite(ledDpression, ledStateDp);
                                      }
                                }
      
                             if ((pressionCap < previousPression - eventPression2) && (pressionCap > previousPression - eventPression1))
                             // si pression mesurée < a pression memorisée - eventPression2 --> 0.2
                             // <ET> pression mesurée > a pression memorisée - eventPression1 --> 0.8
                             // si la pression est entre -0.2 et -0.8
                                {
                                  if(ledStateDp == LOW)
                                    {
                                     ledStateDp = HIGH;
                                     digitalWrite(ledDpression, ledStateDp); 
                                    }
                                }
                                  
                            previousTime1 = currentTime;
                            previousPression = pressionCap;
                   }

                     // code pour allumer une autre led si la pression augmente trop rapidement en fonction du temp 
                     if((currentTime - previousTime1 >= eventTime1) || (currentTime < eventTime1))
                        // si temps compris entre previousTime et eventTime
                           {
                             if (pressionCap < previousPression + eventPression2)
                             // si pression mesurée < a pression memorisée + eventpression2 --> 0.2
                                {
                                    if(ledStatePp == HIGH)
                                      {
                                       ledStatePp = LOW;
                                       digitalWrite(ledDpression, ledStateDp);
                                      }
                                }
      
                             if ((pressionCap > previousPression + eventPression2) && (pressionCap < previousPression + eventPression1))
                             // si pression mesurée > a pression memorisée + eventPression2 --> 0.2
                             // <ET> pression mesurée < a pression memorisée + eventPression1 --> 0.8
                             // si la pression est entre +0.2 et +0.8
                                {
                                  if(ledStateDp == LOW)
                                    {
                                     ledStateDp = HIGH;
                                     digitalWrite(ledDpression, ledStateDp); 
                                    }
                                }
                                  
                            previousTime1 = currentTime;
                            previousPression = pressionCap;
                   }       
}

J'insiste, il faut que les variables qui doivent persister soient static

           static long previousTime1 = 0;
           static float previousPression;

+1
Suis le conseil de kamill.
Ainsi déclarée la variable previousTime1 est initialisée à ZÉRO à chaque fois.
C'est une variable locale.

merci !!!

cela marche mieux :slight_smile: :slight_smile: :slight_smile:
mais j'ai encore un tout petit problème ... que je ne comprend pas ...

je rappelle ce que je souhaite faire
pouvoir comparer sur une plage de temps la pression mémorisée ...
... la comparer à la mesure de pression du capteur
et allumer une led (ledDpression si pression diminue de 0.3 pendant la plage de temps)
ou ledPression si la pression augmente de 0.3 pendant la plage de temps ...)

mais j'ai la led ledDression qui reste allumée au démarrage du programme ...
j'ai envoyé l'etat des mes variables et lecture des sorties sur moniteur serie ...

la j'ai pressionCap = 1021.582 et memoirePression = 1021.641
"memoirePression - pressionCap n'est pas supérieur a 0.3

je comprend pas pourquoi la ledDpression reste allumée
ca ne devrait pas si la pression est stable ...

Merci :slight_smile:

const char ledPb5= 2;        
const char ledPb4= 3;
const char ledPb3= 4;
const char ledPb2= 5;
const char ledPb1= 6;
const char ledPm= 7;
const char ledPh1= 8;
const char ledPh2= 9;
const char ledPh3= 10;
const char ledPh4= 11;
const char ledPh5= 12;
const char ledPpression= 0;
const char ledDpression= 1;

#include <Wire.h>
#include "SPI.h" //Why? Because library supports SPI and I2C connection
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

//Setup connection of the sensor
Adafruit_BMP280 bmp; // I2C

// Variables capteur pression
float pressure;       //To store the barometric pressure (Pa)
float temperature;    //To store the temperature (oC)
float pressionCap;
int ELEVATION = 18;  //PUT HERE THE ELEVATION OF YOUR LOCATION IN METERS

// variable pour gerer le temps + pression
static float memoirePression = pressionCap;
unsigned long currentMillis;
static long previousMillis = 0;
long interval = 3600000; // 1 heure

void setup() 
  {
    bmp.begin();    //Begin the sensor
    Serial.begin(9600); //Begin serial communication at 9600bps
    pinMode(ledPb5, OUTPUT);
    pinMode(ledPb4, OUTPUT);
    pinMode(ledPb3, OUTPUT);
    pinMode(ledPb2, OUTPUT);
    pinMode(ledPb1, OUTPUT);
    pinMode(ledPm, OUTPUT);
    pinMode(ledPh1, OUTPUT);
    pinMode(ledPh2, OUTPUT);
    pinMode(ledPh3, OUTPUT);
    pinMode(ledPh4, OUTPUT);
    pinMode(ledPh5, OUTPUT);
    pinMode(ledDpression, OUTPUT);
    pinMode(ledPpression, OUTPUT);
  }

void loop() 

{
  currentMillis = millis();
  lectureCapteur();
  gererTemps(); 
  affichPression ();  
  affichSerie(); 
}
      
int gererTemps ()
    {
      if((currentMillis >= 0) && (currentMillis <= 500))
      // si temps au demarrage du programme compris entre 0 et 500 -> memorisation de la pression
        {
            memoirePression = pressionCap;
        }
        if(currentMillis - previousMillis >= interval)
        // si interval atteint -> ecriture temps actuel dans temps precedant + memorisation pression 
        {
            previousMillis = currentMillis;
            memoirePression = pressionCap;
        }

        while( currentMillis - previousMillis > 500 )
        // tant que Temps actuel - Temps precedant > 500ms ...
        {
            if( memoirePression - pressionCap > 0.3 )
                {
                   digitalWrite(ledDpression, HIGH);
                }

            if( memoirePression - pressionCap < 0.3 )
                {
                   digitalWrite(ledDpression, LOW);
                }

            if( memoirePression + pressionCap > 0.3 )
                {
                   digitalWrite(ledPpression, HIGH);
                }

            if( memoirePression + pressionCap < 0.3 )
                {
                   digitalWrite(ledPpression, LOW);
                }

           if(( memoirePression + pressionCap < 0.3 ) || ( memoirePression - pressionCap < 0.3 ))
               {
                 break; 
               }
            
        }
    }
         
  
int lectureCapteur ()
  {
  //Read values from the sensor:
  pressure = bmp.readPressure();
  temperature = bmp.readTemperature();
  pressionCap = ((((pressure)/pow((1-((float)(ELEVATION))/44330), 5.255))/100.0))/1.001862;
  delay(2000); //Update every 5 sec
  return pressionCap;
  }

Tu as

   if ( memoirePression + pressionCap > 0.3 )
   {
     digitalWrite(ledPpression, HIGH);
   }

Comme memoirePression + pressionCap est de l'ordre de 2000, il y a toutes les chances que ce soit > 0.3

ah oula j'avais pas vu ^^
merci

mais sinon j'ai vu un autre truc ^^
c'est que j'utilisais les sortie D0 et D1 pour ces leds ...
et j'ai vu que c'est lé a la communication serie Rx et Tx
donc je comprend pourquoi j'avais des choses bizarres sur le moniteur serie
a la place j'ai utilisé 2 sorties analogique en tout ou rien ...
merci

Effectivement.