esp8266 : blocage aléatoire

Bonjour,

j'ai encore besoin de vos conseils, j'utilise un esp8266 qui transmet les données issues d'un HX711, d'une part, via le Wifi à ThingSpeak, d'autre part, via udp à une base influxdb sur un raspberry local ce qui me permet de disposer de deux dispositifs graphiques d'analyse de mes données indépendants.

Quand je n'utilise que l'une des procédures, ça marche sans problème, mais quand j'utilise les deux, ça plante au niveau de thingspeak de manière erratique, par exemple, 6 heures sans souci puis plus de données ou plutôt la dernière mesure qui se répète.

J'ai tenté d'introduire des fonctions yield de manière à m'assurer que les procédures vont au bout de leur tâche, sans succès.

La solution provisoire consiste à couper l'alim toutes les 6 heures (pendant un quart d'heure au moyen d'un programmateur) ce qui revient à faire un hard reboot. Ça marche mais question élégance...

Voilà la partie de code en question :

void setup() {

  Serial.begin(115200);
  DS18B20.begin();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(50);
    Serial.println("Addresse ip: ");
    Serial.println(WiFi.localIP());
    Serial.println();
    delay(100);
    Serial.print("connexion à  ");
    Serial.println(host);

    scale.set_scale();
    //scale.tare(); //Remet la balance a zero. Attention à chaque redemarrage il reinitialise la tare
    long zero_factor = scale.read_average(); //Get a baseline reading
    Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
    Serial.println(zero_factor);
    scale.set_offset(-250794); //fixe le zero (la tare) a partir d'un zero_factor

  }
  scale.set_scale(calibration_factor); //ajuste la calibration
  poidsPrecedent = scale.get_units();
}
void loop() {

  //Enregistrement de la temperature
  DS18B20.requestTemperatures();
  delay(50);
  temperature = DS18B20.getTempC(Capteur); // enregistre les températures
  
  //Enregistrement de la pesée

  poids = scale.get_units();
  
  Serial.print("Lecture: ");
  Serial.print(poids);
  Serial.print(" kg");
  Serial.print(" calibration: ");
  Serial.print(calibration_factor);
  Serial.println();
  //Enregistrement de la température
  Serial.print("temperature : ");
  Serial.println(temperature);

  if (Serial.available())
  {
    char temp = Serial.read();
    if (temp == '+' || temp == 'a')
      calibration_factor += 10;
    else if (temp == '-' || temp == 'z')
      calibration_factor -= 10;
    else if (temp == 's')
      calibration_factor += 100;
    else if (temp == 'x')
      calibration_factor -= 100;
    else if (temp == 'd')
      calibration_factor += 1000;
    else if (temp == 'c')
      calibration_factor -= 1000;
    else if (temp == 'f')
      calibration_factor += 10000;
    else if (temp == 'v')
      calibration_factor -= 10000;
    else if (temp == 't')
      scale.tare();  //Remet la balance a zero
  }
  
  // Mesure la force du signal de la connexion WiFi (RSSI)
  long int rssi = WiFi.RSSI();
  if (!client.connect(host, port)) {
    Serial.println("erreur de connexion");
    Serial.println("attente x sec...");
    delay(250);
    return;
  }
  StrPoids = "";
  // print RSSI of packet
  Serial.print("' with RSSI ");
  rssi = WiFi.RSSI();

  //Transmission UDP
  if ( millis() - previousMillis >= interval) { //interval = 3 minutes
    previousMillis = millis();
    sendUdp();
  }

  Renvoi = millis();
  // if (poids != 0) { // Elimine les valeurs nulles
  if (poids <= (poidsPrecedent - 0.150)) { // si changement brutal de la valeur, remplace valeur aberrante par valeur précédente
    poids = poidsPrecedent;
  }
  if (poids >= (poidsPrecedent + 0.150)) {
    poids = poidsPrecedent;
  }

  // prépare la requête GET à ThingSpeak
  String url = "/update?key=";
  url += thingspeak_key;
  url += "&field1=";
  url += String(rssi);
  url += "&field2=";
  url += String(temperature);
  url += "&field3=";
  url += String(poids);

  // envoie la requête GET au serveur
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  client.stop();
  
  //  } // Fin de condition "Elimination des données aberrantes"
  delay(postingInterval); //posting Interval = 15 minutes

} // Fin de boucle

