Go Down

Topic: faire une moyenne de la temperature ... (Read 18102 times) previous topic - next topic

djbouns

bon ...

j'ai tout modifier mon code de gestion aquarium.
avec fonction map (pour la temperature et eclairage)
dite moi si quelque chose ne vas pas. pour le momment il tourne correct je regarde pendant 24h si pas de probleme.
lve123, tu a une solution pour mes delays ?

Code: [Select]


#include "LiquidCrystal.h"
#include "WProgram.h"
#include "Wire.h"
#include "DS1307.h"

LiquidCrystal lcd(7, 2, 3, 4, 5, 6);
int pompe = 8;
int soleil = 9;
int ventilateur = 10;
int rampeled = 11;
int led = 12;
int niveau = 13;

int valeurPWM=0;

int minut;
int heure;
int seconde;
int time;

float sensorPin;
float temp;
int Vact = 0;  // variable valeur instantanée
int Fd=10; // facteur de division de la moyenne = moyenne toutes les FD boucles ici 20
long Accm=0; // accumulateur pour moyenne
int Nbcl=0; // compteur de boucles
int tempmax=28;
int tempmin=26.5;
int vitventilo;


void setup() {
 
 lcd.begin(16,2);
Serial.begin(9600);

 pinMode(pompe, OUTPUT);  
 pinMode(ventilateur, OUTPUT);  
 pinMode(soleil, OUTPUT);  
 pinMode(led, OUTPUT);  
 pinMode(rampeled, OUTPUT);
 pinMode(niveau, INPUT);
}
 
 
 void loop(){
 
sensorPin = analogRead(0);
Vact = (sensorPin*0.5)+1.5 ;
Accm=Accm+Vact;
Nbcl ++;

if (Nbcl == Fd) {
 temp = Accm / Fd ;
 Accm= Accm-temp ;
 Nbcl= 9;
 }  
else{
  temp = Vact;
  }

//Récupération de l'heure du DS1307**********************************************************************************************
 heure = RTC.get(DS1307_HR,true);  
 minut = RTC.get(DS1307_MIN,true);
 seconde = RTC.get(DS1307_SEC,true);
 time = (heure * 100) + minut;
 
//Affichage ******************************************************************************************
lcd.setCursor(0,0);
  lcd.print ("  AQUA GESTION  ");
  lcd.setCursor(0,1);
  lcd.print("     ");
 if (heure < 10)
 {
   lcd.print("0");
 }
 lcd.print(heure);
 lcd.print("H");
 if (minut < 10)
 {
   lcd.print("0");
 }
 lcd.print(minut);
lcd.print("     ");
 delay (5000);
lcd.setCursor(0,1);
lcd.print("     ");
 lcd.print(temp);
 lcd.print((char)223);
 lcd.print("     ");
 delay (5000);


//*****Controle des sorties eclairage *********
//***on-off***** soleil ***
 
if ((time >= 1000) && (time < 1045)){
   valeurPWM = map(time, 1000, 1044, 0, 255);
   analogWrite (soleil, valeurPWM);
lcd.setCursor(0,1);
   lcd.print(" + + soleil + + ");
   delay(5000);
 }
else if ((time >= 2230) && (time < 2300)){  
  valeurPWM = map(time, 2230, 2259, 255, 0);
   analogWrite (soleil, valeurPWM);
lcd.setCursor(0,1);
   lcd.print(" - - soleil - - ");
   delay(5000);
 }  
 else if ((time >= 1045 ) && (time < 2230)) {
   analogWrite(soleil, 255);
 }
else {
   analogWrite(soleil, 0);
     lcd.setCursor(0,0);
   lcd.print("   BONNE NUIT   ");
   delay(5000);
}


//***on-off*****led 1w***
    if((time >= 1040) && (time < 2235)){
   digitalWrite(led, HIGH);
  }
 else{
   digitalWrite(led, LOW);
  }
   
   
//***on-off***** rampe led ***
if((time >= 1045) && (time < 2230)){
   digitalWrite(rampeled, HIGH);
  }
 else{
   digitalWrite(rampeled, LOW);
  }

//***on-off***** ventilateur  ***

if (temp > tempmax){
 tempmax = temp;
}
if (temp < tempmin){
  tempmin = temp;
}
vitventilo = map(temp, tempmin, tempmax, 0, 255);
analogWrite(ventilateur, vitventilo);


//***on-off***** pompe ***
if (digitalRead (niveau) == HIGH)
{
  lcd.setCursor(0,0);
   lcd.print("niveau d'eau BAS");
   delay(5000);
 
if (minut == 01){
   digitalWrite(pompe, HIGH);
   delay (1000);
   digitalWrite(pompe, LOW);
   delay (5000);
}
   else if (minut == 11){
   digitalWrite(pompe, HIGH);
   delay (1000);
   digitalWrite(pompe, LOW);
   delay (5000);
}
   else if (minut == 21){
   digitalWrite(pompe, HIGH);
   delay (1000);
   digitalWrite(pompe, LOW);
   delay (5000);
}
   else if (minut == 31){
   digitalWrite(pompe, HIGH);
   delay (100);
   digitalWrite(pompe, LOW);
   delay (5000);
}
   else if (minut == 41){
   digitalWrite(pompe, HIGH);
   delay (1000);
   digitalWrite(pompe, LOW);
   delay (5000);
}
   else if (minut == 51){
   digitalWrite(pompe, HIGH);
   delay (1000);
   digitalWrite(pompe, LOW);
   delay (5000);
}
}
else if (digitalRead (niveau) == LOW){
     lcd.setCursor(0,0);
   lcd.print("niveau d'eau  OK");
   delay(5000);
digitalWrite(pompe, LOW);
}

}



