Code pour affichage info sur MAX7219

Bonjour à tous,

Je me suis lancé depuis un moment sur la construction d’un affichage dans mon salon, d’information provenant de ma box domotique (accessible en HTTP). L’affichage est basé sur un MAX7219. Hors j’ai crée mon code pas correctement, car basé essentiellement sur des delay, ce qui m’empêche aujourd’hui de rajouter du code pour d’autre élément que je souhaiterai rajouter. Je peux utiliser les millis, mais la librairie utilisée (MD_Parola) ne gérant pas les informations avec type de “compteur”, cela ne m’aide pas trop.

Mais voilà, je me casse la tête dessus, car j’ai besoin d’afficher des informations différentes toutes les X secondes récupérer via HTTP, avec des effets différents, mais j’ai vraiment du mal à comprendre la logique du fonctionnement des librairies MD_Parola pour cela.

Vous trouverez mon code (un peu sale je l’avoue) qui me sert aujourd’hui afin de comprendre le fonctionnement actuel.

Merci de votre aide pour quelques pistes, sachant que j’ai chercher sur mon amis Google, mais impossible de trouver un code qui correspond.

Code.ino (10 KB)

Tu devrais organiser ton programme avec des fonctions élémentaires, typiquement des fonctions pour lire les valeurs de tes capteurs sur ton serveur. Ça faciliterait la lecture.

Si ton problème est d'afficher les données à des intervalles de temps prédéfinis, tu devrais essayer la bibliothèque de gestion du temps écrite par Bricoleau, tu peux la trouver dans la section tutos du forum français.

Mais avant, crée ces fonctions pour y voir plus clair dans ton code. Ça t'aidera...

mais j'ai vraiment du mal à comprendre la logique du fonctionnement des librairies MD_Parola pour cela.

Sans question précise il va être difficile de trouver de l'aide.

@+

Je suis assez basique dans mon code, c'est à dire que je récupère, transforme et afficher les informations.
Hors dans les codes que je peux trouver, tout est traité en amont, dans le setup avec des variables, et je n'ai que if (P.displayAnimate())  {} dans le loop.

En exemple, le code ci-dessous qui pourrait correspondre, mais j'ai besoin d'afficher 3 choses différentes (Température, Consommation et heure) avec des temps d'affichage différents. Alors que le "void" spécifique, affiche la même chose uniquement mis à jour.

void getTime(char *psz)
{
  RTC.readTime();
  sprintf(szBuf, " %02d::%02d::%02d", (RTC.h%12), RTC.m, RTC.s);
}

void setup(void)
{
.......
P.displayText(szBuf, PA_CENTER, 50, 1500, PA_PRINT, PA_NO_EFFECT);
.........
}

void loop(void)
{
  if (P.displayAnimate())
  {
    getTime(szBuf);
    P.displayReset();
  }
}

En espérant être assez clair.

Ce que tu veux faire ressemble à une machine à états, qui lance des actions à des intervalles réguliers (lecture de la température, puis affichage). Cherche le tuto de J-M-L dans la section tutos du forum français, il a une bibliothèque qui devrait répondre à ton besoin

Bonjour,

Le sujet avance, le code arrive bientôt, cela pourra toujours être utile.

Et voilà le résultat. Voici l’utilisation :

  • Récupération des valeurs température et consommation sur le Jeedom pour affichage des informations.
  • Arrêt/Démarrage écran en fonction de la présence ou bouton
  • Intégration d’une sonde BMP280 pour remonter la valeur dans Jeedom
  • MAJ via OTA
  • Affichage de l’heure via NTPClient

Je reste bien sûr ouvert à toutes remarques/amélioration, surtout avec le niveau de novice en code.

//Déclaration des librairies
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

//******* OTA ********
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

//******* NTP ********
#include <NTPClient.h>

//Configuration MAX7219
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN    D6
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

//-------BMP----------
#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11 
#define BMP_CS 10

Adafruit_BMP280 bmp;

// ----NTP-----
WiFiClient espClient;
WiFiUDP ntpUDP;
int16_t utc = +2;
NTPClient timeClient(ntpUDP, "ntp.univ-lyon1.fr", utc*3600, 600000);

// ----WIFI-----
const char* ssid = "Wifi";
const char* password = "xxxxxxxx";

//Déclaration variables
HTTPClient http;
String jeedom_url = "http://192.168.1.xxx/core/api/jeeApi.php?apikey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&type=cmd&id=";
String jeedom_url_post = "http://192.168.1.xxx/core/api/jeeApi.php?plugin=virtual&apikey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&type=virtual&id=";
String id_temp = "322";
String id_conso = "1278";
String id_journuit = "406";
String id_prox = "1117";
String prox = "2";
String journuit = "1";
String temp = "";
String conso = "";
String unit_conso = "kW";
#define BUF_SIZE 75
char temperature[BUF_SIZE] = "%%%%%";
char consomm[BUF_SIZE] = "%%%%%";
char temps[BUF_SIZE] = "1";
uint8_t degC[] = { 6, 3, 3, 56, 68, 68, 68 }; // Deg C
uint8_t pts[] = { 5, 64, 0, 64, 0, 64 }; // 3 points
char szMesg[20] = "";

//BMP280
float pressure;
float hpascals;

//Gestion du temps
unsigned long previousMillisSensor = 0;
unsigned long previousMillisGeneral = 0;
const unsigned long TIME_SENSOR = 30000; //30 secondes
const unsigned long TIME_GENERAL = 300000; // 5 minutes

//Button
const int button = D3;
int buttonState;

