Scintillement lcd

Bonjour,
Cela va faire un peu plus de deux ans que j'ai découvert arduino et ses possibilités. Mais jusqu'à maintenant je me suis toujours contenté de copier/coller des bouts de code. Mais pas cette fois.

J'ai fait un thermostat qui permettrai d'alimenter une prise pour y brancher un petit chauffage.
J'ai fait un montage avec :

  • un écran lcd en i2c
  • des boutons plus/moins/valider/retour
  • un potentiomètre
  • un capteur dht22
  • un relai

Mon code fonctionne mais l'écran scintille, je pense qu'il reçoit tout le temps des infos mais je n'ai pas l'idée pour le simplifier.
J'ai fait un menu qui permet de changer une temperature/une humidité et un délai minimum entre les périodes d'arrêt ou de chauffe (que je n'exploite pas encore). On verra plutard chaque chose en son temps.

Merci pour vos lumières

#include <LiquidCrystal_I2C.h> //Gestion de l'afficheur LCD
#include <DHT.h>
const int typeDeDHT = DHT22;
const int pinCapteurint = 3;
const int pinCapteurext = 2;
DHT dhtInt(pinCapteurint, typeDeDHT);
DHT dhtExt(pinCapteurext, typeDeDHT);
#define pinBoutonPlus 5
#define pinBoutonMoins 6
#define pinBoutonValidation 7
#define pinBoutonAnnulation 8
#define pinRelai 10
#define pinPotentio A2

char boutonPlus = 0;
char boutonMoins = 0;
char boutonValidation = 0;
char boutonAnnulation = 0;
int boutonPotentio;
int boutonDelai;
float temperatureInt = 0;
float humiditeInt = 0;
int temperatureVoulu = 0;
int humiditeVoulu = 0;
unsigned int delaiMin = 10;
char valeurPotentio;
unsigned long tempsActuel = 0;
int fenetre = 0;
int menu = 0;
boolean relai = LOW;
LiquidCrystal_I2C lcd(0x27, 16, 2);

 
void setup() 
 {
 lcd.init();
 dhtInt.begin();
 dhtExt.begin();
 pinMode (pinBoutonPlus,INPUT);
 pinMode (pinBoutonMoins,INPUT);
 pinMode (pinBoutonValidation,INPUT);
 pinMode (pinBoutonAnnulation,INPUT);
 pinMode (pinPotentio,INPUT);
 pinMode (pinRelai,OUTPUT);
 lcd.clear();
 lcd.setBacklight(1);
 }

void loop() 
{ 
  boutonPlus = digitalRead (pinBoutonPlus);
  boutonMoins = digitalRead (pinBoutonMoins);
  boutonValidation = digitalRead (pinBoutonValidation);
  boutonAnnulation = digitalRead (pinBoutonAnnulation);
  boutonPotentio = map(analogRead (pinPotentio),3,1009,-10,100);
  boutonDelai=map(analogRead (pinPotentio),3,1009,0,60);
  tempsActuel=millis()/60000;
  collecteDonnee();
 
   if (fenetre >40 || fenetre <0)
   {
    fenetre = 0; 
    menu = 0;
   }
  
   if(boutonPlus >0)
   {
   fenetre = (menu ++)*10;
   delay(200);
   }
  if(boutonMoins >0 )
   {
   fenetre = (menu --)*10;
   delay(200);
    }
  if(boutonValidation >0 )
    {
   fenetre ++;
   delay(200);
    }
  if(boutonAnnulation >0 )
   {
    fenetre == 0; menu == 0;
   }
 

switch (fenetre)
  {
    case 0 :
lcd.clear();  
lcd.home();
lcd.print("temps :");
lcd.print(tempsActuel);
lcd.print("min");
lcd.setCursor(0,1);
lcd.print("TC ");
lcd.print(temperatureInt);
lcd.print(" Hu ");
lcd.print(humiditeInt);
   break;
   
   case 10 :
lcd.clear();
lcd.home();
lcd.print("Humidite:");
lcd.print(humiditeInt);
lcd.setCursor(0,1);
lcd.print("Regle :");
lcd.print(humiditeVoulu);
   break;
   case 11 :
lcd.clear();
lcd.home();
lcd.print("Humidite:");
lcd.print(humiditeInt);
lcd.setCursor(0,1);
lcd.print("Voulu :");
lcd.print(boutonPotentio);
humiditeVoulu = boutonPotentio;
   break;  
   case 12 :
lcd.clear();
lcd.home();
lcd.print("Valide");
   break;  
   case 13 :
fenetre = 10;
   break;

   case 20 :
lcd.clear();
lcd.home();
lcd.print("Temperatu:");
lcd.print(temperatureInt);
lcd.setCursor(0,1);
lcd.print("Regle :");
lcd.print(temperatureVoulu);
   break;
   case 21 :
lcd.clear();
lcd.home();
lcd.print("Temperatu:");
lcd.print(temperatureInt);
lcd.setCursor(0,1);
lcd.print("Voulu :");
lcd.print(boutonPotentio);
temperatureVoulu=boutonPotentio;
   break;
   case 22 :
lcd.clear();
lcd.home();
lcd.print("Valide");
  break;  
  case 23 :
fenetre = 20;
   break;
   case 30 :
lcd.clear();
lcd.home();
lcd.print("Delai Mini :");
lcd.setCursor(0,1);
lcd.print(delaiMin);
lcd.print("Min");
   break;
   case 31 :
lcd.clear();
lcd.home();
lcd.print("Delai Voulu:");
lcd.setCursor(0,1);
lcd.print(boutonDelai);
delaiMin = boutonDelai;
lcd.print("Min");
  break;
  case 32 :
fenetre = 30;
  break;
  
  case 40 :
lcd.clear();
lcd.home();
lcd.print("TC voul:");
lcd.print(temperatureVoulu);
lcd.setCursor(0,1);
lcd.print("Hu voul:");
lcd.print(humiditeVoulu);
  break;
   }
 activation();
}

void collecteDonnee()
{
humiditeInt = dhtInt.readHumidity();
temperatureInt = dhtInt.readTemperature();
 return;
}
void activation()
{
  if (temperatureVoulu==0 && humiditeVoulu==0)
  {
  digitalWrite(pinRelai,LOW);
  }
  else if (humiditeInt>humiditeVoulu || temperatureInt<temperatureVoulu&&temperatureVoulu!=0 && humiditeVoulu!=0)
  {
   digitalWrite(pinRelai,HIGH);
  }
  else 
  {
  digitalWrite(pinRelai,LOW);
  }
}

A priori tu fait dans ta boucle infinie "loop" l'effacement de ton LCD, puis ton affichage complet.
Pourquoi ne pas faire l'affichage uniquement lorsque quelque chose change dans les données à affiché ?

1 Like

Bonjour,
N'efface pas l'écran à chaque fois.
Pour effacer le reste de la ligne qui était affichée avant, affiche quelques espaces en fin de ligne

par exemple:

    case 0 :
lcd.home();
lcd.print("temps :");
lcd.print(tempsActuel);
lcd.print("min");
lcd.print("   ");

lcd.setCursor(0,1);
lcd.print("TC ");
lcd.print(temperatureInt);
lcd.print(" Hu ");
lcd.print(humiditeInt);
lcd.print("   ");

1 Like

Bonjour @monololo !
Bon, je répète ce qu'ont dit @kamill et @terwal, mais j'ai eu le même problème avec mon écran LCD à un moment et cela venait du rafraîchissement de l'écran avec lcd.clear() qui était trop fréquent. Le mieux c'est de faire ce qu'a conseillé @kamill, c'est à dire d’effacer ce qui reste de la ligne précédente avec des espaces. Cette technique fonctionne très bien !

Cordialement
Pandaroux007

1 Like

Merci je teste cette solution merci

J'ai testé la solution qui a arrêté le scintillement mais les écritures finissent par se chevaucher. La solution de @terwal parait plus approprié finalement.
Il faudrait que je mette un délai sur l'affichage. Je vais chercher de mon coté. Mais je suis preneur de piste.
Comment fait on appel au switch ? On peut l'inclure dans une fonction ?

Mets ton code.
Si ça se chevauche c'est que tu n'as pas mis assez d'espaces à la fin de la ligne pour effacer la ligne précédente.
Cette méthode n'exclue pas ce que suggère @terwal, ça ne sert à rien d'afficher si rien n'a changé.

Tu l'utilises déjà dans ton programme. On peut toujours l'inclure dans une fonction, mais pourquoi faire?

effectivement avec des espaces c'est mieux.

c'était plus par curiosité. J'ai fait des modifs

#include <LiquidCrystal_I2C.h> //Gestion de l'afficheur LCD
#include <DHT.h>
const int typeDeDHT = DHT22;
const int pinCapteurint = 3;
const int pinCapteurext = 2;
DHT dhtInt(pinCapteurint, typeDeDHT);
DHT dhtExt(pinCapteurext, typeDeDHT);
#define pinBoutonPlus 5
#define pinBoutonMoins 6
#define pinBoutonValidation 7
#define pinBoutonAnnulation 8
#define pinRelai 10
#define pinPotentio A2

char boutonPlus = 0;
char boutonMoins = 0;
char boutonValidation = 0;
char boutonAnnulation = 0;
int boutonPotentio;
int boutonDelai;
float temperatureInt = 0;
float humiditeInt = 0;
int temperatureVoulu = 0;
int humiditeVoulu = 0;
unsigned int delaiMin = 10;
char valeurPotentio;
unsigned long tempsActuel = 0;
int fenetre = 0;
int menu = 0;
boolean relai = LOW;
unsigned long temps = 0;
unsigned long tempsPrecedent = 0;
LiquidCrystal_I2C lcd(0x27, 16, 2);

 
 void setup() {
 Serial.begin(9600);
 lcd.init();
 dhtInt.begin();
 dhtExt.begin();
 pinMode (pinBoutonPlus,INPUT);
 pinMode (pinBoutonMoins,INPUT);
 pinMode (pinBoutonValidation,INPUT);
 pinMode (pinBoutonAnnulation,INPUT);
 pinMode (pinPotentio,INPUT);
 pinMode (pinRelai,OUTPUT);
 lcd.clear();
lcd.setBacklight(1);

}

void loop() { 
  
  boutonPlus = digitalRead (pinBoutonPlus);
  boutonMoins = digitalRead (pinBoutonMoins);
  boutonValidation = digitalRead (pinBoutonValidation);
  boutonAnnulation = digitalRead (pinBoutonAnnulation);
  boutonPotentio = map(analogRead (pinPotentio),3,1009,-10,100);
  boutonDelai=map(analogRead (pinPotentio),3,1009,0,60);
  tempsActuel=millis()/60000;
  collecteDonnee();
  temps = millis();
 
if (fenetre >40 || fenetre <0)
  {fenetre = 0; 
  menu = 0;
  delay (200);
  }

 if(boutonPlus >0 )
  {fenetre = (menu ++)*10;
   delay (200);
  }
 if(boutonMoins >0 )
  {fenetre = (menu --)*10;
   delay (200);
  }
 if(boutonValidation >0 )
  {fenetre ++;
   delay (200);
  }
   if(boutonAnnulation >0 )
  {fenetre == 0; menu == 0;
  }
    Menu();
  }

void Menu () 
{
 switch (fenetre)
   {
    case 0 :
  lcd.home();
 lcd.print("temps :");
 lcd.print(tempsActuel);
 lcd.print("min");
 lcd.setCursor(0,1);
 lcd.print("TC ");
 lcd.print(temperatureInt);
 lcd.print(" Hu ");
 lcd.print(humiditeInt);
 lcd.print("            "); 
   break;
   
   case 10 :
  lcd.home();
 lcd.print("Humidite:");
 lcd.print(humiditeInt);
 lcd.setCursor(0,1);
 lcd.print("Regle :");
 lcd.print(humiditeVoulu);
 lcd.print("            "); 
  break;
  case 11 :
 lcd.home();
 lcd.print("Humidite:");
 lcd.print(humiditeInt);
 lcd.setCursor(0,1);
 lcd.print("Voulu :");
 lcd.print(boutonPotentio);
 humiditeVoulu = boutonPotentio;
 lcd.print("            "); 
  break;  
  case 12 :
 lcd.home();
 lcd.print("Valide");
 lcd.print("            "); 
  break;  
  case 13 :
 fenetre = 10;
  break;

  case 20 :
 lcd.home();
 lcd.print("Temperatu:");
 lcd.print(temperatureInt);
 lcd.setCursor(0,1);
 lcd.print("Regle :");
 lcd.print(temperatureVoulu);
 lcd.print("            "); 
  break;
  case 21 :
 lcd.home();
 lcd.print("Temperatu:");
 lcd.print(temperatureInt);
 lcd.setCursor(0,1);
 lcd.print("Voulu :");
 lcd.print(boutonPotentio);
 temperatureVoulu=boutonPotentio;
 lcd.print("            "); 
  break;
  case 22 :
 lcd.home();
 lcd.print("Valide");
 lcd.print("            "); 
  break;  
  case 23 :
 fenetre = 20;
  break;
   case 30 :
 lcd.home();
 lcd.print("Delai Mini :");
 lcd.setCursor(0,1);
 lcd.print(delaiMin);
 lcd.print("Min");
 lcd.print("            "); 
  break;
  case 31 :
 lcd.home();
 lcd.print("Delai Voulu:");
 lcd.setCursor(0,1);
 lcd.print(boutonDelai);
 delaiMin = boutonDelai;
 lcd.print("Min");
 lcd.print("            "); 
  break;
  case 32 :
 fenetre = 30;
  break;
  
  case 40 :
 lcd.home();
 lcd.print("TC voul:");
 lcd.print(temperatureVoulu);
 lcd.setCursor(0,1);
 lcd.print("Hu voul:");
 lcd.print(humiditeVoulu);
 lcd.print("            "); 
  break;
    }
 activation();
 }
 void collecteDonnee()
 {
 humiditeInt = dhtInt.readHumidity();
 temperatureInt = dhtInt.readTemperature();
 return;
 }
void activation()
{
  if (temperatureVoulu==0 && humiditeVoulu==0)
{digitalWrite(pinRelai,LOW);
}
else if (humiditeInt>humiditeVoulu || temperatureInt<temperatureVoulu&&temperatureVoulu!=0 && humiditeVoulu!=0)
{digitalWrite(pinRelai,HIGH);
 
  }
else {
digitalWrite(pinRelai,LOW);
}}

Pour le coup mon code est stable et fonctionne parfaitement

Merci pour vos conseils.
Après réflexion je voudrais ajouter un bout de code pour que l'écran s'éteigne tout seul au bout d'un certain temps. Je ne sais pas trop où le mettre pour ne pas faire bugger le programme.

Comme tu utilise une fonction pour ton affichage, tu peux le mettre au moment ou tu appel cette fonction.
Le plus simple étant d'affecter une variable avec la fonction "millis" au endroit ou tu veux démarrer ton chronos et tu mets ta fonction "menu" dans un "if" qui l'appel uniquement si tu n'a pas dépasser le temps d'inactivité.

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