I am having trouble resolving an issue with sending an email with a jpg file via smtp2go using code posted by SurferTim in this thread by donfrankrice.
I have adjusted the code to my specific hardware and local settings and am able to successfully email a jpg file, however there is an issue with the length of time for encoding the image file. I have tried sending a 640x480 image totaling about 47k as well as a 320x240 image totaling about 11k. In each case the time to encode and send the email has been between 6 and 8 minutes.
I have tried commenting out/in various lines without success. I have added serial.print lines at the major events in the code, and it is definitely the encode or rather encodeblock portion of the code where the delay is occurring.
I am using an arduino mega 2560 and an adafruit winc1500 wifi shield. I've gone over the original code and my own sketch repeatedly and cannot find any discrepancies, but I'm obviously missing something. Any tips would be appreciated.
/*
Portions of this code adapted from code created by the following:
SuferTim
Email client sketch for IDE v1.0.5 and w5100/w5200
Posted 07 May 2015
modified 23 Oct 2019
Tom Igoe
Connects to WiFi network, then print MAC address, IP address, and
network details.
created 13 July 2010
by dlf (Metodo2 srl)
modified 31 May 2012
modified 23 Oct 2019
Eric Ayars
Test/demo of read routines for a DS3231 RTC.
created 00 Apr 2011
Public Domain
This is a basic snapshot sketch using the VC0706 library.
On start, the Arduino will find the camera and SD card and
then snap a photo, saving it to the SD card.
BARRAGAN <http://barraganstudio.com>
Servo control
modified 08 Nov 2013 by Scott Fitzgerald
*/
#include <Wire.h>
#include <WiFi101.h>
#include <SPI.h>
#include <SD.h>
#include "arduino_secrets.h" //enter login data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS; // the WiFi radio's status
// this must be unique
byte mac[] = { 0xF8, 0xF0, 0x05, 0x90, 0x1E, 0x09 };
// change network settings to yours
IPAddress ip( 192, 168, 43, 164 );
IPAddress gateway( 192, 168, 0, 1 );
IPAddress subnet( 255, 255, 255, 0 );
char server[] = "mail.smtp2go.com"; // change server to your email server domain
int port = 2525;
WiFiClient client;
File myFile;
char b64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char tBuf[64];
char b64Buf[128];
byte bufCount;
void setup()
{
Serial.begin(115200);
//pinMode(10,OUTPUT); // WiFi Shield pin
//digitalWrite(10,HIGH);
pinMode(4,OUTPUT); // SD card pin
// attempt to connect to WiFi network:
while ( status != WL_CONNECTED)
{
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network:
delay(10000); // wait 10 seconds for connection:
}
if(!SD.begin(4))
Serial.println(F("SD failed"));
Serial.println(F("Ready. Press 'e' to send.")); // <<<<<<<<<<< !!!need to change/remove this!!!! <<<<<<<<<<<<<<
}
void loop()
{
byte inChar;
inChar = Serial.read();
if(inChar == 'e')
{
if(sendEmail()) Serial.println(F("Email sent")); // infinite loop - need to change this somehow
else Serial.println(F("Email failed"));
}
}
byte sendEmail()
{
byte thisByte = 0;
byte respCode;
// char tBuf[64];
if(client.connect(server,port) == 1) {
Serial.println(F("connected"));
} else {
Serial.println(F("connection failed"));
return 0;
}
if(!eRcv()) return 0;
Serial.println(F("Sending hello"));
strcpy_P(tBuf,PSTR("EHLO\r\n"));
client.write(tBuf);
if(!eRcv()) return 0;
Serial.println(F("Sending auth login"));
strcpy_P(tBuf,PSTR("auth login\r\n"));
client.write(tBuf);
if(!eRcv()) return 0;
Serial.println(F("Sending User"));
strcpy_P(tBuf,PSTR("xxxxxxxxxxxxxxxxx\r\n"));
client.write(tBuf);
if(!eRcv()) return 0;
Serial.println(F("Sending Password"));
strcpy_P(tBuf,PSTR("xxxxxxxxxxxxxxxxxxxx\r\n"));
client.write(tBuf);
if(!eRcv()) return 0;
// change to your email address (sender)
Serial.println(F("Sending From"));
strcpy_P(tBuf,PSTR("MAIL From: <xxxxxxx@xxxxx.xxxx>\r\n"));
client.write(tBuf);
if(!eRcv()) return 0;
// change to recipient address
Serial.println(F("Sending To"));
strcpy_P(tBuf,PSTR("RCPT To: <xxxxxxxxxx@xxxx.com>\r\n"));
client.write(tBuf);
if(!eRcv()) return 0;
Serial.println(F("Sending DATA"));
strcpy_P(tBuf,PSTR("DATA\r\n"));
client.write(tBuf);
if(!eRcv()) return 0;
Serial.println(F("Sending email"));
// change to recipient address
strcpy_P(tBuf,PSTR("To: You <xxxxxxxxx@gmail.com>\r\n"));
client.write(tBuf);
// change to your address
strcpy_P(tBuf,PSTR("From: Fish <xxxxxxxx@xxxxxxxxxxx.xyz>\r\n"));
client.write(tBuf);
client.println("Subject: Arduino email image");
client.write("MIME-Version: 1.0\r\n");
client.write("Content-Type: Multipart/mixed; boundary=frontier\r\n\r\n");
client.write("--frontier\r\n");
client.write("Content-Type: text/plain\r\n\r\n");
client.write("This is an image from my Arduino!\r\n");
client.write("--frontier\r\n");
client.write("Content-Type: image/jpeg\r\n");
client.write("Content-Disposition: attachment; filename=IMAGE01.JPG\r\n");
client.print("Content-Transfer-Encoding: base64\r\n\r\n");
// this is where you would send your file
int clientCount = 0;
// change this to a valid jpg image file name
myFile = SD.open("IMAGE01.JPG",FILE_READ);
if(myFile) {
encode();
myFile.close();
}
else {
Serial.println(F("File open failed"));
}
client.write("--frontier--\r\n");
client.println(".");
if(!eRcv()) return 0;
Serial.println(F("Sending QUIT"));
strcpy_P(tBuf,PSTR("QUIT\r\n"));
client.write(tBuf);
if(!eRcv()) return 0;
client.stop();
Serial.println(F("disconnected"));
return 1;
}
byte eRcv()
{
byte respCode;
byte thisByte;
int loopCount = 0;
while(!client.available()) {
delay(1);
loopCount++;
// if nothing received for 10 seconds, timeout
if(loopCount > 10000) {
client.stop();
Serial.println(F("\r\nTimeout"));
return 0;
}
}
respCode = client.peek();
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
if(respCode >= '4')
{
efail();
return 0;
}
return 1;
}
void efail()
{
byte thisByte = 0;
int loopCount = 0;
client.println("QUIT");
while(!client.available()) {
delay(1);
loopCount++;
// if nothing received for 10 seconds, timeout
if(loopCount > 10000) {
client.stop();
Serial.println(F("\r\nTimeout"));
return;
}
}
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
client.stop();
Serial.println(F("disconnected"));
}
void encode()
{
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (myFile.available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) myFile.read();
if (myFile.available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
for(i=0;i<4;i++) client.write(out[i]);
blocksout++;
}
if (blocksout>=19||myFile.available()==0){
if (blocksout) client.print("\r\n"); blocksout=0;
}
}
}
void encodeblock( byte *in, byte *out, int len )
{
out[0] = (byte) b64Chars[ (in[0] >> 2) ];
out[1] = (byte) b64Chars[ (in[0] & 0x03) << 4 | (in[1] & 0xf0) >> 4 ];
out[2] = (byte) (len > 1 ? b64Chars[ (in[1] & 0x0f) << 2 | (in[2] & 0xc0) >> 6 ] : '=');
out[3] = (byte) (len > 2 ? b64Chars[ (in[2] & 0x3f) ] : '=');
}