//***************************************************************
void sendUdp() {
  udp.begin(localport);
  String line, grenier; // définit le nom de la série de données
  if (poids != 0) { //pour éliminer les valeurs nulles et absentes
    line = String("temperature value=" + String(temperature));
    Serial.println(line);
    Serial.println("Sending UDP packet...");
    Serial.print("localport :");
    Serial.println(localport);
    udp.beginPacket(host2, localport);
    udp.print(line);
    udp.endPacket();
    delay(200);
    line = String("poids value=" + String(poids));
    Serial.println(line);
    // send the packet
    Serial.print("localport :");
    Serial.println(localport);
    Serial.println("Sending UDP packet...");
    udp.beginPacket(host2, localport);
    udp.print(line);
    udp.endPacket();
    delay(200);

  }
}

Deux pistes possibles, comme je le disais un problème de procédure, les différentes opérations liées à une action ne sont pas achevées que l'action suivante est lancée.

l'autre voie est le timing, les données udp sont envoyées toutes les 3 mn via millis alors que le timing global de l'envoi des données est de 15 mn (via delay)

merci d'avance pour vos coups de main.

Lacuzon:
Bonjour,

j'ai encore besoin de vos conseils, j'utilise un esp8266 qui transmet les données issues d'un HX711, d'une part, via le Wifi à ThingSpeak, d'autre part, via udp à une base influxdb sur un raspberry local ce qui me permet de disposer de deux dispositifs graphiques d'analyse de mes données indépendants.

Quand je n'utilise que l'une des procédures, ça marche sans problème, mais quand j'utilise les deux, ça plante au niveau de thingspeak de manière erratique, par exemple, 6 heures sans souci puis plus de données ou plutôt la dernière mesure qui se répète.

J'ai tenté d'introduire des fonctions yield de manière à m'assurer que les procédures vont au bout de leur tâche, sans succès.

La solution provisoire consiste à couper l'alim toutes les 6 heures (pendant un quart d'heure au moyen d'un programmateur) ce qui revient à faire un hard reboot. Ça marche mais question élégance...

Voilà la partie de code en question :

bonsoir Lacuzon
C'est juste la derniere mesure de poids qui se repete "chez" thingspeak ou c'est aussi les autres champs variables (RSSI, temperature ?

Bonsoir artouste,

Tu es devin ?

Oui ce n'est que la mesure du poids qui plante la mesure du rssi et de la température sont OK.

Lacuzon:
Bonsoir artouste,

Tu es devin ?

Oui ce n'est que la mesure du poids qui plante la mesure du rssi et de la température sont OK.

Bonjour Lacuzon
:grin:

Je ne suis ni devin ni plombier;D

Si la propagation vers thingspeak perdure globalement , avec de l'info changeante pour RSSI, temperature et que seul poids reste figé , c'est pour moi le signe que le "coupable" :wink: est AMHA plus à rechercher du coté de la reactualisation des mesures (appel fonction de la lib HX711 ? ) poids conservant derniére valeur actualisée .

Pas trop le temps de regarder plus avant ce W-E

mais je pense, que j'irais gratter vers tes conditions pour ejecter poids selon ce que tu considére une mesure aberrante ou pas ( //changement brutal)

Ok,

Je vois ça, en tout cas, côté transmission udp tout fonctionne sans blocage.

Bon weekend

J-M-L va passer par là et dire qu’utiliser String c’est pas propre et qu’il faut mieux utiliser les chaînes de caractère, soit les c-string.

Bon dans ce cas de figure c’est pas tout à fait le problème mais il y a peut être de ça

Bon, j'attends...

bonjour à tous,

toujours le même problème, les données sont transmises correctement via udp sur ma base influxdb installée sur mon pi3 mais du côté de thingspeak, ça bloque régulièrement et de manière aléatoire. J,'ai fait un nettoyage de mon sketch pour le rendre plus lisible et compréhensible.

je le reposte ici :

void setup() {
  Serial.begin(115200);
  DS18B20.begin();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(50);

    /***************** envoie au terminal les conditions de connexion WiFi*************/
    Serial.println("Addresse ip: ");
    Serial.println(WiFi.localIP());
    Serial.println();
    delay(100);
    Serial.print("connexion à  ");
    Serial.println(host);

    /******************Précise les modalités d'enregistrement des données de la balance***********/
    Serial.println("HX711 Calibration");
    Serial.println("Remove all weight from scale");
    Serial.println("des la lecture commencee, placer un poids connu sur la balance");
    Serial.println("Press a,s,d,f ajoute a la calibration 10,100,1000,10000 respectivement");
    Serial.println("Press z,x,c,v retranche a la calibration10,100,1000,10000 respectivement");
    Serial.println("taper t dans le moniteur pour tarer la balance");

    /******************Définit les conditions d'enregistrement des données***************/
    scale.set_scale();
    //scale.tare(); //Remet la balance a zero. Attention à chaque redemarrage il reinitialise la tare
    long zero_factor = scale.read_average(); //Get a baseline reading
    Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
    Serial.println(zero_factor);
    scale.set_offset(-250794); //fixe le zero (la tare) a partir d'un zero_factor
  }
  scale.set_scale(calibration_factor); //ajuste la calibration
  poidsPrecedent = scale.get_units();
} // Fin de setup

