Arduino+Wifi Shield sending email - 501 NULL character error

Hi guys,

I’ve been trying to send an email through an Arduino+Wifi shield and I’m using my phone’s 3G internet to make a portable hotspot for the Arduino to connect to.
I’ve tested USB tethering my laptop to my phone and used telnet to send an email through SMTP2GO and it works fine, but once I try to do it through the arduino I keep getting a “501 NULL characters are not allowed in SMTP commands.” I’ve used every instance of print, println, write("\r\n") because I thought it might have something to do with my newline/carriage returns. I can connect to the server fine but when I try to send it commands it just keeps returning the 501 error.

I tried Googling what is it that I’m possibly sending to get that error but I’ve come up blank. Most of the code was taken from the Wifi WPA example and AndyPRR’s code from a year ago: http://forum.arduino.cc/index.php/topic,104449.msg784053.html#msg784053

 #include <WiFi.h>
 #include <SPI.h>

char ssid[] = "AndroidAP";     //  your network SSID (name) 
char pass[] = "*******";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

WiFiClient client; // Wifi client instead of Ethernet

IPAddress server(207,58,147,66); // smtpcorp.com

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 
  
 // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:    
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
   
  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();
  

}

void loop() {
  // check the network connection once every 10 seconds:
  delay(10000);
  printCurrentNet();
  
  // Check for serial input
  byte inChar;
  
  inChar = Serial.read();
  
  if (inChar == 'e')
  {
    if(sendEmail())  {
      Serial.println("Email sent");
    }
    else {
      Serial.println("Email failed");
    }
  }
      
}

// Andy's code
byte sendEmail() {
  byte thisByte = 0;
  byte respCode;
  
  if (client.connect(server,2525)) {
    Serial.println("connected");
  } else {
    Serial.println("connection failed");
    return 0;
  }

  if(!eRcv()) return 0;

// EHLO
  client.print("EHLO\r\n");    //Problem starts here
 
  if(!eRcv()) return 0;
  
  client.print("AUTH LOGIN\r\n");
  
  if(!eRcv()) return 0;
  
  client.print("****************************\r\n");
  
  if(!eRcv()) return 0;
  
  client.print("*********\r\n");
  
  if(!eRcv()) return 0;

// change this
  client.print("MAIL From: <arduinoleonardo@laptop.com>\r\n");
 
  if(!eRcv()) return 0;

// change this  
  client.print("RCPT To: <**********************>\r\n");

  if(!eRcv()) return 0;

  client.print("DATA\r\n");

  if(!eRcv()) return 0;

//change this
  client.print("To: You <*************************>\r\n");

// change this
  client.print("From: Me <arduinoleonardo@laptop.com>\r\n");
  
  client.print("Subject: Arduino email test\r\n");
  
  client.print("Suck it\r\n");
  
  client.print(".\r\n");

  if(!eRcv()) return 0;

  client.print("QUIT\r\n");

  if(!eRcv()) return 0;

  client.stop();
  Serial.println("disconnected");
  return 1;
}

byte eRcv()
{
  byte respCode;
  byte thisByte;
  
  while(!client.available()) delay(1);

  respCode = client.peek();

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
  return 1;
}

void efail()
{
  byte thisByte = 0;

  client.write("QUIT\r\n");

  while(!client.available()) delay(1);

  while(client.available())
  {  
    thisByte = client.read();    
    Serial.write(thisByte);
  }

  client.stop();
  Serial.println("disconnected");
}



void printWifiData() {
  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
    Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println(ip);
  
  // print your MAC address:
  byte mac[6];  
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  Serial.print(mac[5],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.println(mac[0],HEX);
 
}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);    
  Serial.print("BSSID: ");
  Serial.print(bssid[5],HEX);
  Serial.print(":");
  Serial.print(bssid[4],HEX);
  Serial.print(":");
  Serial.print(bssid[3],HEX);
  Serial.print(":");
  Serial.print(bssid[2],HEX);
  Serial.print(":");
  Serial.print(bssid[1],HEX);
  Serial.print(":");
  Serial.println(bssid[0],HEX);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption,HEX);
  Serial.println();
}

Thanks guys :slight_smile:

I don't know if this is causing your problem, but when you send helo, it should be followed by the public ip address.

// change this ip to your public ip
  client.println(F("helo 1.2.3.4"));

You could also be running out of SRAM. I don't know how much SRAM the wifi stuff takes. Try using the F() macro to keep the static strings in program memory. You must use client.print() or client.println() to use the F() macro. It fails with client.write().

edit: I added the F() macro to the code line above as an example.

Ah thanks. The F() macro did it. Regarding its use, am I only supposed to use it when sending strings?

Slothenstein: Ah thanks. The F() macro did it. Regarding its use, am I only supposed to use it when sending strings?

According to plyon, using F(), the FLASH helper, in client.print will result the wifi shield sending one packet per character, i.e. very slow. I tried to under the reason but the syntax of F() in the source file stopped me dead. I'm not too big with templates etc. but I trust plyon's judgement. I would only do F() with serial messages. If you want to try, have a timer to time the entire send process of your whole email and print the delay after you send the email.