Timer pour un relais pour chauffage piscine

Bonjour,
je souhaite chauffer une piscine rapidement avec un chauffe eau solaire(intex), un arduino ( esp32), un capteur de température ds18b20 (fixé sous le chauffe eau solaire) et un relais branché sur la pompe.

Je souhaite juste pouvoir régler le temps de fonctionnement de mon relay, de 2 à 4 secondes pour ne pas faire trop baisser la température du chauffe eau.

Actuellement, le relais reste en marche trop longtemps, 15 à 20sec ,pour chauffer efficacement; ce qui refroidit trop le panneau, perte de 10 ou 15°. Je ne veux pas que le relais SE COUPE en fonction de la température lut sur le capteur, mais d'un temps défini.

La fonction delay de 2 seconde de fonctionne pas, doit-je utiliser la fonction millis , ou autre, pour temporiser mon relais une fois déclenché.

Merci d'avance pour votre aide.

Voici mon code :

#include <OneWire.h>
#include <DallasTemperature.h>
#define RELAIS 18

// GPIO where the DS18B20 is connected to
const int oneWireBus = 14;     

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);

// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

void setup() {
  // Start the Serial Monitor
  Serial.begin(115200);
  // Start the DS18B20 sensor
  sensors.begin();
  pinMode(RELAIS,OUTPUT);
}

void loop() {
  sensors.requestTemperatures(); 
  float temperatureC = sensors.getTempCByIndex(0);
  
  Serial.print(temperatureC);
  Serial.println("ºC");
{


  //Print the results
  if (sensors.getTempCByIndex(0) > 40) 

  // si temperature inferieur à 40° 
              {
                
                digitalWrite(RELAIS, HIGH); //Relais1 ON  
                delay(2000);               //relais temporiser pour 2 secondes
              }
           else 
            {
                 digitalWrite(RELAIS, LOW); // Relais1  OFF
             
              } 

}
}

Bonjour,

Dans votre code:

if (sensors.getTempCByIndex(0) > 40) 

  // si temperature inferieur à 40° 
          

Vous écrivez en commentaire "si température inférieur à 40", et dans le code vous écrivez
"if (sensors.getTempCByIndex(0) > 40)"
Avec le signe supérieur (>) au lieu de inférieur (<).

Ensuite, votre algorithme ne me semble pas clair quand vous écrivez

Toujours est-il que juste après votre "delay(2000)", vous n'éteignez pas votre relais!

Selon moi il aurait fallut écrire

              {
                digitalWrite(RELAIS, HIGH); //Relais1 ON  
                delay(2000);               //relais temporiser pour 2 secondes
                digitalWrite(RELAIS, LOW); // Relais1  OFF
             
              } 

Et supprimer le "else..."

Techniquement la fonction delay ne peut que fonctionner, par contre ton algorithme (ce que tu demande à ton Arduino de faire), lui n'est pas cohérent avec ce que tu veux faire, comme l'a indiqué @jef59

Si on traduit ton code cela donne

faire en boucle la chose suivante :

  • acquisition de la température
  • affichage de la température sur le moniteur série
  • Si température supérieur à 40° faire ce qui suit:
    1. activer le relais
    2. attendre 2000ms
  • sinon désactiver le relais

Donc commue l'a indiqué @jef59 si tu désactive ton relais uniquement quand la température est inférieur ou égale à 40°, ton programme ne peux pas faire autrement.

Attention par exemple ajouter une instruction "digitalWrite(RELAIS, LOW);" après le "delay", va bien désactiver après 2s, mais ta condition de température sera immédiatement réévaluer après cette désactivation.
Ce qui n'est pas forcément négatif.

Après plutôt que de tâtonner avec un temps d'activité, tu peux aussi faire ce que l'on appel une hystérésis, c'est à dire avoir une température d'activation et une autre température de désactivation.
Comme ce qui te gêne c'est une perte de température trop importante(> à 10°)
tu peux utiliser le test de condition suivant

if (condition de température 1) {
    ...
} else if (condition de température 2) {
    ...
}

Idéalement on préconise de plutôt utiliser la fonction "millis", qui est non bloquante, si ce programme à vocation à gérer plus de chose , mais demande à modifier la structure de ton programme et est moins "logique" pour un débutant.

Autre chose ton code n'est pas indenté correctement, tu peux utiliser dans l'IDE Arduino le raccourcis clavier ctr-T pour le faire automatiquement.

Bonjour,

Est ce vraiment utile de lancer une lecture de température à chaque boucle ?

Une lecture toutes les 5 secondes ( par exemple) ne suffirait pas ? D.autant plus que la conversion de lecture prend jusqu’à 750ms selon la résolution adoptée.

