Affichage LCD avec fonction "FOR"

Bonjour à tous,

Je souhaite avoir l'affichage d'une valeur sur le lcd et que le positionnement de cette valeur soit différent en fonction de cette valeur
En concret, le programme détecte une fuite d'eau par zone d'arrosage : Par exemple,
si la fuite est sur la zone 1, l'affichage du " 1 " doit se positionner sur le 10ème curseur de la ligne N° 3,
si la fuite est sur la zone 2, l'affichage du " 1 " doit se positionner sur le 11ème curseur de la ligne N° 3,
si la fuite est sur la zone 3, l'affichage du " 1 " doit se positionner sur le 12ème curseur de la ligne N° 3,
ainsi de suite..
Ci dessous la partie du code qui me pose problème

        case STOP:
          const int zoneIndex = &zone - zones + 1;
          lcd.setCursor(0, 2);
          lcd.print("Fuite Zone  ");       // Affiche un avertissement de fuite
          lcd.print(zoneIndex);  // affiche numéro de zone en déplaçant le curseur en fonction du N° de la zone
          if (tempsActuel - zone.tempsDebutFerme >= delaiTempsFermElectrovanne){
              digitalWrite(brocheElectrovanneFerm, HIGH);}

Ci dessous l'intégralité du code

#define MY_GATEWAY_SERIAL
#include <MySensors.h>

//Definition des NODES: ou NOEUD
#define NODE_ID_FUITE_ZONE1         1
#define NODE_ID_FUITE_TEXTE         4
#define NODE_ID_FUITE_SELECTOR         5

//https://www.mysensors.org/download/serial_api_20
// pour une node fuite d'eau il faut utiliser V_TRIPPED ou V_ARMED
MyMessage msgFuiteZone1(NODE_ID_FUITE_ZONE1, V_TRIPPED);
MyMessage msgFuiteTexte(NODE_ID_FUITE_TEXTE, V_TEXT);
MyMessage msgFuiteSelector(NODE_ID_FUITE_SELECTOR, V_PERCENTAGE);

#include <Wire.h>               // Bibliothèque pour la communication I2C
#include <LiquidCrystal_I2C.h>  // Bibliothèque pour le contrôle de l'écran LCD en mode I2C


LiquidCrystal_I2C lcd(0x27, 20, 4);  // Adresse I2C de l'écran LCD 20x4


const int brocheDebit = 2;         // Broche de la sonde de débit d'eau
const int brocheElectrovanneOuv = 14;  // Broche pour contrôler l'électrovanne ouverte
const int brocheElectrovanneFerm = 15;  // Broche pour contrôler l'électrovanne fermée
const int brocheBouton = 16;        // Broche du bouton-poussoir pour remise à zéro

unsigned int compteImpulsions = 0;
float debitInstantane = 0.0;
float totalLitres = 0.0;  // Changement d'unité de litres à mètres cubes
unsigned long tempsPrecedent = 0;
const long intervalle = 500;                            // Intervalle d'échantillonnage en millisecondes
const unsigned long dureeControleFuite = 1000;  // Durée de controle d'une fuite éventuelle en millisecondes
const unsigned long delaiTempsOuvElectrovanne = 10000;  // Délai du tempds d'ouverture de l'électrovanne en millisecondes
const unsigned long delaiTempsFermElectrovanne = 10000;  // Délai du temps de fermeture de l'électrovanne en millisecondes
unsigned long tempsOuvert = 0;

enum Etat { REPOS, 
            OUVERT,  
            ACTIF,
            STOP,
            FERMER
            };

// tous les éléments contenus dans la structure seront identifiés par un . précédant le nom de l'élément à rechercher
//par exemple, pour identifier le "seuilDebitCoupe", on inscrit "digitalRead(zone.seuilDebitCoupe)" 
struct SZone {            
  const byte broche;    // N° de la broche pour information de la zone d'arrosage
  const float seuilDebitCoupe;  // Débit maxi autorisé
  Etat etat;                    //
  unsigned long tempsDebutDebit;
  unsigned long tempsDebutEtat;
  unsigned long tempsDebutOuvre;
  unsigned long tempsDebutFerme;
  bool emis;
};

SZone zones[] = {
  {3, 1.1, REPOS, 0, 0, 0, 0, false},  // N° broche , Débit maxi, Etat etat , temps début débit, temps début Etat,
  {4, 2.1, REPOS, 0, 0, 0, 0, false},  // temps debut Ouvre, temps début Ferme, message émis
  {5, 3.1, REPOS, 0, 0, 0, 0, false},
  {6, 4.1, REPOS, 0, 0, 0, 0, false},
  {7, 5.1, REPOS, 0, 0, 0, 0, false},
  {8, 6.1, REPOS, 0, 0, 0, 0, false}
};

