surveillance de température

Bonjour,

Je cherche à construire un dispositif de surveillance et de contrôle de la température de montages électroniques. Ce dispositif doit afficher la température sur un LCD, mettre en route, de façon progressive un ventilateur à partir d'un seuil défini et allumer une LED et un buzzer si la température maxi est atteinte. Le code ci après fonctionne à ceci près que je voudrais faire fonctionner le buzzer de façon intermittente (1 seconde marche, 1 seconde arrêt) à partir de la temp max. Ici le buzzer fonctionne tout le temps ... Le code compile normalement dans l'IDE.
Toute aide est la bienvenue :slight_smile:

#include <LiquidCrystal.h>
//source: https://www.electroschematics.com/9540/arduino-fan-speed-controlled-temperature/
//version Nano, les No de pin correspondent au marquage sur circuit imprimé
LiquidCrystal lcd(2,5,6,9,10,11);
int tempPin = A1;   // entrée analogique du Nano pour le LM35
int fan = 3;        // Pin ou est le ventilo : D3
int led = 7;        // led sur pin D7
int temp;
int tempMin = 30;   // the temperature to start the fan
int tempMax = 50;   // the maximum temperature when fan is at 100% (initialement 70 degré)
int fanSpeed;
int fanLCD;
int buzzer = 4;    // buzzer sur pin D4 arduino Nano

// Les variables sont modifiées au cours du programme
int buzzerState = LOW;             // buzzerState est utilisée pour fixer l'état du buzzer (HIGH/LOW)

// les variables suivantes sont de type long car le temps, mesuré en millisecondes
// devient rapidement un nombre qui ne peut pas être stocké dans un type int.

unsigned long previousMillis = 0;        // variable pour mémoriser le temps écoulé depuis le dernier changement du buzzer
const long interval = 1000;           //intervalle de clignotement du buzzer (en millisecondes)


void setup() {
  pinMode(fan, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(tempPin, INPUT);
  lcd.begin(16,2);
  pinMode(buzzer, OUTPUT); // Set pin buzzer comme sortie
  
}

void loop()
   {  
   temp =  readTemp();  // get the temperature
   
   if(temp  < tempMin) { // if temp is lower than minimum temp 
      fanSpeed = 0; // fan is not spinning 
      digitalWrite(fan, LOW); 
   }
   
   if((temp  >= tempMin) && (temp <= tempMax)) { // if temperature is higher than minimum temp 
      fanSpeed = map(temp, tempMin, tempMax, 60, 255); // the actual speed of fan (initial 32, 255)
      fanLCD = map(temp, tempMin, tempMax, 0, 100); // vitesse du ventilo à afficher sur LCD 
      analogWrite(fan, fanSpeed); // spin the fan at the fanSpeed speed 
   }
   
   if(temp  > tempMax) {          // if temp is higher than tempMax
     digitalWrite(led, HIGH);     // turn on led
     digitalWrite(buzzer, buzzerState); // buzzer ON 
   }
   else
   {                    // else turn off led
     digitalWrite(led, LOW);
     digitalWrite(buzzer, LOW); // sinon buzzer OFF 
   }
      unsigned long currentMillis = millis();            // stocke la valeur courante de la fonction millis()
      if(currentMillis - previousMillis > interval) {    // mémorise la valeur de la fonction millis()
      previousMillis = currentMillis;  
      }
    // inverse la variable d'état du buzzer
      if (buzzerState == LOW)
      buzzerState = HIGH;
      else
      buzzerState = LOW;
      digitalWrite(buzzer, buzzerState);  // modifie l'état du buzzer
      
   lcd.print("TEMP: ");
   lcd.print(temp);      // display the temperature
   
   lcd.print((char)223); // caractère spécial ° (degré)
   lcd.print("C ");
   lcd.setCursor(0,1);   // move cursor to next line
   lcd.print("VENTILO: ");
   lcd.print(fanLCD);    // display the fan speed
   lcd.print("%");
   delay(100);           // rafraichissement tous les 100 ms
   lcd.clear();   
   }
   int readTemp() {  // get the temperature and convert it to celsius
      temp = analogRead(tempPin);
      return temp * 0.48828125;
      }

Regardez l’exemple blink without delay pour voir comment alterner un état sans bloquer la loop avec des delays

Si le buzzer doit beeper vous mettez une variable booléenne (bool buzzEnCours;) à vrai et à la fin de la loop vous mettez

  if (buzzEnCours) {
    .... (ici un code similaire à blink without delay)....
  }

Bonjour,

Tu étais bien parti ici

      if(currentMillis - previousMillis > interval) {    // mémorise la valeur de la fonction millis()
      previousMillis = currentMillis; 
      }
    // inverse la variable d'état du buzzer
      if (buzzerState == LOW)
      buzzerState = HIGH;
      else
      buzzerState = LOW;
      digitalWrite(buzzer, buzzerState);  // modifie l'état du buzzer

Malheureusement

  • ton } est mal placé (formates ton code avec ctrl T pour y voir plus clair)
  • ton indicateur buzzerState est mal utilisé.

