Automatic regulation of a fan depending on the temperature variation

Hello,
I need help with a part of my arduino program that doesn't work as I want.
Indeed, I have to make a manual and automatic control program. With the help of a keyboard, I have to control the fan speed according to the temperature of a radiator that I display with an LCD screen. The manual control works well. That is to say that I increase the speed or decrease it when I want. However, when I press the # key on the keyboard I should have an automatic regulation. The fan speed should change by itself each time the temperature exceeds a certain value.
My problem is that when I press #, the regulation is done automatically the first time but when the temperature changes again, I have to press # again to have a new regulation when it should be done automatically.
I am attaching my code for you to look at.
Thanks in advance.

#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <String.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,20,4); //20 caractères peuvent être affichés sur chacune des 4 lignes de l'écran LCD

float Temperature1 = 0;         //Température1
float Temperature2 = 0;
float Temperature3 = 0;
float Temperature4 = 0;

int start = 0;          //ventilateur allumé ou non
int pwm_v = 0;          // Commande de la vitesse du ventilateur    

String T1;
String T2;
String T3;
String T4;
String V;
String Mode;

int relais = 42;
int moteurPin1 = 24;
int moteurPin2 = 25;
int moteurEN = 4 ;    //Pin4 PWM

//Configuration du clavier

const byte LIGNES = 4;   // 4 lignes
const byte COLONNES = 3; // 3 colonnes
char keys[LIGNES][COLONNES] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[LIGNES] = {7, 8, 9, 10}; 
byte colPins[COLONNES] = {11, 12, 13}; 
Keypad CLV = Keypad( makeKeymap(keys), rowPins, colPins, LIGNES, COLONNES);

void setup() {
  Serial.begin(9600);
  pinMode(relais, OUTPUT);
  pinMode(moteurPin1, OUTPUT);
  pinMode(moteurPin2, OUTPUT);
  pinMode(moteurEN, OUTPUT);
  
  //Transmission des valeurs sur Excel
  Serial.println("CLEARDATA"); 
  Serial.println("LABEL, Date, Temps, Te1, Te2, Te3, Te4, pwm");

  //Initialisation de l'écran
  lcd.init();
  lcd.backlight();
}   

void loop() {
  char key = CLV.getKey();
  if (key != NO_KEY){
    Serial.println(key);
    if (key == '3'){digitalWrite(relais, HIGH);}
    if (key == '6'){digitalWrite(relais, LOW);}
  }
  
  //1ère partie du code : Evolution des températures sans ventilateur (pas de régulation)
  //Lecture des valeurs du capteurs
  int reading1 = analogRead (14);
  int reading2 = analogRead (15);
//  int reading3 = analogRead (2);
//  int reading4 = analogRead (3);

  //Changement des valeurs de température en degré
  Temperature1 = reading1 * (5.0 / 1023.0) * 100.0;
  Temperature2 = reading2 * (5.0 / 1023.0) * 100.0;
//  Temperature3 = reading3 * (5.0 / 1023.0) * 100.0;
//  Temperature4 = reading4 * (5.0 / 1023.0) * 100.0;

  //Mettre les valeurs de température dans Excel
  Serial.println((String)"DATA, DATE, TIME," + Temperature1 + "," + Temperature2 + "," + pwm_v);
  
  T1 = "T1=";
  T1 += Temperature1;
  T2 = "T2=";
  T2 += Temperature2;
  T3 = "T3=";
  T3 += Temperature3;
  T4 = "T4=";
  T4 += Temperature4;

  //Intervention du ventilateur
  digitalWrite (moteurPin1, 1);     // Envoie l'électricité dans in1 donc dans la broche 22 ce qui fait tourner le moteur dans le sens in1
  digitalWrite (moteurPin2, 0);     // On met le in2 à 0 pour continuer à tourner dans le sens de rotation de in1 
  analogWrite  (moteurEN, pwm_v);
  
  if (key != NO_KEY){
    Serial.println(key);
    if (key == '4' ) {
      pwm_v = 50;           //Allumage du ventilateur
      start = 1;
      V = "V = ";
      V += pwm_v;
      Mode = "Allu";
    }
    if (key == '*'){
      pwm_v = 0;
      start = 0;
      V = "V=";             //Extinction du ventilateur
      V += pwm_v;
      Mode = "Stop";
    }
    
    if (start == 1 && key == '2'){
      pwm_v += 10;
      if (pwm_v > 255){pwm_v = 255;}
      Mode = "REG MAN";
      V = "V=";
      V += pwm_v;
    }
    if (start == 1 && key == '8'){
      pwm_v -= 20;
      if (pwm_v < 0){pwm_v = 0;}
      Mode = "REG MAN";
      V = "V=";
      V += pwm_v;
      }
//Régulation automatique
      while(start == 1 && key == '#'){
        
        char key = CLV.getKey();
        
        if (Temperature1 < 25){
          pwm_v = 60;
          V = "V=";
          V += pwm_v;
          Mode = "Auto";
        }
        if (Temperature1 > 25 && Temperature1 < 30){
          pwm_v = 75;
          V = "V=";
          V += pwm_v; 
          Mode = "Auto"; 
         }
         if (Temperature1 > 30){
          pwm_v = 150;
          V = "V=";
          V += pwm_v;
          Mode = "Auto";
         }
         if (key == '9'){
          V = "V=";
          V += pwm_v;
          Mode = "Fin reg";
         }
         break;
      }
  }
    //Affichage des valeurs sur l'écran
    lcd.clear();
    lcd.setCursor (0,0);
    lcd.print(T1);
    lcd.setCursor (0,1);
    lcd.print(T2);
    lcd.setCursor (9,0);
    lcd.print(V);
    lcd.setCursor (9,1);
    lcd.print(Mode);
    delay (250);          
}

