MKR1010 using EMailSender library works twice then will not connect to email server

I'm using a MKR1010 and EMailSender library. Sketch will send an email two times but on the third attempt will not connect to mail server. Restart the sketch and will connect again, but only twice, again. Code waited an hour between email sends and uses different subject and message text. Code is the example sketch with emailSend.send(... moved to the loop.

I tried to post code, but as a new user it appears it will not let me.

#include "Arduino.h"
#include <EMailSender.h>
#include <WiFiNINA.h>

uint8_t connection_state = 0;
uint16_t reconnect_interval = 000;

  EMailSender emailSend("--sending_email@gmail.com", "--apppassword");
  EMailSender::EMailMessage message;

uint8_t WiFiConnect(const char* nSSID = nullptr, const char* nPassword = nullptr)
{
    static uint16_t attempt = 0;
    Serial.print("Connecting to ");
    if(nSSID) {
        WiFi.begin(nSSID, nPassword);
        Serial.println(nSSID);
    }

    uint8_t i = 0;
    while(WiFi.status()!= WL_CONNECTED && i++ < 50)
    {
        delay(200);
        Serial.print(".");
    }
    ++attempt;
    Serial.println("");
    if(i == 51) {
        Serial.print("Connection: TIMEOUT on attempt: ");
        Serial.println(attempt);
        if(attempt % 2 == 0)
            Serial.println("Check if access point available or SSID and Password\r\n");
        return false;
    }
    Serial.println("Connection: ESTABLISHED");
    Serial.print("Got IP address: ");
    Serial.println(WiFi.localIP());
    return true;
}

void Awaits()
{
    uint32_t ts = millis();
    while(!connection_state)
    {
        delay(50);
        if(millis() > (ts + reconnect_interval) && !connection_state){
            connection_state = WiFiConnect();
            ts = millis();
        }
    }
}

void setup()
{
    Serial.begin(115200);
    const char* ssid = "--network";
    const char* password = "--networkpassword";

    connection_state = WiFiConnect(ssid, password);
    if(!connection_state)  // if not connected to WIFI
        Awaits();          // constantly trying to connect

}

void loop()
{
  message.subject = "Subject #1";
  message.message = "Message #1";
  EMailSender::Response resp = emailSend.send("--to_email@gmail.com", message);

  Serial.println("Sending status: ");
  Serial.println(resp.status);
  Serial.println(resp.code);
  Serial.println(resp.desc);

  delay(60*60*1000);

  message.subject = "Subject #2";
  message.message = "Message #2";
  resp = emailSend.send("--to_email@gmail.com", message);

  Serial.println("Sending status: ");
  Serial.println(resp.status);
  Serial.println(resp.code);
  Serial.println(resp.desc);

  delay(60*60*1000);

  message.subject = "Subject #3";
  message.message = "Message #3";
  resp = emailSend.send("--to_email@gmail.com", message);

  Serial.println("Sending status: ");
  Serial.println(resp.status);
  Serial.println(resp.code);
  Serial.println(resp.desc);

  delay(60*60*1000);

}

Your expecting the network connection to remain open for an hour?

Check for a valid network connection before sending, if not connected, connect then send.

Disconnect, sleep, reconnect.

Learn to use millis()

I was checking WiFi.status() ==3 to monitor WiFi connection, but even with WiFi.status() ==3 I needed to reconnect to WiFi to send third message.

I'm also having this issue on Arduino NANO 33 IoT using EMailSender library with WiFiNINA. I'm interested in finding the root cause here.

I've traced this down to the following sequence of calls (so far):

EmailSender::send-->WiFiSSLClient::connect*-->WiFiClient::connectSSL**-->WiFiClient::connected

*this fails giving the "Could not connect to mail server" after 2x successful tries)
**There is a hardcoded loop checking WiFiClient::connected() 1 time per millisecond for 10 seconds;
WiFiClient::connected() fails if socket is not available/ready

I do notice that EmailSender::send seems to create and start a WiFiSSLClient, but never stops it. Unclear if this is a problem...

So I think I got to the bottom of this, or at least found a reasonable workaround

It's an omission in EMailSender library (at least for versions <= 2.4.1). The EMailSender::send never closes the WiFiClient/WiFiSSLClient causing a pile-up of open sockets to the smtp server from the same client. Why 2 is the limited? I don't know yet, but each EMailSender::send call opens a new socket to the server and leaves it open/in a "consumed" state until the WiFi is disconnected/reset. By exposing the WiFiClient _sock variable, you can see that with each email you sent, the ServerDrv::getSocket() returns a brand new socket incrementally with each email; when it gets to 2, starting the client fails. Interestingly enough, the WiFiClient::connect/connected functions can only go to 254 (255 indicates NO_SOCKET_AVAILABLE) so even if you can somehow get past _sock=1 successfully with the gmail smtp server, any code would only be able to send 255 emails and then it will stop working.