Tu aurais du faire par exemple

  if (temp  > tempMax) {         // if temp is higher than tempMax
    digitalWrite(led, HIGH);     // turn on led
    buzzerState = true;
  }
  else
  { // else turn off led
    digitalWrite(led, LOW);
    buzzerState = false;
  }
  unsigned long currentMillis = millis();            // stocke la valeur courante de la fonction millis()
  if (currentMillis - previousMillis > interval) {   // mémorise la valeur de la fonction millis()
    previousMillis = currentMillis;
    if (buzzerState)
      digitalWrite(buzzer, !digitalRead(buzzer)); // inverse la sortie buzzer
    else
      digitalWrite(buzzer, LOW);
  }

Autre remarque: tes tests peuvent être améliorés: par exemple si ton programme démarre avec une température supérieure à tempMax, le ventilateur ne démarrera pas.

J-M-L:
Regardez l’exemple blink without delay pour voir comment alterner un état sans bloquer la loop avec des delays

Si le buzzer doit beeper vous mettez une variable booléenne (bool buzzEnCours;) à vrai et à la fin de la loop vous mettez

  if (buzzEnCours) {

.... (ici un code similaire à blink without delay)....
  }

Merci JML pour ta réponse. Je me suis bien inspiré de l'exemple "blink without delay" pour la partie "buzzer". Je suis cependant débutant et j'ai quitté les bancs de l'école il y a bien longtemps (un peu plus de 40 ans). J'ai donc une marge de progrès importante :slight_smile:

kamill:
Bonjour,

Tu étais bien parti ici

      if(currentMillis - previousMillis > interval) {    // mémorise la valeur de la fonction millis()

previousMillis = currentMillis;
     }
   // inverse la variable d'état du buzzer
     if (buzzerState == LOW)
     buzzerState = HIGH;
     else
     buzzerState = LOW;
     digitalWrite(buzzer, buzzerState);  // modifie l'état du buzzer




Malheureusement
- ton } est mal placé (formates ton code avec ctrl T pour y voir plus clair)
- ton indicateur buzzerState est mal utilisé.

Tu aurais du faire par exemple


if (temp  > tempMax) {         // if temp is higher than tempMax
   digitalWrite(led, HIGH);     // turn on led
   buzzerState = true;
 }
 else
 { // else turn off led
   digitalWrite(led, LOW);
   buzzerState = false;
 }
 unsigned long currentMillis = millis();            // stocke la valeur courante de la fonction millis()
 if (currentMillis - previousMillis > interval) {   // mémorise la valeur de la fonction millis()
   previousMillis = currentMillis;
   if (buzzerState)
     digitalWrite(buzzer, !digitalRead(buzzer)); // inverse la sortie buzzer
   else
     digitalWrite(buzzer, LOW);
 }




Autre remarque: tes tests peuvent être améliorés: par exemple si ton programme démarre avec une température supérieure à tempMax, le ventilateur ne démarrera pas.

Merci Kamill pour ta réponse : çà marche nickel. Tu es décidément mon sauveur ! Je n'y serais pas arrivé seul.
Pour les autres tests (temp>tempMax), je n'y avais pas pensé mais çà pourrait être intéressant dans certains cas (en industrie notamment). Dans mon cas -et tout bien réfléchi-, il ne s'agit que de la surveillance de température d'ampli HF ou autre (ces bêtes là n'aiment être chauffées trop fort). Donc pas d'intérêt pour un ventilo type PC mais je prends note.
Pour le Raccourci "CTRL T", je note et c'est super !