ProgrammeArd2.ino (4.36 KB)

If you post your code as described in the forum guidelines more members will see your code.

If You read the topic "How to use this Forum", #7, more helpers will read Your code and assist.

You're assigning the string variable mode "Auto" but You never use "mode" in the code.....
Why use a string variable? Use an Enum consisting of the allowed states.

amediop:
Hello,
I need help with a part of my arduino program that doesn't work as I want.
Indeed, I have to make a manual and automatic control program. With the help of a keyboard, I have to control the fan speed according to the temperature of a radiator that I display with an LCD screen. The manual control works well. That is to say that I increase the speed or decrease it when I want. However, when I press the # key on the keyboard I should have an automatic regulation. The fan speed should change by itself each time the temperature exceeds a certain value.
My problem is that when I press #, the regulation is done automatically the first time but when the temperature changes again, I have to press # again to have a new regulation when it should be done automatically.
I am attaching my code for you to look at.
Thanks in advance.

groundFungus:
If you post your code as described in the forum guidelines more members will see your code.

Thx i will

Hello,
I post my code for help.

#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <String.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,20,4); //20 caractères peuvent être affichés sur chacune des 4 lignes de l'écran LCD

float Temperature1 = 0;         //Température1
float Temperature2 = 0;
float Temperature3 = 0;
float Temperature4 = 0;

int start = 0;          //ventilateur allumé ou non
int pwm_v = 0;          // Commande de la vitesse du ventilateur    

String T1;
String T2;
String T3;
String T4;
String V;
String Mode;

int relais = 42;
int moteurPin1 = 24;
int moteurPin2 = 25;
int moteurEN = 4 ;    //Pin4 PWM

//Configuration du clavier

const byte LIGNES = 4;   // 4 lignes
const byte COLONNES = 3; // 3 colonnes
char keys[LIGNES][COLONNES] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[LIGNES] = {7, 8, 9, 10}; 
byte colPins[COLONNES] = {11, 12, 13}; 
Keypad CLV = Keypad( makeKeymap(keys), rowPins, colPins, LIGNES, COLONNES);

void setup() {
  Serial.begin(9600);
  pinMode(relais, OUTPUT);
  pinMode(moteurPin1, OUTPUT);
  pinMode(moteurPin2, OUTPUT);
  pinMode(moteurEN, OUTPUT);
  
  //Transmission des valeurs sur Excel
  Serial.println("CLEARDATA"); 
  Serial.println("LABEL, Date, Temps, Te1, Te2, Te3, Te4, pwm");

  //Initialisation de l'écran
  lcd.init();
  lcd.backlight();
}   

