Recherche assistance

Bonjour,

je recherche quelqu'un pour jeter un oeil sur un sketch qui ne me satisfait pas et j'ai des questionnements sur la faisabilité de plusieurs choses.
Passer par le forum a certains avantages mais aussi des inconvénients et je recherche quelqu'un de disponible le cas échéant pour avoir une conversion téléphonique.
Sachant que l'échange peut aboutir à une collaboration si c'est judicieux de procéder et sachant également que je suis assez autonome et souvent contraint financièrement.
Bref, un minimum d'intérêt pour ma requête qui dépasse la simple question sur un forum sans pour autant rechercher une véritable prestation de service.
Merci de vos retours et de vos conseils.
Belle journée d'hiver à tous.

Bonjour dormio

En quoi ton sketch te rends insatisfait?
Quelles sont tes constatations/désirs?

Mets ton sketch en ligne..

A+
Une bonne journée, ici beau soleil, mais froid, brrrrr .
jpbbricole

Salut @jpbbricole

Entendu, voir en PJ mais malgré quelques nettoyages pour faciliter la lecture je crains une réaction rédhibitoire.

ça tourne sur des esp01 et le problème est le suivant, je ne parviens pas à synchroniser correctement les modules. Par exemple au lieu d'avoir des allumages bien séquentiels, à intervalles réguliers, j'obtiens des allumages mal synchronisés et donc les séquences sont un peu erratiques.
Etant parfaitement autodidacte Je ne parviens pas à comprendre si mon code est incorrect ou si le MCU (simple coeur) est mal adapté pour traiter à la fois la réception du wifi et l'allumage d'un pattern

Correction : les nouveaux utilisateurs ne peuvent pas envoyer de fichiers. Dois-je mettre mon code de 458 lignes dans un block code dans le corps de ce post ?

@admin : quelqu'un peut-il me permettre d'envoy er un sketch en pj. Merci.

Bonjour dormio

Ca n'est pas défendu, c'est simplement moins pratique.Tu peux simplement copier/coller ton fichier INO.

A+
Cordialement
jpbbricole

Ce n'est pas nécessaire, tu peux mettre ton code directement dans les balises codes.
Cela donne quelque chose de tout aussi exploitable qu'un fichier en pièce jointe.

Le forum n'est pas limité a une question unique et différent échange vont assez loin dans l'analyse et la technique.
Le forum est là pour mettre les différent sachant en rapport avec différent demandeur, mais aussi à des non sachant et non demandeur de s'informer en suivant silencieusement la discutions des différents protagoniste.

Donc je pense que tu trouveras plusieurs personnes près à aider et encore plus de personnes qui suivront vos échanges.

Okay merci pour les explications, voici le code un peu nettoyé.
Donc je rappelle ma question : est-il possible, en Wifi de déclencher les mcu en cascade avec une précision de qq 10aines ou au maximum 100aine de ms ?
Si oui y a -t-il un problème avec ceci :


#define DATA_PIN 2

byte BRIGHTNESS  = 60;
byte fadeAmount = 5;


byte gHue = 124; // hue pour HSV
byte prev_gHue = gHue;

byte gSat = 255;// saturation pour HSV

byte gBpm = 10; // beat per minutes, 40 max !
byte prev_gBpm = 2;//autre bpm pour un glissement progressif des valeurs

byte fadeval = 20;

byte gCol = 0; //color index #1
byte gCol2 = 1; //color index #2


int gDel = 50;//variable pour delay()
int gDel2 = 2000;
int prev_gDel = 2000;
int pas = 100; 


WiFiClient ESP01client;
PubSubClient client(ESP01client);

//Variables pour recevoir patterns 
byte ledPattern = 0; // pattern # : 255 patterns maximum
unsigned int startTime; 

String clientID = WiFi.hostname();
String topicName = clientID + "/#";

bool global_enabled = false;

//diagnostique Wifi, sans perturber la loop() et il existe des fonctions asynchrones pour cela :
//les fonctions "Generic" de l'ESP8266
//https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/generic-examples.html
WiFiEventHandler gotIpEventHandler, disconnectedEventHandler;
long lastReconnectAttempt = 0;//variable lié à la fonction de reconnexion mqtt non bloquante, voir l'exemple mqtt_reconnect_nonblocking.ino




