Send email with attachments (v2.x library): Arduino Ethernet – Part 1

Spread the love
  •  
  •  
  •  
  • 1
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    1
    Share

Here I’d like to explain the version 2 of the EMailSender library, a big evolution respect to version 1, with support for Arduino with w5100, w5200 and w5500 ethernet shield and enc28J60 clone devices, and support for esp32 and esp8266.
Now you can add attachments also, loaded from storage device like SD or SPIFFS.

You can refer at the version 1 on this article Send email with esp8266 and Arduino

Introduction

A simple method to notify a problem is to use email, so I created a library to do It.

Send email with attachments Arduino library
Send email with attachments Arduino library

This library use the SMTP:

The Simple Mail Transfer Protocol (SMTP) is a communication protocol for electronic mail transmission. As an Internet standard, SMTP was first defined in 1982 by RFC 821, and updated in 2008 by RFC 5321 to Extended SMTP additions, which is the protocol variety in widespread use today. Mail servers and other message transfer agents use SMTP to send and receive mail messages. Proprietary systems such as Microsoft Exchange and IBM Notes and webmail systems such as Outlook.com, Gmail and Yahoo! Mail may use non-standard protocols internally, but all use SMTP when sending to or receiving email from outside their own systems. SMTP servers commonly use the Transmission Control Protocol on port number 25. (cit WiKi)

For the examples I use a gmail dedicated account, I create a new one account because you must reduce security to use It with an external program.

Library

You can find my library here.

To download.

Click the DOWNLOADS button in the top right corner, rename the uncompressed folder EMailSender.

Check that the EMailSender folder contains EMailSender.cpp and EMailSender.h.

Place the EMailSender library folder your /libraries/ folder.

You may need to create the libraries subfolder if its your first library.

Restart the IDE.

Usage

Constructor: Default value is quite simple and use GMail as smtp server.

EMailSender emailSend("smtp.account@gmail.com", "password");

If you want use onother provider you can use more complex (but simple) contructor

EMailSender(const char* email_login, const char* email_password);

EMailSender(const char* email_login, const char* email_password, const char* email_from);

EMailSender(const char* email_login, const char* email_password, const char* email_from, const char* smtp_server, uint16_t smtp_port);
  • email_login: login to account smtp
  • email_password: password account smtp
  • email_from: email of sender
  • smtp_server: server SMTP
  • smtp_port: SMTP port

Now respect to the v1.x library you can note that isSecure flag no more exist

  • isSecure = false: if false BearSSL allows for ‘insecure’ TLS connections (only for >2.4.2 esp8266 core)

but you can manage It with

void setIsSecure(bool isSecure = false);

Other parameters that you can set post constructor are

void setUseAuth(bool useAuth = true);
void setPublicIpDescriptor(const char *publicIpDescriptor = "mischianti");

The first allow to exclude the authentication handshake, the second change the HELO message identification.

You must connect to the internet :P.

Basic example with GMail smtp

You must refert to Part 2 to setup your GMail account and to check all parameter.

Create a message with the structure EMailMessage

    EMailSender::EMailMessage message;
    message.subject = "Subject";
    message.message = "Hi, How are you<br>Fine.";

Send message:

    EMailSender::Response resp = emailSend.send("account_to_send@gmail.com", message);

Then check the response:

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

Example output:

Connection: ESTABLISHED
Got IP address: 192.168.1.104
Sending status: 
1
0
Message sent!

Arduino

Arduino, normally, manage network with external device, the standard device like w5100 use Ethernet library the clones ENC28J60 have some libraries to select.

To select your device you must go on EMailSenderKey.h library file and set the correct one

#define DEFAULT_EMAIL_NETWORK_TYPE_ARDUINO 	NETWORK_ENC28J60 // Default

The library loaded to manage this type of device is UIPEthernet, you can find the library on library manager of the Arduino IDE

or you can change default network type

#define DEFAULT_EMAIL_NETWORK_TYPE_ARDUINO 	NETWORK_W5100

This is the standard implementation and use Ethernet library.

An important think to consider is that this Ethernet shield not support SSL or TLS, so you must find a provider SMTP that offer an SMTP connection without this type of encription.

I create a topic on forum where you can add the provider you use, that you can find mine also.

SMTP server to use with the EMailSender library

As I already say I use an ENC28J60 with Arduino Mega 2560, here the connection schema:

