Problème de delay pour utiliser un bouton

Bonjour,
Je suis débutant en programmation et j’adapte des codes trouvés sur internet pour correspondre à mes besoins. Dans ce cas je désire gérer l’affichage de la température d’un aquarium, sa valeur mini et maxi.
Matériel utilisé :

  • Arduino nano
  • Ecran lcd i2c 16 x 2
  • Sonde étanche DS18B20
  • 3 boutons poussoirs

Fonctionnement :

  • sur la ligne 1 affichage de la température en cours
  • sur la ligne 2 la valeur mini et la valeur maxi
  • En pressant un bouton, reset de la valeur mini, sur le 2ème bouton reset valeur maxi et sur le 3ème bouton arrêt/marche du lcd.

Le code suivant fonctionne, même s’il est loin d’être optimisé. Le problème se trouve au niveau du delay de 1 seconde entre la prise de la mesure et la lecture de la valeur. Du coup pour allumer/éteindre le lcd, le bouton n’est pas très réactive. J’ai pensé utiliser la fonction millis pour le code

  ds.reset(); // Reset le bus 1-Wire
  // skip saute la sélection du composant qui doit normalement être faite avec la fonction search.
  //Ceci fonctionne uniquement si vous utilisez un seul composant : vous pouvez éviter de le rechercher et vous pouvez l'utiliser immédiatement
  ds.skip();
  ds.write(0x44, 0);   // Déclenche la prise de mesure

ça va mieux, mais le code continuant ça ne respecte pas la temporisation avant la lecture.
Merci de mon conseiller sur une procédure plus adaptée.
Cordialement

// Gestion température Mini Aquarium
#include <OneWire.h>              // Appel de la bibliothèque protocole dédié pour les capteurs "One Wire" (température Sonde étanche DS18B20)
OneWire  ds(2);                   // Création de l'objet (sonde température) sur la pin 2
#include <Wire.h>                 // Appel de la bibliothèque protocole de communication avec composants I2C 
#include <LiquidCrystal_I2C.h>    // Appel de la bibliothèque contrôleur d'un affichage LCD (circuit intégré PCF8574)
LiquidCrystal_I2C lcd(0x27,16,2);  // Déclare l'adresse 0x27 du LCD pour 16 caractères et 2 lignes d'affichage

// --- Déclaration des variables globales pour la température ---
byte data[12];              // Tableau de 12 octets pour lecture des 9 registre de RAM et des 3 registres d'EEPROM du capteur One Wire
float celsius;              // Déclaration de la variable celsius en numérique avec décimales (virgules flottantes)
float minimum, maximum;     // Déclaration des variables pour les températures minimum et maximum
int MAJ;                    // Variable pour l'initialisation de la température minimum

// Constantes des bouttons
const int buttonEcran = 3;     // Broche du boutton marche/arrêt Ecran
const int buttonMin =  4;      // Broche du boutton reset Mini
const int buttonMax =  5;      // Broche du boutton reset Maxi

// variables etat écran et + -
int EtatEcran = 0;       // Variable pour lire l'état du boutton marche/arrêt Ecran
int EtatMin = 0;         // Variable pour lire l'état du boutton reset Mini
int EtatMax = 0;         // Variable pour lire l'état du boutton reset Maxi
int FonctEcran = 1;      // Variable du fonctionnement du LCD (1 Allumé, 0 éteint)

// --- Déclaration des tableaux de caractères spéciaux ---
byte plus[] = {
  B11000,
  B11100,
  B11110,
  B11111,
  B11111,
  B11110,
  B11100,
  B11000
};
byte moins[] = {
  B00011,
  B00111,
  B01111,
  B11111,
  B11111,
  B01111,
  B00111,
  B00011
};

void setup()
{
  // Initialisation des bouttons en input:
  pinMode(buttonEcran, INPUT);
  pinMode(buttonMin, INPUT);
  pinMode(buttonMax, INPUT);
  
   // --- Initialisation du LCD ---
  lcd.init();
  lcd.backlight();
   // --- Initialisation des caractères spéciaux ---
  lcd.createChar(0, plus);
  lcd.createChar(1, moins);
  // --- Affichage du texte permanent (temp, °C, < et > ---
  lcd.setCursor(1,0);
  lcd.print("Temp : ");
  lcd.setCursor(13,0);
  lcd.print((char)223);
  lcd.print("C");
  lcd.setCursor(0,1);
  lcd.write(byte(1));
  lcd.setCursor(15,1);
  lcd.write(byte(0));
}

