Besoin d'y voir clair : Communication entre Arduinos, puis serveur Web

Bonsoir à tous,
Je vous décris ma situation :
Depuis 6 ans je gère mon chauffage (à pellets réalisé en "Do It Yourself) , sur place et à distance, avec le matériel suivant :
1 Arduino Mega (appelons-le A) gérant la chaudière
1 Arduino Mega (appelons-le B) gérant la distribution d'air chaud dans 4 locaux ainsi que l'accès à distance de toute l'installation. il gère aussi l'aspect calendrier et horloge RTC
1 module Wifi spécial (Appelons-le C) avec firmware dédié vendu par Miupanel permettant via leur cloud de dialoguer avec un smartphone via une application dédiée. Les pages étaient écrites en "htcml" (de leur invention) et permettaient de créer une ergonomie et un design formidables, incomparables quand on voit ce que permettent Blynk, Arduino IoT cloud ou autres...

Les communications :

  • A et B conversent en liaison série (via des shifters 5 / 12v du fait des 5m de distance)
  • B et C conversent en liaison série classique (courte distance).
  • Les informations passent en bidirectionnel A <-> B <-> C <-> Smartphone.

Le module C sert également de mémoire Flash Disk pour stockage des paramètres de réglages.

Le dialogue avec smartphone permet via 3 "mini" pages html :

  • La lecture rafraîchie toutes les 5s de valeurs numériques et alphanumériques
  • L'accès aux réglages de températures consignes et aux horaires de mode réduit / normal pour chacun des 4 locaux donc 4 valeurs par local ( temp jour - temp nuit - heure jour - heure nuit)
  • Des boutons déclenchant des actions comme des relances en cas de défaut d'allumage, le forçage en mode réduit ou l'inverse d'un local et autres.

Le module C permet aussi d'émettre des notifications (push) en cas de défaut.
Il permet aussi d'enregistrer chaque jour une ligne d'un fichier texte contenant des valeurs de consommations et des statistiques de températures (extérieur, fumées, etc...). L'accès à ces données se fait par communication via un PC de la maison via une adresse IP locale et un numéro de port.

Problème récent : Le fournisseur et hébergeur de Cloud Miupanel est en faillite, l'application tourne encore, mais pas pour longtemps, donc je dois traiter autrement le maillon "C"

Je m'intéresse au MKR Wifi Arduino et rencontre beaucoup de problèmes que j'ai du mal à régler :
Je parviens à faire tourner un mini serveur Web tel que décrit
Je parviens à traiter la communication entre B et C
Je parviens à traiter l'envoi de push (via Prowl)
Je parviens à traiter la sauvegarde de paramètres sur carte SD
Je parviens à utiliser la RTC via internet (NTP)

Par contre je ne parviens pas à faire tourner 2 de ces applications sur le même sketch. Le mieux que j'ai pu simuler est l'association du serveur Web + RTC + accès aux statistiques via PC.
Je ne parviens pas à intégrer la communication au sketch du serveur Web.
Je n'ai trouvé nulle part des exemples de cette combinaison.

Les effets sont sérieux et étranges, comme par exemple le plantage de l'IDE au téléchargement, ainsi le blocage du MKR en mode boot.

A mon sens la taille du sketch complet ne poserait pas de problème, pas plus que la taille prise par les variables. Reste l'occupation de RAM qui n'est pas aisée à cerner face à de tels plantages.

Dans d'autres domaines j'ai travaillé avec des Teensy (3.6) qui me semblent supérieurs au MKR mais n'intègrent pas de Wifi, donc une 4ème liaison série...

Je n'attends pas de solution "toute faite", mais plutôt des avis, et si possible des infos me permettant de grouper les fonctions décrites plus haut, quitte à sélectionner une autre architecture pour remplacer C...

Un grand merci d'avance pour vos lumières .
Je regrette le bon temps où depuis une plage des caraïbes en plein février je pouvais redémarrer ma chaudière suite à un défaut d'allumage ...

Bonjour

Que donnent les infos d'ocupation mémoire (code et ram) à la fin de la compilation ?

Je m'intéresse au MKR Wifi Arduino et rencontre beaucoup de problèmes que j'ai du mal à régler :

Sur ce forum très peu d'intervenants font ce choix de cette carte.
La tendance, dès, qu'il est question de WIFi sous IDE Arduino, consiste à prendre une des diverses cartes trournant exclusivement autour d'un ESP32, parfois encore d'un ESP8266

Dans d'autres domaines j'ai travaillé avec des Teensy (3.6) qui me semblent supérieurs au MKR ....

Tu es donc prêt à piocher en dehors du catalogue de la 'boutique Arduino' pour trouver une carte adaptée aux besoins !!

Avec un ESP32 tu peux, dans la console, avoir des infos sur le plantage (état du processeur, fonction ayant déclenché le plantage...)

Sur ce site un bon choix d'utilisations d'ESP32 sous IDE Arduino :
https://randomnerdtutorials.com/projects-esp32/

La documentation de l'extension ESP32 pour IDE Arduino est là :
https://docs.espressif.com/projects/arduino-esp32/en/latest/

Bonjour et merci de te pencher sur mes soucis.

Que donnent les infos d'ocupation mémoire (code et ram) à la fin de la compilation ?

Voici un sketch réduit pour tester le traitement de strings :

float ts = 20.2;  //Température actuelle Salon
float tp = 18.2;  //Température actuelle Ch. Parents
float te = 18.7;  //Température actuelle Ch. Eva
float tv = 17.5;  //Température actuelle Ch. Victor
float cs = 21;    //Consigne Température actuelle Salon
float cp = 18.5;  //Consigne Température actuelle Ch. Parents
float ce = 15;    //Consigne Température actuelle Ch. Eva
float cv = 15;    //Consigne Température actuelle Ch. Victor
int tex = 0;     //Température extérieure
int tch = 0;     //Température Chaudière
int tct = 0;     //Température circuit
int tec = 0;     //Température ECS
int alarm = 0;    //Numéro d'alarme
int cons = 0;  //Consommation session en temps de vis (s)
int all = 0;    //Temps d'allumage de la session ou maxi si pas en chauffe
int fum = 0;    //Température de fumée actuelle ou maxi si pas en chauffe
int ses = 0;     //Nombre de sessions de la journée
int state = 0;    //Etat du graphe de chauffe
int Date = 0;     //Graphe d'envoi de date
int Mex = 0;
int mex = 0;
int Mfu = 0;
int Mal = 0;
bool ecs = 0;     //Etat de besoin d'ECS
bool hiver = 0;   //Mode hiver
char local =' ';  //Lettre du local concerné
char c;
String etat = "Chaudi&egravere&nbsppr&ecircte";   //chaîne de l'état (en clair)
String Rtemp = "203182197167";                    // températures réelles locaux
String Chaud = "65353600331481236532125512";      // état chaudière
String TimeJ = "135080090090";                    // heures de début de jour ASCII 4 x 3 caractères
String TimeN = "230230225225";                    // heures de début de nuit ASCII 4 x 3 caractères
String TempJ = "210150150150";                    // températures de jour ASCII 4 x 3 caractères
String TempN = "195185150150";                    // températures de nuit ASCII 4 x 3 caractères
String consEnCours = "210150150150150";           // Consignes appliquées en temps réel
String chaufEnCours = "0101";                     // Demandes de chauffage en temps réel
String Msg;
String stat ="30/8/2021  4.29  16  21  182 171 12 \r";  // chaîne contenu du fichier Log.txt
int DJS;                    // heure de début jour Salon ASCII 3 caractères
int DJP;                    // heure de début jour ChP ASCII 3 caractères
int DJE;                    // heure de début jour ChE ASCII 3 caractères
int DJV;                    // heure de début jour ChV ASCII 3 caractères
int DNS;                    // heure de début nuit Salon ASCII 3 caractères
int DNP;                    // heure de début nuit ChP ASCII 3 caractères
int DNE;                    // heure de début nuit ChE ASCII 3 caractères
int DNV;                    // heure de début nuit ChV ASCII 3 caractères
int djs;                    // heure de début jour Salon ASCII 3 caractères
int djp;                    // heure de début jour ChP ASCII 3 caractères
int dje;                    // heure de début jour ChE ASCII 3 caractères
int djv;                    // heure de début jour ChV ASCII 3 caractères
int dns;                    // heure de début nuit Salon ASCII 3 caractères
int dnp;                    // heure de début nuit ChP ASCII 3 caractères
int dne;                    // heure de début nuit ChE ASCII 3 caractères
int dnv;                    // heure de début nuit ChV ASCII 3 caractères
int affich = 0;
bool sal;                    // Chauffe en cours salon
bool par;                    // Chauffe en cours Ch. Parents
bool eva;                    // Chauffe en cours Ch. Eva
bool vic;                    // Chauffe en cours Ch. Victor
float TJS;                   // Consigne température de jour Salon ASCII 3 caractères
float TJP;                   // Consigne température de jour CHP ASCII 3 caractères
float TJE;                   // Consigne température de jour ChE ASCII 3 caractères
float TJV;                   // Consigne température de jour ChV ASCII 3 caractères
float TNS;                   // Consigne température de nuit Salon ASCII 3 caractères
float TNP;                   // Consigne température de nuit ChP ASCII 3 caractères
float TNE;                   // Consigne température de nuit ChP ASCII 3 caractères
float TNV;                   // Consigne température de nuit ChV ASCII 3 caractères
float tjs;                   // Consigne température de jour Salon ASCII 3 caractères
float tjp;                   // Consigne température de jour CHP ASCII 3 caractères
float tje;                   // Consigne température de jour ChE ASCII 3 caractères
float tjv;                   // Consigne température de jour ChV ASCII 3 caractères
float tns;                   // Consigne température de nuit Salon ASCII 3 caractères
float tnp;                   // Consigne température de nuit ChP ASCII 3 caractères
float tne;                   // Consigne température de nuit ChP ASCII 3 caractères
float tnv;                   // Consigne température de nuit ChV ASCII 3 caractères

void setup() {
  Serial.begin(9600);
}

void loop() {

  //****************************************** Récupération valeurs chaudière via ventilation ***********************************
  
  while ((c = Serial.read()) > '\n') Msg += (char) c; 
       if (c == '\n')
          {if (Msg.substring(0,3).equals("tch")) 
            { tch = (int)(Msg.substring(3,5)).toInt();
              Serial.print("Temp Chaudiere :");
              Serial.println(tch);
              Msg = ""; }
          if (Msg.substring(0,3).equals("tct")) 
            { tct = (int)(Msg.substring(3,5)).toInt();
              Serial.print("Temp Circuit :");
              Serial.println(tct);
              Msg = ""; }
          if (Msg.substring(0,3).equals("tex")) 
            { tex = ((int)(Msg.substring(3,5)).toInt())-20;
              Serial.print("Temp Ext :");
              Serial.println(tex);
              Msg = ""; }
          if (Msg.substring(0,3).equals("ecs")) 
            { ecs = (bool)(Msg.substring(3,4)).toInt();
              Serial.print("Besoin d'ECS :");
              Serial.println(ecs);
              Msg = ""; }
          if (Msg.substring(0,5).equals("alarm")) 
            { alarm = (int)(Msg.substring(5,6)).toInt();
              Serial.print("Alarme :");
              Serial.println(alarm);
              Msg = ""; }
          if (Msg.substring(0,5).equals("state")) 
            { state = ((int)(Msg.substring(5,7)).toInt())-10;
              Serial.print("Etat :");
              Serial.println(state);
              Msg = ""; }
          if (Msg.substring(0,5).equals("hiver")) 
            { hiver = (bool)(Msg.substring(5,6)).toInt();
              Msg = ""; 
              Serial.print("Hiver :");
              Serial.println(hiver);}
          if (Msg.substring(0,3).equals("tec")) 
            { tec = (int)(Msg.substring(3,5)).toInt();
              Serial.print("Temp ECS :");
              Serial.println(tec);
              Msg = ""; }
          if (Msg.substring(0,4).equals("cons"))   
            { cons = ((int)(Msg.substring(4,9)).toInt())-10000;
              Serial.print("Consommation :");
              Serial.println(cons);
              Msg = ""; }
          if (Msg.substring(0,3).equals("fum"))   
            { fum = ((int)(Msg.substring(3,6)).toInt())-100;
              Serial.print("Temp Fumee :");
              Serial.println(fum);
               Msg = "";}
          if (Msg.substring(0,3).equals("all"))   
            { all = ((int)(Msg.substring(3,5)).toInt())-100;
              Serial.print("Temps d'Allumage :");
              Serial.println(all);
              Msg = ""; }
          if (Msg.substring(0,3).equals("ses"))   
            { ses = ((int)(Msg.substring(3,5)).toInt())-10;
              Serial.print("Nb Sessions :");
              Serial.println(ses);
              Msg = ""; }  }  }

Ce sketch en compilation me donne ceci :

Le croquis utilise 15880 octets (6%) de l'espace de stockage de programmes. Le maximum est de 262144 octets.
Les variables globales utilisent 2756 octets (8%) de mémoire dynamique, ce qui laisse 30012 octets pour les variables locales. Le maximum est de 32768 octets.

Une fois téléchargé, impossible d'ouvrir le moniteur série ni de fermer l'IDE. Seule issue : reset du MKR et là l'IDE se ferme tout seul...

La tendance, dès, qu'il est question de WIFi sous IDE Arduino, consiste à prendre une des diverses cartes trournant exclusivement autour d'un ESP32, parfois encore d'un ESP8266

J'ai effectivement l'intention de creuser du côté du ESP8266 que j'ai sous la main, en espérant trouver plus de retours avec ce "vieux" module

Tu es donc prêt à piocher en dehors du catalogue de la 'boutique Arduino' pour trouver une carte adaptée aux besoins !!

Non et oui, j'ai eu recours à ces modules pour traiter l'animation sonore de mon modèle réduit de moteur diesel en qualité CD. Ils avaient tout pour faire, et ça donne ça :

Avec un ESP32 tu peux, dans la console, avoir des infos sur le plantage (état du processeur, fonction ayant déclenché le plantage...)

Le MKR Wifi 1010 embarque un ESP32 géré par la librairie WIFININA, mais je ne sais pas si je peux "enjamber" cette lib en utilisant celles spécifiques au ESP 32 ... Qu'en penses-tu ?

C'est probablement possible, je n'en sais pas plus n'ayant jamais été intéressé par ce type de carte hybride dans lequel l'ESP32 est cantonné au rôle de 'coprocesseur radio' via un firmware d'origine Arduino lus ou moisn mature

(les cartes à ESP32 'en solo' sont désormais devenues mes 'cartes à tout faire', que j'ai ou non besoin de WiFi, Bluetooth ou BLE. J'utilise encore parfois des cartes Wemos D1 MIni (ESP8266) avec le core ESP8266 pour IDE Arduino., mais les ESP-01 ont pris leur retraite)

Port série : il faut attendre le retour d'un intervenant au fait du comportement particulier des SAMD21 sous IDE Arduino, (mode DFU...etc...)

....j'ai eu recours à ces modules pour traiter l'animation sonore de mon modèle réduit de moteur diesel en qualité CD. Ils avaient tout pour faire,
:+1:

Pour avoir le coudées franches en WiFi il me semble qu'il est bon 'd'aller voir ailleurs' ,en profitant du fait que le 'Core ESP32 pour Arduino' à le niveau de Teensyduino pour ce qui le concerne !!

Pour avoir le coudées franches en WiFi il me semble qu'il est bon 'd'aller voir ailleurs' ,en profitant du fait que le 'Core ESP32 pour Arduino' à le niveau de Teensyduino pour ce qui le concerne !!

Je crains que discuter de ce thème ici risque de ne pas satisfaire aux règles... mais si tu pouvais développer ta pensée ...

En attendant la réception de mes ESP32, j'essaie - en temps que newbee en WiFi - à partir du sketch de la bibliothèque ESP8266WiFi "WiFiManualWebServer" de commander la led soit par les liens de la page html soit par la lecture du moniteur série (par exemple par des String simples comme "on" ou "off".
Le but final étant (vu la taille probable de mes 3 ou 4 pages html) d'envoyer les contenus des "client.print" par des String provenant d'un Arduino (ou autre :wink: )

J'avoue patiner grave, et un exemple d'architecture de sketch m'aiderait beaucoup à comprendre...

Bien sûr tout ceci pour l'instant sur un ESP8266, car une fois les ESP32 en mains, le site
"160+ ESP32 Projects, Tutorials and Guides with Arduino IDE​ | Random Nerd Tutorials" qui me semble une vraie mine d'or devrait répondre à mon besoin .

Aucune crainte à ce sujet , ce forum n'est pas le SAV d'Arduino.cc mais un forum d'entraîde entre utilisateurs d'Arduino ( l'IDE et/ou les cartes)
On y échange sur tout ce qui , d'une manière ou d'une autre, à un rapport avec Arduino, ne serait-ce que l'IDE et les librairies.

Je ne vois pas (il semble que je ne sois pas le seul...) dans le catalogue Arduino de cartes économiques dotées de WiFI et Bluetooth. Je les trouve aisément en marge d'Arduino, elles mettent en oeuvre un ESP8266 ou un ESP32 programmable sous IDE Arduino.et utilsiation d'une grande partie des librairies historiques.

De plus on peut facilement trouver 'sa carte idéale' avec un ESP32 : ça va des cartes minimales -idéales pour optiminer l'autonomie) aux cartes plus complexes de LiLYGO /TTGO, ou HELTEC sans oublier les modules 'habillés' de M5STACK.

Arduino.cc ne me parait pas avoir renouvelé , pour les objets connectés, avec ce qui a vait si bien réussi auparavant avec les cartes basiques Uno, Nano, Mega . D'autres savent faire, avec la complicité d'Arduino.cc qui a ouvert son IDE aux architectures externes (board manager)

Exemples d'utilsation d' ESP8266 : https://randomnerdtutorials.com/projects-esp8266/

Merci pour le lien vers le site de tutos, vraiment riche d'exemples intéressants (quasiment 5 ou 6 répondent exactement à mes attentes).

J'étais en causerie avec sur un autre membre sur le site anglais où tu pourras lire en détail mes déboires et les réponses de mon interlocuteur...

Suite à mes derniers essais, j'ai à présent démontré que ce MKR 1010 n'ayant pas de chip USB dédié, la partie correspondante codée est corruptible par le code utilisateur (voir mon dernier post ici ).
Je laisse donc tomber ce module.

Dans l'impatience de recevoir mes ESP32, je m'essaie sur mon ESP8266 à jouer avec l'UART (lecture, décodage, écriture).

Je rencontre un souci lié au fait que le firmware attend un recours régulier aux fonctions Wifi, faute de quoi le watchdog reset le module.

L'ESP32 exige t'il la même chose ? (tu m'as dit l'utiliser pour d'autre domaines que la connexion WiFi)

on s'en sort en général en insérant des yield() ou delay() pour rendre temporairement la main au WiFi

voir la doc : https://arduino-esp8266.readthedocs.io/en/3.0.2/reference.html#timing-and-delays

Les ESP32 (sauf quelques variantes particulières présentes sur le catalogue Espressif mais peu distribuées) ont deux coeurs, l'un étant dédié au WiFi ou au Bluetooth quand on les active. On est donc dans une situation moins tendue.

Comme je suis têtu et obstiné, j'ai fini par trouver la source des ennuis avec le MKR Wifi 1010.
Il n'accepte pas le "Serial.read", ce qui provoque tous les ennuis décrits auparavant.
C'est en remplaçant l'écriture par "Serial.parseInt" que tout s'est mis à fonctionner.
Il m'a bien sûr fallu réécrire toute la communication Série, mais le résultat positif est là.
J'espère que cette information pourra servir à d'autres...

Me re-voici après avoir finalement abandonné le MKR WiFi 1010.

Pourtant tout près du but, l'interdiction du Serial.read et son contournement par des commandes rendant les échanges d'une lenteur insupportable, je m'en retourne donc vers l'ESP32.
Dans la jungle des échanges et des versions, j'y perds mon latin et mon grec en tentant de communiquer entre Arduino's et ESP32.
On lit de tout et son contraire, y compris pour une version donnée.
La mienne est un NodeMCU DevKitC V4, avec puce WROOM-32 avec 2 x 19 pins comme ceci
J'ai compris (et vérifié) que les GPIO1 et 3 ne doivent pas être utilisés car prévus pour du debug comme avec l'USB.
Utilisant un module SD Card en SPI, les GPIO22 et 23 me sont donc également interdits.
J'ai donc pensé à utiliser les GPIO16 et 17, repérés sur les pinouts comme RXD2 et TXD2.
En tentant un sketch rudimentaire d'échanges croisés entre ESP et Mega2560, le moniteur part en rafale à la première saisie avec des caractères spéciaux et sans retour, alors que mes Strings sont en "ln" :

char c;
char d;
String Msg;
String Msg1;

void setup() {
 Serial.begin(115200);
 Serial2.begin(115200);
}

void loop() {
while ((c = Serial.read()) > '\n') Msg += (char) c;
if (c == '\n')  {
 Serial.println(Msg);
 Serial2.println(Msg);
 Msg=""; }
   
while ((d = Serial2.read()) > '\n') Msg1 += (char) d;
if (d == '\n')  {
 Serial.println(Msg1);
 Msg1=""; }
} 

L'arduino d'en-face a le même sketch, aux paramètres UART près.

Je lis par place le besoin d'utiliser un hardwareSerial, par ailleurs d'autres s'en passent.
On lit aussi des déclarations du style

#define RXD1 22
#define TXD1 23

et en setup

  Serial1.begin(115200, SERIAL_8N1, RXD1, TXD1);

Bref, je suis dans le brouillard (d'automne aussi) ...

Juste un petit feedback après la cloture de mon projet de chauffage, donc supervisé par un ESP32. Tous mes problèmes sont résolus et mon seveur Web esexactement conforme à ce dont je rêvais.
J'ai bien chargé l'ESP32 (plus de 85% de mémoire programme). et ça tourne super bien.
Les fonctions qu'il effectue :

  • Dialogue série avec 2 Mega 2560
  • Archivage en flash de paramètres (bibiothèque Preferences)
  • Envoi de mail quotidien avec le bilan de la journée
  • Envoi de notifications push en cas de défaut (Prowl)
  • Serveur Web à pages multiples (8) avec affichage de données fluctuantes et actions sur des variables du sketch.
  • Horloge RTC ...

Merci pour le conseil du choix ESP32, c'est un produit génial.

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