Thursday, September 3, 2009

Arduino POP3 Email Checker

Since it turns out people actually occasionally READ this blog, I decided it was time to go back to do an Arduino project and try something different. Since I hadn't done any Arduino work with the Internet before, I decided to try something I thought would be relatively simple - having the Arduino check my email and give me some sort of visual indication of how many emails I have. I started out with:
Both were bought from the good people at Robotshop.ca.




These are just combined with a high intensity LED - which really should have a resistor and will have one eventually!



Here is a quick video - sorry it is a bit murky and the LED is a bit bright!



This was actually probably the hardest Arduino code I ever wrote! For one thing, I hadn't done anything substantial with the Arduino for a while and I found I had forgotten much of what I thought I knew. Also, getting the timing right and getting the number of emails out of the return string actually proved pretty difficult. I made things more difficult for myself by trying to use the String library (formerly TextString), which for some reason didn't return consistent results and was generally not documented and finicky. Then I found the usual LED 13 wouldn't work properly - perhaps because the Ethernet Shield was interfering with it. All-in-all, this small program must have taken me three weeks to write!

I did have a bit of help with the code from Digger450 on the Arduino forum in this exchange, which I am very grateful for!

However, now that it is done, this is a nice little demo of Ardunio on the Internet that does do something at least semi-useful. My next extension may be to hook it up to a servo so that it shows my emails on a physical chart or something. I could also use my SparkFun SerialLCD unit to display the subject lines or something.

Here is the source code:

/*=================================================
Ethernet POP3 Mail Checker & indicator

Checks how many messages are waiting on the POP 3 server
and flashed LED on Pin 9 to indicate number of messages.

It will handle up to 99 messages in the POP3 mailbox.

Uncomment the serial lines for troubleshooting.

Copyright by Chris Armour
3 September 2009
http://opensourceprojects-torchris.blogspot.com/

===================================================*/

#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,0,167 }; // IP address you wish to assign to Arduino
byte server[] = { XXX, XXX, XXX, XXX }; // IP address of your POP3 server
char inString[165]; // Number of characters to be collected
int i = 0;
int mailNum1 = 0; // First digit of the email number
int mailNum2 = 0; // Second digit
int mailTotal = 0; // Total # of messsage
char d;
int ledPin = 9;

Client client(server, 110); //The default POP port is 110

long updateTimer;
boolean clientConnected = false;

void setup()
{
//  Serial.begin(9600);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
}

void loop()
{
   
updateClient();
d = checkAvail();
if (d >= 10){
getMailNum();
}

}

/*========================================
        Functions
=========================================*/

void updateClient() //This function contacts the POP3 server
{
if ((millis() - updateTimer) > 5000)
{
 Ethernet.begin(mac, ip);
//    Serial.println("connecting...");
 delay(1000);
 if (client.connect())
 {
//    Serial.println("connected");
 client.println("user Your.Name"); //Insert your usual email login name
 client.println("pass PassWord"); //And your password here
 client.println("quit");
 client.println();
 clientConnected = true;
 }
 else
 {
//    Serial.println("connection failed");
 }
 updateTimer = millis();
}
}

char checkAvail() //This checks if there is data available and returns a char
{
if (clientConnected)
{
 if (client.available())
 {
 char c = client.read();
     return(c);
 }
 if (!client.connected())
 {
//    Serial.println();
//    Serial.println("disconnecting.");
 client.stop();
 clientConnected = false;
 }
}
}

int getMailNum() //This actually loads the char returned by checkAvail() and puts in into an array
{
inString[i] = d;
i++;
if (i == 165){
   i = 0;
       client.flush();
       mailNum1 = inString[106] - 48; //Array position 106 contains the first digit
       mailNum2 = inString[107] - 48; //Array position 107 contains the 2nd digit if it is available
       if ((mailNum2 >= 0) && (mailNum2 <= 9)){ //If mailNum2 is present, then it is a two digit mail count
         mailTotal = (mailNum1 * 10) + mailNum2; //when 2 digits are present, multiply the 1st by 10 then add to mailTotal
//            Serial.print("Total emails:  ");
//            Serial.println(mailTotal);
          blinkLED(); //Run the blink function as many times as there are emails
       }
       else {
         if ((mailNum1 >= 0) && (mailNum1 <= 9)){//if there is only one digit, then that is mailTotal
         mailTotal = mailNum1;
//        Serial.print("Total emails:  ");
//        Serial.println(mailTotal);
         blinkLED(); //Blink the LED
         }
         }
     }
 }

void blinkLED(){ //Blinks the LED for as many times as indicated by mailTotal
         for(int x = mailTotal; x >= 1; x--){
           digitalWrite(ledPin, HIGH);
           delay(200);             
           digitalWrite(ledPin, LOW);
           delay(200);
         }
}

7 comments:

  1. Outstanding! Since my ethernet shield arrived courtesy of the good folks at Tinker.it on Wednesday, this looks like an ideal first project for it. Thanks Torchris!

    ReplyDelete
  2. Do i need a atmega 328, i have a 168 diec arduino and would like to get a net shield but just making sure it would be compatible. thank you.

    ReplyDelete
  3. I just ran a quick check with my older Diecimilia (ATMega 168) and it runs just fine. The compiler reports: "5244 bytes (of a 14336 byte maximum)" so there is lots of memory for this program.

    ReplyDelete
  4. Very cool, I have been looking to make something like this for a long time! Thanks so much.

    ReplyDelete
  5. Great! That's why I write this is to help others save some time.

    I actually have a very small modificaton I will post shortly so it signals if it loses Ethernet connectivity.

    ReplyDelete
  6. Great project! I just ordered an Arduino clone and waiting for it's arrival.

    www.Nerdful.com

    ReplyDelete