void loop()
{
  // Lecture le l'état des bouttons
  EtatEcran = digitalRead(buttonEcran);
  EtatMin = digitalRead(buttonMin);
  EtatMax = digitalRead(buttonMax);

  // Récupération de la température
  ds.reset(); // Reset le bus 1-Wire
  // skip saute la sélection du composant qui doit normalement être faite avec la fonction search.
  //Ceci fonctionne uniquement si vous utilisez un seul composant : vous pouvez éviter de le rechercher et vous pouvez l'utiliser immédiatement
  ds.skip();
  ds.write(0x44, 0);   // Déclenche la prise de mesure
  delay(1000);         // Délais entre renvoie d'infos de 1000ms soit 1 seconde
  ds.reset();          // Reset le bus 1-Wire
  ds.skip();           // skip saute la sélection du composant
  ds.write(0xBE);      // Envoie une demande de lecture du scratchpad
  for (unsigned char i = 0; i < 9; i++) {   // Lecture du scratchpad, nous avons besoin de 9 octets
    data[i] = ds.read();
  }
  // Convertir les données en température réelle
  // parce que le résultat est un entier signé de 16 bits, il devrait
  // être stocké dans un type "int16_t", qui a toujours 16 bits
  // même lorsqu'il est compilé sur un processeur 32 bits.
  int16_t raw = (data[1] << 8) | data[0];
  byte cfg = (data[4] & 0x60);
  // en basse résolution, les bits bas sont indéfinis, alors remettons-les à zéro
  if (cfg == 0x00) raw = raw & ~7;      // Résolution de 9 bits, 93,75 ms
  else if (cfg == 0x20) raw = raw & ~3; // Résolution 10 bits, 187,5 ms
  else if (cfg == 0x40) raw = raw & ~1; // Résolution 11 bits, 375 ms
  // Calcul en celsius.
  celsius = (float)raw / 16.0;

  // Reset température Mini
  if (EtatMin == LOW) {
    minimum=celsius;
  }
  // Reset température Max
  if (EtatMax == LOW) {
    maximum=celsius;
  }

  // Marche / arrêt LCD
  if (EtatEcran == LOW) {
    if (FonctEcran == 1) {
      lcd.noBacklight(); // Eteindre le retro-eclairage
      lcd.noDisplay();   // Eteind le LCD
      FonctEcran = 0;
    }
    else {
      lcd.backlight();  // Allumer le retro-eclairage
      lcd.display();    // Allumer le LCD
      FonctEcran = 1;
    }
  }

  // Initialisation pour la première lecture de valeur minimale
  if (MAJ != 1) {
    minimum=celsius;
    MAJ=1;
  }
  // Mise à jour des valeurs mini et maxi en fonction de la temp. en cours
  if (minimum > celsius) {
    minimum = celsius;
  }
  if (maximum<celsius) {
    maximum=celsius;
  }
  // Affichage des valeurs temp, mini et maxi
  lcd.setCursor(8,0);  
  lcd.print(celsius);
  lcd.setCursor(2,1);
  lcd.print(minimum);
  lcd.print("  ");
  lcd.print(maximum);
}

Cela ne changera rien. Le "delay (1000) laisse une seconde à la sonde de température pour faire sa mesure, sa conversion, mettre le résultat dans un registre. Vous pouvez réduire ce délai, en tatonnant, jusqu'à ce que ça ne fonctionne plus, puis le rallonger de 10% par sécurité. Vous pouvez aussi diminuer la résolution pour faire une première lecture après l'appuis sur le bouton, pour afficher un résultat provisoire, avec un délai encore plus court. Puis faire une seconde lecture avec un délai un peu plus long en demandant une meilleure précision. L'utilisateur verra s'afficher, par exemple au bout de 150ms une température de 23.8°C, puis après encore 800ms 24.3°C. Vous lui expliquerez que les électrons se sont réchauffés lentement dans le trajet entre la sonde et l'afficheur :slight_smile:

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