Blocage Servo Moteur

Bonjour,
J'ai un projet qui utilise plusieurs servo moteurs pour ouvrir ou fermer des vannes. Une de ces vannes s'est bloquée ce qui a fait chauffer le servo moteur et a détruit la carte Arduino
Je recherche une solution pour limiter voire annuler la commande du servo moteur en cas de blocage
Quelles seraient vos suggestions pour améliorer mon projet
Je vous joins l'intégralité du code pour vous aider à comprendre mon besoin

/**
Code opérationnel avec les adresses des anciennes sondes de T°
   Exemple de code pour lire plusieurs capteurs DS18B20 sur un même bus 1-Wire via leur adresse unique sans délai.
   Version avec les sondes Laboratoires
   Modification de la durée totale d'ouverture avec une fermeture impérative avant de reprendre une prise de T°
*/
#include "Servo.h" //inclure la bibliothèque Servomoteur
/* Dépendance pour le bus 1-Wire */
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>   // inclure la bibliothèque I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // adresse i2c , nombre de colonnes, nombre de lignes de l'écran
int PinModeManuel = 4;   //Bleu
int PinServoEst = 7;     // Vert
int PinServoOuest = 8;  // Jaune
int PinServoNord = 12;  // Orange

/* Broche du bus 1-Wire */
const byte BROCHE_ONEWIRE = 3;

/* Adresses des capteurs de température */
const byte SENSOR_ADDRESS_1[] = { 0x28, 0xBA, 0xC5, 0x99, 0x5F, 0x20, 0x01, 0xEF }; //28 7D 21 16 B0 23 06 3D Piscine
const byte SENSOR_ADDRESS_2[] = { 0x28, 0xF6, 0xD2, 0x13, 0x37, 0x20, 0x01, 0x88 }; //28 5C 69 04 B0 23 06 54 Est
const byte SENSOR_ADDRESS_3[] = { 0x28, 0x64, 0x09, 0x80, 0x5C, 0x20, 0x01, 0x74 }; //28 F3 18 25 B0 23 06 73 Ouest
const byte SENSOR_ADDRESS_4[] = { 0x28, 0x58, 0xE0, 0xDB, 0x5F, 0x20, 0x01, 0x65 }; //28 3F 82 3E A2 23 06 32 nord


/* Création de l'objet OneWire pour manipuler le bus 1-Wire */
OneWire ds(BROCHE_ONEWIRE);
Servo servoEst; // création de l'objet "servoEst"
Servo servoOuest; // création de l'objet "servoOuest"
Servo servoNord; // création de l'objet "servoNord"


/**
   Fonction de démarrage de la prise de mesure de la température via un capteur DS18B20.
*/
void startTemperatureMeasure(const byte addr[]) {
  // addr[] : Adresse du module 1-Wire détecté

  /* Reset le bus 1-Wire et sélectionne le capteur */
  ds.reset();
  ds.select(addr);

  /* Lance une prise de mesure de température et attend la fin de la mesure */
  ds.write(0x44, 1);
}

/**
   Fonction de récupération de la prise de mesure de la température via un capteur DS18B20.
*/
float readTemperatureMeasure(const byte addr[]) {
  byte data[9];
  // data[] : Données lues depuis le scratchpad
  // addr[] : Adresse du module 1-Wire détecté

  /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
  ds.reset();
  ds.select(addr);
  ds.write(0xBE);

  /* Lecture du scratchpad */
  for (byte i = 0; i < 9; i++) {
    data[i] = ds.read();
  }

  /* Calcul de la température en degré Celsius */
  return ((data[1] << 8) | data[0]) * 0.0625;
}


/** Fonction setup() **/
void setup() {

  /* Initialisation du port série */
  Serial.begin(115200);
  /* Ecran LCD  */

  lcd.init();   // initialisation du LCD
  lcd.backlight();   // active le rétroéclairage

  pinMode(PinModeManuel, INPUT);
  pinMode(PinServoEst, INPUT);
  pinMode(PinServoOuest, INPUT);
  pinMode(PinServoNord, INPUT);

  servoEst.attach(6); // attache le servo au pin spécifié (bleu)
  servoOuest.attach(9); // attache le servo au pin spécifié (jaune)
  servoNord.attach(11); // attache le servo au pin spécifié (noir)
}


/** Fonction loop() **/
void loop() {
  float temperature[4];

  /* Lit les températures des quatre capteurs */
  startTemperatureMeasure(SENSOR_ADDRESS_1);
  startTemperatureMeasure(SENSOR_ADDRESS_2);
  startTemperatureMeasure(SENSOR_ADDRESS_3);
  startTemperatureMeasure(SENSOR_ADDRESS_4);
  delay(800);
  temperature[0] = readTemperatureMeasure(SENSOR_ADDRESS_1);
  temperature[1] = readTemperatureMeasure(SENSOR_ADDRESS_2);
  temperature[2] = readTemperatureMeasure(SENSOR_ADDRESS_3);
  temperature[3] = readTemperatureMeasure(SENSOR_ADDRESS_4);

  /* Affiche les températures */
  Serial.print(F("Temperatures : "));
  Serial.print(temperature[0], 2);
  Serial.write(176); // Caractère degré
  Serial.print(F("C, "));
  Serial.print(temperature[1], 2);
  Serial.write(176); // Caractère degré
  Serial.print(F("C, "));
  Serial.print(temperature[2], 2);
  Serial.write(176); // Caractère degré
  Serial.println('C');

  /* Affiche les températures sur l'écran lcd */

  lcd.setCursor(0, 0);  // mettre le curseur à la première colonne, première ligne
  lcd.print("P="); // Piscine
  lcd.print(temperature[0], 0);
  lcd.print((char)223);   // symbole °
  
  lcd.setCursor(0, 1);  // mettre le curseur à la première colonne, deuxième ligne
  lcd.print("E="); // plage EST
  lcd.print(temperature[1], 0);
  lcd.print((char)223);   // symbole ° 

  lcd.setCursor(8, 1);  // mettre le curseur à la huitième colonne, deuxième ligne
  lcd.print("O=");  // plage Ouest
  lcd.print(temperature[2], 0);
  lcd.print((char)223);   // symbole °

  lcd.setCursor(8, 0);  // mettre le curseur à la huitième colonne, première ligne
  lcd.print("N=");  // plage Nord
  lcd.print(temperature[3], 0);
  lcd.print((char)223);   // symbole °

   // servoEst.write(0);
  //servoOuest.write(0);
  //servoNord.write(0);

  
 
 if(digitalRead(PinModeManuel)== HIGH){
    lcd.setCursor(6, 0);  // mettre le curseur à la sixième colonne, première ligne
    lcd.print("M");  // mode Manuel
  if(digitalRead(PinServoEst)== HIGH){
    servoEst.write(0); // Ouverture Vanne Est
    lcd.setCursor(6, 1);  // mettre le curseur à la sixième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
  }
  else{
    servoEst.write(80); // Fermeture Vanne Est
    lcd.setCursor(6, 1);  // 
    lcd.print("F");  // Vanne Fermée
  }
    if(digitalRead(PinServoOuest)== HIGH){
      servoOuest.write(0); // Ouverture Vanne Ouest
      lcd.setCursor(14, 1);  // mettre le curseur à la quatorzième colonne, première ligne
      lcd.print("O");  // Vanne Ouverte
    }
    else{
      servoOuest.write(80); // Fermeture Vanne Ouest
      lcd.setCursor(14, 1);  // 
      lcd.print("F");  // Vanne Fermée
    }
      if(digitalRead(PinServoNord)== HIGH){
        servoNord.write(0); // Ouverture Vanne Nord
        lcd.setCursor(14, 0);  // mettre le curseur à la quatorzième colonne, première ligne
        lcd.print("O");  // Vanne Ouverte
      }
      else{
        servoNord.write(80); // Fermeture Vanne Nord
        lcd.setCursor(14, 0);  // 
        lcd.print("F");  // Vanne Fermée
      }


 }

else
{     lcd.setCursor(6, 0);  // 
      lcd.print("A");  // Mode automatique
  {
  {
  servoEst.write(0);  // Vanne Est Ouverte
    lcd.setCursor(6, 1);  // mettre le curseur à la sixième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
  servoOuest.write(0);  // Vanne Ouest Ouverte
    lcd.setCursor(14, 1);  // mettre le curseur à la quatorzième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
  servoNord.write(0);  // Vanne Nord Ouverte
      lcd.setCursor(14, 0);  // mettre le curseur à la quatorzième colonne, première ligne
      lcd.print("O");  // Vanne Ouverte
  }
delay(15000);  // délai d'ouverture des vannes pour avoir la T° de l'eau des plages 15000 pour les essais sinon 60000
 { if((temperature[0])<(temperature[1])){
    servoEst.write(0); // Ouverture Vanne Est
    lcd.setCursor(6, 1);  // mettre le curseur à la sixième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
    
  }
  else{servoEst.write(80); // Fermeture Vanne Est
      lcd.setCursor(6, 1);  // 
      lcd.print("F");  // Vanne Fermée
    
  }
    if((temperature[0])<(temperature[2])){
    servoOuest.write(0); // Ouverture Vanne Ouest
    lcd.setCursor(14, 1);  // mettre le curseur à la quatorzième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
    
  }
  else {servoOuest.write(80); // Fermeture Vanne Ouest
        lcd.setCursor(14, 1);  // 
        lcd.print("F");  // Vanne Fermée
  
  }
     if((temperature[0])<(temperature[3])){
      servoNord.write(0); // Ouverture Vanne Nord
      lcd.setCursor(14, 0);  // mettre le curseur à la quatorzième colonne, première ligne
      lcd.print("O");  // Vanne Ouverte
    
  }
  else {servoNord.write(80); // Fermeture Vanne Nord
        lcd.setCursor(14, 0);  // 
        lcd.print("F");  // Vanne Fermée
  } 
}
}
delay(30000);  // Délai d'attente avant la fermeture de toutes les vannes 30000 pour les essais sinon 600000
servoEst.write(80); // Fermeture Vanne Est
servoOuest.write(80); // Fermeture Vanne Ouest
servoNord.write(80); // Fermeture Vanne Nord
delay(10000);  // Délai d'attente avant la prochaine prise de T°
}
}


Post mis dans la mauvaise section, on parle anglais dans les forums généraux, je viens de déplacer le post dans la section francophone.

Merci de prendre en compte les recommandations listées dans "Les bonnes pratiques du Forum Francophone".

  1. Est-ce que le servo a un couple en adéquation avec le besoin? Le servo peut fonctionner sur une vanne neuve avec le temps celle-ci peut se gripper et le servo n'est alors plus capable de la manœuvrer.

  2. On suppose que ce sont des servos classiques sans retour de position. Donc il faudrait soit :

    1. avoir un moyen de savoir si le servo tourne, donc un retour de position ou à minima deux fins de course et si la vanne n'a pas quitté la position de départ ou n'est pas arrivée à la fin dans un temps donné, couper le servo et activer une alarme.
    2. mesurer le courant consommé par le servo pour voir si celui-ci doit fournir un effort inhabituel.

Reste quand même une question sur le montage actuel. Je vois mal comment un servo bloqué peut avoir cramé ta carte Arduino. Sauf bien sûr si c'était la carte Arduino qui alimentait les servos ce qui est déconseillé car le régulateur sur celle-ci n'est pas prévu pour fournir un courant élevé.

La commande servo.detach(); supprime l'envoi de pulse vers le servo et, en général, celui-ci s'arrête et n'oppose plus de résistance autre que celle "à vide" lorsqu'il n'est pas branché.

Oui ce sont bien des servos sans retour de position,et je ne savais pas que d'autres modèles existaient

L'alimentation des servo moteurs est indépendante de la carte mais cette dernière ne pilotait plus un nouveau servo moteur branché sur la même fiche que celui qui était en défaut. En remplaçant la carte arduino, tout est rentré dans l'ordre. C'est pour cela que je cherche une solution pour améliorer la conception de mon projet
Je pourrais ajouter une temporisation pour le faire fonctionner un certain temps, mais je n'ai pas assez de connaissance pour programmer autrement qu'avec un " delay ".
J'ai bien essayé de copier des temporisations existantes mais il y a toujours plus ou moins un blocage que je n'arrive pas à identifier
Est-ce qu'il y a un moyen de le modéliser sur le moniteur série par exemple ou ailleurs sans faire systématiquement une maquette et attendre le résultat ?

C'est peut-être une solution pour le rendre inactif après une temporisation (éternel sujet..la maitrise de la temporisation.)

Pour simuler un Arduino et des servos, il y a Wokwi si c'est ce que tu cherches.

Voici un exemple de ce qu'on peut faire (pour un autre fil de discussion)

Il y a des servos numériques dont on peut relire la position. Ce n'est bien sûr pas la même gamme de prix.

Bonsoir

