Suite du sujet [Régulation chauffage Hyundai Matrix](https://forum.arduino.cc/t/regulation-chauffage-hyundai-matrix/1098498)

Bonjour à tous,

J'avais créer un système de régulation pour piloter le volet de chauffage de ma voiture. Le régulateur interne étant HS.

Le programme me permettait de configurer l'ouverture du volet de 0 à 100%, ajustement manuel selon la température ressentie.

Et puis, je me suis dit qu'une régulation PID ce serait quand même mieux. Donc je l'ai implémentée. J'ai aussi implémenté un système de menu avec les 2 boutons afin de pouvoir régler le PID à la volée. A cette fin, j'utilise la librairie Onebutton.

Tout cela fonctionne très bien. Du moins quand je fais les essais sur mon bureau. Je test le programme sur un autre arduino en désactivant les fonctions oled pour les tests car l'arduino qui me sert à tester le programme n'en possède pas.

Après injection du programme dans l'arduino de la voiture, les boutons réagissent avec 2 à 3 secondes de latence. Là où un simple clic d'1/2s me permet de changer des valeurs, il faut que je reste appuyé 3s et pour accéder au menu de réglage, appui réglé à 2,5s, je dois rester appuyé 5 à 6s.

Il y a quelque chose dans mon programme qui ralenti la boucle je pense, ou qui pompe de la ressource, ou alors j'ai mal organisé mon programme et il y a des sous-programmes qui se télescopent...

Je ne suis pas assez aguerri en arduino pour déterminer quel est le problème.
Voici mon programme. Est-ce que quelqu'un serait assez aimable pour regarder ce que je pourrais améliorer dedans ?

Toutes les explications quant à l'utilisation de ce programme se trouvent là : Régulation chauffage Hyundai Matrix
Et le programme en lui même est assez bien documenté pour s'y retrouver facilement je pense.

Merci beaucoup.


/**************************************************************************************************

VERSION 6 du 20 décembre 2024 - Version installée le 20/12/2024

Régulation du chauffage de la HyundaiMatrix
- Récupère la température interieure à partir d'un capteur de température OneWire DS18B20
- Récupère la position du papillon de chauffage à partir du potentiomètre interne du moteur
- Pilote le moteur de papillon par impulsions
- Consigne réglable par boutons +/-
- Affiche les informations imporantes sur un écran oled I2C

Version 6 - Ajout d'un menu permettant le réglage des parametres de consigne, Kp, Ki, Kd + sauvegarde en EEPROM
            Ajout de la librairie OneButton
            Ajout de 4 fonctions de gestion des boutons
            

Version 5 - Sauvegarde de la température en mémoire EEPROM

Version 4.1 - Ajout de :
                    Arrondi des mesures à 0,5 près - Fonction arrondir() - Ligne 144
                    Réglage du PID à 4, 0.2 et 1 - Ligne 50
                    Limitation du PID de 5 à 98 - Ligne 71
**************************************************************************************************/

// Inclusion des librairies nécessaires au programme
#include <EEPROM.h>              // Librairie pour utiliser la mémoire EEPROM de l'arduino (Mémoire de 1ko non-volatile)
#include <PID_v2.h>              // Librairie du régulateur PID
#include <OneWire.h>             // Librairie OneWire pour le capteur de température
#include <OneButton.h>           // Librairie des gestion des 2 boutons
#include <DallasTemperature.h>   // Librairie pour le capteur DS18B20
#include "SSD1306AsciiAvrI2c.h"  // Librairie de l'écran Oled en I2C

// Initialisation de l'écran
#define I2C_ADDRESS 0x3C  // Définition de l'adresse de l'écran
SSD1306AsciiAvrI2c oled;  // Initialisation de l'écran

// Initialisation des pins des boutons
#define PIN_BOUTON_PLUS 7
#define PIN_BOUTON_MOINS 12
// Crée un nouveau bouton sur la pin PIN_BOUTON_PLUS
OneButton boutonPlus(PIN_BOUTON_PLUS, true);
// Crée un nouveau bouton sur la pin PIN_BOUTON_MOINS.
OneButton boutonMoins(PIN_BOUTON_MOINS, true);

// Initialisation des pins arduino
const int pinCapteurTemp = 2;      // Pin du capteur de température
const int pinOuvertureMoteur = 3;  // Pin 1 de commande d'ouverture du moteur
const int pinFermetureMoteur = 4;  // Pin 2 de commande de fermeture du moteur
const int pin_potar = A0;          // Pin du potentiomètre de volet

// Entrées/Sorties

// Initialisation des variables et constantes
double positionAnaPotar = 0;       // Valeur analogique du potentiomètre
double positionPourcentPotar = 0;  // Position calculée en % du potentiomètre
double positionVoletPID;           // Position du volet calculée par le PID
double echelle_mini = 305;         // Valeur mini de l'échelle de mesure du potentiomètre
double echelle_maxi = 720;         // Valeur maxi de l'échelle de mesure du potentiomètre
int impulsion = 100;               // Durée des impulsions moteur en ms
int menu = 0;                      // Numéro du menu en cours : 0=consigne / 1=Kp / 2=Ki / 3=KD
int reglage = 0;                   // Validation du mode réglage 0=non / 1=oui  (Byte ??)

// Variables PID
double consigneTemperature;       // Consigne de température (°C) que l'on va aller chercher en mémoire EEPROM
double temperatureActuelle = 25;  // Température mesurée (°C)
double sortiePID = 0;             // Position volet calculée par le PID (0-100 %)

//EEPROM.put(0, 25);  // A décommenter au 1er démarrage afin d'initialiser l'EEPROM pour la consigne
//EEPROM.put(1, 5);   // A décommenter au 1er démarrage afin d'initialiser l'EEPROM pour le Kp
// EEPROM.put(2, 1);   // A décommenter au 1er démarrage afin d'initialiser l'EEPROM pour le Kp
// EEPROM.put(3, 2);   // A décommenter au 1er démarrage afin d'initialiser l'EEPROM pour le Kp
double Kp = EEPROM.read(1);  //récupère la dernière valeur de Kp en EEPROM
double Ki = EEPROM.read(2);  //récupère la dernière valeur de Ki en EEPROM
double Kd = EEPROM.read(3);  //récupère la dernière valeur de Kd en EEPROM

// Initialisation du PID(kP, kI, kD, mode: DIRECT/REVERSE)
PID pid(&temperatureActuelle, &sortiePID, &consigneTemperature, Kp, Ki, Kd, DIRECT);

// Initialisation du capteur de température
OneWire oneWire(pinCapteurTemp);
DallasTemperature capteurTemp(&oneWire);

void setup() {

  // Initialisation des périphériques
  Serial.begin(115200);                      // Communication série pour débogage
  capteurTemp.begin();                       // Initialisation du capteur de température
  oled.begin(&Adafruit128x64, I2C_ADDRESS);  // Initialise l'écran Oled

  consigneTemperature = EEPROM.read(0);  //Récupère la dernière valeur de consigneTemperature en EEPROM

  // Configuration du PID
  pid.SetOutputLimits(5, 98);  // Limite de la sortie : 0 à 100 %
  pid.SetMode(AUTOMATIC);      // Activer le PID en mode automatique

  // Initialise les broches de commandes du moteur
  pinMode(pinOuvertureMoteur, OUTPUT);    // Pin d'ouverture en sortie
  digitalWrite(pinOuvertureMoteur, LOW);  // On met la sortie à 0
  pinMode(pinFermetureMoteur, OUTPUT);    // Pin de fermeture en sortie
  digitalWrite(pinFermetureMoteur, LOW);  // On met la sortie à 0

  // lie les fonctions du bouton +
  boutonPlus.attachClick(clickPlus);
  //boutonPlus.attachDoubleClick(doubleclickPlus);
  boutonPlus.attachLongPressStart(longPressStartPlus);
  //boutonPlus.attachLongPressStop(longPressStopPlus);
  //boutonPlus.attachDuringLongPress(longPressPlus);
  boutonPlus.setPressMs(2500);
  // lie les fonctions du bouton -
  boutonMoins.attachClick(clickMoins);
  //boutonMoins.attachDoubleClick(doubleclickMoins);
  boutonMoins.attachLongPressStart(longPressStartMoins);
  //boutonMoins.attachLongPressStop(longPressStopMoins);
  //boutonMoins.attachDuringLongPress(longPressMoins);
  boutonMoins.setPressMs(2500);
}

void loop() {

  // Garde l'oeil sur les boutons:
  boutonPlus.tick();
  boutonMoins.tick();

  positionPapillon();    // Appelle la fonction de lecture de la position du papillon (retourne la variable "positionPourcentPotar")
  lectureTemperature();  // Appelle la fonction de lecture de la température (Retourne la variable "temperatureActuelle")
  pid.Compute();         // Calcule la commande PID
  sortiePID = arrondir(sortiePID);
  actionMoteur();      // Fonction d'activation du moteur en fonction de la position du volet
  affichageConsole();  // Affichage des valeur sur la console pour débuggage
  affichageOled();     // Affichage des valeurs sur l'écran interne
}

// **************  FONCTIONS  *************


// Fonction pour arrondit un décimal au multiple de 0,5 le plus proche
float arrondir(float number) {
  return round(number / 0.5) * 0.5;  // Diviser par 0.5, arrondir au plus proche entier, puis multiplier par 0.5
}

/**************************************************************************************/

// Fonction appellée lorsque l'on appuie sur le bouton + une fois
void clickPlus() {
  //Serial.print("Button Plus click.");

  // Cette partie permet de naviguer dans les menus
  if (reglage == 0) {         // Vérification que l'on ne soit pas en mode réglage
    menu++;                   // On incrémente le menu de 1
    if (menu == 4) menu = 0;  // On bloque les menus à 3
  }
  affichageConsole();  // Affichage des donnée sur la console série
  affichageOled();     // Affichage des valeurs sur l'écran interne

  // Cette partie permet d'effectuer les réglages
  if (reglage == 1) {                                              // Vérification que l'on soit en mode réglage
    if (menu == 0) {                                               // Si on est dans le menu 0 (réglage de la consigne de température)
      consigneTemperature += 0.5;                                  // On peut incrémenter
      if (consigneTemperature > 30.0) consigneTemperature = 30.0;  // On limite à la valeur maxi
      EEPROM.write(0, consigneTemperature);                        // On écrit la valeur en EEPROM
      affichageConsole();                                          // Affichage des donnée sur la console série
      affichageOled();                                             // Affichage des valeurs sur l'écran interne
    }                                                              //Fin du if (menu == 0)
    if (menu == 1) {                                               // On est dans le menu 1 (réglage du Kp)
      Kp += 0.5;                                                   // On incrémente le Kp
      if (Kp < 0) Kp = 0;                                          //On limite le mini à 0
      EEPROM.write(1, Kp);                                         // On écrit la valeur en EEPROM
      affichageConsole();                                          // Affichage des donnée sur la console série
      affichageOled();                                             // Affichage des valeurs sur l'écran interne
    }                                                              // Fin du if (menu==1)
    if (menu == 2) {                                               // On est dans le menu 2 (réglage du Ki)
      Ki += 0.1;                                                   // On incrémente le Ki
      if (Ki < 0) Ki = 0;                                          //On limite le mini à 0
      EEPROM.write(2, Ki);                                         // On écrit la valeur en EEPROM
      affichageConsole();                                          // Affichage des donnée sur la console série
      affichageOled();                                             // Affichage des valeurs sur l'écran interne
    }                                                              // Fin du if (menu==2)
    if (menu == 3) {                                               // On est dans le menu 3 (réglage du Kd)
      Kd += 0.5;                                                   // On incrémente le Kd
      if (Kd < 0) Kd = 0;                                          //On limite le mini à 0
      EEPROM.write(3, Kd);                                         // On écrit la valeur en EEPROM
      affichageConsole();                                          // Affichage des donnée sur la console série
      affichageOled();                                             // Affichage des valeurs sur l'écran interne
    }                                                              // Fin du if (menu==3)
  }                                                                // Fin du if (reglage == 1)
}  // Fin de la fonction clickPlus

void longPressStartPlus() {  // Fonction appellée lorsque l'on appuie longtemps sur le bouton +
  //Serial.println("Button Plus longPress start");
  reglage = 1;
  affichageConsole();  // Affichage des donnée sur la console série
  affichageOled();     // Affichage des valeurs sur l'écran interne
}  // longPressStartPlus

void clickMoins() {  // Fonction appellée lorsque l'on appuie sur le bouton - une fois
  // Cette partie permet de naviguer dans les menus
  if (reglage == 0) {          // Vérification que l'on ne soit pas en mode réglage
    menu--;                    // On incrémente le menu de 1
    if (menu == -1) menu = 3;  // On bloque les menus à 3
  }
  affichageConsole();  // Affichage des donnée sur la console série
  affichageOled();     // Affichage des valeurs sur l'écran interne

  // Cette partie permet d'effectuer les réglages
  if (reglage == 1) {                                              // Vérification que l'on soit en mode réglage
    if (menu == 0) {                                               // Si on est dans le menu 0 (réglage de la consigne de température)
      consigneTemperature -= 0.5;                                  // On peut décrémenter la consigne de température
      if (consigneTemperature < 15.0) consigneTemperature = 15.0;  // On limite à la valeur mini
      EEPROM.write(0, consigneTemperature);                        // On écrit la valeur en EEPROM
      affichageConsole();                                          // Affichage des donnée sur la console série
      affichageOled();                                             // Affichage des valeurs sur l'écran interne
    }                                                              //Fin du if (menu == 0)
    if (menu == 1) {                                               // On est dans le menu 1 (réglage du Kp)
      Kp -= 0.5;                                                   // On décrémente le Kp
      EEPROM.write(1, Kp);                                         // On écrit la valeur en EEPROM
      affichageConsole();                                          // Affichage des donnée sur la console série
      affichageOled();                                             // Affichage des valeurs sur l'écran interne
    }                                                              // Fin du if (menu==1)
    if (menu == 2) {                                               // On est dans le menu 2 (réglage du Ki)
      Ki -= 0.1;                                                   // On décrémente le Ki
      EEPROM.write(2, Ki);                                         // On écrit la valeur en EEPROM
      affichageConsole();                                          // Affichage des donnée sur la console série
      affichageOled();                                             // Affichage des valeurs sur l'écran interne
    }                                                              // Fin du if (menu==2)
    if (menu == 3) {                                               // On est dans le menu 3 (réglage du Kd)
      Kd -= 0.5;                                                   // On décrémente le Kd
      EEPROM.write(3, Kd);                                         // On écrit la valeur en EEPROM
      affichageConsole();                                          // Affichage des donnée sur la console série
      affichageOled();                                             // Affichage des valeurs sur l'écran interne
    }                                                              // Fin du if (menu==3)
  }                                                                // Fin du if (reglage == 1)
}  // Fin de la fonction clickMoins

void longPressStartMoins() {  // Fonction appellée lorsque l'on appuie longtemps sur le bouton + et sert à sortir du mode réglage
  //Serial.println("Button Moins longPress start");
  reglage = 0;
  affichageConsole();  // Affichage des donnée sur la console série
  affichageOled();     // Affichage des valeurs sur l'écran interne
}  // longPressStartMoins



/**************************************************************************************/

// Fonction d'acquisition de la position du papillon
void positionPapillon() {
  positionAnaPotar = analogRead(pin_potar);                                                           // On lit la résistance du potentiomètre
  positionPourcentPotar = ((positionAnaPotar - echelle_mini) / (echelle_maxi - echelle_mini)) * 100;  // On transforme la valeur en ohm en 0 à 100% selon les échelles mini et maxi
  positionPourcentPotar = arrondir(positionPourcentPotar);                                            // On arrondit la valeur à 0,5 près
}

/**************************************************************************************/

// Fonction de lecture de la température
void lectureTemperature() {
  capteurTemp.requestTemperatures();                     // On emet une demande globale de lecture de température sur le bus
  temperatureActuelle = capteurTemp.getTempCByIndex(0);  // On récupère les valeurs sur le bus
  temperatureActuelle = arrondir(temperatureActuelle);   // On arrondit la valeur à 0,5 près
  affichageOled();                                       // On appelle la fonction d'affichage global
}

/**************************************************************************************/

// Fonction de gestion du moteur **************/
void actionMoteur() {
  if (positionPourcentPotar < sortiePID) {    // Si le volet n'est pas assez ouvert par rapoort à la consigne, alors
    if (positionPourcentPotar >= 99) stop();  // Si la papillon est en dessus de 99%, on bloque le moteur
    else ouvre();                             // sinon on l'ouvre
  }
  if (positionPourcentPotar > sortiePID + 1) {  // Si le volet est trop ouvert par rapport à la consigne, alors
    if (positionPourcentPotar <= 1) stop();     // si le papillon est en dessous de 1%, on bloque le moteur
    else ferme();                               // sinon on ferme le papillon
  }
  if ((positionPourcentPotar >= (sortiePID - 1)) && (positionPourcentPotar <= (sortiePID + 1))) {  // Si le volet est ouvert entre consigne-1 et consigne+1, alors
    stop();                                                                                        // on stoppe le volet
  }
}

/**************************************************************************************/

// Fonction d'ouverture du volet (commande du moteur)
void ouvre() {
  // oled.setCursor(110, 20);                 // Place le curseur en bas à droite
  // oled.print("+");                         // Affiche les impulsions d'ouverture
  digitalWrite(pinOuvertureMoteur, HIGH);  // On met la pin 1 du moteur à l'état haut
  digitalWrite(pinFermetureMoteur, LOW);   // On met la pin 2 du moteur à l'état bas
  delay(impulsion);                        // Cette tempo gère le temps de marche du moteur
  stop();                                  // Appel de la fonction qui stoppe le moteur
}

/**************************************************************************************/

// Fonction de fermeture du volet (commande du moteur)
void ferme() {
  digitalWrite(pinOuvertureMoteur, LOW);   // On met la pin 1 du moteur à l'état bas
  digitalWrite(pinFermetureMoteur, HIGH);  // On met la pin 2 du moteur à l'état haut
  delay(impulsion);                        // Cette tempo gère le temps de marche du moteur
  stop();                                  // Appel de la fonction qui stoppe le moteur
}

/**************************************************************************************/

// Fonction qui stoppe le volet (commande du moteur)
void stop() {
  digitalWrite(pinOuvertureMoteur, LOW);  // On met la pin 1 du moteur à l'état bas
  digitalWrite(pinFermetureMoteur, LOW);  // On met la pin 2 du moteur à l'état bas
}

/**************************************************************************************/

// Fonction d'affichage sur la console série
void affichageConsole() {
  //Serial.print("Température actuelle : ");
  //Serial.print(temperatureActuelle, 1);
  //Serial.print(" °C | Consigne : ");
  //Serial.print(consigneTemperature, 1);
  //Serial.print(" °C | Sortie PID : ");
  //Serial.print(sortiePID, 0);
  //Serial.print(" %");
  //Serial.print("Papillon: ");

  if (positionPourcentPotar <= 1) {  // Si le papillon est à moins de 1% d'ouverture
    //Serial.print("mini  ");          // On affiche "mini"
  } else {
    if (positionPourcentPotar >= 99) {  // Sinon si le papillon est à plus de 99%
      //Serial.print("maxi  ");           // on affiche "maxi"
    } else {
      //Serial.print(positionPourcentPotar, 1);  // Dans tous les autres cas on affiche la position en %
      //Serial.print(" % ");
    }
  }
  if (positionPourcentPotar < (sortiePID - 1)) {  // Si l'ouverture est inférieure à la consigne
    //Serial.println("Ouvre   ");                   // On affiche l'ouverture en cours
  } else {
    if (positionPourcentPotar > (sortiePID + 1)) {  // Si l'ouverture est supérieure à la consigne
      //Serial.println("Ferme   ");                   // On affiche la fermeture en cours
    } else {
      //Serial.println("Stand by");  // Sinon on affiche l'attente.
    }
  }
  //Serial.print(" | Réglage ");
  //Serial.print(reglage);
  //Serial.print(" | Menu ");
  //Serial.println(menu);
  switch (menu) {
    case 0:
      //Serial.print(" Consigne Température: ");
      //Serial.println(consigneTemperature, 1);
      break;
    case 1:
      //Serial.print(" Kp : ");
      //Serial.println(Kp, 1);
      break;
    case 2:
      //Serial.print(" Ki : ");
      //Serial.println(Ki, 1);
      break;
    case 3:
      //Serial.print("Kd : ");
      //Serial.println(Kd, 1);
      break;
  }
}


// Fonction d'affichage sur l'écran Oled
void affichageOled() {
  oled.setFont(System5x7);
  oled.set2X();
  oled.setCursor(0, 0);
  oled.print("Temp ");
  oled.print(temperatureActuelle, 1);
  oled.println("c");
  // Partie de l'affichage interactif !!
  switch (menu) {
    case 0:  // Quand on est dans la consigne
      switch (reglage) {
        case 0:  // Quand on n'est pas en mode réglage, pas de surbrillance
          oled.setInvertMode(0);
          break;
        case 1:  // Quand on est en mode réglage, activation de la surbrillance
          oled.setInvertMode(1);
          break;
      }
      oled.print("Cons: ");
      oled.print(consigneTemperature, 1);
      oled.println("c ");
      oled.setInvertMode(0);  //Toujours enlever la surbrillance ici !
      break;
    case 1:  // Quand on est sur le Kp
      switch (reglage) {
        case 0:  // Quand on n'est pas en mode réglage, pas de surbrillance
          oled.setInvertMode(0);
          break;
        case 1:  // Quand on est en mode réglage, activation de la surbrillance
          oled.setInvertMode(1);
          break;
      }
      oled.print("Kp : ");
      oled.print(Kp, 1);
      oled.println("   ");    // Efface les caractère qui restent derrière
      oled.setInvertMode(0);  //Toujours enlever la surbrillance ici !
      break;
    case 2:  // Quand on est sur le Ki
      switch (reglage) {
        case 0:  // Quand on n'est pas en mode réglage, pas de surbrillance
          oled.setInvertMode(0);
          break;
        case 1:  // Quand on est en mode réglage, activation de la surbrillance
          oled.setInvertMode(1);
          break;
      }
      oled.print("Ki : ");
      oled.print(Ki, 1);
      oled.println("   ");    // Efface les caractère qui restent derrière
      oled.setInvertMode(0);  //Toujours enlever la surbrillance ici !
      break;
    case 3:  // Quand on est sur le Kd
      switch (reglage) {
        case 0:  // Quand on n'est pas en mode réglage, pas de surbrillance
          oled.setInvertMode(0);
          break;
        case 1:  // Quand on est en mode réglage, activation de la surbrillance
          oled.setInvertMode(1);
          break;
      }
      oled.print("Kd : ");
      oled.print(Kd, 1);
      oled.println(" ");      // Efface les caractère qui restent derrière
      oled.setInvertMode(0);  //Toujours enlever la surbrillance ici !
      break;
  }
  // Fin de la partie interactive
  oled.print("PID : ");
  oled.println(sortiePID, 1);
  oled.print("Volet ");
  oled.println(positionPourcentPotar, 1);
}

Là, pour le coup, on est pas dans un projet fini.
Donc, je déplace dans la partie général du forum francophone où il aura une meilleure visibilité et lorsque le problème sera réglé, on pourra toujours rouvrir le post initial pour l'enrichir.

J'ai pas tout compris, mais merci @fdufnews . Je pense que c'est pour mon bien :grin:

votre loop est simple :

void loop() {

  // Garde l'oeil sur les boutons:
  boutonPlus.tick();
  boutonMoins.tick();

  positionPapillon();    // Appelle la fonction de lecture de la position du papillon (retourne la variable "positionPourcentPotar")
  lectureTemperature();  // Appelle la fonction de lecture de la température (Retourne la variable "temperatureActuelle")
  pid.Compute();         // Calcule la commande PID
  sortiePID = arrondir(sortiePID);
  actionMoteur();      // Fonction d'activation du moteur en fonction de la position du volet
  affichageConsole();  // Affichage des valeur sur la console pour débuggage
  affichageOled();     // Affichage des valeurs sur l'écran interne
}

Les boutons sont vérifiés à chaque début de loop par l'appel à tick() qui déclenche le callback si un appui est détecté.

si ça ne fonctionne pas comme vous voulez et qu'il y a de la latence, c'est que le reste

  positionPapillon();    // Appelle la fonction de lecture de la position du papillon (retourne la variable "positionPourcentPotar")
  lectureTemperature();  // Appelle la fonction de lecture de la température (Retourne la variable "temperatureActuelle")
  pid.Compute();         // Calcule la commande PID
  sortiePID = arrondir(sortiePID);
  actionMoteur();      // Fonction d'activation du moteur en fonction de la position du volet
  affichageConsole();  // Affichage des valeur sur la console pour débuggage
  affichageOled();     // Affichage des valeurs sur l'écran interne

prend trop longtemps

  • positionPapillon n'est pas en cause, le code est simple et rapide

  • pour lectureTemperature, vous utilisez un DS18B20 avec la bibliothèque DallasTemperature configuré par défaut, soit en 12 bits de précision. Un appel à requestTemperatures() prend alors ~750 milliseconds et ensuite vous faites à tous les coups un affichageOled()` qui est aussi une opération lente. A mon avis vous passez sans doute une seconde environ dans cet appel.
    ➜ li faudrait passer la lecture en asynchrone. Vous demandez une lecture puis vous ne lisez pas le résultat tant que les 750ms ne se sont pas écoulées. vous n'allez la chercher que si la valeur est dispo et vous la lisez et faites la mise à jour etc, sinon vous continuez votre chemin. De même pour l'affichage, si le contenu à afficher n'a pas changé ce n'est pas la peine de mettre à jour l'affichage. Mémorisez donc ce qu''il y a déjà à l'écran et ne faites une mise à jour que si l'écran va changer significativement
    Dans mon exemple Contrôleur de T°, Humidité avec pilotage manuel ou automatique j'utilise cette approche. J'utilise aussi un Si7021 en I2C qui est beaucoup plus rapide pour lire la température.

  • ensuite vous avez pid.Compute(). ça c'est assez rapide même si dans l'absolu ce n'est pas la peine d'appeler trop souvent le PID

  • actionMoteur est toujours exécutée même si elle ne conduit pas à un changement d'état donc ça veut dire que même si ouvre() avait déjà été appelé, vous l'appelez de nouveau, ce qui conduit à exécuter tout le temps un delay(impulsion); qui vous fait perdre 100ms. Il conviendrait d'utiliser une approche qui détecte le changement d'état et ne fait les modification que si nécessaire.

  • affichageConsole prend un peu de temps, ça sert à rien j'imagine si vous êtes dans la voiture. Il y a un peu à gratter de ce côté là

  • puis vous appelez à nouveau affichageOled()` alors que vous l'aviez déjà fait dans la lecture de la température.

  • Quand vous touchez les boutons, vous appelez aussi affichageOled()

➜ ici je pense que c'est l'affichage Oled et la lecture de la température qui sont les gros coupables — our moi il conviendrait de récrire le système sous forme d'une machine à états pour n'avoir aucune action bloquante trop longtemps et virer tous ces affiches superflus ou redondants.

➜ prenez éventuellement exemple sur mon code Contrôleur de T°, Humidité avec pilotage manuel ou automatique

Bonjour JML, merci beaucoup pour le retour.
C'est là que je vois mes lacunes en programmation, ayant appris par moi-même depuis peu.

Votre analyse m'en apprend beaucoup. J'ai débranché la sonde de température dans la voiture et tout est rentré dans l'ordre.
Alors oui il y a sûrement à gratter sur les différents appels de fonction mais la sonde est la grande coupable.

Je n'ai aucune idée de ce qu'est une machine à états et je vais étudier votre code avec grande attention. D'ailleurs j'avais déjà pris de l'avance sur votre réponse en désactivant les messages de la console via une variable booléenne 0 ou 1 selon qu'on veuille débugger ou pas et j'avais en effet remarqué une petite différence de réactivité.

Merci beaucoup pour votre réactivité et votre retour. Je vous tiens informé de l'avancement des modifications.
En attendant, passez de belles fêtes de fin d'année.

Arno

cf mon tuto éventuellement

bonnes fêtes !

:sweat_smile: c'est celui que j'avais commencé à regarder !!

@J-M-L J'ai regardé votre exemple sur le capteur de température et régulation. Je suis très impressionné. Je vois le squelette général mais je ne comprends que 10% de votre programme. Par exemple, je suis incapable de lire ceci : if ((ventilateurOn ? MARCHE : ARRET) != c) {
Je vais épurer le mien, éviter les requêtes inutiles et essayer de trouver comme faire une lecture asynchrone de la température.

Merci pour votre aide.

Arno.

C’est l’opération ternaire

Si ventilateurOn est vrai, ça retourne MARCHE sinon ça retourne ARRÊT (qui sont des valeurs énumérées)

cette valeur est ensuite comparée avec c qui est du même type énuméré.

Donc en gros ça dit si c est différent de l’état du ventilateur alors …

C'est vachement classe !!

J'ai trouvé la librairie [NonBlockingDallas]. Je pense me débrouiller avec ça.

Étudiez comment utiliser millis pour ne pas bloquer le code

Vous demandez la lecture et notez la valeur de millis et 750 ms plus tard vous savez que la valeur est dispo donc vous pouvez effectuer la requête pour lire la valeur et ce sera instantané et vous en profitez pour redemander la lecture et notez la valeur de millis et ainsi de suite

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.