void loop() {
  char key = CLV.getKey();
  if (key != NO_KEY){
    Serial.println(key);
    if (key == '3'){digitalWrite(relais, HIGH);}
    if (key == '6'){digitalWrite(relais, LOW);}
  }
  
  //1ère partie du code : Evolution des températures sans ventilateur (pas de régulation)
  //Lecture des valeurs du capteurs
  int reading1 = analogRead (14);
  int reading2 = analogRead (15);
//  int reading3 = analogRead (2);
//  int reading4 = analogRead (3);

  //Changement des valeurs de température en degré
  Temperature1 = reading1 * (5.0 / 1023.0) * 100.0;
  Temperature2 = reading2 * (5.0 / 1023.0) * 100.0;
//  Temperature3 = reading3 * (5.0 / 1023.0) * 100.0;
//  Temperature4 = reading4 * (5.0 / 1023.0) * 100.0;

  //Mettre les valeurs de température dans Excel
  Serial.println((String)"DATA, DATE, TIME," + Temperature1 + "," + Temperature2 + "," + pwm_v);
  
  T1 = "T1=";
  T1 += Temperature1;
  T2 = "T2=";
  T2 += Temperature2;
  T3 = "T3=";
  T3 += Temperature3;
  T4 = "T4=";
  T4 += Temperature4;

  //Intervention du ventilateur
  digitalWrite (moteurPin1, 1);     // Envoie l'électricité dans in1 donc dans la broche 22 ce qui fait tourner le moteur dans le sens in1
  digitalWrite (moteurPin2, 0);     // On met le in2 à 0 pour continuer à tourner dans le sens de rotation de in1 
  analogWrite  (moteurEN, pwm_v);
  
  if (key != NO_KEY){
    Serial.println(key);
    if (key == '4' ) {
      pwm_v = 50;           //Allumage du ventilateur
      start = 1;
      V = "V = ";
      V += pwm_v;
      Mode = "Allu";
    }
    if (key == '*'){
      pwm_v = 0;
      start = 0;
      V = "V=";             //Extinction du ventilateur
      V += pwm_v;
      Mode = "Stop";
    }
    
    if (start == 1 && key == '2'){
      pwm_v += 10;
      if (pwm_v > 255){pwm_v = 255;}
      Mode = "REG MAN";
      V = "V=";
      V += pwm_v;
    }
    if (start == 1 && key == '8'){
      pwm_v -= 20;
      if (pwm_v < 0){pwm_v = 0;}
      Mode = "REG MAN";
      V = "V=";
      V += pwm_v;
      }
//Régulation automatique
      while(start == 1 && key == '#'){
        
        char key = CLV.getKey();
        
        if (Temperature1 < 25){
          pwm_v = 60;
          V = "V=";
          V += pwm_v;
          Mode = "Auto";
        }
        if (Temperature1 > 25 && Temperature1 < 30){
          pwm_v = 75;
          V = "V=";
          V += pwm_v; 
          Mode = "Auto"; 
         }
         if (Temperature1 > 30){
          pwm_v = 150;
          V = "V=";
          V += pwm_v;
          Mode = "Auto";
         }
         if (key == '9'){
          V = "V=";
          V += pwm_v;
          Mode = "Fin reg";
         }
         break;
      }
  }
    //Affichage des valeurs sur l'écran
    lcd.clear();
    lcd.setCursor (0,0);
    lcd.print(T1);
    lcd.setCursor (0,1);
    lcd.print(T2);
    lcd.setCursor (9,0);
    lcd.print(V);
    lcd.setCursor (9,1);
    lcd.print(Mode);
    delay (250);          
}

Hello,
I need help with a part of my arduino program that doesn't work as I want.
Indeed, I have to make a manual and automatic control program. With the help of a keyboard, I have to control the fan speed according to the temperature of a radiator that I display with an LCD screen. The manual control works well. That is to say that I increase the speed or decrease it when I want. However, when I press the # key on the keyboard I should have an automatic regulation. The fan speed should change by itself each time the temperature exceeds a certain value.
My problem is that when I press #, the regulation is done automatically the first time but when the temperature changes again, I have to press # again to have a new regulation when it should be done automatically.
I am attaching my code for you to look at.
Thanks in advance.

