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 ();
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
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
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.
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
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
Maintaining a repository (or site or forum) is a lot like tending to a garden - it requires constant care and attention to keep it thriving. If you're a skilled gardener (or coder!) and want to help keep our repository blooming, we'd love to have you on board! We're also looking for talented writers and forum moderators to help us grow our community. Interested in joining our team? Don't hesitate to reach out and let us know how you can contribute!
Are you a fan of electronics or programming? Share your knowledge with others, write a simple tutorial or how to make a great project Contact me: share_your_ideas@mischianti.org
The content displayed on this website is protected under a CC BY-NC-ND license. Visitors are prohibited from using, redistributing, or altering any content from this website for commercial purposes, including generating revenue through advertising. Any unauthorized use is a violation of the license terms and legal action may be taken against individuals or entities found to be in violation.
You must also provide the link to the source.
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.