Home › Forums › The libraries hosted on the site › EMailSender send email with attachments › Arduino memory availability monitoring and email sending
Tagged: Memory Leak
- This topic has 5 replies, 1 voice, and was last updated 3 years, 11 months ago by
Renzo Mischianti.
-
AuthorPosts
-
-
21 June 2021 at 16:14 #12830
Gilles
Hello!
As part of the realization of my debug monitoring function on my connected beehive project with sending emails via an Ethernet shield and Arduino Mega I noticed this:
14: 10: 38.500 -> Correct assembly and card present
14: 10: 40.937 -> Number of tests requested: 2
14: 10: 40.937 -> <span style=”text-decoration: underline;”>2784</span> = free memory before email
14: 10: 40.971 -> Hi, it’s Hive N ° 2 to give you my IP address.
…..
then once the sending of this first email is done:
14: 10: 42.124 -><span style=”text-decoration: underline;”> 2155</span> = memory after sending the 1st email
14: 10: 42.090 -> resp code = 0
14: 10: 42.124 -> Message sent!then just after sending a second email:
14: 10: 42.328 -> <span style=”text-decoration: underline;”>2053</span> = free memory before sending second email
14: 10: 42.367 -> Hi, it’s Hive # 2, I just adjusted the time on the clock
14: 10: 43.556 -> resp code = 0
14: 10: 43.590 -> <span style=”text-decoration: underline;”>1940</span> = memory after sending the second email
14: 10: 43.590 -> Message sent!
14: 10: 43.590 -> we just readjusted the clock!
14: 10: 43.624 -> Free memory: <span style=”text-decoration: underline;”>2242</span>And after the free memory of the Arduino remains at 2242, however before sending the 2 emails it was 2784. A loss of 542 bytes …
Has anyone tracked this problem and found the origin of it?
Thank you
PS to know the available memory I use the function: freeMemory (); -
22 June 2021 at 09:23 #12866
Gilles
I rebooted my program several times the free memory value is not always the same, but the memory loss after sending the first 2 mails is the same! 542 bytes.
example: 2780 of free memory at boot time then after sending the 2 boot emails (IP address and setting the clock time)
2238 …..
Thank you -
3 July 2021 at 20:56 #13167
Gilles
Hello, I have again just had a loss of internet on my Ethernet shield (but it still works locally (access by its IP address)).
These crashes occur approximately every 15 days, but systematically after sending an email …
My test Arduino seems to be working fine … but not the one on my hive …
Any ideas?
PS: sending an email that crashes internet access is not the same type every time: once sent with an attachment, other times without attachments …
Thank you -
4 July 2021 at 15:21 #13182
Hi Gilles,
sending email need a good quantity of ram, so if you have a memory leack in some part of your code, It’s possible that when EMailSender request It’s quote of memory the microcontroller reboot.A good practique is to separate all the functionality in function with a specified scope, so qhen function finish you free all memory.
Bye Renzo
-
6 July 2021 at 21:43 #13265
Gilles
What do you call: “A good practice is to separate all functionality according to a specified scope, so that when the function is complete, you free all memory.”?
I defined the sending of email in a specific function envoimail ();
int envoimail(int lequel, String NomFichierMensuel, int nbessai) { //nomfichier mensuel contient soit l’adresse IP soit le nom du fichier mensuel à envoyer selon les besoins… Serial.print(F("Nb d’essai demandé :")); Serial.println(nbessai); if (Debug == 1) { commentaires = F(" = mémoire libre avant email"); memory = freeMemory(); // interroge la mémoire libre de l’Arduino Serial.println(memory); Serial.println(commentaires); ecritureJdB(rtc.now(), Mois, -1, memory, commentaires); } // fin du if debug boolean piecejointe; // variable pour savoir si on a une pièce jointe à envoyer avec le mail String msgsujet; // chaine de caractère contenant les textes des emails selon les cas String msgsujet1; // chaine de caractère contenant les textes des emails selon les cas String msgsujet2; // chaine de caractère contenant les textes des emails selon les cas String msgcorps; // chaine de caractère contenant les textes des emails selon les cas String msgcorps1; // chaine de caractère contenant les textes des emails selon les cas String msgcorps2; // chaine de caractère contenant les textes des emails selon les cas String msgcorps3; // chaine de caractère contenant les textes des emails selon les cas String msgcorps4; // chaine de caractère contenant les textes des emails selon les cas String msgcorps5; // chaine de caractère contenant les textes des emails selon les cas switch (lequel) { // test pour savoir quel email envoyer case 1: { // envoi mail vol piecejointe = 0; msgsujet = F("ATTENTION VOL d’une ruche en cours!"); msgcorps1 = F("Le capteur de poids vient de tomber à moins de 5kg, < br > soit la balance a un problème, soit quelqu’ un embarque votre ruche n ° "); msgcorps2 = F( "<br>Soit vous faites une visite approfondie et vous testez la fonction…<br>Pour mémoire mon adresse IP est :"); msgcorps3 = F("<br>Le poids mesuré est de :"); msgcorps4 = F("Kg"); msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel + msgcorps3 + units + msgcorps4; break; } // on sort du test case 2: { // envoi mail mensuel piecejointe = 1; msgsujet = F("Pas de panique c’est le relevé mensuel!"); msgcorps1 = F("Veuillez trouver ci-joint le relevé du mois de "); msgcorps2 = F(" de la ruche n° "); msgcorps = msgcorps1 + NomFichierMensuel + msgcorps2 + numRuche; break; } // on sort du test case 3: { // envoi mail essaimage primaire… piecejointe = 0; msgsujet = F("ATTENTION essaimage possible…"); msgcorps1 = F("Ici la Ruche N° "); msgcorps2 = F(" <br> Détection d’un possible essaimage, < br > soit vous intervenez sur la ruche soit il y a essaimage, soit à voir… <br> La perte de poids est de : "); msgcorps3 = F("Kg <br>Voici les valeurs mémorisées : <br>"); msgcorps4 = F("Kg<br>"); msgcorps5 = F("<br>Pour mémoire mon adresse IP est :"); msgcorps = msgcorps1 + numRuche + msgcorps2 + resultat + msgcorps3 + tableaumemoirepoids[0] + msgcorps4 + tableaumemoirepoids[1] + msgcorps4 + tableaumemoirepoids[2] + msgcorps4 + tableaumemoirepoids[3] + msgcorps4 + tableaumemoirepoids[4] + msgcorps4 + msgcorps5 + NomFichierMensuel; break; } // on sort du test case 4: { // envoi adresse IP… piecejointe = 0; msgsujet1 = F("Salut, c’est la Ruche N° ") ; msgsujet2 = F(" pour te donner mon adresse IP."); msgsujet = msgsujet1 + numRuche + msgsujet2; msgcorps1 = F("Bonjour ici la Ruche N° "); msgcorps2 = F( ".<br>Je viens de démarrer ou de rebooter mon adresse IP est :"); msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel; // ici je me sers de nomfichiermensuel pour transmettre l’adresse IP break; } // on sort du test case 5: { // envoi mise à jour de l’heure… piecejointe = 0; msgsujet1 = F("Salut, c’est la Ruche N° ") ; msgsujet2 = F(".Je viens d’ajuster l’heure de l’horloge"); msgsujet = msgsujet1 + numRuche + msgsujet2; msgcorps1 = F("Bonjour ici la Ruche N° "); msgcorps2 = F( ".<br>Je viens de mettre à jour l’heure avec ces valeurs : "); msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel; // ici je me sers de nomfichiermensuel pour transmettre l’heure break; } // on sort du test case 6: { // envoi message erreur carte SD… piecejointe = 0; msgsujet1 = F("Salut, c’est la Ruche N° ") ; msgsujet2 = F(".Il y a un problème de carte SD"); msgsujet = msgsujet1 + numRuche + msgsujet2; msgcorps1 = F("Bonjour ici la Ruche N° "); msgcorps2 = F(".<br>Mon adresse IP est : "); msgcorps3 = F( ".<br>Il faudrait vérifier car il y a un problème de carte SD!"); msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel + msgcorps3; // ici je me sers de nomfichiermensuel pour transmettre l’adresse IP break; } // on sort du test case 7: { // envoi message pb capteur température et hygrométrie extérieur… piecejointe = 0; msgsujet1 = F("Salut, c’est la Ruche N° ") ; msgsujet2 = F( ".Il y a un problème de capteur Température et hygrométrie"); msgsujet = msgsujet1 + numRuche + msgsujet2; msgcorps1 = F("Bonjour ici la Ruche N° "); msgcorps2 = F(".<br>Mon adresse IP est : "); msgcorps3 = F( ".<br>Il faudrait vérifier mais j’ai un problème de capteur Température et hygrométrie!"); msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel + msgcorps3; // ici je me sers de nomfichiermensuel pour transmettre l’adresse IP break; } // on sort du test case 8: { // envoi message pb d’horloge… piecejointe = 0; msgsujet1 = F("Salut, c’est la Ruche N° ") ; msgsujet2 = F(". Il y a un problème d’horloge"); msgsujet = msgsujet1 + numRuche + msgsujet2; msgcorps1 = F("Bonjour ici la Ruche N° "); msgcorps2 = F(".<br>Mon adresse IP est : "); msgcorps3 = F( ".<br>Un problème d’horloge signifie de nombreuses fonctions Hors Service!<br> Tu risques d’avoir des soucis sur beaucoup d’autres fonctions, une visite urgente s’impose!") ; msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel + msgcorps3; // ici je me sers de nomfichiermensuel pour transmettre l’adresse IP break; } // on sort du test case 9: { // envoi message pb de capteur de température intérieure… piecejointe = 0; msgsujet1 = F("Salut, c’est la Ruche N° ") ; msgsujet2 = F( ".Il y a un problème de capteur de température intérieure"); msgsujet = msgsujet1 + numRuche + msgsujet2; msgcorps1 = F("Bonjour ici la Ruche N° "); msgcorps2 = F(".<br>Mon adresse IP est : "); msgcorps3 = F(".<br>Il y a un problème de capteur de température intérieure, il géle dans la ruche!<br> Le capteur indique une température < à 2°c.") ; msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel + msgcorps3; // ici je me sers de nomfichiermensuel pour transmettre l’adresse IP break; } // on sort du test case 10: { // envoi message pb de capteur de température intérieure… piecejointe = 0; msgsujet1 = F("Salut, c’est la Ruche N° ") ; msgsujet2 = F(".Il y a peut-être un essaimage secondaire"); msgsujet = msgsujet1 + numRuche + msgsujet2; msgcorps1 = F("Bonjour ici la Ruche N° "); msgcorps2 = F(".<br>Mon adresse IP est : "); msgcorps3 = F(".<br>La perte de poids est de : "); msgcorps4 = F("Kg <br> "); msgcorps5 = F("Kg <br>Voici les valeurs mémorisées : <br>"); msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel + msgcorps3 + resultat + msgcorps5 + tableaumemoirepoids[0] + msgcorps4 + tableaumemoirepoids[1] + msgcorps4 + tableaumemoirepoids[2] + msgcorps4 + tableaumemoirepoids[3] + msgcorps4 + tableaumemoirepoids[4] + msgcorps4; break; } // on sort du test case 11: { // envoi message pb de mise à jour ThingSpeak… piecejointe = 0; msgsujet1 = F("Salut, c’est la Ruche N° ") ; msgsujet2 = F(". Il y a un problème de mise à jour ThingSpeak"); msgsujet = msgsujet1 + numRuche + msgsujet2; msgcorps1 = F("Bonjour ici la Ruche N° "); msgcorps2 = F(".<br>Le code erreur de ThingSpeak est : "); msgcorps3 = F( ".<br>Un problème de mise à jour de ThingSpeak et peut-être aussi de ton serveur personnel est survenu ce jour!<br> Il faut vérifier si c’est juste un problème fugitif ou si le problème est durable.<br> Un reboot de l’Arduino pourrait être nécessaire…"); msgcorps = msgcorps1 + numRuche + msgcorps2 + NomFichierMensuel + msgcorps3; // ici je me sers de nomfichiermensuel pour transmettre le code d’erreur de retour de ThingSpeak break; } // on sort du test } // fin du switch /* début de l’envoi du mail */ EMailSender::EMailMessage message; // structure défine dans EmailSender.h message.subject = msgsujet; message.message = msgcorps; Serial.println(message.subject); // pour infos peut-être masqué Serial.println(message.message); // pour infos peut-être masqué if (piecejointe != 0) { EMailSender::FileDescriptior fileDescriptor[piecejointe]; // début envoi mail avec piece jointe structure défine dans EmailSender.h fileDescriptor[0].filename = NomFichierMensuel; fileDescriptor[0].url = NomFichierMensuel; fileDescriptor[0].mime = "text / csv"; fileDescriptor[0].encode64 = false; fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SD; EMailSender::Attachments attachs = { piecejointe, fileDescriptor }; // structure défine dans EmailSender.h EMailSender::Response resp = emailSend.send(arrayOfEmail, nb_Destinaire_Mail, message, attachs); // on envoi l’email Serial.println(F("Statut de l’envoi avec piece jointe : ")); // pour infos peut-être masqué Serial.println(resp.status); // pour infos peut-être masqué Serial.print(F("resp Code: ")); // pour infos peut-être masqué Serial.println(resp.code); // pour infos peut-être masqué Serial.print(F("Description : ")); // pour infos peut-être masqué Serial.println(resp.desc); // pour infos peut-être masqué if (Debug == 1) { commentaires = resp.desc; // on recopie le messge de retour de la fonction email dans la zone texte du debug code1 = resp.code.toInt(); // conversion de la chaine resp.code dans l’entier code1 memory = freeMemory(); // interroge la mémoire libre de l’Arduino Serial.println(memory); Serial.println(commentaires); ecritureJdB(rtc.now(), Mois, memory, code1, commentaires); // envoi à la fonction d’écriture du journal de bord sur la SD } // fin if Debug if (resp.code == "0") { // l’envoi du mail c’est bien passé retourmail = 0; // positionne retourmail à 0 return (retourmail); // retourne la valeur de retourmail 0 } // fin de c’est bon le mail avec pièce jointe else { // on a un problème d’envoi d’email retourmail = 1; // positionne retourmail à 1 return (retourmail); // retourne la valeur de retourmail 1 } // fin du else (fin du on a un problème d’envoi mail) } // fin du if il y a une piece jointe else { // début envoi mail sans pièce jointe! EMailSender::Response resp = emailSend.send(arrayOfEmail, nb_Destinaire_Mail, message); // on envoi l’email nbessai = nbessai - 1; // on vient de faire un esai de plus on décrémente Serial.print(F("Nb d’essai restant :")); Serial.println(nbessai); Serial.print(F("resp code = ")); Serial.println(resp.code); if (Debug == 1) { commentaires = resp.desc; // on recopie le messge de retour de la fonction email dans la zone texte du debug code1 = resp.code.toInt(); // conversion de la chaine resp.code dans l’entier code memory = freeMemory(); // interroge la mémoire libre de l’Arduino Serial.println(memory); Serial.println(commentaires); ecritureJdB(rtc.now(), Mois, memory, code1, commentaires); // envoi à la fonction d’écriture du journal de bord sur la SD } // fin if Debug if (resp.code == "0") { // on vient de faire un essai d’envoi de mail desarmement = 1; // positionne desarmement à 1 retourmail = 0; // positionne retourmail à 0 return (retourmail); // retourne la valeur de retourmail 0 } // c’est bon on sort en retournant la valeur 0 while (nbessai > 0) { // tant qu’on a choisit de faire un essai on recommence if (resp.code != "0") { //début d’un autre essai d’envoi des mails delay(30000); // on attends 30 secondes avant de reessayer pendant ce temps on ne fait rien…. Serial.println(F("On vient d’attendre 30 secondes")); // peut-être masqué EMailSender::Response resp = emailSend.send(arrayOfEmail, nb_Destinaire_Mail, message); // on envoi l’email nbessai = nbessai - 1; // on vient de faire un essai de plus… Serial.print(F("Nb d’essai restant :")); Serial.println(nbessai); Serial.print(F("resp code = ")); Serial.println(resp.code); if (Debug == 1) { commentaires = resp.desc; // on recopie le messge de retour de la fonction email dans la zone texte du debug code1 = resp.code.toInt(); // conversion de la chaine resp.code dans l’entier code memory = freeMemory(); // interroge la mémoire libre de l’Arduino Serial.println(memory); Serial.println(commentaires); ecritureJdB(rtc.now(), Mois, memory, code1, commentaires); // envoi à la fonction d’écriture du journal de bord sur la SD } // fin if Debug if (resp.code == "0") { // on a réussi à envoyer l’email desarmement = 1; // positionne desarmement à 1 retourmail = 0; // positionne retourmail à 0 return (retourmail); // retourne la valeur de retourmail 0 } // fin du if on a bien envoyé le mail if (nbessai <= 0) { // si on a atteint le nombre d’essai maxi on arrête retourmail = 1; // positionne retourmail à 1 return (retourmail); // retourne la valeur de retourmail 1, c’est un echec } // fin du nombre d’essai d’envoi d’email sans succés… } // fin d’un autre essai } // fin du while } // fin de l’envoi de mail sans pièce jointe } //fin fonction envoi mail
Thank you
-
7 July 2021 at 08:00 #13269
Hi,
ok, perfect.
So if your device was resetting every 15 days there isn’t a problem of EMailSender.
Probably you have a little memory leak that eat a minimal quantity of ram.
The execution of this function use the same quantity of memory, and when the function end free all memory of the function scope.
But, if the main scope increase day by day the memory usage in the long term the device reset at the execution of the function.
Bye Renzo
-
-
AuthorPosts
- You must be logged in to reply to this topic.