Pages: [1] 2   Go Down
Author Topic: How do you get the arduino to send an email notification  (Read 3194 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I want to set my laser trip wire, which has a keypad to enable/disable the laser, to send me an email notification when the laser has been crossed.  I have an ethernet shield but I am new to ethernet shields.  Here is my code below:


Code:
#include <Password.h> //http://www.arduino.cc/playground/uploads/Code/Password.zip
#include <Keypad.h> //http://www.arduino.cc/playground/uploads/Code/Keypad.zip

Password password = Password( "1234" );

const byte ROWS = 4; // Four rows
const byte COLS = 3; //  columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 5, 4, 3, 2 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 8, 7, 6 };


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int pin = 0;
int laser = 0;
int i = 0;
int alarm = 0;
int firstTime = 0;
boolean crossed;
boolean failed;

void setup()
{
  pinMode(13,OUTPUT);  //Green LED
  pinMode(12,OUTPUT);  //Red LED
  pinMode(11,OUTPUT);  //Laser
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}

void loop()
{
  keypad.getKey();
  
  //Check to see if laser has been crossed
  if(laser == 1)
  {
    checkLaser();
    if(i >= 3)
    {
      failed = true;  //Activates alarm
      
    }
    else
    {
      failed = false;  //Deactivates alarm
    }
  }
  else
  {
    i = 0;
    crossed = false;
  }

  //Code for the alarm
  if(crossed || failed)
  {
    if(alarm < 1)
    {
      if(failed)
      {
        //Write code to send log information to servers about too many password attempts
      }
      if(crossed)
      {
        //Write code to send log info to servers about laser being crossed
      }
      
      Serial.println("Alarm Activated");
      alarm = 1;
    }
    digitalWrite(12,HIGH);  //Turns on red LED
  }
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
    case PRESSED:
Serial.print("Pressed: ");
Serial.println(eKey);
switch (eKey){
 case '*': checkPassword(); break;
 case '#': password.reset(); break;
 default: password.append(eKey);
     }
  }
}

void checkPassword(){
  if (password.evaluate()){
    Serial.println("Success");
    //Flash green LED
    digitalWrite(13,HIGH);
    delay(100);
    digitalWrite(13,LOW);
    delay(100);
    digitalWrite(13,HIGH);
    delay(100);
    digitalWrite(13,LOW);
    
    i = 0;
    failed = false;
    crossed = false;
    alarm = 0;
    firstTime = 0;
    digitalWrite(12,LOW);
    password.reset();
    //Turn on/off laser
    if(laser == 0)
    {
      //Turn on laser
      laser = 1;
      Serial.println("Laser ON\n");
      digitalWrite(11,HIGH);
    }
    else
    {
      //Turn off laser
      laser = 0;
      Serial.println("Laser OFF\n");
      digitalWrite(11,LOW);
    }
   }
   else
   {
    Serial.println("Wrong");
    //Flash red LED
    digitalWrite(12,HIGH);
    delay(100);
    digitalWrite(12,LOW);
    delay(100);
    digitalWrite(12,HIGH);
    delay(100);
    digitalWrite(12,LOW);
    
    password.reset();
    //If wrong more than 3 times will activate the alarm
    i++;
  }
}

void checkLaser()
{
  //Checks laser to see if it has been crossed
  if(firstTime < 1)
  {
    delay(5000);  //Delays the alarm so that the laser has time to hit photocell
    firstTime = 1;
  }
  //Serial.println(analogRead(0));  //Used to calibrate photocell, debuging purposes only
  if(analogRead(0) > 600)  //checks the photocell's resistance
  {
    crossed = true;
  }
  else
  {
    crossed = false;
  }
}


Moderator edit: [code] [/code] tags added.
« Last Edit: July 12, 2012, 02:14:13 pm by Coding Badly » Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3114
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you have access to a mail host that will accept unsecured SMTP? Most ISPs and mail providers don't, so you may need to provide your own relay.

See this thread - http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235534880
Logged

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have successfully tested base64 algorithm to receive mail on my gmail account.
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3114
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A lot of people would appreciate it if you posted your sketch.
Logged

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure.