Arduino Mega And Enc28j60 Ethernet connection schema
Arduino Mega And Enc28j60 Ethernet connection schema

Send simple email

So here an example of simple EMail send with SendGrid provider.

/*
 * EMailSender library for Arduino, esp8266 and esp32
 * Arduino Mega and UIPEthernet send example with Sendgrid provider
 *
 * Pay attention you must set in the library
 * #define DEFAULT_EMAIL_NETWORK_TYPE_ARDUINO 	NETWORK_ENC28J60
 * for UIPEthernet
 *
 * #define DEFAULT_EMAIL_NETWORK_TYPE_ARDUINO 	NETWORK_W5100
 * for standard Ethernet
 *
 *
 * https://www.mischianti.org
 *
 */

#include "Arduino.h"
#include <SPI.h>
#include <UIPEthernet.h>

#include <EMailSender.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

EMailSender emailSend("<YOUR-SENDGRID-API-KEY>", "<YOUR-SENDGRID-PASSWD>", "<FROM-EMAIL>", "smtp.sendgrid.net", 25);

void setup()
{
    // Open serial communications and wait for port to open:
    Serial.begin(115200);
//    while (!Serial) {}

    delay(2000);

    Serial.println("Starting!");

    // start the Ethernet connection:
    if (Ethernet.begin(mac) == 0) {
      Serial.println("Failed to configure Ethernet using DHCP");
      while(1);
    }
    Serial.print("IP address ");
    Serial.println(Ethernet.localIP());


    EMailSender::EMailMessage message;
    message.subject = "Soggetto";
    message.message = "Ciao come stai<br>io bene.<br>www.mischianti.org";

    EMailSender::Response resp = emailSend.send("email_to_receive@gmail.com", message);

    Serial.println("Sending status: ");

    Serial.println(resp.status);
    Serial.println(resp.code);
    Serial.println(resp.desc);
}

void loop()
{

}

Send email with attachments

Send email with attachments Arduino esp8266 esp32 test with image and txt
Send email with attachments Arduino esp8266 esp32 test with image and txt

I’m going to add this example only for explain how to do, I can’t test It because I don’t have a provider SMTP without SSL and TLS that support attachments.

Naturally you need a storage device where you put the data to attach, I use a normal SD adapter attached to CS pin 4.

You can find all information on how to connect SD card in this article “How to use SD card with esp8266, esp32 and Arduino“.

Arduino Mega Enc28j60 SD connection schema EMailSender
Arduino Mega Enc28j60 SD connection schema EMailSender

The core of the code is the generation of structure to pass the information to load and stream the files.

    EMailSender::FileDescriptior fileDescriptor[1];
    fileDescriptor[0].filename = F("test.txt");
    fileDescriptor[0].url = F("/test.txt");
    fileDescriptor[0].mime = MIME_TEXT_PLAIN;
    fileDescriptor[0].encode64 = false;
    fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SD;

    EMailSender::Attachments attachs = {1, fileDescriptor};

    EMailSender::Response resp = emailSend.send("email_to_receive@gmail.com", message, attachs);

The fields of EMailSender::FileDescriptior are quite comprehensive, but pay attention to encode64 that specify if you want encode all the content, this is usefully if there are some special character non supported.
For image if you don’t specify the encode64 probably they arrive with artefact.

But pay attention, the encoding af big file request a bit of time.

The filed mime specify the mime type of the file you want attach. Here some examples of existing mime type.

Than you must specify the storageType, in genera we only support SD and SPIFFS, for Arduino only SD.

The filename and url the filename is the name that appear to the receiver, the url is where is the file located in the FS selected.

Than in the EMailSender::Attachments you must specify the number of attachments and set the array of EMailSender::FileDescriptior.

The resulting code is this

/*
 * EMailSender library for Arduino, esp8266 and esp32
 * Arduino Mega and UIPEthernet send example with attach
 * this example is not tested for all, I can't find a provider
 * that manage attach without SSL and TLS
 *
 * Pay attention you must set in the library
 * #define DEFAULT_EMAIL_NETWORK_TYPE_ARDUINO 	NETWORK_ENC28J60
 * for UIPEthernet
 *
 * #define DEFAULT_EMAIL_NETWORK_TYPE_ARDUINO 	NETWORK_W5100
 * for standard Ethernet
 *
 * The base64 encoding of the image is slow, so be patient
 *
 *
 * https://www.mischianti.org
 *
 */