djbouns

Bonjour,

merci lve123,
il y avait des petite erreur dans le code que tu m'as gentille-ment modifier,
j'ai modifier un peut tout sa et sa donne sa:

Code: [Select]
#include "LiquidCrystal.h"
#include "WProgram.h"
#include "Wire.h"
#include "DS1307.h"

LiquidCrystal lcd(7, 2, 3, 4, 5, 6);
int pompe = 8;
int soleil = 9;
int ventilateur = 10;
int rampeled = 11;
int led = 12;
int niveau = 13;

int valeurPWM=0;

int minut;
int heure;
int seconde;
int time;

float sensorPin;
float temp;
float Vact = 0;  // variable valeur instantanée
int Fd=10; // facteur de division de la moyenne = moyenne toutes les FD boucles ici 20
long Accm=0; // accumulateur pour moyenne
int Nbcl=0; // compteur de boucles
int vitventilo;
int off;
byte TAFF;
boolean FLB1;
boolean FP;
byte TP;
int FT;
int indexmessage;
int duree;

void setup() {
 
  lcd.begin(16,2);
Serial.begin(9600);

  pinMode(pompe, OUTPUT); 
  pinMode(ventilateur, OUTPUT); 
  pinMode(soleil, OUTPUT); 
  pinMode(led, OUTPUT); 
  pinMode(rampeled, OUTPUT);
  pinMode(niveau, INPUT);
}
 
 
  void loop(){
 
sensorPin = analogRead(0);
Vact = ((sensorPin*0.5)+1.5)*10 ;
Accm=Accm+Vact;
Nbcl ++;

if (Nbcl == Fd) {
  temp = (Accm / Fd) ;
  temp = temp/10;
  Accm= Accm-(Accm/10) ;
  Nbcl= 9;
  }   
else{
   temp = Vact/10;
   }

//Récupération de l'heure du DS1307**********************************************************************************************
  heure = RTC.get(DS1307_HR,true); 
  minut = RTC.get(DS1307_MIN,true);
  seconde = RTC.get(DS1307_SEC,true);
  time = (heure * 100) + minut;
 
//Affichage ******************************************************************************************
lcd.setCursor(0,0);
   lcd.print ("  AQUA GESTION  ");
   

if (FLB1 == LOW) { //lcd dispo ?
    if (indexmessage == 0){
    TAFF = 50;
    lcd.setCursor(0,1);
    lcd.print("     ");
   if (heure < 10) {
    lcd.print("0");
    }
   lcd.print(heure);
   lcd.print("H");
   if (minut < 10) {
   lcd.print("0");
   }
   lcd.print(minut);
   FLB1 = HIGH; // lcd occupé
   indexmessage = 1;
  }
  }
if (FLB1 == LOW) { //lcd dispo ?
    if (indexmessage == 1){
    TAFF = 50;
    lcd.setCursor(0,1);
    lcd.print("     ");
    lcd.print(temp);
    lcd.print((char)223);
    lcd.print("     ");
   FLB1 = HIGH; //lcd occupé
   indexmessage = 2;
    }
    }

//*****Controle des sorties eclairage *********
//***on-off***** soleil ***
 
  if (FLB1 == LOW) { //lcd dispo ?
     if (indexmessage == 2){
     TAFF = 50;
     lcd.setCursor(0,1);
     lcd.print(" + + soleil + + ");
     FLB1 = HIGH; // lcd occupé
     indexmessage = 3;
   }
   }
 
else if ((time >= 2230) && (time < 2300)){ 
   valeurPWM = map(time, 2230, 2259, 255, 0);
    analogWrite (soleil, valeurPWM);
  if (FLB1 == LOW) { //lcd dispo ?
     if (indexmessage == 2){
     TAFF = 50;
     lcd.setCursor(0,1);
     lcd.print(" - - soleil - - ");
     FLB1 = HIGH; // lcd occupé
     indexmessage = 3;
   }
   }
  }   
  else if ((time >= 1045 ) && (time < 2230)) {
    analogWrite(soleil, 255);
    }
  else {
    analogWrite(soleil, 0);
   if (FLB1 == LOW) { //lcd dispo ?
     if (indexmessage == 2){
     TAFF = 50;
     lcd.setCursor(0,1);
     lcd.print("   BONNE NUIT   ");
     FLB1 = HIGH; // lcd occupé
     indexmessage = 3;   
   }
   }
    }


//***on-off*****led 1w***
     if((time >= 1040) && (time < 2235)){
    digitalWrite(led, HIGH);
   }
  else{
    digitalWrite(led, LOW);
   }
   
   
//***on-off***** rampe led ***
if((time >= 1045) && (time < 2230)){
    digitalWrite(rampeled, HIGH);
   }
  else{
    digitalWrite(rampeled, LOW);
   }


//***on-off***** ventilateur  ***

if (temp > 29.00){
  temp = 29.00;
}

if (temp < 26.20){
  temp = 26.20;
}


vitventilo = map(temp,26.20,29.00, 0, 255);
analogWrite(ventilateur, vitventilo);
off = ((vitventilo*100)/255);
     if (FLB1 == LOW) { //lcd dispo?
     if (indexmessage == 3){
     TAFF = 50;
     lcd.setCursor(0,1);
     lcd.print("ventilateur ");
     if (off = 0){
    lcd.print(" OFF");
     }
    else {
    lcd.print((vitventilo*100)/255);
    lcd.print(" %");
     FLB1 = HIGH; // lcd occupé
     indexmessage = 0;
     }
     }
     }

//***on-off***** pompe ***
if (digitalRead (niveau) == HIGH) {
   if (FLB1 == LOW) { //lcd dispo?
     if (indexmessage == 3){
     TAFF = 50;
     lcd.setCursor(0,1);
     lcd.print("niveau d'eau BAS");
     FLB1 = HIGH; // lcd occupé
     indexmessage = 0;
     }
  }
}
     
if ((minut % 10)== 0) { //toutes les 10 minutes
    if(FP == LOW) { //pompe off
      if (TP == 0) { //début pompage
      digitalWrite (pompe,HIGH);
      TP = 10; // 1 sec
      FP = HIGH; // pompe on
      }
    }
         if (FLB1 == LOW) { //lcd dispo?
     if (indexmessage == 3){
     TAFF = 50;
     lcd.setCursor(0,1);
     lcd.print("  ajout d'eau  ");
     FLB1 = HIGH; // lcd occupé
     indexmessage = 0;
     }
    }
    else {
     if (TP== 0) { //fin pompage
       digitalWrite (pompe, LOW);
       TP = 50;  // 5 sec
       FP = LOW; // pompe off
       }
}
}
else if (digitalRead (niveau) == LOW){
   if (FLB1 == LOW) { //lcd dispo?
     if (indexmessage == 3){
     TAFF = 50;
     lcd.setCursor(0,1);
     lcd.print("niveau d'eau OK ");
     FLB1 = HIGH; // lcd occupé
     indexmessage = 0;
     }
   }
  digitalWrite(pompe, LOW);
}

duree = millis();
if ((duree % 100)>=50){
  if (FT == true){
    if(TP != 0){
      TP--;
    }
    if(TAFF ==0){
      FLB1 = LOW; //LCD libéré
    }
    else{
     TAFF--;
    }
  }
  FT = false;
}
else {
FT = true;
}
}