void fermerVanne()
{
digitalWrite(brocheElectrovanneOuv, HIGH);
digitalWrite(brocheElectrovanneFerm, HIGH); 
  Etat etat = REPOS;
}

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.begin(20, 4);  // Initialisation de l'écran LCD 20x4
  //lcd.print("Debit: 0.0 m3/h");
  //lcd.setCursor(0, 1);
  //lcd.print("Total: 0.0 m3");
  fermerVanne();
   Serial.begin(115200);
   // Serial.print("Debit: 0.0 m3/h");
   Serial.print(debitInstantane, 0);

  pinMode(brocheDebit, INPUT);
  pinMode(brocheElectrovanneOuv, OUTPUT);
  pinMode(brocheElectrovanneFerm, OUTPUT);
  pinMode(brocheBouton, INPUT_PULLUP);
  
  attachInterrupt(digitalPinToInterrupt(brocheDebit), compteurImpulsions, FALLING);
}

void loop() {
  unsigned long tempsActuel = millis();  // Obtient le temps actuel en millisecondes

if (tempsActuel - tempsPrecedent >= intervalle) {
    // calcul et affichage du débit
    noInterrupts();
    unsigned int compteurLocal = compteImpulsions;  // Conversion du nombre d'impulsions en débit instantané en Litres par minute
    compteImpulsions = 0;
    interrupts();
    tempsPrecedent = tempsActuel;

    float volume=compteurLocal/450.0;   // volume en litre
    debitInstantane=volume/intervalle*1000*60;  // débit en l/mn
    totalLitres += volume;

    lcd.clear();
    lcd.print("Debit: ");
    lcd.print(debitInstantane, 0);
    lcd.print(" L/mn");

    lcd.setCursor(0, 1);
    lcd.print("Total: ");
    lcd.print(totalLitres, 0);
    lcd.print(" L");
  }

  for (auto &zone : zones)  // effectue le traitement pour toutes les zones
  {

      switch (zone.etat) {
        case REPOS:
        if (digitalRead(zone.broche) == HIGH) {
            digitalWrite(brocheElectrovanneOuv, LOW);
            digitalWrite(brocheElectrovanneFerm, HIGH);
            zone.tempsDebutOuvre = tempsActuel;
          const int zoneArrosage = &zone - zones + 1;
          lcd.setCursor(0, 3);
          lcd.print("Arrosage Zone ");       // Affiche la zone d'arrosage
          lcd.print(zoneArrosage);  // affiche numéro de zone
          //lcd.scrollDisplayRight(zoneArrosage);
          const int zoneSerie = &zone - zones + 1;   // ligne essai monteur serie
          const int zoneBroche = zone.broche;
          Serial.print("Repos Ouvert  "); // affiche l'état de la zone.etat sur moniteur serie
          Serial.print(zoneSerie);   // affiche le N° de la zone sur moniteur serie
          Serial.println(zoneBroche);   // affiche le N° de la zone sur moniteur serie
          zone.etat = OUVERT;
        }
 
          break;
        case OUVERT:
        if (digitalRead(zone.broche) == HIGH) {
          const int zoneArrosage = &zone - zones + 1;
          lcd.setCursor(0, 3);
          lcd.print("Arrosage Zone ");       // Affiche la zone d'arrosage
          lcd.print(zoneArrosage);  // affiche numéro de zone
      
          if (tempsActuel - zone.tempsDebutOuvre >= delaiTempsOuvElectrovanne){
          digitalWrite(brocheElectrovanneOuv, HIGH);
         }
          if (debitInstantane > zone.seuilDebitCoupe) {
            zone.tempsDebutDebit = tempsActuel;
          const int zoneSerie = &zone - zones + 1;   // ligne essai monteur serie
          Serial.print("Ouvert Actif  ");  // affiche l'état de la zone.etat sur moniteur serie
          Serial.println(zoneSerie);   // affiche le N° de la zone sur moniteur serie 
            zone.etat = ACTIF;
          }
        }
       
        else {
             digitalWrite(brocheElectrovanneOuv, HIGH);
             digitalWrite(brocheElectrovanneFerm, LOW);
            zone.tempsDebutFerme = tempsActuel;
          const int zoneSerie = &zone - zones + 1;   // ligne essai monteur serie
          Serial.print("Ouvert Fermer  ");  // affiche l'état de la zone.etat sur moniteur serie
          Serial.println(zoneSerie);   // affiche le N° de la zone sur moniteur serie            Serial.println("Ouvert Fermer");
            zone.etat = FERMER;
            zone.tempsDebutEtat = tempsActuel;
          }
         
          break;
        case FERMER:
        

          if (tempsActuel - zone.tempsDebutFerme >= delaiTempsFermElectrovanne)
          {
              digitalWrite(brocheElectrovanneFerm, HIGH);
//          if (digitalRead(zone.broche) == HIGH) { 
          const int zoneSerie = &zone - zones + 1;   // ligne essai monteur serie
          Serial.print("Fermer Repos  ");  // affiche l'état de la zone.etat sur moniteur serie
          Serial.println(zoneSerie);   // affiche le N° de la zone sur moniteur serie              Serial.println("Fermer Repos");
              zone.etat = REPOS;
//          }
        }
           break;   

        case ACTIF:

          if (debitInstantane > zone.seuilDebitCoupe) {
            if (tempsActuel - zone.tempsDebutDebit >= dureeControleFuite) {
              digitalWrite(brocheElectrovanneOuv, HIGH);
              digitalWrite(brocheElectrovanneFerm, LOW);
              zone.tempsDebutFerme = tempsActuel;
          const int zoneSerie = &zone - zones + 1;   // ligne essai monteur serie
          Serial.print("Actif Stop  ");  // affiche l'état de la zone.etat sur moniteur serie
          Serial.println(zoneSerie);   // affiche le N° de la zone sur moniteur serie              Serial.println("Actif Stop");
              zone.etat = STOP;
              zone.tempsDebutEtat = tempsActuel;
             
            }
          }
          else {
          const int zoneArrosage = &zone - zones + 1;
          lcd.setCursor(0, 3);
          lcd.print("Arrosage Zone ");       // Affiche la zone d'arrosage
          lcd.print(zoneArrosage);  // affiche numéro de zone 
          const int zoneSerie = &zone - zones + 1;   // ligne essai monteur serie
          Serial.print("Actif Repos  ");  // affiche l'état de la zone.etat sur moniteur serie
          Serial.println(zoneSerie);   // affiche le N° de la zone sur moniteur serie          Serial.println("Actif Repos");
            zone.etat = REPOS;
            zone.tempsDebutEtat = tempsActuel;
           // zone.tempsDebutOuvre = tempsActuel;

          }
          break;

        case STOP:
          const int zoneIndex = &zone - zones + 1;
          lcd.setCursor(0, 2);
          lcd.print("Fuite Zone  ");       // Affiche un avertissement de fuite
          lcd.print(zoneIndex);  // affiche numéro de zone en déplaçant le curseur en fonction du N° de la zone
          if (tempsActuel - zone.tempsDebutFerme >= delaiTempsFermElectrovanne){
              digitalWrite(brocheElectrovanneFerm, HIGH);}

          // On ne signale l'erreur que si ça n'a pas déjà été fait
          if (zone.emis == false) {
            char messageFuite[] = "Fuite zone 0"; 
            messageFuite[11] += zoneIndex; 
            send(msgFuiteTexte.set(messageFuite));
            zone.emis = true;
          }
          if ((digitalRead(brocheBouton) == LOW) & (digitalRead(zone.broche) == HIGH)) {
            if (tempsActuel - zone.tempsDebutEtat >= 2000) {
          const int zoneSerie = &zone - zones + 1;   // ligne essai monteur serie
          Serial.print("Stop Repos  ");  // affiche l'état de la zone.etat sur moniteur serie
          Serial.println(zoneSerie);   // affiche le N° de la zone sur moniteur serie              Serial.println("Stop Repos");
              zone.etat = REPOS;
              zone.emis = false;
              lcd.setCursor(0, 0);
              lcd.print("                 ");  // Efface le texte "Fuite" lors du retour à l'état REPOS
              lcd.setCursor(0, 1);
              lcd.print("                 ");  // Efface le texte "Fuite" lors du retour à l'état REPOS
            }
          } else {
            zone.tempsDebutEtat = tempsActuel;
            zone.tempsDebutOuvre = tempsActuel; 
          }
          break;
      }
 // }  // if commande = high

  }  // for
}

  void compteurImpulsions() {
    compteImpulsions++;
  }