boolean connect_mqtt() {
  Serial.println("");

  if (client.connect(clientID.c_str())) {
    client.publish("welcomeled", clientID.c_str()); 
    client.subscribe("led");//led pattern


    Serial.println("connexion OK !!");
    Serial.printf("welcome : %s\n", clientID.c_str());
  }
  return client.connected();
}

//=================================================================================
int payloadToInt(byte* payload, int length) {
  String payloadFromMQTT = "";
  for (int i = 0; i < length; i++) { //itérer dans toute la longueur message, length est fourni dans le callback
    if (isDigit(payload[i]))// tester si le payload est bien un chiffre décimal
      payloadFromMQTT += (char)payload[i];//caster en type char et ajouter/placer dans la variable
  }
  return payloadFromMQTT.toInt();
}



//-------------FONCTION CALLBACK------------
void callback(char* topic, byte* payload, unsigned int length)
{
  String debugMessage = "";
  global_enabled = true; // open flag : PLAY !
  debugMessage = clientID + " - Topic entrant : [" + topic + "] ";

  //--------------- nom du mc ----------------
  if ( (strcmp(topic, (clientID + "/helloled").c_str()) == 0)
       || (strcmp(topic, "helloled") == 0)) { 
    client.publish("welcomeled", clientID.c_str());
  }
}


typedef void (*voidfunc)();
voidfunc func[] = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19};
int nFunc = sizeof(func) / sizeof(func[0]); // sizeof returns the total number of bytes.

void setPattern() {
  if ((ledPattern >= 0) && (ledPattern <= nFunc))
  {
    func[ledPattern](); 
  }
}


void setup() {
  delay(3000); // 3 second delay for recovery

  WiFi.softAPdisconnect (true);//encore mieux avec?
  WiFi.mode(WIFI_STA);//s'assurer que l'on est mode STAtion et pas autre chose

  Serial.begin(74880);// initialize menu Tools > serial monitor
  delay(100);

  //Par défaut le diagnostique Wifi est désactivé, pour l'activer
  //Serial.setDebugOutput(true);

  /*
    //////////// ESP01 settings //////////
    //********************* CHANGE ESP01 PIN FUNCTION **************************************
    pinMode(3, FUNCTION_0); //(RX) pin (nommé également pin3 dans la doc) devient GPIO 3
    //**************************************************************************************
  */
  FastLED.addLeds<WS2812, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);// set master brightness control.
  FastLED.setBrightness(BRIGHTNESS);// (255) = puissance maximale -----> ATTENTION POWER !

  //------------- wifi-------------
  /*A activer pour un téléversement pour une connexion sur un nouveau réseau
     https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html#disconnect
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
  */

  // setup_wifi();//connexion effective au réseau wifi



  //-------------event handlers asynchrone: ne perturbent pas la loop()------
  //cet event handler, surveille en permanence, en tâche de fond si une adresse IP est attribuée au module
  gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP & event)
  {
    Serial.print("Station connected, IP: ");
    Serial.println(WiFi.localIP());
  });

  //cet event handler, surveille en permanence, en tâche de fond si le module est déconnecté
  disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected & event)
  {
    Serial.println("Station disconnected");
  });

  Serial.printf("Connecting to %s ...\n", ssid);
  delay(1000);

  //------------- mqtt-------------
  //IP et port 
  client.setServer(mon_broker, 1883);
  client.setCallback(callback);

  WiFi.begin(ssid, password);//begin établi la connexion en tant que tel
  delay(1500);// Allow the hardware to sort itself out


  lastReconnectAttempt = 0;

  //indique dans le moniteur le nombre de fonctions à disposition
  Serial.print("le nombre de fonctions diponibles est :");
  Serial.println(nFunc);
  Serial.println();
}


void loop() {

  //  erreur 1 : ce-dessous, inutile ! car l'ESP tente lui-même de se reconnecter lorsqu'il est déconnecté du Wifi
  /*  https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-class.html#start-here
    if (WiFi.status() != WL_CONNECTED)
    setup_wifi();
  */

  //monitorer le status de la connexion en continue
  //Serial.printf("Status de la Connection: %d\n", WiFi.status());//retourne un entier
  /*
    WiFi.status() retourne un code qui décrit la situation :
    0 : WL_IDLE_STATUS when Wi-Fi is in process of changing between statuses
    1 : WL_NO_SSID_AVAILin case configured SSID cannot be reached
    3 : WL_CONNECTED after successful connection is established
    4 : WL_CONNECT_FAILED if password is incorrect
    6 : WL_DISCONNECTED if module is not configured in station mode
  */


  //------------ non blocking mqtt connexion ----------
  if (!client.connecte()) {
    long now = millis();
    if (now - lastReconnectAttempt > 5000) {
      lastReconnectAttempt = now;
      // Attempt to reconnect
      if (connect_mqtt()) {
        lastReconnectAttempt = 0;
      }
    }
  } else {
    // Client connected
    client.loop();
  }

  if (!global_enabled) //Global "display enable" flag
    return;
  setPattern();
// insert a delay to keep the framerate modest
  FastLED.delay(1000 / FRAMES_PER_SECOND);

}