#include "Arduino.h"
#include <SPI.h>
#include <UIPEthernet.h>
#include <SD.h>

#include <EMailSender.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

//	EMailSender(const char* email_login, const char* email_password, const char* email_from, const char* smtp_server, uint16_t smtp_port, bool isSecure = false);
EMailSender emailSend("<LOGIN>", "<PASSWD>", "<EMAIL-FROM>", "<SMTP-SERVER>", "<SMTP-SERVER-PORT>");

void printDirectory(File dir, int numTabs);

//The setup function is called once at startup of the sketch
void setup()
{
    Serial.begin(115200);

    delay(2000);

    Serial.println("Starting!");

    Serial.print("Initializing SD card...");

    if (!SD.begin(4)) {
      Serial.println("initialization failed!");
      while (1);
    }
    Serial.println("initialization done.");

    File root = SD.open("/");

    printDirectory(root, 0);

    Serial.println("done!");

//	File myFile = SD.open("/TEST.TXT", "r");
//	  if(myFile) {
//		  myFile.seek(0);
//		  DEBUG_PRINTLN(F("OK"));
//		myFile.close();
//	  }
//	  else {
//		  DEBUG_PRINTLN(F("KO"));
//	  }
//
//
    // start the Ethernet connection:
    if (Ethernet.begin(mac) == 0) {
      Serial.println("Failed to configure Ethernet using DHCP");
      while(1);
    }
    Serial.print("IP address ");
    Serial.println(Ethernet.localIP());


    EMailSender::EMailMessage message;
    message.subject = "Soggetto";
    message.message = "Ciao come stai<br>io bene.<br>www.mischianti.org";
    message.mime = MIME_TEXT_PLAIN;

// 		Two file
//    EMailSender::FileDescriptior fileDescriptor[2];
//    fileDescriptor[1].filename = F("test.txt");
//    fileDescriptor[1].url = F("/test.txt");
//    fileDescriptor[1].storageType = EMailSender::EMAIL_STORAGE_TYPE_SD;
//
//    fileDescriptor[0].filename = F("logo.jpg");
//    fileDescriptor[0].url = F("/logo.jpg");
//    fileDescriptor[0].mime = "image/jpg";
//    fileDescriptor[0].encode64 = true;
//    fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SD;
//
//    EMailSender::Attachments attachs = {2, fileDescriptor};

// 		One file
    EMailSender::FileDescriptior fileDescriptor[1];
    fileDescriptor[0].filename = F("test.txt");
    fileDescriptor[0].url = F("/test.txt");
    fileDescriptor[0].mime = MIME_TEXT_PLAIN;
    fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SD;

    // Pay attention base64 encoding is quite slow
//	EMailSender::FileDescriptior fileDescriptor[2];
//	fileDescriptor[0].filename = F("logo.jpg");
//	fileDescriptor[0].url = F("/logo.jpg");
//	fileDescriptor[0].mime = "image/jpg";
//	fileDescriptor[0].encode64 = false;
//	fileDescriptor[0].storageType = EMailSender::EMAIL_STORAGE_TYPE_SD;

    EMailSender::Attachments attachs = {1, fileDescriptor};

    EMailSender::Response resp = emailSend.send("email_to_receive@gmail.com", message, attachs);

    Serial.println("Sending status: ");

    Serial.println(resp.status);
    Serial.println(resp.code);
    Serial.println(resp.desc);

    File root2 = SD.open("/");

    printDirectory(root2, 0);

    Serial.println("done!");
    SD.end();
}

void loop()
{

}

void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

Thanks

  1. Send email with attachments (EMailSender v2.x library): Arduino Ethernet
  2. Send email with attachments (EMailSender v2.x library): esp32 and esp8266

GitHub library


Spread the love
  •  
  •  
  •  
  • 1
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    1
    Share

You may also like...

1 Response

  1. 9 June 2019

    […] I finally upgrade this library with support for Arduino (Ethernet, UIPEthernet and SD as storage), esp32 (SD and SPIFFS) and esp8266 (SD and SPIFFS), with the possibility of attaching files.Refer to this article for the version 2.x of the library “Send email with attachments (v2.x library)“. […]

Leave a Reply

Your email address will not be published. Required fields are marked *