#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <String.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,20,4); //20 caractères peuvent être affichés sur chacune des 4 lignes de l'écran LCD

float Temperature1 = 0;         //Température1
float Temperature2 = 0;
float Temperature3 = 0;
float Temperature4 = 0;

int start = 0;          //ventilateur allumé ou non
int pwm_v = 0;          // Commande de la vitesse du ventilateur    

String T1;
String T2;
String T3;
String T4;
String V;
String Mode;

int relais = 42;
int moteurPin1 = 24;
int moteurPin2 = 25;
int moteurEN = 4 ;    //Pin4 PWM

//Configuration du clavier

const byte LIGNES = 4;   // 4 lignes
const byte COLONNES = 3; // 3 colonnes
char keys[LIGNES][COLONNES] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[LIGNES] = {7, 8, 9, 10}; 
byte colPins[COLONNES] = {11, 12, 13}; 
Keypad CLV = Keypad( makeKeymap(keys), rowPins, colPins, LIGNES, COLONNES);

void setup() {
  Serial.begin(9600);
  pinMode(relais, OUTPUT);
  pinMode(moteurPin1, OUTPUT);
  pinMode(moteurPin2, OUTPUT);
  pinMode(moteurEN, OUTPUT);
  
  //Transmission des valeurs sur Excel
  Serial.println("CLEARDATA"); 
  Serial.println("LABEL, Date, Temps, Te1, Te2, Te3, Te4, pwm");

  //Initialisation de l'écran
  lcd.init();
  lcd.backlight();
}   

void loop() {
  char key = CLV.getKey();
  if (key != NO_KEY){
    Serial.println(key);
    if (key == '3'){digitalWrite(relais, HIGH);}
    if (key == '6'){digitalWrite(relais, LOW);}
  }
  
  //1ère partie du code : Evolution des températures sans ventilateur (pas de régulation)
  //Lecture des valeurs du capteurs
  int reading1 = analogRead (14);
  int reading2 = analogRead (15);
//  int reading3 = analogRead (2);
//  int reading4 = analogRead (3);

  //Changement des valeurs de température en degré
  Temperature1 = reading1 * (5.0 / 1023.0) * 100.0;
  Temperature2 = reading2 * (5.0 / 1023.0) * 100.0;
//  Temperature3 = reading3 * (5.0 / 1023.0) * 100.0;
//  Temperature4 = reading4 * (5.0 / 1023.0) * 100.0;

  //Mettre les valeurs de température dans Excel
  Serial.println((String)"DATA, DATE, TIME," + Temperature1 + "," + Temperature2 + "," + pwm_v);
  
  T1 = "T1=";
  T1 += Temperature1;
  T2 = "T2=";
  T2 += Temperature2;
  T3 = "T3=";
  T3 += Temperature3;
  T4 = "T4=";
  T4 += Temperature4;

  //Intervention du ventilateur
  digitalWrite (moteurPin1, 1);     // Envoie l'électricité dans in1 donc dans la broche 22 ce qui fait tourner le moteur dans le sens in1
  digitalWrite (moteurPin2, 0);     // On met le in2 à 0 pour continuer à tourner dans le sens de rotation de in1 
  analogWrite  (moteurEN, pwm_v);
  
  if (key != NO_KEY){
    Serial.println(key);
    if (key == '4' ) {
      pwm_v = 50;           //Allumage du ventilateur
      start = 1;
      V = "V = ";
      V += pwm_v;
      Mode = "Allu";
    }
    if (key == '*'){
      pwm_v = 0;
      start = 0;
      V = "V=";             //Extinction du ventilateur
      V += pwm_v;
      Mode = "Stop";
    }
    
    if (start == 1 && key == '2'){
      pwm_v += 10;
      if (pwm_v > 255){pwm_v = 255;}
      Mode = "REG MAN";
      V = "V=";
      V += pwm_v;
    }
    if (start == 1 && key == '8'){
      pwm_v -= 20;
      if (pwm_v < 0){pwm_v = 0;}
      Mode = "REG MAN";
      V = "V=";
      V += pwm_v;
      }
//Régulation automatique
      while(start == 1 && key == '#'){
        
        char key = CLV.getKey();
        
        if (Temperature1 < 25){
          pwm_v = 60;
          V = "V=";
          V += pwm_v;
          Mode = "Auto";
        }
        if (Temperature1 > 25 && Temperature1 < 30){
          pwm_v = 75;
          V = "V=";
          V += pwm_v; 
          Mode = "Auto"; 
         }
         if (Temperature1 > 30){
          pwm_v = 150;
          V = "V=";
          V += pwm_v;
          Mode = "Auto";
         }
         if (key == '9'){
          V = "V=";
          V += pwm_v;
          Mode = "Fin reg";
         }
         break;
      }
  }
    //Affichage des valeurs sur l'écran
    lcd.clear();
    lcd.setCursor (0,0);
    lcd.print(T1);
    lcd.setCursor (0,1);
    lcd.print(T2);
    lcd.setCursor (9,0);
    lcd.print(V);
    lcd.setCursor (9,1);
    lcd.print(Mode);
    delay (250);          
}