void loop() {
  /*****************Enregistrement de la temperature*************************/
  DS18B20.requestTemperatures();
  delay(50);
  temperature = DS18B20.getTempC(Capteur); // enregistre les temperatures

  /***********************Enregistrement de la pesée************************/
  poids = scale.get_units();
  // Envoie sur le terminal des données de la pesée****************************
  Serial.print("Lecture: ");
  Serial.print(poids);
  Serial.print(" kg");
  Serial.print(" calibration: ");
  Serial.print(calibration_factor);
  Serial.println();

  /***********************Enregistrement de la température******************/
  Serial.print("temperature : ");
  Serial.println(temperature);

  /****************réglage en temps réel des conditions de mesure de la pesée via le terminal*************/
  if (Serial.available())
  {
    char temp = Serial.read();
    if (temp == '+' || temp == 'a')
      calibration_factor += 10;
    else if (temp == '-' || temp == 'z')
      calibration_factor -= 10;
    else if (temp == 's')
      calibration_factor += 100;
    else if (temp == 'x')
      calibration_factor -= 100;
    else if (temp == 'd')
      calibration_factor += 1000;
    else if (temp == 'c')
      calibration_factor -= 1000;
    else if (temp == 'f')
      calibration_factor += 10000;
    else if (temp == 'v')
      calibration_factor -= 10000;
    else if (temp == 't')
      scale.tare();  //Remet la balance a zero
  }

  if (!client.connect(host, port)) {
    Serial.println("erreur de connexion");
    Serial.println("attente x sec...");
    delay(250);
    return;
  }

  /********************Affichage de la force du signal WiFi******************/
  Serial.print("' with RSSI ");
  rssi = WiFi.RSSI();

  /***************Transmission par UDP vers raspberry, stockage dans influxdb**************/
  if ( millis() - previousMillis >= interval) {
    previousMillis = millis();
    sendUdp();
  }
  /*******************Correction des valeurs aberrantes***************************/
  if (poids <= (poidsPrecedent - 0.150)) { // si changement brutal de la valeur, remplace valeur aberrante par valeur précédente
    poids = poidsPrecedent;
  }
  if (poids >= (poidsPrecedent + 0.150)) {
    poids = poidsPrecedent;
  }

  /*****************Préparation de la requête GET à ThingSpeak*************/
  String url = "/update?key=";
  url += thingspeak_key;
  url += "&field1=";
  url += String(rssi);
  url += "&field2=";
  url += String(poids);
  url += "&field3=";
  url += String(temperature);
  yield(); // Permet de terminer les processus en cours

  /***************Envoi de la requête GET au serveur********************/
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  client.stop();
  delay(postingInterval); // donne le tempo

} /**********************Fin de boucle*************************/

/******************Fonction d'envoi via udp*****************************/
void sendUdp() {
  udp.begin(localport);
  String line, essai; // définit le nom de la série de données
  if (poids != 0) { //pour éliminer les valeurs nulles et absentes
    line = String("temperature value=" + String(temperature));
    Serial.println(line);
    Serial.println("Sending UDP packet...");
    Serial.print("localport :");
    Serial.println(localport);
    udp.beginPacket(host2, localport);
    udp.print(line);
    udp.endPacket();
    delay(200);
    line = String("poids value=" + String(poids));
    Serial.println(line);
    // send the packet
    Serial.print("localport :");
    Serial.println(localport);
    Serial.println("Sending UDP packet...");
    udp.beginPacket(host2, localport);
    udp.print(line);
    udp.endPacket();
    delay(200);
  }
}

Bonjour

Peut être descendre dans le code la connection au serveur ThingSpeak pour réduire l'intervalle de temps entre cette connection et l'envoi de la requête GET. Pourquoi intercaler la liaison UDP vers un Raspberry entre la connection au serveur ThingSpeak et l'envoi de la requête GET ?

Ok,

Je vois ça rapidement.

Merci!

Bonjour,
@ al1fch,

Apparemment, c'était bien ça, pas de blocage depuis ma modif d'hier. En fait, quand on fait un peu attention, ça saute aux yeux (problème de copier-coller entre deux programmes qui marchent séparément....)

Encore merci pour le coup de main.