Mise à jour sans latence entre serveur et matrice MAX7912

Bonjour la communauté,

Je suis coincé entre la mise à jour de la page web du serveur et les matrices MAX7219. Le code suivant me donne un retard de 7sec environs sur la page du serveur quand aux matrices elles se mettent bien à jour. Pour tenter de comprendre, j'enlève les matrices et le serveur se met à jour toutes les secondes donc mon code sans matrice, ok. Mise à jour du serveur + Matrice, j'ai une latence du serveur et je n'arrive pas à comprendre ce que je "loop" (pour ajouter un grain de lol). Serveur sans matrices, ok. Serveur avec matrice TKO !
Un amateur super expérimenté mettant le doigt sur ma problématique ? je peux être plus clair si je ne l'ai été.
edit: En relisant le code ici, je m'aperçois que je fais appelle aux matrices intégrées de la carte. Ce dont je n'ai pas pris le temps de faire évolué dans le code. Merci de ne pas en prendre compte.

#include <MD_Parola.h>
#include <MD_MAX72XX.h>
#include <SPI.h>
#include <WiFiS3.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <DHT.h>
#include <FontCollection.h>
#include "arduino_secrets.h"
#include <time.h>
#include <Arduino_LED_Matrix.h>
#include <ArduinoJson.h>

#define DHTPIN 2
#define DHTTYPE DHT11

const char* hostname = "MonArduinoR4";
int status = WL_IDLE_STATUS;

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 16
#define CS_PIN 10
#define DATA_PIN 11
#define CLK_PIN 13

MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600 * 1); // CET (UTC+1)
ArduinoLEDMatrix ledMatrix;

DHT dht(DHTPIN, DHTTYPE);
unsigned long previousMatrixMillis = 0;
const long matrixInterval = 2000; // 2 secondes pour les matrices

unsigned long previousServerMillis = 0;
const long serverInterval = 1000; // 1 seconde pour le serveur

WiFiServer server(80);

void connectToWiFi() {
  Serial.print("Connexion au WiFi");
  WiFi.begin(SECRET_SSID, SECRET_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" Connexion réussie!");
  Serial.print("Adresse IP : ");
  Serial.println(WiFi.localIP());
}
void serveSensorData(WiFiClient &client) {
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  StaticJsonDocument<200> jsonDoc;

  jsonDoc["temperature"] = t;
  jsonDoc["humidity"] = h;
  jsonDoc["time"] = timeClient.getFormattedTime();

  String jsonData;
  serializeJson(jsonDoc, jsonData);

  Serial.println(jsonData); // Affiche les données JSON dans le moniteur série

  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: application/json");
  client.println("Connection: close");
  client.println();
  client.println(jsonData);
}