//Fonction de presentation a rajouter
void presentation()
{
  // Present locally attached sensors
  present(NODE_ID_FUITE_ZONE1, S_WATER_LEAK);
  present(NODE_ID_FUITE_TEXTE, S_INFO);
  present(NODE_ID_FUITE_SELECTOR, S_DIMMER);

}

ça a dégainé plus vite que prévu...!

J'ai oublié ma politesse !!

" Merci par avance de votre aide et conseil "

Il faut utiliser setCursor() pour positionner le texte où tu veux.

Bonsoir fdufnews

Je suis ok avec toi, mais là mon problème est le déplacement automatique du curseur en fonction de la zone, de telle façon que je devrais avoir " Fuite Zone 12 456 " si les zones 1; 2; 4; 5; et 6 qui sont en fuite
est-ce plus clair ?

Hello
LCD.setCursor(9+zone,3);
LCD.print("1");

Bonjour dfgh,

Sans être trop exigeant , puis-je avoir les explications de ta proposition ?

Comment l'intégrer dans cette partie de mon code ci dessous ?

        case STOP:
          const int zoneIndex = &zone - zones + 1;
          lcd.setCursor(0, 2);
          lcd.print("Fuite Zone  ");       // Affiche un avertissement de fuite
          lcd.print(zoneIndex);  // affiche numéro de zone en déplaçant le curseur en fonction du N° de la zone