Try this:
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

byte MAC[]={0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};  // Your MAC
File Data_3; EthernetClient client;

static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
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 (Data_3.available()!=0) {
    len=0; for (i=0;i<3;i++) { in[i]=(unsigned char) Data_3.read(); if (Data_3.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||Data_3.available()==0) { if (blocksout) client.print("\r\n");  blocksout=0; }
  }
}

void setup() {
  Ethernet.begin(MAC); delay(2000);
  pinMode(10,OUTPUT); SD.begin(4);
}

void loop() {
  Data_3=SD.open("Data_3.csv",FILE_READ);
  client.connect("smtp.mail.yahoo.com",25);
  client.print("HELO\nAUTH PLAIN\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n");
  client.print("MAIL FROM:<foo@yahoo.com>\nRCPT TO:<YOUR_EMAIL@gmail.com>\nDATA\nFrom: \"Foo\" <foo@yahoo.com>\r\nTo: YOUR_EMAIL@gmail.com\r\nSubject: MAIL NOTIFICATION\r\n");
  client.print("Content-Type: text/html; name=\"Data_3.csv\"\r\nContent-Disposition: attachment; filename=\"Data_3.csv\"\r\nContent-Transfer-Encoding: base64\r\n\r\n");
  encode();
  client.print("\r\n.\r\nQUIT\n");
  client.stop();
  Data_3.close();
  //while(1);
}

This sketch is sending me a mail with an attachment, a file present on SD card.
I hope this helps.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What lines of your code would I need to change in order to send to my email account?
Logged

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try this.
Code:
#include <Password.h> //http://www.arduino.cc/playground/uploads/Code/Password.zip
#include <Keypad.h> //http://www.arduino.cc/playground/uploads/Code/Keypad.zip
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