void serveHTML(WiFiClient &client) {
  client.print("HTTP/1.1 200 OK\r\n");
  client.print("Content-Type: text/html\r\n");
  client.print("Connection: close\r\n");
  client.print("\r\n");
  client.print("<!DOCTYPE HTML>");
  client.print("<html>");
  client.print("<head>");
  client.print("<meta charset=\"UTF-8\">");
  client.print("<title>Server Arduino R4</title>");
  client.print("<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css\">");
  client.print("<style>");
  client.print("body { font-family: Arial, sans-serif; background-color: #40E0D0; color: #333; text-align: center; margin: 0; padding: 0; }");
  client.print("h1 { background-color: #20B2AA; color: white; padding: 20px; margin: 0; }");
  client.print("p { font-size: 1.2em; }");
  client.print(".data-container { display: inline-block; background: white; padding: 20px; margin: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); transition: transform 0.3s ease-in-out; }");
  client.print(".data-container:hover { transform: scale(1.05); }");
  client.print(".data-container span { display: block; font-size: 2em; margin-top: 10px; }");
  client.print("#temperature { color: #7CFC00; }"); // Vert pomme
  client.print("#humidity { color: #87CEEB; }"); // Bleu ciel
  client.print("#time { color: #8B0000; }"); // Rouge bordeaux
  client.print("button { background-color: #20B2AA; color: white; border: none; padding: 10px 20px; margin: 10px; cursor: pointer; border-radius: 5px; transition: background-color 0.3s ease-in-out; }");
  client.print("button:hover { background-color: #1e90ff; }");
  client.print("</style>");
  client.print("<script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>");
  client.print("<script>");
  client.print("let temperatureData = [];");  // Code JavaScript pour afficher les données en graphique
  client.print("let humidityData = [];");
  client.print("let labels = [];");
  client.print("function fetchData() {");
  client.print("  fetch('/json').then(response => {");
  client.print("    if (!response.ok) { throw new Error('Network response was not ok ' + response.statusText); }");
  client.print("    return response.json();");
  client.print("  }).then(data => {");
  client.print("    document.getElementById('temperature').innerText = data.temperature + ' °C';");
  client.print("    document.getElementById('humidity').innerText = data.humidity + ' %';");
  client.print("    document.getElementById('time').innerText = data.time;");
  client.print("    updateChart(data.time, data.temperature, data.humidity);");
  client.print("  }).catch(error => {");
  client.print("    console.error('Error fetching data:', error);");
  client.print("  });");
  client.print("}");
  client.print("function updateChart(time, temperature, humidity) {");
  client.print("  labels.push(time);");
  client.print("  temperatureData.push(temperature);");
  client.print("  humidityData.push(humidity);");
  client.print("  if (labels.length > 20) {");
  client.print("    labels.shift();");
  client.print("    temperatureData.shift();");
  client.print("    humidityData.shift();");
  client.print("  }");
  client.print("  window.myChart.update();");
  client.print("}");
  client.print("window.onload = function() {");
  client.print("  var ctx = document.getElementById('myChart').getContext('2d');");
  client.print("  window.myChart = new Chart(ctx, {");
  client.print("    type: 'line',");
  client.print("    data: {");
  client.print("      labels: labels,");
  client.print("      datasets: [{");
  client.print("        label: 'Température (°C)',");
  client.print("        borderColor: '#7CFC00',");
  client.print("        backgroundColor: 'rgba(124, 252, 0, 0.2)',");
  client.print("        fill: false,");
  client.print("        data: temperatureData");
  client.print("      }, {");
  client.print("        label: 'Humidité (%)',");
  client.print("        borderColor: '#87CEEB',");
  client.print("        backgroundColor: 'rgba(135, 206, 235, 0.2)',");
  client.print("        fill: false,");
  client.print("        data: humidityData");
  client.print("      }]");
  client.print("    },");
  client.print("    options: {");
  client.print("      responsive: true,");
  client.print("      scales: {");
  client.print("        x: { display: true, title: { display: true, text: 'Temps' } },");
  client.print("        y: { display: true, title: { display: true, text: 'Valeurs' } }");
  client.print("      }");
  client.print("    }");
  client.print("  });");
  client.print("  fetchData();");
  client.print("  setInterval(fetchData, 1000);");
  client.print("};");
  client.print("</script>");
  client.print("</head>");
  client.print("<body>");
  client.print("<h1><i class=\"fas fa-server\"></i> Server Arduino R4</h1>");
  client.print("<div class=\"data-container\">");
  client.print("<p><i class=\"fas fa-temperature-high\"></i> Température : <span id='temperature'>...</span></p>");
  client.print("<p><i class=\"fas fa-tint\"></i> Humidité : <span id='humidity'>...</span></p>");
  client.print("<p><i class=\"fas fa-clock\"></i> Heure : <span id='time'>...</span></p>");
  client.print("<canvas id='myChart' width='400' height='200'></canvas>");
  client.print("</div>");
  client.print("<button onclick=\"fetchData()\">Rafraîchir les données</button>");
  client.print("</body>");
  client.print("</html>");
}
void setup() {
  Serial.begin(9600);
  connectToWiFi();
  server.begin();

  timeClient.begin();
  timeClient.setTimeOffset(3600); // Définir le décalage UTC pour CET

  while (!timeClient.update()) {
    Serial.println("Erreur de mise à jour NTP, nouvelle tentative...");
    delay(1000);
  }
  Serial.println("Synchronisation de l'heure réussie!");

  dht.begin();
  myDisplay.begin();
  myDisplay.setIntensity(1);
  myDisplay.displayClear();
  Serial.println("Matrice LED initialisée !");
  ledMatrix.begin(); // Initialiser la matrice intégrée
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousServerMillis >= serverInterval) {
    previousServerMillis = currentMillis;
    Serial.println("Mise à jour du serveur...");
    updateServer();
    Serial.println("Mise à jour du serveur terminée.");
  }

  if (currentMillis - previousMatrixMillis >= matrixInterval) {
    previousMatrixMillis = currentMillis;
    Serial.println("Mise à jour des matrices...");
    updateMatrix();
    Serial.println("Mise à jour des matrices terminée.");
  }

  if (Serial.available()) {
    int newIntensity = Serial.parseInt();
    if (newIntensity >= 0 && newIntensity <= 25) {
      myDisplay.setIntensity(newIntensity);
      Serial.print("Nouvelle intensité: ");
      Serial.println(newIntensity);
    }
  }
}