lve123

Bonjour

Attention duree doit être une variable long.
Mais si ça marche tant mieux
Si tu as compris le principe avec millis() et le  drapeau FLB0 c'est parfait.
Pour les petites erreurs, j'ai fait ça en vitesse, n'ayant pas d'aquarium, je n'ai essayé que la boucle de temps avec millis()
A+

lve123

Bonjour (re)
Dans la partie contrôle des sorties éclairage, tu as oublié:
if ((time >= 1000) && (time < 1045)){
valeur PWM = map (time, 1000, 1044, 0, 255);
analogWrite(soleil, valeurPWM);

Tu as ajouté un message, du coup il faut:
après
lcd.print(" %");
FLB1 = HIGH; // lcd occupé
indexmessage = 4;
et
dans on-off  pompe remplacer les
if (indexmessage == 3){
par if (indexmessage == 4) {

où tu défini int FT; remplace par boolean FT, ça prend 3 octet en moins.
A+

corsaire50

La moyenne est une solution, voire une moyenne glissante et analyser la dérivée de celle ci (pour déterminer la tendance : température en augmentation...).

Sans connaître ta problématique 'aquarium' au sens contraintes, tu as aussi une méthode plus simple que la moyenne qui consiste à compter combien de fois successives ta température mesurée est au dessus de ton seuil. Par exemple, si ta température est sur 3 mesures consécutives supérieure à 20° alors tu enclenches ton ventilo. Sans écrire le code, voici le pseudo-code simplifié :

int compteurSeuilDepasse = 0
...
// mesure de la température
si (temperature > seuil) alors
  compteur = compteur + 1
sinon
  compteur = 0

si (compteur > nbFoisSuffisante) alors
  demarrer ventilo


infobarquee


de rien, fais vite fait comme ca, donc peut etre optimisé.
le principe est simple :
chaque fourchette de temp comporte un compteur
si la temp est dans cette fourchette, on incrémente le compteur de cette fourchette et on met à zéro les autres.
si le nb du compteur (compteurmax de mémoire ) est atteint on lance le ventilo à la valeur attribuée et on remet tous les compteurs à zéro.
et ainsi de suite.


déjà donné comme solution ;)
AUCUNE AIDE PAR MP

lve123

Bonjour
Je crois qu'il y a un problème d'inertie ou de temps de réponse entre le moment où on détecte un dépassement de t°, que l'on actionne le ventilo et que la sonde détecte une baisse de t°; ce qui pourrait expliquer les marche / arrêt du ventilo.
Comment s'effectue le refroidissement de l'eau : le ventilo souffle sur la surface de l'eau, sur la paroi de l'aquarium, sur un radiateur (ce qui serait le mieux) ?
A+

infobarquee

en relisant un peu le tout, tu as un lm35 pour la temp.
je me pose une question aussi en complément de lve123, est il immergé ou non?
AUCUNE AIDE PAR MP

djbouns


en relisant un peu le tout, tu as un lm35 pour la temp.
je me pose une question aussi en complément de lve123, est il immergé ou non?



oui, il est immergé ... c'est le mieu pour prendre la temperature de l'eau non ?  :D

Go Up