Arduino memory availability monitoring and email sending

Home Forums The libraries hosted on the site EMailSender send email with attachments Arduino memory availability monitoring and email sending

Tagged: 

Viewing 5 reply threads
  • Author
    Posts
    • #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 ();

      • #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

        • #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

          • #13182
            Renzo Mischianti
            Keymaster

              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

            • #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

              • #13269
                Renzo Mischianti
                Keymaster

                  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

              Viewing 5 reply threads
              • You must be logged in to reply to this topic.
              Exit mobile version