void updateServer() {
  WiFiClient client = server.available();

  if (client) {
    Serial.println("Nouveau client connecté");
    String currentLine = "";
    bool isJsonRequest = false;

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n') {
          if (currentLine.length() == 0) {
            if (isJsonRequest) {
              Serial.println("Servir les données du capteur...");
              serveSensorData(client);
              Serial.println("Données du capteur servies.");
            } else {
              Serial.println("Servir la page HTML...");
              serveHTML(client);
              Serial.println("Page HTML servie.");
            }
            break;
          } else {
            if (currentLine.indexOf("GET /json") >= 0) {
              isJsonRequest = true;
            }
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    client.stop();
    Serial.println("Client déconnecté");
  }
}

void updateMatrix() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  timeClient.update();

  char formattedTime[14];
  snprintf(formattedTime, sizeof(formattedTime), "%02dh%02d", timeClient.getHours(), timeClient.getMinutes());

  myDisplay.displayClear();
  myDisplay.displayText(formattedTime, PA_CENTER, 15, 2000, PA_SCROLL_DOWN, PA_SCROLL_RIGHT); 
  while (!myDisplay.displayAnimate()) {}

  char formattedTemp[41];
  snprintf(formattedTemp, sizeof(formattedTemp), "%.1fC et %.1f%%", t, h);

  myDisplay.displayClear();
  myDisplay.displayText(formattedTemp, PA_CENTER, 10, 2000, PA_SCROLL_UP, PA_SCROLL_LEFT);
  while (!myDisplay.displayAnimate()) {}

  Serial.print("Heure : ");
  Serial.println(formattedTime);
  Serial.print("Température: ");
  Serial.print(t);
  Serial.print("°C  Humidité: ");
  Serial.print(h);
  Serial.println("%");
}

Votre serveur devrait écouter en permanence, pas la peine de mettre un timer qui va vérifier les connexions possible chaque seconde.

Vous aurez de toutes façons un appel par seconde puisque que vous faites dans la page web

setInterval(fetchData, 1000);

vous n'avez que peu de données qui transitent et vous utilisez AJAX pour la mise à jour de la page donc si le réseau n'a pas trop de latence, une fois la page initiale transmise, ça ne devrait pas prendre trop longtemps.

Vous pourriez gagner un peu de temps en lisant de manière régulière (avec millis) les capteurs et dans les requêtes de mise à jour de la matrice ou du web, vous envoyez les dernières valeurs lues.

Vous pourriez aussi réduire la taille du payload JSON en virant les labels et en envoyant juste un tableau - par exemple au lieu de

{
  "temperature": 23.5,
  "humidity": 60.2,
  "time": "12:34:56"
}

vous pourriez envoyer

[23.5,60.2,"12:34:56"]

Notez aussi (suivant comment vous configurez le terminal série) que Serial.parseInt() peut mettre le bazar

vous devriez rajouter un petit bout de code qui test combien de temps prend l'appel à updateServer() et updateMatrix()

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