Afficheur LCD : bonnes pratiques de code

nonjour,

Je bricole avec un arduino nano et un afficheur LCD. Branchement réalisé comme https://circuitdigest.com/microcontroller-projects/arduino-interrupt-tutorial-with-examples J'ai juste ajouté des condensateurs parce que sinon c'était le carnaval des rebonds :frowning:

Je rajouterai un capteur de T et de lumière par la suite mais là, c'est la partie affichage que je travaille...

L'afficheur LCD 20x4 qui sert à afficher les mesures. Un des poussoirs provoque une interruption pour faire les mesures et calculs nécessaires puis l'affichage est effectué dans le loop()

Je n'ai pas mis de delay() dans le loop() pour que l'affichage soit le plus instantané possible mais alors il y a un clignotement si je rafraîchi à chaque boucle. Logique...

Ce que j'ai fait :

  • ajout d'une variable globale
       volatile bool rafraichir = false;
  • dans l'interruption :
       rafraichir = true;
  • dans le loop() :
  if (rafraichir) {
    rafraichir = false;
    lcd.clear();   
   << tout le code d'affichage>>

Ma question :
Il n'est pas forcement nécessaire de rafraichir 20x4 = 80 caractères, la plupart du temps, ce sera seulement les valeurs numériques, par exemple si j'affiche la première fois

Voici les mesures
  capteur 1 : 42
  capteur 2 : 1664

Il n'y a que les chiffres qu'il faudra changer. Je suppose que je clignotement sera moins perceptible

Avez-vous un exemple de code (j'aime bien apprendre en m'inspirant du code des autres) permettant d'optimiser l'affichage ?

le mieux effectivement c'est de ne pas faire de clear() et de ne repeindre que ce qui est nécessaire. il faut donc se souvenir de l'ancienne valeur ou ancien texte affiché et si changement effacer (afficher des espaces dans le champ dédié) si la longueur peut être plus courte puis écrire la nouvelle valeur et s'en souvenir. Si la longueur est toujours la même vous pouvez vous passer de l'écriture des espace et directement écrire par dessus

Merci...

pour la clarté du code, j'ai remplacé mes morceaux de chaines dans tous les sens par une déclaration globale :

char LCD[4][21];  // c'est bien 21 qu'il faut mettre pour le \0 final ?

et puis des manipulations de cette variable avec des choses comme :

  strcpy(LCD[0], "du blabla ligne 0");
  String S = "T  = ";
  S.concat(String(fl));
  S.concat(" s");
  S.replace('.',',');
  strcpy(LCD[1], S.c_str());

et une routine appelée par le loop si nécessaire :

void afficheLCD() {
       lcd.clear();   
       lcd.setCursor(0,0);
       lcd.print(LCD[0]);
       lcd.setCursor(0,1);
       lcd.print(LCD[1]);
       lcd.setCursor(0,2);
       lcd.print(LCD[2]);
       lcd.setCursor(0,3);
       lcd.print(LCD[3]);
}

Il faudrait donc plutôt deux déclarations

char LCD_new[4][21];
char LCD_old[4][21];

et faire des comparaisons puis passer comme paramètres à afficheLCD() (qu'il faudra bien sûr modifier) les parties à réécrire ?

Je vais me pencher sur les fonctions de chaînes de caractères :frowning: je suis plus à l'aise avec les nombre :wink:

Faire du buffering intermédiaire pourquoi pas mais dans l’absolu ça mange de la mémoire pour rien

Mettez vos données à afficher dans une structure sous forme texte ou numérique comme ça convient au bon déroulement du programme et vous créez deux exemplaires un pour ce qui est affiché et un pour les traitements en cours
En fin de loop vous comparez les deux structures et si elles sont différentes alors vous mettez à jour le ou les champs appropriés puis vous copiez la structure en cours dans la structure écran et vous repartez pour un tour de loop

Comme cela pas d’allocation mémoire multiple et l’affichage se fait à un endroit centralisé ce qui rend la maintenance aisée

je trouve comme le dit @J-M-L que la comparaison est la meilleure solution.
Pour ma part je crée des variables d'affichage genre lcdPosX a laquelle j'associe le contenu de la variable PosX, de cette façon si le contenu de lcdPosX et de PosX est identique je ne rafraichi pas.
Sinon un lcd.setCursor a l'endroit de positionnement de l'affichage, suivi d'un lcd.print (" ") pour effacer puis je reinscris la valeur.
J'ai essayer avec des "void" sur des critères de compteur ou autre, jamais convaincant.