On peut se poser la question effectivement, mais on peut aussi se demandé de l'intérêt de ne pas le faire ?
Ou dit autrement ce que cela apporte de "complexifier" le programme ?

Entiérement d'accord, c'est pour cela que je trouve qu'il y a un flou à propos de ce qui est attendu de l'algorithme par son concepteur.

Bonjour à tous et merci pour votre réactivité.

if (sensors.getTempCByIndex(0) > 40)

// si temperature inferieur à 40°

c'est bien une coquille, c'est supérieur, mais vous l'avez compris.

Donc commue l'a indiqué @jef59 si tu désactive ton relais uniquement quand la température est inférieur ou égale à 40°, ton programme ne peux pas faire autrement.

Attention par exemple ajouter une instruction "digitalWrite(RELAIS, LOW);" après le "delay", va bien désactiver après 2s, mais ta condition de température sera immédiatement réévaluer après cette désactivation.
Ce qui n'est pas forcément négatif.

C'est ce que je veux pour le moment, je recherche à réchauffer la piscine le plus rapidement possible pour le mois de mai et pas de gérer la température.

Pour un hystérésis, ce sera une fois que la piscine aura chauffé car j'ai essayé mais la température du panneau descend trop à cause de l'inertie du capteur de température qui est situé sous le panneau.

Et le ctr-T c'est super, je vais l'appliquer sur mes autres codes, Merci.

voici donc le nouveau code :

#include <OneWire.h>
#include <DallasTemperature.h>
#define RELAIS 18


const int oneWireBus = 14;  // GPIO where the DS18B20 is connected to pin 14


OneWire oneWire(oneWireBus);  // Setup a oneWire instance to communicate with any OneWire devices


DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature sensor

void setup() {

  Serial.begin(115200);  // Start the Serial Monitor

  sensors.begin();          // Start the DS18B20 sensor
  pinMode(RELAIS, OUTPUT);  // Relais1 OFF
}

void loop() {
  sensors.requestTemperatures();
  float temperatureC = sensors.getTempCByIndex(0);

  Serial.print(temperatureC);  // temperature reading
  Serial.println("ºC");        //Print the results
  {


    (sensors.getTempCByIndex(0) > 40);  // si temperature supérieur à 40°

    {
      digitalWrite(RELAIS, HIGH);  //Relais1 ON
      delay(2000);                 //relais temporiser pour 2 secondes
      digitalWrite(RELAIS, LOW);   // Relais1  OFF
    }
  }
}

Encore un grand merci à tous, je vous tient informé dans la journée.

Oui et non, c'est là ou la remarque de @EGT59 prend tout son sens.
Si tu attends justement un temps supérieur à l'inertie de ton capteur avant de redemander la température, cela ne se produira pas.

En faite tu gères la température indirectement.
Par contre comme le temp que tu indiques étant assez court et surtout à priori supérieur à la latence de ta sonde, il ne doit pas être possible de le gérer avec une hystérésis, qui aura un temps de réaction trop long.

Sinon ton deuxième code me parait bien, des que la température est supérieur à 40°, tu ouvres la vanne pendant 2s :slight_smile:

Vous ne pouvez pas mettre la sonde directement au contact de l’eau réchauffée en sortie de panneau chauffant ?
Vous allez gagner sur le temps de réaction de la sonde et cela permettrait de faire une régulation du genre si temp > 40 j.envoie l.eau chaude et si < 35 (par exemple) je ferme le circuit jusqu’au retour à la condition >40.
Il existe des raccords pvc pour mettre des sondes sur les circuits de piscine.

Retour d'expérience sur la journée, le code précèdent n'est pas opérationnel, le relais fonctionne bien pendant 2 secondes, s'arrête, puis repart pendant 2 secondes, s'arrête, puis repart pendant 2 secondes, etc..., Il faut bien mettre une condition if / else. 5 secondes de fonctionnement/ 9 secondes d'arrêt.

j'ai donc mit un "delay" pour le relais off.

Vous ne pouvez pas mettre la sonde directement au contact de l’eau réchauffée en sortie de panneau chauffant ?

Non, car c'est un panneau souple, les raccords entrée et sortie sont rigide mais si je met le capteur en sortie je n'est pas la température du panneau. Grosse précision : le panneau chauffant souple est enfermé dans un caisson étanche à l'air, le fond et le bord sont en bois, la vitre en plexis; en plein soleil l'eau dans le panneau chauffant peu atteindre 70 à 80° (estimation de ma part) ce qui le fait "fondre"" et créée des fuites, la sonde situé sous le panneau mais dans le caisson indiquait autour de 60°.