Bonsoir dormio

Même nettoyé, c'est trop "gros" pour moi, navré :frowning_face:

Cordialement
jpbbricole

Et oui c'est ce que je craignais. Merci cependant.
Je vais laisser mon topic jusque demain et si j'ai pas de retour je le fermerai.
Si d'ici là quelqu'un est intéressé pour prendre contact avec moi qu'il n'hésite pas.
A vrai dire il y a du pain sur la planche, ce code est juste l'entrée..

Bonsoir @dormio

Un portage vers l'un des ESP32 double coeurs (ESP32, ESP32-S2 , ESP32-S3) ne serait pas long à faire, on peut espérer du mieux sur les défauts constatés.

Espressif a commencé il y a dix ans se 'faire la main' avec l'ESP8266 en matière de soc WiFi. Ce fut une réussite
Ce composant est désormais 'déconseillé pour de nouvelles applications' par Espressif sur son site, il a 'fait son temps'

Nickel, ton code me semble super propres, c'est déjà un très bon point.

Le code que tu nous à donné correspond à chaque mcu que tu veux synchroniser ?
Tu as autant de MCU que d'anneau et donc le code doit uniquement gérer l'animation d'un anneau ?

Si tu fais un test avec uniquement deux MCU, tu peux décrire le comportement constaté et celui que tu aurais aimé avoir ?

@al1fch c'est noté, merci pour cette info utile. En effet j'ai le sentiment que les problèmes de synchro peuvent venir de là.
Deux questions, la première est inutile :

  1. ai je davantage de chance d'obtenir une performance wifi avec un esp32 , par exemple le code leds sur un coeur et le code wifi sur l'autre ?
  2. est-ce que l'esp32 C6 est une bonne idée puisqu'il intègre Wifi 6 (802.11ax) ou je prends un risque de compatibilité avec d'autres choses dans la chaine (serveur MQTT, antennes, code ....)

@terwal
merci ! oui 40 arceaux
Ce code est uploadé dans chacun des 40 esp01 pour les strips et une version modifiée pour 40 esp01 pour l'audio
Chaque arceau possède 2 esp 01 indépendants, ça en fait 80 à gérer par le serveur.
L'idée c'est:
A. je publie un nombre en direction du serveur depuis mon ordi.
ce nombre est ni plus ni moins qu'un n° de pattern de leds et/ou un n° de sample à déclencher
B. ce nombre est soit publié en global : tous les arceaux doivent faire la même chose
soit en cascade temporelle, dans ce cas je choisis un intervalle, par exemple 100 ms et dans ce cas je veux que l'ensemble de mes arceaux s'allument les uns après les autres à une fréquence de 10 arceaux par seconde (donc).
Cette partie est gérée du côté de mon programme sur mon ordi (en MaxMSP avec nodeJS), pas dans le sketch.

Le problème c'est que j'en 4 qui s'allument en cascade, puis les 2 suivants qui réagissent 1/2 seconde trop tard et les 5 suivants eux s'allument correctement, donc ceux qui sont en retard s'illuminent tardivement.
L'effet est foiré du coup !
Et je suis absolument incapable de comprendre d'où ça vient.
J'ai imaginé que l'esp01 est occupé à gérer le pattern publié précédemment (300 leds à gérer par arceau quand-même) lorsqu'il reçoit un nouveau n° de pattern.
Donc je me laisse penser que c'est un problème de gestion de tâche, mais je galère grave avec trop peu d'expertise.

J'en doute , l'ESP32-C6 n'a qu'un seul coeur (RISC-V) et son WiFI6 n'est qu'en 2.4GHz
le -C6 pourra intéresser si l'on veut tester Zigbee à faible coût, sa prise en charge par le core Arduino pour ESP32 débute.

Comment tu assures la synchronisation entre les différents arceaux?

