Hi everyone,
I am using a Redboard with an Ethernet Shield 2. I have an SD card with an image file called “motion.jpg” inserted in the shield, and I am attempting to send this file as an attachment via an email relayed through smtp2go. I can get the email to send well enough, and it even has an attached file called “motion.jpg”. This file, however, has 0 bytes. I’ve done some searching through the Arduino boards, and have come across other posts with code that should encode the image file to send as an attachment. I think I am following along well enough, but I am missing something. Since I am fairly new to this, what I am missing is probably obvious. Can someone please tell me where I am going wrong?
Here is the code that I am using:
/*
Email client sketch for IDE v1.0.5 and w5100/w5200
Posted 7 May 2015 by SurferTim
Encoding Routines by Razorblade
https://www.base64encode.org/ Encoder Site
http://forum.arduino.cc/index.php?topic=296897.0 SurferTim's Addition Thread
http://forum.arduino.cc/index.php?topic=67701.30 Encoding Thread by Razorblade
*/
#include <SD.h>
#include <SPI.h>
#include <Ethernet2.h>
#define W5200_CS 10 //Denotes Pin 10 as W5200 Pin
#define SDCARD_CS 4 //Denotes Pin 4 as SD Card Pin
File SendFile;
static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//Mac must be unique
byte mac[] = { 0, 0, 0, 0, 0, 0 };
char server[] = "mail.smtp2go.com";
int port = 80;
EthernetClient client;
void setup()
{
Serial.begin(9600);
//Initialize SD Card
Serial.print("Initializing SD card...");
pinMode(W5200_CS, OUTPUT);
digitalWrite(W5200_CS,HIGH);
pinMode(SDCARD_CS,OUTPUT);
if (!SD.begin(SDCARD_CS)) {
Serial.println("Initialization Failed!");
return;
}
Serial.println("Initialization Successful");
delay(2000);
//Ethernet.begin(mac, ip, gateway, gateway, subnet);
Serial.println("Trying to connect");
if (!Ethernet.begin(mac)){
Serial.println("Failed to DHCP");
// verifyng connection
while(true);
}
delay(10000);
// IP address is:
Serial.print("IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
Serial.println();
Serial.println(F("Ready. Press 'e' to send."));
}
void loop(){
byte inChar;
inChar = Serial.read();
if(inChar == 'e'){
if(sendEmail()) Serial.println(F("Email Sent"));
else Serial.println(F("Email Failed"));
}
}
byte sendEmail(){
byte thisByte = 0;
byte respCode;
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"));
//replace 1.2.3.4 with your Arduino's ip**************************
client.println("EHLO");
if(!eRcv()) return 0;
Serial.println(F("Sending authorizes login"));
client.println("auth login");
if(!eRcv()) return 0;
Serial.println(F("Sending User"));
//Change to your base64 encoded user**************************
client.println("xxxxxxxxxx");
if(!eRcv()) return 0;
Serial.println(F("Sending Password"));
//change to your base64 encoded password**************************
client.println("yyyyyyyyyy");
if(!eRcv()) return 0;
//change to your email address (sender)**************************
Serial.println(F("Sending From"));
client.println("MAIL From: <sender@gmail.com>");
if(!eRcv()) return 0;
//change to recipient address**************************
Serial.println(F("Sending To"));
client.println("RCPT To: <receiver@gmail.com>");
if(!eRcv()) return 0;
Serial.println(F("Sending DATA"));
client.println("DATA");
if(!eRcv()) return 0;
Serial.println(F("Sending email"));
//change to recipient address**************************
client.println("To: You <receiver@gmail.com>");
//change to your address**************************
client.println("From: Me <sender@gmail.com>");
client.println("Subject: Arduino email test");
//****************************************************
//Start of Attach File
SendFile =SD.open("motion.jpg",FILE_READ);
client.print("Content-Type: image/jpg; name=\"motion.jpg\"\r\n");
client.write("Content-Disposition: attachment; filename=motion.jpg\r\n");
client.print("Content-Transfer-Encoding: base64\r\n\r\n");
encode();
SendFile.close();
//End of Attach File
//****************************************************
client.print("\r\n.\r\nQUIT\n");
if(!eRcv()) return 0;
client.stop();
//SendFile.close();
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(F("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("isconnected"));
}
void encodeblock(unsigned char in[3],unsigned char out[4],int len) {
out[0]=cb64[in[0]>>2]; out[1]=cb64[((in[0]&0x03)<<4)|((in[1]&0xF0)>>4)];
out[2]=(unsigned char) (len>1 ? cb64[((in[1]&0x0F)<<2)|((in[2]&0xC0)>>6)] : '=');
out[3]=(unsigned char) (len>2 ? cb64[in[2]&0x3F] : '=');
}
void encode() {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (SendFile.available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) SendFile.read();
if (SendFile.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||SendFile.available()==0){
if (blocksout) client.print("\r\n"); blocksout=0;
}
}
}
This is what I see in the serial monitor when I run the code:
Initializing SD card...Initialization Successful
Trying to connect
IP address: 1.2.3.4.
Ready. Press 'e' to send.
Connected
220 mail.smtp2go.com ESMTP Exim 4.87 Thu, 18 Aug 2016 21:57:22 +0000
Sending Hello
250-mail.smtp2go.com Hello [76.100.163.175]
250-SIZE 52428800
250-8BITMIME
250-DSN
250-PIPELINING
250-AUTH CRAM-MD5 PLAIN LOGIN
250-STARTTLS
250-PRDR
250 HELP
Sending authorizes login
334 VXNlcm5hbWU6
Sending User
334 UGFzc3dvcmQ6
Sending Password
235 Authentication succeeded
Sending From
250 OK
Sending To
250 Accepted <recipient@gmail.com>
Sending DATA
354 Enter message, ending with "." on a line by itself
Sending email
250 OK id=1baVJT-NRKK26-53
221 mail.smtp2go.com closing connection
disconnected
Email Sent
The card is initializing, but is it not being read?
Thanks in advance!