Merci pour ce renseignement, mais c'est pour les essais sur le paramétrage de temporisation autre que " delay" que je souhaiterai visualiser ce qui se passe car je n'ai toujours pas acquis le principe de programmation (avec par exemple " tempsdebut, tempsfin, tempsactuel, etc...)
Et je n'arrive pas à comprendre où positionner ces paramètres ( au début, dans le setup, dans le loop, ou un peu partout) ?

Pour comprendre comment remplacer delay() par une solution non blocante, tu peux lire BlinkWithoutDelay.

Mais ça n'apporte qu'une temporisation. Si ton servo est bloqué, la solution serait peut-être de lire le courant qu'il absorbe pour vérifier qu'il ne dépasse pas certaines limites.

Tu peux poster un code qui ne fonctionne pas et on te dira où ça coince et comment faire...

Merci de ta réponse rapide et efficace
Le composant pour lire la conso du servo est intéressant, je vais essayer de le commander et de l'intégrer
Pour ce qui est des essais de temporisation, voici le code que j'ai essayé de faire à partir de celui qui est au début de ce post (avec delay)
Pour bien comprendre ce qui se passe, je n'ai utilisé que le pilotage de la vanne Ouest , mais au final j'ai trois vannes à piloter avec temporisation
Le principe de ce code est d'ouvrir les vannes pendant 10 Sec pour lire la T°, puis en fonction de cette dernière de fermer ou de laisser ouverte la vanne concernée en la fermant après 40 Sec, etc....
C'est peut-être un complexe...?

/**

   Exemple de code pour lire plusieurs capteurs DS18B20 sur un même bus 1-Wire via leur adresse unique sans délai.
   Temporisation avec unsigned
*/
#include "Servo.h" //inclure la bibliothèque Servomoteur
/* Dépendance pour le bus 1-Wire */
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>   // inclure la bibliothèque I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // adresse i2c , nombre de colonnes, nombre de lignes de l'écran
const byte PinModeManuel = 4;   //Bleu
const byte PinServoEst = 7;     // Vert
const byte PinServoOuest = 8;  // Jaune
const byte PinServoNord = 12;  // Orange
unsigned long tempsOuvEst = 0;
unsigned long tempsFermEst = 0;
unsigned long OuvTempEst = 0;

/* Broche du bus 1-Wire */
const byte BROCHE_ONEWIRE = 3;

/* Adresses des capteurs de température */
const byte SENSOR_ADDRESS_1[] = { 0x28, 0xBA, 0xC5, 0x99, 0x5F, 0x20, 0x01, 0xEF };
const byte SENSOR_ADDRESS_2[] = { 0x28, 0xF6, 0xD2, 0x13, 0x37, 0x20, 0x01, 0x88 };
const byte SENSOR_ADDRESS_3[] = { 0x28, 0x64, 0x09, 0x80, 0x5C, 0x20, 0x01, 0x74 };
const byte SENSOR_ADDRESS_4[] = { 0x28, 0x58, 0xE0, 0xDB, 0x5F, 0x20, 0x01, 0x65 }; ///à verifier28 58 E0 DB 5F 20 01 65


/* Création de l'objet OneWire pour manipuler le bus 1-Wire */
OneWire ds(BROCHE_ONEWIRE);
Servo servoEst; // création de l'objet "servoEst"
Servo servoOuest; // création de l'objet "servoOuest"
Servo servoNord; // création de l'objet "servoNord"


/**
   Fonction de démarrage de la prise de mesure de la température via un capteur DS18B20.
*/
void startTemperatureMeasure(const byte addr[]) {
  // addr[] : Adresse du module 1-Wire détecté

  /* Reset le bus 1-Wire et sélectionne le capteur */
  ds.reset();
  ds.select(addr);

  /* Lance une prise de mesure de température et attend la fin de la mesure */
  ds.write(0x44, 1);
}

/**
   Fonction de récupération de la prise de mesure de la température via un capteur DS18B20.
*/
float readTemperatureMeasure(const byte addr[]) {
  byte data[9];
  // data[] : Données lues depuis le scratchpad
  // addr[] : Adresse du module 1-Wire détecté

  /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
  ds.reset();
  ds.select(addr);
  ds.write(0xBE);

  /* Lecture du scratchpad */
  for (byte i = 0; i < 9; i++) {
    data[i] = ds.read();
  }

  /* Calcul de la température en degré Celsius */
  return ((data[1] << 8) | data[0]) * 0.0625;
}


/** Fonction setup() **/
void setup() {

  /* Initialisation du port série */
  Serial.begin(115200);
  /* Ecran LCD  */

  lcd.init();   // initialisation du LCD
  lcd.backlight();   // active le rétroéclairage

  pinMode(PinModeManuel, INPUT);
  pinMode(PinServoEst, INPUT);
  pinMode(PinServoOuest, INPUT);
  pinMode(PinServoNord, INPUT);

  servoEst.attach(6); // attache le servo au pin spécifié (bleu)
  servoOuest.attach(9); // attache le servo au pin spécifié (jaune)
  servoNord.attach(11); // attache le servo au pin spécifié (noir)
}


/** Fonction loop() **/
void loop() {
  float temperature[4];

  /* Lit les températures des quatre capteurs */
  startTemperatureMeasure(SENSOR_ADDRESS_1);
  startTemperatureMeasure(SENSOR_ADDRESS_2);
  startTemperatureMeasure(SENSOR_ADDRESS_3);
  startTemperatureMeasure(SENSOR_ADDRESS_4);
  delay(800);
  temperature[0] = readTemperatureMeasure(SENSOR_ADDRESS_1); // Température de la piscine
  temperature[1] = readTemperatureMeasure(SENSOR_ADDRESS_2); // Température du circuit Est
  temperature[2] = readTemperatureMeasure(SENSOR_ADDRESS_3); // Température du circuit Ouest
  temperature[3] = readTemperatureMeasure(SENSOR_ADDRESS_4); // Température du circuit Nord

  /* Affiche les températures */
  Serial.print(F("Temperatures : "));
  Serial.print(temperature[0], 2);
  Serial.write(176); // Caractère degré
  Serial.print(F("C, "));
  Serial.print(temperature[1], 2);
  Serial.write(176); // Caractère degré
  Serial.print(F("C, "));
  Serial.print(temperature[2], 2);
  Serial.write(176); // Caractère degré
  Serial.println('C');

  /* Affiche les températures sur l'écran lcd */

  lcd.setCursor(0, 0);  // mettre le curseur à la première colonne, première ligne
  lcd.print("P="); // Piscine
  lcd.print(temperature[0], 0);
  lcd.print((char)223);   // symbole °
  
  lcd.setCursor(0, 1);  // mettre le curseur à la première colonne, deuxième ligne
  lcd.print("E="); // plage EST
  lcd.print(temperature[1], 0);
  lcd.print((char)223);   // symbole ° 

  lcd.setCursor(8, 1);  // mettre le curseur à la huitième colonne, deuxième ligne
  lcd.print("O=");  // plage Ouest
  lcd.print(temperature[2], 0);
  lcd.print((char)223);   // symbole °

  lcd.setCursor(8, 0);  // mettre le curseur à la huitième colonne, première ligne
  lcd.print("N=");  // plage Nord
  lcd.print(temperature[3], 0);
  lcd.print((char)223);   // symbole °
  
 
 if(digitalRead(PinModeManuel)== HIGH){
    lcd.setCursor(6, 0);  // mettre le curseur à la sixième colonne, première ligne
    lcd.print("M");  // mode Manuel
  if(digitalRead(PinServoEst)== HIGH){
    servoEst.write(0); // Ouverture Vanne Est
    lcd.setCursor(6, 1);  // mettre le curseur à la sixième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
  }
  else{
    servoEst.write(90); // Fermeture Vanne Est
    lcd.setCursor(6, 1);  // 
    lcd.print("F");  // Vanne Fermée
  }
    if(digitalRead(PinServoOuest)== HIGH){
      servoOuest.write(0); // Ouverture Vanne Ouest
      lcd.setCursor(14, 1);  // mettre le curseur à la quatorzième colonne, première ligne
      lcd.print("O");  // Vanne Ouverte
    }
    else{
      servoOuest.write(90); // Fermeture Vanne Ouest
      lcd.setCursor(14, 1);  // 
      lcd.print("F");  // Vanne Fermée
    }
      if(digitalRead(PinServoNord)== HIGH){
        servoNord.write(0); // Ouverture Vanne Nord
        lcd.setCursor(14, 0);  // mettre le curseur à la quatorzième colonne, première ligne
        lcd.print("O");  // Vanne Ouverte
      }
      else{
        servoNord.write(90); // Fermeture Vanne Nord
        lcd.setCursor(14, 0);  // 
        lcd.print("F");  // Vanne Fermée
      }


 }

else
{     lcd.setCursor(6, 0);  // 
      lcd.print("A");  // Mode automatique
  unsigned long tempsActuel = millis();  // Obtient le temps actuel en millisecondes

if (tempsActuel - OuvTempEst >= 40000){
    servoEst.write(0);  // Vanne Est Ouverte
    lcd.setCursor(6, 1);  // mettre le curseur à la sixième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
  servoOuest.write(0);  // Vanne Ouest Ouverte
    lcd.setCursor(14, 1);  // mettre le curseur à la quatorzième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
  servoNord.write(0);  // Vanne Nord Ouverte
    lcd.setCursor(14, 0);  // mettre le curseur à la quatorzième colonne, première ligne
    lcd.print("O");  // Vanne Ouverte
    //tempsFermEst=tempsActuel; // 2;3;4;5;6;8;14
    tempsOuvEst=tempsActuel; // 1;6;7;8;14
 }
 if (tempsActuel - tempsOuvEst >= 10000){
    if((temperature[0])>(temperature[2])){
      
        servoOuest.write(90); // Fermeture Vanne Ouest
        lcd.setCursor(14, 1);  // 
        lcd.print("F");  // Vanne Fermée 
        tempsFermEst=tempsActuel; // 4;6;7;10;11;14;25
}       
  
      else {
        servoOuest.write(0);  // Vanne Ouest Ouverte
        lcd.setCursor(14, 1);  // mettre le curseur à la quatorzième colonne, première ligne
        lcd.print("O");  // Vanne Ouverte 
       // tempsOuvEst=tempsActuel; // 3;4;5;6;7;10;14;25
        tempsFermEst=tempsActuel; 
 /*             if (tempsActuel - tempsOuvEst >= 50000){
        servoOuest.write(90); // Fermeture Vanne Ouest
        lcd.setCursor(14, 1);  // 
        lcd.print("F");  // Vanne Fermée 
        tempsFermEst=tempsActuel; // 4;6;7;10;11;14;25
} 
*/   
      }
    }        
} 
}  

Donc, en position "Automatique", tu lis tes 4 températures, tu les affiches et tu ouvres toutes les vannes.
Chaque vanne restera ouverte minimum 10 secondes puis se ferme soit parce qu'une température (que tu continues à lire) a été atteinte, soit parce que 40 secondes se sont écoulées.
Au bout de 40 secondes, toutes les vannes sont fermées.
Mais qu'est ce qui re-déclenche le cycle ?

c'est la fermeture des vannes après les 40 secondes qui relance la boucle de réouverture pendant 10 secondes pour lire les T°
Ps : J'ai mis des secondes pour faire des essais mais en réalité ce sera des minutes

Donc si la température est atteinte ou même dépassée, tu ouvres 10 minutes toutes les 40 minutes.
Si elle ne l'est pas, tu refermes au bout de 40 minutes pour rouvrir aussitôt.
Ai-je bien compris ? Parce que c'est étrange comme régulation...
Mais si c'est ça, c'est faisable en corrigeant ton programme. Tu peux aussi utiliser une machine à états (par régulation) en lisant ce tutoriel.

EDIT 2 : J'ai l'impression que tu as 3 chauffe-eau solaires et que tu veux chauffer ta piscine en pompant sur le plus chaud. Ai-je vu juste ?
En fait, ma question devrait plutôt être : que veux-tu exactement, quel est le projet global ?

Edit 3 : et quels sont les moyens à ta disposition : vannes 3 voies, vannes On/Off, vannes plus ou moins On, plus ou moins Off (car avec un servo, on peut arrêter à mi-course ou ailleurs), pompes de circulation (qu'il faut piloter pour ne pas les bloquer)...
Un schéma (sur papier par exemple) est une bonne solution pour expliquer.

bonsoir
non ce n'est pas cela
la vanne est ouverte pendant 10 secondes pour faire circuler de l'eau et lire la T°
En fonction de cette T° par rapport à la T° de la piscine je ferme la vanne ou la laisse ouverte
Après ce cycle de 40 secondes je ferme la vanne (pour éviter le grippage) et aussitôt réouverture et ainsi cela repart sur un cycle de 10 secondes...
Cela devrait t'aider à comprendre mon code