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

Bonjour Etienne,
Après plusieurs semaines d'absence, je reprends en main mon projet :

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

Ce sont 3 planchers chauffants qui absorbent la chaleur de la terrasse autour de la piscine. Je mesure la T° sur chaque circuit en ouvrant la vanne pendant un certain temps, puis en fonction de cette T° par rapport à celle de la piscine, je laisse la vanne ouverte ou je la ferme

Edit 3 : et quels sont les moyens à ta disposition :
3 vannes quart de tours on/off sans aucune pompe supplémentaire car j'utilise la pression présente dans le circuit de la piscine

Dans un premier temps pour me perfectionner, je souhaitais remplacer la temporisation " delay " par celle qui calcule le temps actuel, le temps passé etc... comme j'ai essayé dans le code code je t'ai communiqué et qui ne fonctionne pas

Puis la prochaine étape sera d'essayer de coder en machine à états avec plusieurs vannes ( plusieurs switch ?)

Merci par avance de ton aide et ton éclairage pour ma compréhension

Tu veux dire que tu vas manœuvrer la vanne ¼ de tour plus de 1700 fois par jour? Tu penses qu'elle va durer combien de temps?

En 40s, il va circuler combien de litres d'eau? C'est probablement une goutte d'eau dans le volume de la piscine la température n'aura pas évoluée en si peu de temps.

Bonjour,

Question "hors sol" diraient certains puristes!

Pourquoi ne pas avoir protegés les servos moteurs par des fusibles thermiques (réarmables) s'ils ont des risques non négligeable de forcer?

C'est basique comme protection.

Partant de ce que tu as fait, j'ai un programme fonctionnel (avec encore quelques défauts) mais tu veux peut-être améliorer le tiens plutôt que prendre celui d'un autre.

Concernant ton delay() (il ne t'en reste qu'un, celui pour mesurer les températures), voilà ma version :

#include <OneWire.h>
#include <DallasTemperature.h>

typedef uint16_t short_time_t;
typedef uint32_t time_t;

#include "Servo.h" //inclure la bibliothèque Servomoteur

#include <OneWire.h>
#include <DallasTemperature.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

enum : byte {NORD, EST, OUEST, PISCINE};

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

/* Adresses des capteurs de température */
const byte SENSOR_PISCINE_ADDRESS[] = { 0x28, 0xBA, 0xC5, 0x99, 0x5F, 0x20, 0x01, 0xEF };
const byte SENSOR_EST_ADDRESS[] = { 0x28, 0xF6, 0xD2, 0x13, 0x37, 0x20, 0x01, 0x88 };
const byte SENSOR_OUEST_ADDRESS[] = { 0x28, 0x64, 0x09, 0x80, 0x5C, 0x20, 0x01, 0x74 };
const byte SENSOR_NORD_ADDRESS[] = { 0x28, 0x58, 0xE0, 0xDB, 0x5F, 0x20, 0x01, 0x65 };

/* Création de l'objet OneWire pour manipuler le bus 1-Wire */
OneWire ds(BROCHE_ONEWIRE);
DallasTemperature sensors(&ds);

float temperature[4];
time_t tempsActuel;

void afficheTemperatures(const float *temperature) {
  Serial.print(F("Temperatures: Piscine:"));
  Serial.print(temperature[PISCINE], 4);
  Serial.write('°'); // Caractère degré
  Serial.print(F("C, Est: "));
  Serial.print(temperature[EST], 4);
  Serial.write('°'); // Caractère degré
  Serial.print(F("C, Ouest: "));
  Serial.print(temperature[OUEST], 4);
  Serial.write('°'); // Caractère degré
  Serial.print(F("C, Nord: "));
  Serial.print(temperature[NORD], 4);
  Serial.write('°'); // Caractère degré
  Serial.println("C, -10, 50"); // <- Utile pour afficher les limites hautes et basses sur un graphe, mettre "C" sinon
}

short_time_t tempsMesureCapteur;
short_time_t mesureCapteurFaite;

void setup() {
  uint8_t sensorAddress[8];

  // Start serial communication for debugging purposes
  Serial.begin(115200);

  sensors.begin();
  sensors.setResolution(12);
  sensors.setWaitForConversion(false);
  sensors.setCheckForConversion(true);

  sensors.requestTemperatures();
  tempsMesureCapteur = 750 / (1 << (12 - sensors.getResolution()));
  mesureCapteurFaite = millis() + tempsMesureCapteur;

  Serial.println("Ready");
}

void loop(void) {
  tempsActuel = millis();  // Obtient le temps actuel en millisecondes

  // Afficher les températures lorsqu'elles sont mesurées et démarrer une nouvelle mesure
  if (tempsActuel > mesureCapteurFaite) {
    temperature[PISCINE] = sensors.getTempC(SENSOR_PISCINE_ADDRESS); // Température de la piscine
    temperature[EST] = sensors.getTempC(SENSOR_EST_ADDRESS); // Température du circuit Est
    temperature[OUEST] = sensors.getTempC(SENSOR_OUEST_ADDRESS); // Température du circuit Ouest
    temperature[NORD] = sensors.getTempC(SENSOR_NORD_ADDRESS); // Température du circuit Nord
    sensors.requestTemperatures();
    mesureCapteurFaite = millis() + tempsMesureCapteur; // Utiliser millis() car beaucoup de temps s'est
    afficheTemperatures(temperature);                   // écoulé depuis la MàJ de tempsActuel
  }
}

J'ai utilisé la bibliothèque Dallas plus pratique...

J'ai fait tourner ça sur un simulateur mais, malgré la résolution de 12 bits, les valeurs affichées sont 9 bits. As-tu aussi ce défaut avec les vrais capteurs (températures finissant avec x.0°C ou x.5°C alors que 12 bits est au 16e de degré) ?

J'ai découvert que, sur simulateur, pour valider la résolution 12 bits, il fallait que je le lui dise 2 fois, plus mesures...

Bonsoir,
Comme je l'ai noté précédemment, j'utilise les secondes pour faire mes essais, mais dans la réalité ce sont des minutes pour avoir le temps d'effectuer la circulation nécessaire à lire les T°
Tout ceci a fonctionné pendant tout l'été sans problème particulier hormis le fait qu'une vanne est restée grippée en position ouverte car aucune action n'avait été opérée pendant plusieurs jours (dû au fait d'une période de canicule qui chauffait trop la terrasse)
C'est ainsi que j'ai prévu une fermeture de la vanne pour redémarrer un cycle de lecture de la T°