Voici le code que j'ai utilisé :

#include <OneWire.h>
#include <DallasTemperature.h>
#define RELAIS 18


const int oneWireBus = 14;  // GPIO where the DS18B20 is connected to pin 14


OneWire oneWire(oneWireBus);  // Setup a oneWire instance to communicate with any OneWire devices


DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature sensor

void setup() {

  Serial.begin(115200);  // Start the Serial Monitor

  sensors.begin();          // Start the DS18B20 sensor
  pinMode(RELAIS, OUTPUT);  // Relais1 OFF
}

void loop() {
  sensors.requestTemperatures();
  float temperatureC = sensors.getTempCByIndex(0);

  Serial.print(temperatureC);  // temperature reading
  Serial.println("ºC");        //Print the results

  {


    //Print the results
    if (sensors.getTempCByIndex(0) > 45)

    // si temperature inferieur à 40°
    {

      digitalWrite(RELAIS, HIGH);  //Relais1 ON
      delay(5000);
      digitalWrite(RELAIS, LOW);
      delay(9000);  //relais temporiser pour 2 secondes
    } 
    else 
    {
      digitalWrite(RELAIS, LOW);  // Relais1  OFF
    }
  }
}

J'attends un journée vraiment ensoleillé pour évaluer la pertinence de ce montage.
Je vous tient informé.

Pourquoi ce n'est pas opérationnel, le comportment que tu indiques, ne peut se faire que si ta sonde indique toujours une température supérieur à 40°.
Donc si cela ne te va pas, c'est que la latence de ta sonde est très importante.
As tu estimé la latence de celle-ci?
L'idéal serait plutot que tu fasse une temporisation entre deux tests de température.

:+1:

Voir le #4

Ou l'idéal serait que uniquement lorsque tu a finit d'ouvrir pendant 2s ton relais, tu fasse une temporisation avant le prochain test.

hello, un truc comme ça

`#include <OneWire.h>
#include <DallasTemperature.h>
#define RELAIS 18             // bobine relais de commande de la pompe sur D18
const int oneWireBus = 14;  //com avec le capteur de température par D14
OneWire oneWire(oneWireBus);  // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature sensor
unsigned long travail = 2000.00;//2 secondes
unsigned long repos   = 9000.00;//9 secondes
void setup() {
  Serial.begin(115200);       // Start the Serial Monitor
  sensors.begin();            // Start the DS18B20 sensor
  digitalWrite(RELAIS, LOW);  // pour etre off à l'init de D18 en sortie
  pinMode(RELAIS, OUTPUT);    // D18 enn sortie pour commande du relais de pompe
}

void loop()
{
  sensors.requestTemperatures();//pour avoir une conversion récente
  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print(temperatureC);  // affichage de la température
  Serial.println("ºC");        // en degrés celsius
  if (temperatureC > 45) // si temperature supérieure à 45°
  {
    digitalWrite(RELAIS, HIGH);  //Relais1 ON
    Serial.println(F("pompe on"));
    delay(travail);
    digitalWrite(RELAIS, LOW);
    Serial.println(F("pompe off"));
    delay(repos);
  }
  else {
    if (temperatureC < 43) // si temperature inférieure à 43°
    {
      digitalWrite(RELAIS, LOW);  // Relais1  OFF
    }
  }
}

J'aurais plutot pensé à quelque chose comme ça, puisque le "ELSE" est inutile.

void loop() {
  sensors.requestTemperatures();//pour avoir une conversion récente
  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print(temperatureC);  // affichage de la température
  Serial.println("ºC");        // en degrés celsius
  if (temperatureC > 45) { 
    // si temperature supérieure à 45°
    digitalWrite(RELAIS, HIGH);  //Relais1 ON
    Serial.println(F("pompe on"));
    delay(travail);
    digitalWrite(RELAIS, LOW);
    Serial.println(F("pompe off"));
  }
  delay(temp);
}

bonsoir,

`#include <OneWire.h>
#include <DallasTemperature.h>
#define RELAIS 18             // bobine relais de commande de la pompe sur D18
const int oneWireBus = 14;  //com avec le capteur de température par D14
OneWire oneWire(oneWireBus);  // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature sensor
unsigned long travail = 2000.00;//2 secondes
unsigned long repos   = 9000.00;//9 secondes
void setup() {
  Serial.begin(115200);       // Start the Serial Monitor
  sensors.begin();            // Start the DS18B20 sensor
  digitalWrite(RELAIS, LOW);  // pour etre off à l'init de D18 en sortie
  pinMode(RELAIS, OUTPUT);    // D18 enn sortie pour commande du relais de pompe
}