//################# SETUP ########################################
void setup()
{
  Serial.begin(115200);
  ArduinoOTA.setHostname("MAX7219");
  P.begin();
  P.setIntensity(5);
  
  //Wifi
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(500);
  WiFi.begin(ssid, password);
  WiFi.hostname("ESP_Salon");
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println();
    Serial.println("Connecting..");
    P.print("Start.");
    delay(4000);
   }
   
   Serial.print("Connecting to ");
   Serial.println(ssid);
   Serial.println("WiFi connected");  
   Serial.print("IP address: ");
   Serial.println(WiFi.localIP()); 
   P.print("Wifi ok");
   delay(2500);
   timeClient.begin();
  
  //Display
  P.displayText(szMesg, PA_CENTER, 25, 5000, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
  P.addChar('

, degC);
  P.addChar(’%’, pts);
  delay(2500);
  P.displayClear();

// OTA

ArduinoOTA.onStart( {
    Serial.println(“Start”);
  });
  ArduinoOTA.onEnd( {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress((unsigned int progress, unsigned int total) {
    Serial.printf(“Progress: %u%%\r”, (progress / (total / 100)));
  });
  ArduinoOTA.onError((ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println(“Auth Failed”);
    else if (error == OTA_BEGIN_ERROR) Serial.println(“Begin Failed”);
    else if (error == OTA_CONNECT_ERROR) Serial.println(“Connect Failed”);
    else if (error == OTA_RECEIVE_ERROR) Serial.println(“Receive Failed”);
    else if (error == OTA_END_ERROR) Serial.println(“End Failed”);
  });
  ArduinoOTA.begin();
  bmp.begin();

// Déclaration bouton
pinMode(button, INPUT_PULLUP);

//MAJ NTP pour première
timeClient.update();
String TM=timeClient.getFormattedTime().substring(0,5);
TM.toCharArray(temps,50);
}

//#####################LOOP######################################
void loop()
{
buttonState = digitalRead(button);

unsigned long currentMillis = millis();

//----------------- GET PARAMETERS ---------------------
  if (currentMillis - previousMillisGeneral >= TIME_GENERAL) {
  previousMillisGeneral = currentMillis;

http.begin(jeedom_url+id_prox);
    int httpCode = http.GET();
    if (httpCode > 0) {
      prox = http.getString();
      http.end();
      delay(50);
      Serial.print("Promixité : ");
      Serial.println(prox);
    }

http.begin(jeedom_url+id_journuit);
    httpCode = http.GET();
    if (httpCode > 0) {
      journuit = http.getString();
      http.end();
      Serial.print("Jour / Nuit : ");
      Serial.println(journuit);
    }
   
    //Read data
  pressure = bmp.readPressure();
  hpascals = (pressure/100)+34;
  Serial.println(hpascals);

if (isnan(pressure)) {
      Serial.println(“BMP280 inaccessible!”);
  }
  else{
  String urlp = jeedom_url_post+“1194&value=”+hpascals;
  http.begin(urlp);  //Virtuel Pression
  httpCode = http.GET();
  http.end();
  Serial.println(urlp);
  }
   
  }

static uint8_t  display = 0;

if (journuit==“1”){
  P.setIntensity(3);
}
else {
  P.setIntensity(0);
}

if (prox==“0” || buttonState == LOW){
P.displayClear();
Serial.print(“Pause”);
delay(60000);
  }
else
  {

// ------------ GET INFO CAPTEUR -------------------------------

if (currentMillis - previousMillisSensor >= TIME_SENSOR) {
  previousMillisSensor = currentMillis;

http.begin(jeedom_url+id_temp);
    int httpCode = http.GET();
    if (httpCode > 0) {
      String temp = http.getString()+"$";
      temp.toCharArray(temperature,50);
      http.end();
      Serial.print("Température : ");
      Serial.println(temperature);
      delay(50);
    }
   
    http.begin(jeedom_url+id_conso);
    httpCode = http.GET();
    if (httpCode > 0) {
      String conso = http.getString()+unit_conso;
      conso.toCharArray(consomm,50);
      http.end();
      Serial.print("Consommation : ");
      Serial.println(consomm);
    }

timeClient.update();
    String TM=timeClient.getFormattedTime().substring(0,5);
    TM.toCharArray(temps,50);
    Serial.print("Horloge : ");
    Serial.println(temps);
  }
 
  if (P.displayAnimate())
  {
    switch(display)
    {
      case 0: //Temp
      P.setTextEffect(0, PA_OPENING, PA_CLOSING);
      P.setPause(10000);
      display++;
      strcpy(szMesg,temperature);
      break;
     
      case 1: //Conso
      P.setTextEffect(0, PA_GROW_UP, PA_GROW_DOWN);
      P.setPause(5000);
      display++;
      strcpy(szMesg,consomm);
      break;

case 2: //Temp
      P.setTextEffect(0, PA_OPENING, PA_CLOSING);
      P.setPause(10000);
      display++;
      strcpy(szMesg,temperature);
      break;
     
      default:
      P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
      P.setPause(5000);
      display = 0;
      strcpy(szMesg,temps);
      break;
    }
    P.displayReset();
  }
} //prox
ArduinoOTA.handle();
}

Un projet fini placé dans le forum général sera vite perdu dans la masse des topics.
Si tu finalise avec un schéma (un vrai schéma, pas un fritzing ou une photo de breadboard STP), tu pourrais faire un topic dans "Réalisations et projets finis", avec un titre bien explicite.

@+

@hbachetti : Bonne idée. as-tu un bon outil pour faire un "vrai" schéma ?

J'utilise KICAD.
Il tourne sous LINUX et Windows.

@+