WiFi shield POP3 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 then deleted.

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 WiFi shield
  3.    Posted 24 May 2015 by SurferTim
  4. */
  5. #include <SPI.h>
  6. #include <WiFi.h>
  7.  
  8. WiFiClient client;
  9. char ssid[] = "MySSID";     // the name of your network
  10. char pass[] = "MyPassphrase";  // your network password
  11. int status = WL_IDLE_STATUS;     // the Wifi radio's status
  12.  
  13. // change server to your email server ip or domain
  14. IPAddress server( 1,2,3,4 );
  15. // char server[] = "myemailserver.com";
  16. int port = 110;
  17.  
  18. char subjectLine[] = "Arduino";
  19. char userName[] = "myuser";
  20. char passWord[] = "mypassword";
  21.  
  22. char rtnBuf[100];
  23. unsigned long currentMillis;
  24. unsigned long lastMillis;
  25. // check every 10 minutes
  26. unsigned long checkMillis = 600000UL;
  27.  
  28. void setup()
  29. {
  30.   delay(2000);
  31.  
  32.   Serial.begin(115200);
  33.   pinMode(4,OUTPUT);
  34.   digitalWrite(4,HIGH);
  35.  
  36.   pinMode(6,OUTPUT);
  37.   pinMode(8,OUTPUT);
  38.  
  39.   // check for the presence of the shield:
  40.   if (WiFi.status() == WL_NO_SHIELD) {
  41.     Serial.println(F("WiFi shield not present"));
  42.     // don't continue:
  43.     while(true);
  44.   }
  45.  
  46.   // check firmware version
  47.   Serial.print(F("Firmware version: "));
  48.   Serial.println(WiFi.firmwareVersion());
  49.  
  50.  // attempt to connect to Wifi network:
  51.   while ( status != WL_CONNECTED) {
  52.     Serial.print(F("Attempting to connect to SSID: "));
  53.     Serial.println(ssid);
  54.     status = WiFi.begin(ssid,pass);
  55.  
  56.     // wait 10 seconds for connection:
  57.     delay(10000);
  58.   }
  59.  
  60.   // you're connected now, so print out the data:
  61.   Serial.print(F("You're connected to the network"));
  62.   printCurrentNet();
  63.   printWifiData();
  64.   delay(5000);
  65.  
  66.   Serial.println(F("Ready. Press 'e' to receive."));
  67.  
  68.   if(getEmail()) Serial.println(F("Email received"));
  69.   else Serial.println(F("Email failed"));
  70.  
  71.   currentMillis = millis();
  72.   lastMillis = currentMillis;
  73. }
  74.  
  75. void loop()
  76. {
  77.   byte inChar;
  78.  
  79.   inChar = Serial.read();
  80.  
  81.   if(inChar == 'e')
  82.   {
  83.       if(getEmail()) Serial.println(F("Email received"));
  84.       else Serial.println(F("Email failed"));
  85.   }
  86.  
  87.   currentMillis = millis();
  88.  
  89.   if(currentMillis - lastMillis > checkMillis) {
  90.     if(getEmail()) Serial.println(F("Email received"));
  91.     else Serial.println(F("Email failed"));
  92.     lastMillis = millis();  
  93.   }    
  94. }
  95.  
  96. byte getEmail()
  97. {
  98.   byte thisByte = 0;
  99.   byte respCode;
  100.   char rtnVal[64];
  101.   int mailCount,mailSize;
  102.   char tBuf[64];
  103.  
  104.   if(client.connect(server,port) == 1) {
  105.     Serial.println(F("connected"));
  106.   } else {
  107.     client.stop();
  108.     Serial.println(F("connection failed"));
  109.     return 0;
  110.   }
  111.  
  112.   if(!eRcv()) return 0;
  113.   Serial.println(rtnBuf);
  114.  
  115.   Serial.println(F("Sending User"));
  116.   strcpy_P(tBuf,PSTR("USER "));
  117.   strcat(tBuf,userName);
  118.   strcat_P(tBuf,PSTR("\r\n"));
  119.   client.write(tBuf);
  120.   if(!eRcv()) return 0;
  121.   Serial.println(rtnBuf);
  122.  
  123.   Serial.println(F("Sending Password"));
  124.   strcpy_P(tBuf,PSTR("PASS "));
  125.   strcat(tBuf,passWord);
  126.   strcat_P(tBuf,PSTR("\r\n"));
  127.   client.write(tBuf);
  128.   if(!eRcv()) return 0;
  129.   Serial.println(rtnBuf);
  130.  
  131.   Serial.println(F("Sending STAT"));
  132.   strcpy_P(tBuf,PSTR("STAT\r\n"));
  133.   client.write(tBuf);
  134.   if(!eRcv()) return 0;
  135.   Serial.println(rtnBuf);
  136.  
  137.   sscanf(rtnBuf,"%s %u %u",rtnVal,&mailCount,&mailSize);
  138.   Serial.print(F("mail count: "));
  139.   Serial.println(mailCount);
  140.  
  141.   for(int i = 1;i<=mailCount;i++) {
  142.     strcpy_P(tBuf,PSTR("RETR "));
  143.     itoa(i,rtnBuf,10);
  144.     strcat(tBuf,rtnBuf);
  145.     strcat(tBuf,"\r\n");
  146.     client.write(tBuf);
  147.     if(ePrint() == 2) {
  148.       strcpy(tBuf,"DELE ");      
  149.       itoa(i,rtnBuf,10);
  150.       strcat(tBuf,rtnBuf);
  151.       strcat(tBuf,"\r\n");
  152.       client.write(tBuf);
  153.  
  154.       if(!eRcv) Serial.println("Not deleted");
  155.       else Serial.println("Deleted");
  156.     }
  157.  
  158.     Serial.println(F("\r\nEND"));
  159.   }
  160.  
  161.   Serial.println(F("Sending QUIT"));
  162.   strcpy_P(tBuf,PSTR("QUIT\r\n"));
  163.   client.write(tBuf);
  164.   if(!eRcv()) return 0;
  165.   Serial.println(rtnBuf);
  166.  
  167.   client.stop();
  168.  
  169.   Serial.println(F("disconnected"));
  170.  
  171.   return 1;
  172. }
  173.  
  174.  
  175.  
  176. byte eRcv()
  177. {
  178.   byte respCode;
  179.   byte thisByte;
  180.   int loopCount = 0;
  181.   byte rtnCount = 0;
  182.  
  183.   while(!client.available()) {
  184.     delay(1);
  185.     loopCount++;
  186.  
  187.     // if nothing received for 10 seconds, timeout
  188.     if(loopCount > 10000) {
  189.       client.stop();
  190.       Serial.println(F("\r\nTimeout"));
  191.       return 0;
  192.     }
  193.   }
  194.  
  195.   while(client.available())
  196.   {
  197.     thisByte = client.read();  
  198. //    Serial.write(thisByte);
  199.     if(rtnCount < 99) {
  200.       rtnBuf[rtnCount]=thisByte;
  201.       rtnCount++;
  202.       rtnBuf[rtnCount]=0;
  203.     }
  204.   }
  205.  
  206.   if(rtnBuf[0] == '-') return 0;
  207.  
  208.   return 1;
  209. }
  210.  
  211. byte ePrint()
  212. {
  213.   byte respCode;
  214.   byte thisByte;
  215.   int loopCount = 0;
  216.   byte rtnCount = 0;
  217.   byte lineLength = 0;
  218.   bool endMsg = false;
  219.   bool msgBody = false;
  220.   bool forArduino = false;
  221.   char lineBuf[64];
  222.   byte pinNo;
  223.   char pinState[8];
  224.  
  225.   while(!client.available()) {
  226.     delay(1);
  227.     loopCount++;
  228.  
  229.     // if nothing received for 10 seconds, timeout
  230.     if(loopCount > 10000) {
  231.       client.stop();
  232.       Serial.println(F("\r\nTimeout"));
  233.       return 0;
  234.     }
  235.   }
  236.  
  237.   while(!endMsg) {
  238.     while(client.available())
  239.     {
  240.       thisByte = client.read();  
  241.  
  242.       // if it is for the Arduino and past the header
  243.       if(forArduino && msgBody) Serial.write(thisByte);
  244.  
  245.       if(thisByte == '\n') {
  246.         // end of line      
  247.         if(strlen(lineBuf) == 0) {
  248.           if(!msgBody) Serial.println("Message body");
  249.           msgBody = true;
  250.         }
  251.         if(strcmp(lineBuf,".") == 0) {
  252.           // end of message
  253.           endMsg = true;
  254.         }
  255.         if(!msgBody && (strncmp(lineBuf,"From:",5) == 0)) {
  256.           // from
  257.           Serial.println(lineBuf);
  258.         }
  259.         if(!msgBody && (strncmp(lineBuf,"Subject:",8) == 0)) {
  260.           // subject
  261.           Serial.println(lineBuf);
  262.           if(strcmp(&lineBuf[9],subjectLine) == 0) {
  263.             Serial.println("For my Arduino!");
  264.             forArduino= true;
  265.           }
  266.         }
  267.  
  268.         if(msgBody && strncmp(lineBuf,"command ",8) == 0) {
  269.           Serial.print("Command! D");        
  270.           sscanf(lineBuf,"%*s %u %s",&pinNo,pinState);
  271.           Serial.print(pinNo);
  272.           Serial.print(" ");
  273.           Serial.println(pinState);
  274.  
  275.           if(strcmp(pinState,"on") == 0) digitalWrite(pinNo,HIGH);        
  276.           if(strcmp(pinState,"off") == 0) digitalWrite(pinNo,LOW);        
  277.         }
  278.  
  279.         lineLength = 0;
  280.         lineBuf[0] = 0;
  281.       }
  282.       else if(thisByte != '\r') {
  283.         // another character
  284.         if(lineLength < 63) {
  285.           lineBuf[lineLength] = thisByte;
  286.           lineLength++;
  287.           lineBuf[lineLength] = 0;
  288.         }
  289.  
  290.       }
  291.     }
  292.   }
  293.  
  294.   if(forArduino) return 2;
  295.   return 1;
  296. }
  297.  
  298. void efail()
  299. {
  300.   byte thisByte = 0;
  301.   int loopCount = 0;
  302.  
  303.   client.println("QUIT");
  304.  
  305.   while(!client.available()) {
  306.     delay(1);
  307.     loopCount++;
  308.  
  309.     // if nothing received for 10 seconds, timeout
  310.     if(loopCount > 10000) {
  311.       client.stop();
  312.       Serial.println(F("\r\nTimeout"));
  313.       return;
  314.     }
  315.   }
  316.  
  317.   while(client.available())
  318.   {
  319.     thisByte = client.read();  
  320.     Serial.write(thisByte);
  321.   }
  322.  
  323.   client.stop();
  324.  
  325.   Serial.println(F("disconnected"));
  326. }
  327.  
  328. void printCurrentNet() {
  329.   // print the SSID of the network you're attached to:
  330.   Serial.print(F("SSID: "));
  331.   Serial.println(WiFi.SSID());
  332.  
  333.   // print the MAC address of the router you're attached to:
  334.   byte bssid[6];
  335.   WiFi.BSSID(bssid);  
  336.   Serial.print(F("BSSID: "));
  337.   Serial.print(bssid[5],HEX);
  338.   Serial.print(F(":"));
  339.   Serial.print(bssid[4],HEX);
  340.   Serial.print(F(":"));
  341.   Serial.print(bssid[3],HEX);
  342.   Serial.print(F(":"));
  343.   Serial.print(bssid[2],HEX);
  344.   Serial.print(F(":"));
  345.   Serial.print(bssid[1],HEX);
  346.   Serial.print(F(":"));
  347.   Serial.println(bssid[0],HEX);
  348.  
  349.   // print the received signal strength:
  350.   long rssi = WiFi.RSSI();
  351.   Serial.print(F("signal strength (RSSI):"));
  352.   Serial.println(rssi);
  353.  
  354.   // print the encryption type:
  355.   byte encryption = WiFi.encryptionType();
  356.   Serial.print(F("Encryption Type:"));
  357.   Serial.println(encryption,HEX);
  358. }
  359.  
  360. void printWifiData() {
  361.   // print your WiFi shield's IP address:
  362.   IPAddress ip = WiFi.localIP();
  363.     Serial.print(F("IP Address: "));
  364.   Serial.println(ip);
  365.   Serial.println(ip);
  366.  
  367.   // print your MAC address:
  368.   byte mac[6];
  369.   WiFi.macAddress(mac);
  370.   Serial.print(F("MAC address: "));
  371.   Serial.print(mac[5],HEX);
  372.   Serial.print(F(":"));
  373.   Serial.print(mac[4],HEX);
  374.   Serial.print(F(":"));
  375.   Serial.print(mac[3],HEX);
  376.   Serial.print(F(":"));
  377.   Serial.print(mac[2],HEX);
  378.   Serial.print(F(":"));
  379.   Serial.print(mac[1],HEX);
  380.   Serial.print(F(":"));
  381.   Serial.println(mac[0],HEX);
  382.  
  383.   // print your subnet mask:
  384.   IPAddress subnet = WiFi.subnetMask();
  385.   Serial.print(F("NetMask: "));
  386.   Serial.println(subnet);
  387.  
  388.   // print your gateway address:
  389.   IPAddress gateway = WiFi.gatewayIP();
  390.   Serial.print(F("Gateway: "));
  391.   Serial.println(gateway);
  392. }

Share