void loop()
{
  sensors.requestTemperatures();//pour avoir une conversion récente
  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print(temperatureC);  // affichage de la température
  Serial.println("ºC");        // en degrés celsius
  if (temperatureC > 45) // si temperature supérieure à 45°
  {
    digitalWrite(RELAIS, HIGH);  //Relais1 ON
    Serial.println(F("pompe on"));
    delay(travail);
    digitalWrite(RELAIS, LOW);
    Serial.println(F("pompe off"));
    delay(repos);
  }
  else {
    if (temperatureC < 43) // si temperature inférieure à 43°
    {
      digitalWrite(RELAIS, LOW);  // Relais1  OFF
    }
  }
}

Je vais testé ce code début de semaine prochaine, mais je pense faire évoluer le système, avec une pompe dédié au chauffage sur un tuyau noir pour l'arrosage automatique(j'avais fait un test par rapport au panneau chauffant souple intex, cela chauffait plus fort l'année précédente) mais le contrôle était manuel... d'où les fuites suite à la surchauffe.
De plus, je pourrai placé la sonde directement au contact de l'eau à l'aide d'un T dans le tuyau., 2 clapet anti-retour seront fixé au extrémités du tuyau pour que l'eau reste dans le circuit pendant la chauffe.
Je vous tient informé et vous envoi des photos prochainement.

Merci encor pour votre aide.

Bonjour,

On peut ou on peut pas ?

Et deuxième question (pour mon info perso) :
pourquoi lancer une requête a chaque boucle, soient quelques ms alors que la conversion prend entre 93 et 750ms selon la résolution adoptée ? Sans tenir compte des delay du code bien sûr.

Je pense que le T sera après la pompe, mais je n'ai pas compris comment on peut connecter un tuyau d'arrosage et pas un raccord pour une sonde :slight_smile:

Bonjour voici la différence,
actuellement panneau souple :
image

tuyau arrosage automatique :
image

voici mon installation avec panneau souple intex :

J'espère que vous visualisez mieux.

Re-bonjour tardivement... impossible de faire des test sans soleil et nuit fraiche.
J'ai donc modifier l'installation et abandonner le panneau intex( le debit de la pompe est trop fort et trop d'inertie avec le capteur sous le panneau souple.
J'ai utilisé 10 m de tuyaux noir d'arrosage, une pompe aquarium 60w 3200l/h, 2 clapets anti-retour ( un dans la pompe et l'autre en sortie pour éviter que l'eau ne retombe par gravité à l'arrêt) et mon capteur dans un T situé au centre du tuyau.

IMG20240604104624

J'ai réglé la température du déclenchement de la pompe à 22C° au lieu de 40c° pendant 1 minute puis pause 1 sec pour relecture température ( avec la sonde de température directement dans le circuit c'est mieux pour les tests)
Avec le soleil, le système est constamment en fonctionnement, la piscine était à 18-19° il y a 4 jour, aujourd'hui elle est à 28C° soit presque 10C° en quelques jours. Je précise que j'ai également une bache à bulle qui doit réchauffer également un peu.

La température de sortie du circuit est toujours supérieur de 1 à 2 C° voir plus à celle de la piscine.

#include <OneWire.h>
#include <DallasTemperature.h>
#define RELAIS 18


const int oneWireBus = 14;  // GPIO where the DS18B20 is connected to pin 14


OneWire oneWire(oneWireBus);  // Setup a oneWire instance to communicate with any OneWire devices


DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature sensor

void setup() {

  Serial.begin(115200);  // Start the Serial Monitor

  sensors.begin();          // Start the DS18B20 sensor
  pinMode(RELAIS, OUTPUT);  // Relais1 OFF
}

void loop() {
  sensors.requestTemperatures();
  float temperatureC = sensors.getTempCByIndex(0);

  Serial.print(temperatureC);  // temperature reading
  Serial.println("ºC");        //Print the results

  {


    //Print the results
    if (sensors.getTempCByIndex(0) > 22)// si temperature suprieur à 22°

    
    {

      digitalWrite(RELAIS, HIGH);  //Relais1 ON
      delay(60000);
      digitalWrite(RELAIS, LOW);
      delay(1000);  //relais temporiser pour 1 secondes
    } else {
      digitalWrite(RELAIS, LOW);  // Relais1  OFF
    }
  }
}

Mais, car il y a un mais, avec cette consigne de 22C° dans le code, le système fonctionne la nuit et donc me refroidit la piscine qui est à plus de 22°.

Je vous connaitre la fonction qui me permet de faire fonctionner le système de 11h à 18h par exemple.