POP3 email client

This works with POP3 email servers that do not require TLS or SSL security.

You must change the user and password to your POP3 account.

The sketch checks the server every 10 minutes for new emails. Any email with the correct subject line will be read and the deleted from the server.

To send an email command to the Arduino, your subject must contain the string stored in the subjectLine array in the global variables. The message body must contain the line "command x on" or "command x off", where x is the digital pin to change and the on or off is HIGH or LOW respectively. These are all case sensitive. Each command must be on a line by itself. It will accept multiple command statements per email.

  1. /*
  2.    Email POP3 client sketch for w5100/w5200
  3.    Posted 24 May 2015 by SurferTim
  4. */
  5.  
  6. #include <SPI.h>
  7. #include <Ethernet.h>
  8.  
  9. // this must be unique
  10. byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };  
  11.  
  12. // change network settings to yours
  13. IPAddress ip( 192, 168, 2, 2 );    
  14. IPAddress gateway( 192, 168, 2, 1 );
  15. IPAddress subnet( 255, 255, 255, 0 );
  16.  
  17. // change server to your email server ip or domain
  18. // IPAddress server( 1,2,3,4 );
  19. char server[] = "my.inbox.com";
  20. int port = 110;
  21.  
  22. char subjectLine[] = "Arduino";
  23. char userName[] = "myusername";
  24. char passWord[] = "mypassword";
  25.  
  26. EthernetClient client;
  27. char rtnBuf[100];
  28. unsigned long currentMillis;
  29. unsigned long lastMillis;
  30. // check every 10 minutes
  31. unsigned long checkMillis = 600000UL;
  32.  
  33. void setup()
  34. {
  35.   delay(2000);
  36.  
  37.   Serial.begin(115200);
  38.   pinMode(4,OUTPUT);
  39.   digitalWrite(4,HIGH);
  40.  
  41.   pinMode(6,OUTPUT);
  42.   pinMode(8,OUTPUT);
  43.  
  44. //  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  45.  
  46.   while(!Ethernet.begin(mac)) {
  47.     Serial.println("DHCP failed. Retry in 5 seconds");
  48.     delay(5000);
  49.   }
  50.  
  51.   Serial.println(Ethernet.localIP());
  52.  
  53.   delay(5000);
  54.   Serial.println(F("Ready. Press 'e' to receive."));
  55.   if(getEmail()) Serial.println(F("Email received"));
  56.   else Serial.println(F("Email failed"));
  57.  
  58.   currentMillis = millis();
  59.   lastMillis = currentMillis;
  60. }
  61.  
  62. void loop()
  63. {
  64.   byte inChar;
  65.  
  66.   inChar = Serial.read();
  67.  
  68.   if(inChar == 'e')
  69.   {
  70.       if(getEmail()) Serial.println(F("Email received"));
  71.       else Serial.println(F("Email failed"));
  72.   }
  73.  
  74.   currentMillis = millis();
  75.  
  76.   if(currentMillis - lastMillis > checkMillis) {
  77.     if(getEmail()) Serial.println(F("Email received"));
  78.     else Serial.println(F("Email failed"));
  79.     lastMillis = millis();  
  80.   }    
  81.  
  82.   Ethernet.maintain();
  83. }
  84.  
  85. byte getEmail()
  86. {
  87.   byte thisByte = 0;
  88.   byte respCode;
  89.   char rtnVal[64];
  90.   int mailCount,mailSize;
  91.   char tBuf[64];
  92.  
  93.   if(client.connect(server,port) == 1) {
  94.     Serial.println(F("connected"));
  95.   } else {
  96.     Serial.println(F("connection failed"));
  97.     return 0;
  98.   }
  99.  
  100.   if(!eRcv()) return 0;
  101.   Serial.println(rtnBuf);
  102.  
  103.   Serial.println(F("Sending User"));
  104.   strcpy_P(tBuf,PSTR("USER "));  
  105.   strcat(tBuf,userName);
  106.   strcat_P(tBuf,PSTR("\r\n"));  
  107.   client.write(tBuf);
  108.   if(!eRcv()) return 0;
  109.   Serial.println(rtnBuf);
  110.  
  111.   Serial.println(F("Sending Password"));
  112.   strcpy_P(tBuf,PSTR("PASS "));  
  113.   strcat(tBuf,passWord);
  114.   strcat_P(tBuf,PSTR("\r\n"));  
  115.   client.write(tBuf);
  116.   if(!eRcv()) return 0;
  117.   Serial.println(rtnBuf);
  118.  
  119.   Serial.println(F("Sending STAT"));
  120.   strcpy_P(tBuf,PSTR("STAT\r\n"));  
  121.   client.write(tBuf);
  122.   if(!eRcv()) return 0;
  123.   Serial.println(rtnBuf);
  124.  
  125.   sscanf(rtnBuf,"%s %u %u",rtnVal,&mailCount,&mailSize);
  126.   Serial.print(F("mail count: "));
  127.   Serial.println(mailCount);
  128.  
  129.   for(int i = 1;i<=mailCount;i++) {
  130.     strcpy_P(tBuf,PSTR("RETR "));  
  131.     itoa(i,rtnBuf,10);
  132.     strcat(tBuf,rtnBuf);
  133.     strcat(tBuf,"\r\n");
  134.     client.write(tBuf);
  135.     if(ePrint() == 2) {
  136.       strcpy(tBuf,"DELE ");      
  137.       itoa(i,rtnBuf,10);
  138.       strcat(tBuf,rtnBuf);
  139.       strcat(tBuf,"\r\n");
  140.       client.write(tBuf);
  141.  
  142.       if(!eRcv) Serial.println("Not deleted");
  143.       else Serial.println("Deleted");
  144.     }
  145.  
  146.     Serial.println(F("\r\nEND"));
  147.   }
  148.  
  149.   Serial.println(F("Sending QUIT"));
  150.   strcpy_P(tBuf,PSTR("QUIT\r\n"));  
  151.   client.write(tBuf);
  152.   if(!eRcv()) return 0;
  153.   Serial.println(rtnBuf);
  154.  
  155.   client.stop();
  156.  
  157.   Serial.println(F("disconnected"));
  158.  
  159.   return 1;
  160. }
  161.  
  162.  
  163.  
  164. byte eRcv()
  165. {
  166.   byte respCode;
  167.   byte thisByte;
  168.   int loopCount = 0;
  169.   byte rtnCount = 0;
  170.  
  171.   while(!client.available()) {
  172.     delay(1);
  173.     loopCount++;
  174.  
  175.     // if nothing received for 10 seconds, timeout
  176.     if(loopCount > 10000) {
  177.       client.stop();
  178.       Serial.println(F("\r\nTimeout"));
  179.       return 0;
  180.     }
  181.   }
  182.  
  183.   while(client.available())
  184.   {  
  185.     thisByte = client.read();    
  186. //    Serial.write(thisByte);
  187.     if(rtnCount < 99) {
  188.       rtnBuf[rtnCount]=thisByte;
  189.       rtnCount++;
  190.       rtnBuf[rtnCount]=0;
  191.     }
  192.   }
  193.  
  194.   if(rtnBuf[0] == '-') return 0;
  195.  
  196.   return 1;
  197. }
  198.  
  199. byte ePrint()
  200. {
  201.   byte respCode;
  202.   byte thisByte;
  203.   int loopCount = 0;
  204.   byte rtnCount = 0;
  205.   byte lineLength = 0;
  206.   bool endMsg = false;
  207.   bool msgBody = false;
  208.   bool forArduino = false;
  209.   char lineBuf[64];
  210.   byte pinNo;
  211.   char pinState[8];
  212.  
  213.   while(!client.available()) {
  214.     delay(1);
  215.     loopCount++;
  216.  
  217.     // if nothing received for 10 seconds, timeout
  218.     if(loopCount > 10000) {
  219.       client.stop();
  220.       Serial.println(F("\r\nTimeout"));
  221.       return 0;
  222.     }
  223.   }
  224.  
  225.   while(!endMsg) {
  226.     while(client.available())
  227.     {  
  228.       thisByte = client.read();    
  229.  
  230.       // if it is for the Arduino and past the header
  231.       if(forArduino && msgBody) Serial.write(thisByte);
  232.  
  233.       if(thisByte == '\n') {
  234.         // end of line        
  235.         if(strlen(lineBuf) == 0) {
  236.           if(!msgBody) Serial.println("Message body");
  237.           msgBody = true;
  238.         }
  239.         if(strcmp(lineBuf,".") == 0) {
  240.           // end of message
  241.           endMsg = true;
  242.         }
  243.         if(!msgBody && (strncmp(lineBuf,"From:",5) == 0)) {
  244.           // from
  245.           Serial.println(lineBuf);
  246.         }
  247.         if(!msgBody && (strncmp(lineBuf,"Subject:",8) == 0)) {
  248.           // subject
  249.           Serial.println(lineBuf);
  250.           if(strcmp(&lineBuf[9],subjectLine) == 0) {
  251.             Serial.println("For my Arduino!");
  252.             forArduino= true;
  253.           }
  254.         }
  255.  
  256.         if(msgBody && strncmp(lineBuf,"command ",8) == 0) {
  257.           Serial.print("Command! D");          
  258.           sscanf(lineBuf,"%*s %u %s",&pinNo,pinState);
  259.           Serial.print(pinNo);
  260.           Serial.print(" ");
  261.           Serial.println(pinState);
  262.  
  263.           if(strcmp(pinState,"on") == 0) digitalWrite(pinNo,HIGH);          
  264.           if(strcmp(pinState,"off") == 0) digitalWrite(pinNo,LOW);          
  265.         }
  266.  
  267.         lineLength = 0;
  268.         lineBuf[0] = 0;
  269.       }
  270.       else if(thisByte != '\r') {
  271.         // another character
  272.         if(lineLength < 63) {
  273.           lineBuf[lineLength] = thisByte;
  274.           lineLength++;
  275.           lineBuf[lineLength] = 0;
  276.         }
  277.  
  278.       }
  279.     }
  280.   }
  281.  
  282.   if(forArduino) return 2;
  283.   return 1;
  284. }
  285.  
  286. void efail()
  287. {
  288.   byte thisByte = 0;
  289.   int loopCount = 0;
  290.  
  291.   client.println("QUIT");
  292.  
  293.   while(!client.available()) {
  294.     delay(1);
  295.     loopCount++;
  296.  
  297.     // if nothing received for 10 seconds, timeout
  298.     if(loopCount > 10000) {
  299.       client.stop();
  300.       Serial.println(F("\r\nTimeout"));
  301.       return;
  302.     }
  303.   }
  304.  
  305.   while(client.available())
  306.   {  
  307.     thisByte = client.read();    
  308.     Serial.write(thisByte);
  309.   }
  310.  
  311.   client.stop();
  312.  
  313.   Serial.println(F("disconnected"));
  314. }

Share