This looks like an old topic posted again.

Yes just looking for help

Duplicate topics merged

@amediop

Do not start new topics on the same subject

Cross-posting is against the rules of the forum. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend 15 minutes (or more) writing a detailed answer on this topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting will result in a timeout from the forum.

In the future, please take some time to pick the forum board that best suits the topic of your question and then only post once to that forum board. This is basic forum etiquette, as explained in the sticky "How to use this forum - please read." post you will find at the top of every forum board. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

Your while loop is odd. It looks as though your intent is to loop checking the temperature until the '9' key is pressed. But there's an unconditional break at the end of the loop, so it only runs once. Should that break go up a line?

If you do make that fix though, it still won't work because although you set pwm_v, you never use it in that while loop.

Read and reply to the reply #3.....

wildbill:
Your while loop is odd. It looks as though your intent is to loop checking the temperature until the '9' key is pressed. But there's an unconditional break at the end of the loop, so it only runs once. Should that break go up a line?

If you do make that fix though, it still won't work because although you set pwm_v, you never use it in that while loop.

Thx for your response
I changed the position of the break and put it after the "Mode = End Reg". But if I do that my LCD screen freezes.
My goal is when I press the # key that each time the temperature is checked and the fan speed changes until I press the 9 key to stop the regulation.

Look into finite state machines. You have two states: automatic (after the # is pressed) and normal modes. Behaviour of the program depends on the state it's in.

Did OP read #3? The variable Mode is assigned values but I don't find it being used except for a printout.

Railroader:
Did OP read #3? The variable

Mode

is assigned values but I don't find it being used except for a printout.

Yes mode is just a string which i will print on the screen

Okey, a dead end.
How do You intend to know, in the code, what mode, Automatic or Manual, that is the one to use?

With my keyboard. When i want to have an automatic regulation i just have to press # on my keyboard.
I will press 1 or 7 to increase or decrease the fan speed manually (that's the manual regulation).

You didn't understand my question. I try again. What variable in the code will "remember" what way to run, Automatic or Manual?

So say you are using a Uno with 5V. With a 5V fan and PWM and a few external components thrown in your good to go on that end but the relationship needs to be established between fan speed and temperature.

Just taking the basic Servo library which generates PWM between 500us and 2500us, you can actually use the servo library in this case.

That's a range of 2000us.

Now lets say you want to run the fan from 0 degrees to 100+ degrees.

A starting scale could be for every 1 degree of temp equals 20us of PWM change.

Now if its 0 degress your fan can be PWM'd with 500uS.

When the temperature goes up to 1 degree the fan can be PWM'd at 520us

When the temperature goes up to 2 degree the fan can be PWM'd at 540us

When the temperature goes up to 3 degree the fan can be PWM'd at 560us

With an established relationship of fan speed to temperature an automated system can be realized.