Project 48 – Email Alert System

You are now going to look at a different method of sending data. In this project, you will get the Arduino with the Ethernet Shield to send an e-mail when a temperature is either too cold or too hot. This project is designed to show you the basics of sending an e-mail via the Ethernet Shield. You'll use the same circuit but with just one of the temperature sensors.

Enter the Code

Enter the code from Listing 17-3. You will need to obtain the IP address of your SMTP email server. To do this, open up a terminal window (command window, console, whatever you know it as on your system) and type in ping, followed by the web address you wish to obtain the IP address of. In other words, if you wanted to know the IP address of the Hotmail SMTP server at smtp.live.com , you would type

ping smtp.live.com

and you will get back a reply similar to

PING smtp.hot.glbdns.microsoft.com (65.55.162.200): 56 data bytes

This shows you that the IP address is 65.55.162.200. Do this for the SMTP server of your e-mail service and enter this into the server section of the code. If your SMTP server requires authentication, you will need to obtain the Base-64 version of your username and password. There are many websites that will do this for you, such as

www.motobit.com/util/base64-decoder-encoder.asp

Enter your username and encrypt it to Base-64 and then do the same with your password. Copy and paste the results into the relevant section in the code. Also, change the FROM and TO sections of the code to your own e-mail address and the e-mail address of the recipient.

Listing 17-3. Code for Project 48

// Project 48 – Email Alert System

#include <Ethernet.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define time 1000
#define emailInterval 60
#define HighThreshold 40 // Highest temperature allowed
#define LowThreshold 10 // Lowest temperature

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 12

float tempC, tempF;
char message1[35], message2[35];
char subject[] = "ARDUINO: TEMPERATURE ALERT!!";
unsigned long lastMessage;

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
DeviceAddress insideThermometer = { 0x10, 0x7A, 0x3B, 0xA9, 0x01, 0x08, 0x00, 0xBF };

byte mac[] = { 0x64, 0xB9, 0xE8, 0xC3, 0xC7, 0xE2 };
byte ip[] = { 192,168,0, 105 };
byte server[] = { 62, 234, 219, 95 };  // Mail server address. Change this to your own mail
servers IP.

Client client(server, 25);

void sendEmail(char subject[], char message1[], char message2[], float temp) {
  Serial.println("connecting...");

 if (client.connect()) {
   Serial.println("connected");
   client.println("EHLO MYSERVER");  delay(time); // log in
   client.println("AUTH LOGIN"); delay(time); // authorise
   // enter your username here
   client.println("caFzLmNvbQaWNZXGluZWVsZWN0cm9uNAZW2FsydGhzd3");  delay(time);
   // and password here
   client.println("ZnZJh4TYZ2ds");  delay(time);
   client.println("MAIL FROM:<[email protected]>");      delay(time);
   client.println("RCPT TO:<[email protected]>");      delay(time);
   client.println("DATA");       delay(time);
   client.println("From: <[email protected]>");       delay(time);
   client.println("To: <[email protected]>");       delay(time);
   client.print("SUBJECT: ");
   client.println(subject);       delay(time);
   client.println();      delay(time);
   client.println(message1);      delay(time);
   client.println(message2);      delay(time);
   client.print("Temperature: ");
   client.println(temp);   delay(time);
   client.println(".");      delay(time);
   client.println("QUIT");      delay(time);
   Serial.println("Email sent.");
   lastMessage=millis();
 } else {
   Serial.println("connection failed");
 }

}
void checkEmail() { // see if any data is available from client
  while (client.available()) {
   char c = client.read();
   Serial.print(c);
 }

 if (!client.connected()) {
   Serial.println();
   Serial.println("disconnecting.");
   client.stop();
 }
}

// function to get the temperature for a device
void getTemperature(DeviceAddress deviceAddress)
{
  tempC = sensors.getTempC(deviceAddress);
  tempF = DallasTemperature::toFahrenheit(tempC);
}

void setup()
{
 lastMessage = 0;
 Ethernet.begin(mac, ip);
 Serial.begin(9600);

     // Start up the sensors library
  sensors.begin();
    // set the resolution
  sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);

 delay(1000);
}

void loop()
{
  sensors.requestTemperatures();
  getTemperature(insideThermometer);
  Serial.println(tempC);
// Is it too hot?
if (tempC >= HighThreshold && (millis()>(lastMessage+(emailInterval*1000)))) {
    Serial.println("High Threshhold Exceeded");
    char message1[] = "Temperature Sensor";
    char message2[] = "High Threshold Exceeded";
    sendEmail(subject, message1, message2, tempC);
  } // too cold?
else if (tempC<= LowThreshold && (millis()>(lastMessage+(emailInterval*1000))))
    Serial.println("Low Threshhold Exceeded");
    char message1[] = "Temperature Sensor";
    char message2[] = "Low Threshold Exceeded";
    sendEmail(subject, message1, message2, tempC);
  }
      
    if (client.available()) {checkEmail();}
}

Upload the code and then open up the serial monitor window. The serial monitor will display the temperature from the first sensor over and over. If the temperature drops below the LowThreshold value, the serial monitor will display “Low Threshold Exceeded” and then send the relevant e-mail alert. If the temperature goes above the HighThreshold, it will displays “High Threshold Exceeded” and send the appropriate alert for a high temperature situation.

You can test this by setting the high threshold to be just above the ambient temperature and then holding the sensor until the temperature rises above the threshold. This will set the alert system into action.

Note that for the first 60 seconds the system will ignore any temperature alert situations. It will only start sending alerts once 60 seconds have passed. If the thresholds have been breached, the alert system will keep sending e-mails until the temperature drops to within acceptable levels. E-mails will be sent every emailInterval seconds while the thresholds have been breached. You can adjust this interval to your own settings.

After an e-mail is sent, the system will wait until a successful receipt has been received back from the client, and then it will display the response. You can use this data to debug the system if things do not work as planned.

Project 48 – Email Alert System – Code Overview

First, the libraries are included:

#include <Ethernet.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>

Next, you define the delay, in milliseconds, when sending data to the server

#define time 1000

followed by a time, in seconds, in-between e-mails being sent.

#define emailInterval 60

Then you need to set the temperature high and low levels that will cause an alert:

#define HighThreshold 40 // Highest temperature allowed
#define LowThreshold 10 // Lowest temperature

Next, you set the pin and precision for the sensors

#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 12

and the floats to store the temperatures,

float tempC, tempF;

then two character arrays that will store the message in the e-mail

char message1[35], message2[35];

plus another character array to store the subject of the e-mail. This is declared and initialized:

char subject[] = "ARDUINO: TEMPERATURE ALERT!!";

As you don't want to bombard the user with e-mail messages once the thresholds have been breached, you need to store the time the last e-mail was sent. This will be stored in an unsigned integer called lastMessage:

unsigned long lastMessage;

The instances for the sensor are set up along with the sensor address:

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress insideThermometer = { 0x10, 0x7A, 0x3B, 0xA9, 0x01, 0x08, 0x00, 0xBF };

The MAC and IP address of the Ethernet Shield is defined:

byte mac[] = { 0x64, 0xB9, 0xE8, 0xC3, 0xC7, 0xE2 };
byte ip[] = { 192,168,0, 105 };

Then you set the IP address of your e-mail SMTP server. This must be changed to your own one or the code will not work.

byte server[] = { 62, 234, 219, 95 };

A client instance is created and you pass it the server address and port number 25. If your SMTP server uses a different port, change this as required.

Client client(server, 25);

Next comes the first of your own functions. This one does the job of sending the e-mail to the server. The function requires four parameters: the e-mail subject, the first line of the message, the second line of the message, and finally, the temperature.

void sendEmail(char subject[], char message1[], char message2[], float temp) {

The user is advised that you are attempting to connect:

Serial.println("connecting...");

Then you check if the client has connected. If so, the code within the if-block is executed.

if (client.connect()) {

First, the user is informed that you have connected to the client. The client in this case is your e-mail SMTP server.

Serial.println("connected");

You now send commands to the server in pretty much the same way that you did in Project 46. First, you must introduce yourselves to the SMTP server. This is done with an EHLO command and the server details. After each command, you must wait a while to allow the command to be processed. I found 1000 milliseconds was required for my server; you may need to increase or decrease this number accordingly.

client.println("EHLO MYSERVER");  delay(time); // log in

This is like a shake hands procedure between the server and the client where they introduce themselves to each other. Next, you need to authorize the connection. If your SMTP server does not require authorization, you can comment out this line and the username and password lines.

client.println("AUTH LOGIN"); delay(time); // authorise

Sometimes the server requires an unencrypted login, in which case you would send AUTH PLAIN and the username and password in plain text.

Next, the Base-64 encrypted username and password must be sent to the server:

client.println("caFzLmNvbQaWNZXGluZWVsZWN0cm9uNAZW2FsydGhzd3");  delay(time);
client.println("ZnZJh4TYZ2ds");  delay(time);

Then you need to tell the server who the mail is coming from and who the mail is going to:

client.println("MAIL FROM:<[email protected]>");      delay(time);
client.println("RCPT TO:<[email protected]>");      delay(time);

These must be changed to your own e-mail address and the address of the recipient. Most SMTP servers will only allow you to send e-mail using an e-mail address from its own domain (e.g. you cannot send an e-mail from a Hotmail account using a Yahoo server.)

Next is the DATA command to tell the server that what comes next is the e-mail data, i.e. the stuff that will be visible to the recipient.

client.println("DATA");       delay(time);

You want the recipient to see whom the e-mail is to and from, so these are included again for the recipient's benefit.

client.println("From: <[email protected]>");       delay(time);
client.println("To: <[email protected]>");       delay(time);

Next, you send the e-mail subject. This is the word “SUBJECT:” followed by the subject passed to the function:

client.print("SUBJECT: ");
client.println(subject);       delay(time);

Before the body of the e-mail, you must send a blank line

client.println();      delay(time);

followed by the two lines of the message passed to the function.

client.println(message1);      delay(time);
client.println(message2);      delay(time);

Then you include the temperature:

client.print("Temperature: ");
client.println(temp);   delay(time);

All e-mails must end with a . on a line of its own to tell the server you have finished:

client.println(".");      delay(time);

Then you send a QUIT command to disconnect from the server:

client.println("QUIT");      delay(time);

Finally, the user is informed that the e-mail has been sent:

Serial.println("Email sent.");

Next, you store the current value of millis() in lastMessage as you will use that later to see if the specified interval has passed or not in-between message sends.

lastMessage=millis();

If the connection to the client was not successful, the e-mail is not sent and the user informed:

} else {
   Serial.println("connection failed");
 }

Next comes the function to read the response back from the client:

void checkEmail() { // see if any data is available from client

While data is available to be read back from the client

while (client.available()) {

you store that byte in c

char c = client.read();

and then print it to the serial monitor window.

Serial.print(c);

If the client is NOT connected

if (!client.connected()) {

then the user is informed, the system is disconnecting, and the client connected is stopped.

Serial.println();
Serial.println("disconnecting.");
client.stop();

Next is the function you have used before to obtain the temperature from the one-wire sensor

void getTemperature(DeviceAddress deviceAddress)
{
  tempC = sensors.getTempC(deviceAddress);
  tempF = DallasTemperature::toFahrenheit(tempC);
}

followed by the setup routine that simply sets up the Ethernet and sensors.

void setup()
{
Ethernet.begin(mac, ip);
 Serial.begin(9600);

     // Start up the sensors library
  sensors.begin();
    // set the resolution
  sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);

 delay(1000);
}

Finally, there's the main program loop:

void loop()

You start off by requesting the temperatures from the DallasTemperature library

sensors.requestTemperatures();

then call your getTemperature function, passing it the address of the sensor

getTemperature(insideThermometer);

that is then displayed in the serial monitor window.

Serial.println(tempC);

Next you check that temperature to see if it has reached or exceeded your high threshold. If it has, then the appropriate e-mail is sent. However, you only want to send one e-mail every (emailInterval*1000) seconds so check also that millis() is greater than the last time the e-mail message was sent (lastMessage) plus the interval time. If true, the code is executed.

if (tempC >= HighThreshold && (millis()>(lastMessage+(emailInterval*1000)))) {

The user is informed and then the two lines that make up the e-mail message are sent:

Serial.println("High Threshhold Exceeded");
char message1[] = "Temperature Sensor";
char message2[] = "High Threshold Exceeded";

The sendEmail function is then called, passing it the parameters that make up the subject, message line one and two, and the current temperature:

    sendEmail(subject, message1, message2, tempC);

If the high teperature threshold has not been reached, you check if it has dropped below the low temperature threshold. If so, carry out the same procedure with the appropriate message.

else if (tempC<= LowThreshold && (millis()>(lastMessage+(emailInterval*1000))))
    Serial.println("Low Threshhold Exceeded");
    char message1[] = "Temperature Sensor";
    char message2[] = "Low Threshold Exceeded";
    sendEmail(subject, message1, message2, tempC);
  }
 

Finally, you check if there is any data ready to be received back from the client (after an e-mail has been sent) and display the results:

if (client.available()) {checkEmail();}

This data is useful for debugging purposes.

This project has given you the basic knowledge for sending an e-mail from an Arduino with Ethernet Shield. You can use this to send alerts or report whenever an action has occurred, such as a person has been detected entering a room or a box has been opened. The system can also take other actions, i.e. to open a window if the temperature in a room gets too hot or to top up a fish tank if the water level drops too low.

Next, you will learn how to send data from an Arduino to Twitter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.185.251