byte MAC[]={0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
File logFile; EthernetClient client;
int CS_pin = 10;

static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
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 (logFile.available()!=0) {
    len=0; for (i=0;i<3;i++) { in[i]=(unsigned char) logFile.read(); if (logFile.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||logFile.available()==0) { if (blocksout) client.print("\r\n");  blocksout=0; }
  }
}

Password password = Password( "1234" );

const byte ROWS = 4; // Four rows
const byte COLS = 3; //  columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 5, 4, 3, 2 };// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 8, 7, 6 };


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int pin = 0;
int laser = 0;
int i = 0;
int alarm = 0;
int firstTime = 0;
boolean crossed;
boolean failed;

void setup()
{
  Ethernet.begin(MAC);
  Wire.begin();
  SPI.begin();
  pinMode(10,OUTPUT); SD.begin(4);
  pinMode(13,OUTPUT);  //Green LED
  pinMode(12,OUTPUT);  //Red LED
  pinMode(11,OUTPUT);  //Laser
  Serial.begin(9600);
  keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}

void loop()
{
  keypad.getKey();
 
  //Check to see if laser has been crossed
  if(laser == 1)
  {
    checkLaser();
    if(i >= 3)
    {
      failed = true;  //Activates alarm
     
    }
    else
    {
      failed = false;  //Deactivates alarm
    }
  }
  else
  {
    i = 0;
    crossed = false;
  }

  //Code for the alarm
  if(crossed || failed)
  {
    if(alarm < 1)
    {
      if(failed)
      {
        SDWrite();
        send_email(); //Write code to send log information to servers about too many password attempts
      }
      if(crossed)
      {
        //Write code to send log info to servers about laser being crossed
      }
     
      Serial.println("Alarm Activated");
      alarm = 1;
    }
    digitalWrite(12,HIGH);  //Turns on red LED
  }
}

//take care of some special events
void keypadEvent(KeypadEvent eKey){
  switch (keypad.getState()){
    case PRESSED:
   Serial.print("Pressed: ");
   Serial.println(eKey);
   switch (eKey){
     case '*': checkPassword(); break;
     case '#': password.reset(); break;
     default: password.append(eKey);
     }
  }
}

void checkPassword(){
  if (password.evaluate()){
    Serial.println("Success");
    //Flash green LED
    digitalWrite(13,HIGH);
    delay(100);
    digitalWrite(13,LOW);
    delay(100);
    digitalWrite(13,HIGH);
    delay(100);
    digitalWrite(13,LOW);
   
    i = 0;
    failed = false;
    crossed = false;
    alarm = 0;
    firstTime = 0;
    digitalWrite(12,LOW);
    password.reset();
    //Turn on/off laser
    if(laser == 0)
    {
      //Turn on laser
      laser = 1;
      Serial.println("Laser ON\n");
      digitalWrite(11,HIGH);
    }
    else
    {
      //Turn off laser
      laser = 0;
      Serial.println("Laser OFF\n");
      digitalWrite(11,LOW);
    }
   }
   else
   {
    Serial.println("Wrong");
    //Flash red LED
    digitalWrite(12,HIGH);
    delay(100);
    digitalWrite(12,LOW);
    delay(100);
    digitalWrite(12,HIGH);
    delay(100);
    digitalWrite(12,LOW);
   
    password.reset();
    //If wrong more than 3 times will activate the alarm
    i++;
  }
}

void checkLaser()
{
  //Checks laser to see if it has been crossed
  if(firstTime < 1)
  {
    delay(5000);  //Delays the alarm so that the laser has time to hit photocell
    firstTime = 1;
  }
  //Serial.println(analogRead(0));  //Used to calibrate photocell, debuging purposes only
  if(analogRead(0) > 600)  //checks the photocell's resistance
  {
    crossed = true;
  }
  else
  {
    crossed = false;
  }
}

void SDWrite() {
  if (!SD.begin(CS_pin))
  {
      Serial.println("Card Failure");
      return;
  }
  Serial.println("Card Ready");
 
  File logFile = SD.open("logFile.txt", FILE_WRITE);
  if (logFile)
  {
    String note = "Alarm Activated";
    logFile.println(note);
    logFile.close();
    Serial.println(note);
  }
  else
  {
    Serial.println("Couldn't open logFile");
  }
}


void send_email() {
  logFile=SD.open("logFile.txt",FILE_READ);
  client.connect("smtp.mail.yahoo.com",25);
  client.print("HELO\nAUTH PLAIN\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n");  // x: base64 encoded login: \0foo@yahoo.com\0password
  client.print("MAIL FROM:<foo@yahoo.com>\nRCPT TO:<YOUREMAIL@gmail.com>\nDATA\nFrom: \"Foo\" <foo@yahoo.com>\r\nTo: YOUREMAIL@gmail.com\r\nSubject: Ardunio sending Notification\r\n");
  client.print("Content-Type: text/html; name=\"logFile.txt\"\r\nContent-Disposition: attachment; filename=\"logFile.txt\"\r\nContent-Transfer-Encoding: base64\r\n\r\n");
  encode();
  client.print("\r\n.\r\nQUIT\n");
  client.stop();
  logFile.close();
}

Some instructions:
1. Insert an SD card into the slot
2. If you are using UNO board, ignore this. If using Mega, change:
Code:
int CS_pin = 53;
Code:
pinMode(53,OUTPUT);
in the setup, 53 instead of 10.

3. Search in the code for "YOUREMAIL@gmail.com" to replace with your gmail ID.

Let me know if this works.

Z
Logged

Finland
Offline Offline
Sr. Member
****
Karma: 0
Posts: 270
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First you need to figure out which authentication/encryption method your mail server requires. Chances are that the code zeus2kx posted wont work for you e.g. if your server requires TSL. If your server supports plain authentication you can use zeus2kx code as a template for your implementation. Before writing code for the Arduino try test the stmp communication from a PC using telnet. On Windows start the command prompt and telnet to the the smtp(25) port of your mail server:

Code:
C:\> telnet stmp.somewhere.net 25

When the telnet connection is established, type the stmp commands that send the message. The following commands work when the server do not require authentication (for example, if you send a message to an email address that is hosted locally on that server).

Code:
EHLO somewhere.net
mail from: <me@somewhere.net>
rcpt to: <joe@somewhere.net>
data
Subject: test

the body of the message.
.

You will see that the server writes back when you type the commands. For example, after you have typed the "mail from: <me@somewhere.net>" it may respond with "<me@somewhere.net>... Sender ok".

When you have successfully sent an email from your PC just transfer the command to client.print()-lines for the Arduino. It should work. On the other hand, if you can't send a message from a PC sending  email won't work from the Arduino either.
« Last Edit: July 12, 2012, 02:12:33 pm by pekkaa » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

zeus2kx,
When I compiled the code I got an error saying: Ethernet_Test_ino:55: error: 'Wire' was not declared in this scope.

Do i need to install a library in order for it to work or do I need to declare a value for that?
« Last Edit: July 12, 2012, 02:30:15 pm by rook343 » Logged

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

https://rapidshare.com/files/3947890642/libraries.zip
Download and paste in your Arduino libraries folder..
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, I got it to compile, but my keypad does not work, which means I cannot turn on the laser and no data will be sent to my email.  I am using the UNO and only have limited number of digital inputs.  Also, the LEDs are always on, which I am assuming that means that the digital inputs are being used to control the ethernet shield.  Is there anyway around this?
« Last Edit: July 19, 2012, 08:32:19 am by rook343 » Logged

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Check your code
Code:
if(failed)
      {
        SDWrite();
        send_email(); //Write code to send log information to servers about too many password attempts
      }
      if(crossed)
      {
        //Write code to send log info to servers about laser being crossed
      }

I had inserted these two functions "SDWrite" and "send_email" without knowing how does your code work. So you can remove and place them wherever you want to get notification from.

Do you see "logFile.txt" on SD card? What is written in the file?
Are you receiving emails?
Logged

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If in serial monitor you see "Couldn't open logFile", try changing CS pin.
Code:
int CS_pin = 4;
pinMode(4,OUTPUT); instead of pinMode(10,OUTPUT);

If problem persists, try
Code:
int CS_pin = 4;
pinMode(10,OUTPUT);

You must not use these pins for any other connections. Leave them unused.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It seems to not be doing anything.  I open the serial monitor and no activity shows up.  I even condensed the code so that it would just send an email and commented all the keypad and laser stuff out, but still nothing.
Logged

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay try to test this:

1. create a file on SD card by name "Data_3.csv"
2. Change YOUR_EMAIL@gmail.com to your email.
3. Connect to internet and wait 5 mins, you will see an email in your inbox.

Code:
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

byte MAC[]={0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};  // Your MAC
File Data_3; EthernetClient client;

static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
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 (Data_3.available()!=0) {
    len=0; for (i=0;i<3;i++) { in[i]=(unsigned char) Data_3.read(); if (Data_3.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||Data_3.available()==0) { if (blocksout) client.print("\r\n");  blocksout=0; }
  }
}

void setup() {
  Ethernet.begin(MAC); delay(2000);
  pinMode(10,OUTPUT); SD.begin(4);
}

void loop() {
  Data_3=SD.open("Data_3.csv",FILE_READ);
  client.connect("smtp.mail.yahoo.com",25);
  client.print("HELO\nAUTH PLAIN\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n");
  client.print("MAIL FROM:<foo@yahoo.com>\nRCPT TO:<YOUR_EMAIL@gmail.com>\nDATA\nFrom: \"Foo\" <foo@yahoo.com>\r\nTo: YOUR_EMAIL@gmail.com\r\nSubject: MAIL NOTIFICATION\r\n");
  client.print("Content-Type: text/html; name=\"Data_3.csv\"\r\nContent-Disposition: attachment; filename=\"Data_3.csv\"\r\nContent-Transfer-Encoding: base64\r\n\r\n");
  encode();
  client.print("\r\n.\r\nQUIT\n");
  client.stop();
  Data_3.close();
  //while(1);
}
Logged

Pages: [1] 2   Go Up
Jump to: