Affichage sur oled

Bonjour,

En me basant sur pas mal d’exemples et de littérature, j’ai écris un petit programme pour la gestion d’un arrosage automatique sur base d’un Arduino Uno, un afficheur Oled, un module RTC DS3231 et des relais ‘'(3 relais en “byte PinSorties)

Le but commander les relais à des heures différentes contenues dans un tableau “TabEvt”.

L’heure s’affiche correctement.

La commandes des relais aux heures prévues fonctionne correctement, mais je ne parviens pas à afficher quelle sortie (relais ) est active ligne “ display.print(PinSorties[i]);

Avez-vous une idée ?

Merci

#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// OLED config
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

 byte i;

RTC_DS3231 rtc;

  // Variables de la plage horaire multiples
  int TabEvt [3][4] =
            {
              {12,3,12,5},// 12h00 - 12h14 voie 1 vert
              {12,6,12,8},// 12h15 - 12h25 voie 2 bleu
              {12,9,12,117},// 12h26 - 12h36 voie 3 rouge
              
            };
            byte PinSorties [3] = {8, 9, 10};
           
            

void setup() {
   
  // initialisation pour 3 relais en D8,D9 et D10
  for ( i = 0; i < 3; i++ ) {pinMode(PinSorties[i], OUTPUT); digitalWrite (PinSorties[i], LOW);}

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adresse I2C 0x3C
    for(;;);
  }
  
  if (!rtc.begin()) {
    for(;;);
  }
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Décommenter pour régler l'heure
}

void loop() {
  DateTime now = rtc.now(); // Lecture de l'heure actuelle

  
  // -- logique de commande pour relais multiples ----
  // Rechercher si heure actuelle est dans dans la ou les plages horaires 
        for ( i = 0; i < 3; i++ ) { 
          if (now.hour() == TabEvt [i][0] && now.minute() == TabEvt [i][1]) { // si H et Min spnt dans la plage horaire de la pos1 du tableau
             digitalWrite (PinSorties[i], HIGH);
                
           }
          if (now.hour() == TabEvt [i][2] && now.minute() == TabEvt [i][3]) {               
              digitalWrite (PinSorties[i], LOW);
          }
        }


  // --- Affichage OLED ---
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print("Heure: ");
  display.print(now.hour());
  display.print(":");
  if (now.minute() < 10) display.print("0"); // Affichage propre
  display.print(now.minute());
  display.print(":");
  if (now.second() < 10) display.print("0"); // Affichage propre
  display.print(now.second());

  
  display.setCursor(0, 20);
  display.print("Relais: ");
  display.setCursor(25, 20);
    if (PinSorties[i] == HIGH) {
        display.print(PinSorties[i]);
    }
    
    else {
      //display.print("OFF");
    }
  
  display.display();

  delay(1000); // Mise à jour chaque seconde
}

Vous testez le N° de la pin pas son état

Il faut faire un digitalRead pour avoir l’état

À court terme, votre horloge prendra du retard, car le traitement des lignes de la loop brûle quelques milli-secondes à chaque tour. Le délai devrait être un peu moindre que 1000. Pour tester la durée de traitement et obtenir une approximation de sa valeur, un Serial.print en début de loop et un autre tout juste avant delay, peuvent aider (moyennant que vous affichiez les heures dans votre moniteur série).

disons qu'il ne prendra pas de retard car l'heure vient de la RTC donc au pire on n'est pas complètement synchronisé sur le changement des secondes de la RTC.

Au lieu du délai on pourrait simplement lire en boucle l'heure de la RTC et si les secondes on changées, effectuer l'affichage

Je ne pense pas qu'un arrosage soit à la seconde près. On pourrait même travailler à la minute plutôt qu'à la seconde.

faut que je vous présente ma femme - si elle me demande d'aller arroser les fleurs et que je n'y vais pas tout de suite...

:slight_smile:

Bonjour , je reviens vers vous car je n’arrive toujours pas à lire et afficher le relais qui est actif,
Sur le conseils de J-M-L j’ai essayé un digitalRead mais je m’y prends sûrement très mal

Voici mon code modifié mais qui ne m’affiche hélas pas le relais actif :

#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// OLED config
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

 byte i;

RTC_DS3231 rtc;

  // Variables de la plage horaire multiples
  int TabEvt [3][4] =
            {
              {12,3,12,5},// 12h00 - 12h14 voie 1 vert
              {12,6,12,8},// 12h15 - 12h25 voie 2 bleu
              {12,9,12,117},// 12h26 - 12h36 voie 3 rouge
              
            };
            byte PinSorties [3] = {8, 9, 10};
           
            

void setup() {
   
  // initialisation pour 3 relais en D8,D9 et D10
  for ( i = 0; i < 3; i++ ) {pinMode(PinSorties[i], OUTPUT); digitalWrite (PinSorties[i], LOW);}

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adresse I2C 0x3C
    for(;;);
  }
  
  if (!rtc.begin()) {
    for(;;);
  }
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Décommenter pour régler l'heure
}

void loop() {
  DateTime now = rtc.now(); // Lecture de l'heure actuelle

  
  // -- logique de commande pour relais multiples ----
  // Rechercher si heure actuelle est dans dans la ou les plages horaires 
        for ( i = 0; i < 3; i++ ) { 
          if (now.hour() == TabEvt [i][0] && now.minute() == TabEvt [i][1]) { // si H et Min spnt dans la plage horaire de la pos1 du tableau
             digitalWrite (PinSorties[i], HIGH);
                
           }
          if (now.hour() == TabEvt [i][2] && now.minute() == TabEvt [i][3]) {               
              digitalWrite (PinSorties[i], LOW);
          }
        }


  // --- Affichage OLED ---
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print("Heure: ");
  display.print(now.hour());
  display.print(":");
  if (now.minute() < 10) display.print("0"); // Affichage propre
  display.print(now.minute());
  display.print(":");
  if (now.second() < 10) display.print("0"); // Affichage propre
  display.print(now.second());

  
  display.setCursor(0, 20);
  display.print("Relais: ");
  display.setCursor(25, 20);
  
    digitalRead(PinSorties[i]);
    if (PinSorties[i] == HIGH) {
        display.print(PinSorties[i]);
    }
    
    else {
      display.print("--");
    }
  
  display.display();

  delay(500); // Mise à jour chaque 1/2 seconde
}

je n'ai pas décortiqué tout le code, mais je vois ce truc : ce n'est pas

    digitalRead(PinSorties[i]);
    if (PinSorties[i] == HIGH) { ...

qu'il faut faire, mais

    if (digitalRead(PinSorties[i]) == HIGH) { ...

Petit retour après quelques semaines d’absence sur mon projet que je résume :

Arrosage automatique via 6 relais + 1 1switch qui commande un autre relais pour un mode manuel le tout piloté par un arduino Mega associé à une RTC DS3231 et un écran oled.

Les relais en mode auto sont commutés aux heures prescrites et le relais pour le mode manuel est bien commandé, l’affichage de l’heure est ok, ainsi que l’affichage du mode auto/manuel sont également ok, par contre je ne parviens pas à afficher la voie active correspondant au relais

#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
RTC_DS3231 rtc;

// display config
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

  const int buttonPin = 10;  // défini entrée switch Mode Manuel en D3
  const int relay1Pin = 3; // Pin out relais 1 pour le mode manuel

  int buttonState = 0;  // variable pour lire état status switch définie sur 0


 byte i;



  // Variables de la plage horaire multiples
  int TabEvt [6][4] =
            {
              {23,17,23,18},// 22h00 - 22h14 voie 1 vert
              {23,19,23,20},// 22h15 - 22h25 voie 2 bleu
              {23,21,23,22},// 22h26 - 22h36 voie 3 rouge
              {23,23,23,24},
              {23,25,23,26},
              {23,27,23,28},
              
            };
              
          byte PinSorties [6] = {4, 5, 6, 7, 8, 9};

           
            

void setup() {
  Serial.begin (225200);


    pinMode(buttonPin, INPUT);// initialize the switch pin as an input en D3, R 1K entre D3 et +5v , autre côté du switch à GND
    pinMode(3,OUTPUT); // defini D8 pour sortie voie 1
   
  // initialisation pour 6 relais en D4,D5,D6,D7,D8,D9
  for ( i = 0; i < 6; i++ ) {pinMode(PinSorties[i], OUTPUT); digitalWrite (PinSorties[i], LOW);}

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adresse I2C 0x3C
    for(;;);
  }
  
  if (!rtc.begin()) {
    for(;;);
  }
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Décommenter pour régler l'heure
}

void loop() {
  DateTime now = rtc.now(); // Lecture de l'heure actuelle

  // --- Affichage display ---
            display.clearDisplay();
            display.setTextSize(2);
            display.setTextColor(WHITE);
            display.setCursor(10,0);
            //display.print("Heure: ");
            display.print(now.hour());
            display.print(":");
          if (now.minute() < 10) display.print("0"); // Affichage propre
            display.print(now.minute());
            display.print(":");
          if (now.second() < 10) display.print("0"); // Affichage propre
            display.print(now.second());

  // logique de commande pour switch mode manuel
    buttonState = digitalRead(buttonPin);// lit valeur état du switch en D5    
    
    if (buttonState == HIGH ) // si D10=high on est en mode MAN sinon on reste en AUTO
    
    {  
      
       display.setCursor(2, 50);
              display.print("EV MANUEL");
              digitalWrite(3,HIGH); //relais en D3 est actif 
              }
    else                     // dans le cas contraire D3 est LOW et on est en mode auto
     { 
       display.setCursor(2, 50);
       display.print("MODE AUTO");
       digitalWrite(3,LOW); //relais en D9 est inactif
       }

  
  // -- logique de commande pour relais multiples ----
  // Rechercher si heure actuelle est dans dans la ou les plages horaires 
        for ( i = 0; i < 6; i++ ) { 
          if (now.hour() == TabEvt [i][0] && now.minute() == TabEvt [i][1]) { // si H et Min spnt dans la plage horaire de la pos1 du tableau.
              digitalWrite (PinSorties[i], HIGH);
          }
          if (now.hour() == TabEvt [i][2] && now.minute() == TabEvt [i][3]) {               
              digitalWrite (PinSorties[i], LOW);
          }
        }
                 
                      
                          
             //digitalRead(PinSorties[i]);

              display.setCursor(2, 24);
              display.print("Voie:");
              display.setCursor(52, 24);

              if (digitalRead(PinSorties[i]) == HIGH) {
                //Serial.println (i);
                display.print(i);
                              } 
              //if (digitalRead(PinSorties[i]) == LOW) { 
                    //display.print("--");
                 // }   

              
                else {
                 display.setCursor(62, 24); 
                display.print("-");
                //display.display();
                //}
                
           }
          
        

  
  display.display();

  delay(500); // Mise à jour chaque 1/2sec
}