Il n'y a pas de synchro à proprement parler, il y a des déclenchements qui sont "timés" par un séquenceur en quelque sorte. J'ai tenté de l'expliqué ici :

je ne sais pas si c'est clair pour toi ?
Est-ce que tu suggères qu'il existe un moyen de synchroniser temporellement les MCU ? Si oui peux-tu expliquer. Merci

Du coup c'est ton programme PC qui s'occupe de la synchronisation, c'est du temps réel en fait.
Lorsque l'arceau doit être allumé, il reçoit un message avec l'indice de la fonction à exécuter.
Il exécute cette fonction jusqu'à qu'il reçoit un autre ordre.

Si j'ai bien compris, ta fonction p(x) est appelé en boucle.
de même pour client.loop, qui s'occupe de regarder si un nouveau message est arrivé.

par contre certaine de tes fonction p, contienne des delay avec gDel à 50 par défaut, mais qui peut être modifié par une command MQTT.
Ce n'est pas terrible de bloquer le processeur.

1 Like

Il peut être envisageable avec une RTC, synchroniser par SNTP.
il faut vérifier que la synchronisation par SNTP est suffisante pour ton projet par contre.
Car sur PC, je crois que l'on est au dessus de 10ms, mais je suppose que c'est largement suffisant.
Dans ce cas, tu pourrais donner tes ordres par paquets, chaque ordre contenant un temps d'activation.
Cela permettrais de tamponner la réception des ordres.

Mais ca complique un peu le processus, je pense que ca vaut le coup d'aller au fond de ton idée.
A moins que @fdufnews voit un problème rédhibitoire, que je n'ai pas appréhender ?

1 Like

Oui, mais si les différents éléments n'ont pas une référence de temps commune comment peuvent-ils être synchronisés?
Tu ne peux pas juste te reposer sur la réception des ordres par le WiFi. Il n'y a aucune garantie sur le temps de délivrance d'un message entre ton serveur et les différents éléments.
Il faudrait que tu ais un serveur de temps quelque part pour que tout le monde soit synchrone.
Et les ordres devraient être envoyés par anticipation pour être pris en compte, par exemple, à la prochaine seconde ce qui laisserait le temps à tous de recevoir le message et l'interpréter.

@terwal
bien vu, en effet il y a du bloquant dans mon code, c'est pas bien ça ! :slight_smile:
RTC ? SNTP ? as tu des pistes à me donner pour que j'évites de me noyer dans les recherches ?

@fdufnews
Trèèèèèès interessant. Je n'avais pas vu les choses comme ça.
M'expliquerais-tu comment démarrer ça ? Y a -t-il rapport avec le message de terwal sur RTC/SNTP ?

Merci à vous et excellente journée ensoleillée. :sun_with_face:

Oui, je pense qu'il parle de la même chose.

Normalement tu ne devrais pas être noyé, ne t'inquiète pas :slight_smile:

RTC est l'acronyme anglais pour horloge temps réel, c'est à dire que c'est un composant qui garde l'heure d'une pars et te garantit une dérive de l'horloge dans une certaines marge.
Par contre bien sûre suivant la qualité du module, la dérive est plus ou moins importante entre chaque module, le module DS3231 à très apprécié.

Ensuite, soit tu t'amuse à configurer au moins une fois l'heure sur chaque ESP, pour que le module RTC puisse te restitué une heure avec une dérive limité.
Soit si les ESP peuvent être connecté à internet ou une machine ayant un serveur SNTP, utiliser ce protocole qui permet d'avoir une heure très précise, indépendant de la latence du réseau dans une certaine mesure.
Après comme précis ne veut pas dire grand chose.
je crois que SNTP la précision est de l'ordre de 100ms, mais j'ai un doute.
le protocole NTP est plus précis, puisque l'on enlève le S de simplifié.

Après tout dépend de la précision dont tu as besoin ?
Par exemple la désynchronisation que tu observes est-elle dû à ton code ou le réseau WIFI.
la qualité du réseau dépend de plusieurs chose, de ton routeur WIFI et de la pollution radio.
après de nos jours un ping de l'ordre de la demi-seconde est quand même très important.

Par exemple chez moi ou je ne capte uniquement mon routeur et mon répéteur, j'ai un ping qui fluctue de manière importante entre 1 et 64ms sur mon routeur et de manière plus stable sur mon répéteur entre 1 et 9ms, avec une grande majorité entre 1 et 2ms

1 Like