C'est pour afficher zoneIndex au bon endroit donc il faut le placer avant de faire le print(zoneIndex);

          lcd.setCursor(0, 2);
          lcd.print("Fuite Zone");       // Affiche un avertissement de fuite
          lcd.setCursor(9+zoneIndex,2);
          lcd.print(zoneIndex);  // affiche numéro de zone en déplaçant le curseur en fonction du N° de la zone

Avec ce code cela fonctionne
Donc, si j'ai bien compris:
" 9+ " fait démarrer l'affichage après la dixième colonne
" zoneIndex " est la valeur que je souhaite afficher
" 2 " correspond au N° de la ligne du LCD

Merci

Bonjour !

Ce n'est pas exactement ça.
La fonction setCursor attend deux paramètres, respectivement la colonne et la ligne où placer le curseur.

Quand @dfgh fait

LCD.setCursor(9+zone,3);
LCD.print("1");

Il indique en gros "affiche un 1 à la colonne (9+l'index de la zone ou écrire - c'est une addition qui est faite ici) et à la ligne 3."

Dites moi si j'ai dit une bêtise :woozy_face:
Cordialement
Pandaroux007

Et bien la numérotation des lignes et des colonnes commence à zéro il me semble. Donc l'affichage va se faire à partir de la dixième colonne et sur la quatrième ligne de l'afficheur.

Mais c'est pas grave le principe est là.

hello les amis les lignes du lcd sont 0,1,2,3

oui effectivement, je visais la 4ème ligne de l'afficheur car le demandeur ciblait la ligne 3 .
nous ne parlions pas de la meme ligne.
mais dans sa proposition corrective, il a codé ligne 2 donc la 3ème ligne physique de l'afficheur :smiley:

Oups, désolé :woozy_face: J'avais pas vu...
Merci pour la remarque :wink:

Bonsoir
Merci pour vos explications, car avoir la proposition de solution, c'est très bien
Mais comprendre le code de la solution c'est encore mieux

Encore merci à tous
Amicalement

Bonsoir,
une petite question en marge de mon projet...
Je souhaiterai visualiser l'IDE arduino sur deux écrans, un pour voir le code et l'autre pour voir le moniteur série
Est-ce possible ?
Amicalement

C'était possible sur les versions antérieures à la V2.

Mais tu peux toujours utiliser une application de terminal tierce. Il faut seulement prendre la précaution de la fermer lorsque tu veux faire un téléchargement.

Bonsoir à tous,
J'espère que vous avez passé un très bon été
Je me permets de revenir sur ce sujet pour améliorer mes connaissances

lcd.setCursor(9+zoneIndex,2);

Si je souhaite faire afficher la valeur de " zoneIndex " sur différentes lignes et différentes colonnes en fonction de la zone
Dans le code ci dessus, je déplace de 1 à chaque fois que la zone évolue de 1
Mais puis-je par exemple faire afficher la première valeur de zoneIndex sur la ligne 2 et la colonne 4 , puis la deuxième valeur sur la ligne 3 et la colonne 6, et ainsi de suite sans aucune logique de positionnement ?
Vous allez vous dire que je suis un peu tordu ?
Merci en tout cas de votre collaboration

Bonjour à tous,
Sauf erreur de ma part, je n'ai pas eu de réponse à ma demande de programmation
Merci par avance de votre aide
Amicalement

Il suffit de faire un tableau contenant les numéros de lignes et de colonnes et de l'indexer avec le numéro de la zone.

Merci de ta réponse,
Manquant d'expérience, peux-tu me donner un exemple pour que je puisse comprendre comment et où positionner le tableau
J'apprends doucement....

Il y a même une solution simple qui exploite l'existant.
Tu as actuellement une structure qui décrit tes zones. Il suffit d'y ajouter 2 éléments supplémentaires.

Ensuite dans ton code tu fais

lcd.setCursor(zones[zoneIndex].colonne,zones[zoneIndex].ligne);