When editing the EMailSender library to call WiFiClient::stop() at the end of EMailSender::send, the _sock values are released (no more incrementing to 255) and I no longer get blocked on _sock=2 and emails send OK.

a small code to reproduce:

#include <EMailSender.h>
#include <WiFiNINA.h>

//please enter your sensitive data in the Secret tab
char ssid[] = "my_wifi_ssid";                // your network SSID (name)
char pass[] = "my_wifi_pwd";                // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;             // the Wi-Fi radio's status
int EMAIL_NUMBER = 0;

const char *email_recp = "my_to_email@gmail.com";

EMailSender emailSend("my_from_email@gmail.com", "my_from_email_pwd");

void sendEmail(String subjectStr, String messageStr) {
  
  EMailSender::EMailMessage message;
  message.subject = subjectStr;
  message.message = messageStr;
  bool statusB = false;
  while (!statusB) {
    EMailSender::Response resp = emailSend.send(email_recp, message);

    statusB = resp.status;

    Serial.println("Sending status: ");
    Serial.println(resp.status);
    Serial.println(resp.code);
    Serial.println(resp.desc);
  }
}

void setup() {  
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial);

  // attempt to connect to Wi-Fi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to network: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.println("You're connected to the network");
  Serial.println("---------------------------------------");
  Serial.println("Attempting to send test email to my_to_email@gmail.com");
  sendEmail("From your friendly Arduino board", "The Nano 33 IoT has successfully started and connected to the internet.");
}

void loop() {
  String mess = "Attempt #" + String(++EMAIL_NUMBER);
  sendEmail("What's in a name", mess);
  delay (5000);
}

at the end of EMailSender::send in EMailSender.cpp:

  response.status = true;
  response.code = F("0");
  response.desc = F("Message sent!");

  return response;
}

result:
06:57:24.952 -> Attempting to connect to network: my_wifi_ssid
06:57:37.357 -> Attempting to connect to network: my_wifi_ssid
06:57:48.060 -> You're connected to the network
06:57:48.060 -> ---------------------------------------
06:57:48.060 -> Attempting to send test email to my_to_email@gmail.com
06:57:53.619 -> Sending status:
06:57:53.619 -> 1
06:57:53.619 -> 0
06:57:53.619 -> Message sent!
06:57:58.034 -> Sending status:
06:57:58.034 -> 1
06:57:58.034 -> 0
06:57:58.034 -> Message sent!
06:58:21.557 -> Sending status:
06:58:21.557 -> 0
06:58:21.557 -> 2
06:58:21.557 -> Could not connect to mail server

force WiFiClient/WiFiSSLClient to close in EMailSender::send

  response.status = true;
  response.code = F("0");
  response.desc = F("Message sent!");
  
  client.stop();

  return response;
}

result:
07:01:48.035 -> Attempting to connect to network: my_wifi_ssid
07:02:02.241 -> You're connected to the network
07:02:02.241 -> ---------------------------------------
07:02:02.241 -> Attempting to send test email to my_to_email@gmail.com
07:02:06.661 -> Sending status:
07:02:06.661 -> 1
07:02:06.661 -> 0
07:02:06.661 -> Message sent!
07:02:18.763 -> Sending status:
07:02:18.763 -> 1
07:02:18.763 -> 0
07:02:18.763 -> Message sent!
07:02:28.365 -> Sending status:
07:02:28.365 -> 1
07:02:28.365 -> 0
07:02:28.365 -> Message sent!
07:02:38.185 -> Sending status:
07:02:38.185 -> 1
07:02:38.185 -> 0
07:02:38.185 -> Message sent!
07:02:47.603 -> Sending status:
07:02:47.603 -> 1
07:02:47.603 -> 0
07:02:47.603 -> Message sent!
....and on and on and on

For anyone who comes across this problem, it apparently it is resolved (by stopping the client in EMailSender::send) already in EMailSender 2.4.3. Note, however, that with Arduino IDE 1.X (I don't know about 2.X), the installed library with the IDE's library manager is v2.4.2, which still has the problem. You have to manually download the 2.4.3 library and place it in the ardiuno include library directory.

From the change log in EMailSender v2.4.3:

Change log

  • 12/04/2021: v2.4.3 Fix multiple email send
  • 12/04/2021: v2.4.1 Add support for LITTLEFS and Ffat on esp32 and fix certificate verification from esp32 core 1.0.5
  • 18/03/2021: v2.3.0 Add support for LittleFS on esp8266
  • 02/01/2021: v2.2.0 New support for SAMD devices via WiFiNINA (Arduino MKR WiFi 1010, Arduino Vidor 4000 and Arduino UNO WiFi Rev.2 ecc.).
  • 01/01/2021: v2.1.5 Add possibility to use EHLO instead of HELO, and SASL login.
  • 27/11/2020: v2.1.4 Add more constructor to allow more structure for distribution list (now const char*, char* and String array are supported)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.