email when motion detected

Ive got 2 scketches and I want to combine these. Ive tested them seperated and the work. Now I try to combine them. Ive uploaded thes sketch to my arduino but I think theres a mistake in de 'sendEmail' function. I can`t figure out what it is. I just started with my Arduinoproject. Can someone help me?

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

// my network settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { xxx, 168, 1, xxx};   
byte gateway[] = { 192, xxx, 1, 254 };
byte subnet[] = { 255, 255, 255, 0 };

// my own SP smtp email server
byte server[] = { 194, 134, 41, 21 };

Client client(server,25);


const unsigned int PIR_INPUT_PIN = 2;
const unsigned int BAUD_RATE = 9600;

class PassiveInfraredSensor { // <label id="code.ethernet.pir_class"/>
  int _input_pin;

  public:

  PassiveInfraredSensor(const int input_pin) 
{
    _input_pin = input_pin;
    pinMode(_input_pin, INPUT);
}
  
  const bool motion_detected() const 
{
    return digitalRead(_input_pin) == HIGH;
}

};

PassiveInfraredSensor pir(PIR_INPUT_PIN);

void setup() 
{
  Serial.begin(9600);
  delay(10);
  Ethernet.begin(mac, ip, gateway, subnet); 
  delay(1000);
  Serial.println("Ready");
}

void loop() 
{
  if (pir.motion_detected()) {
    Serial.println("Motion detected");

    	
	delay(5000);// here you will need to determine how often you want to send this alert
    	// that will be up to you, but not 5 times a second!!
    
    if(sendEmail()) Serial.println("Email sent");
    else Serial.println("Email failed");

  } else {
    Serial.println("No motion detected");    
  }
  delay(200);
}



sendEmail()
{
{
  byte inChar;

  inChar = Serial.read();
 
  if(inChar == 'e')
  {
      if(sendEmail()) Serial.println("Email sent");
      else Serial.println("Email failed");
  }
}

byte sendEmail()
{
  byte thisByte = 0;
  byte respCode;
  
  if (client.connect()) {
    Serial.println("connected");
  } else {
    Serial.println("connection failed");
    return 0;
  }

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

  respCode = client.peek();
  
  while(client.available())
  {  
    thisByte = client.read();    
    Serial.print(thisByte);
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
// replace with your public ip
  client.write("helo 83.117.xxx.134\r\n");
  
  while(!client.available()) delay(1);

  respCode = client.peek();

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

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
// replace with a valid from address
  client.write("MAIL From: xxx@online.nl>\r\n");
  
  while(!client.available()) delay(1);

  respCode = client.peek();

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

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
// Replace with the recipient address

  client.write("RCPT To: <xxxxx@hotmail.com>\r\n");

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

  respCode = client.peek();
  
  thisByte = 0;
  
  while(client.available())
  {  
    thisByte = client.read();    
    Serial.print(thisByte);
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
  client.write("DATA\r\n");

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

  respCode = client.peek();

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

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

// Replace with the recipient address as above  
  client.write("To: fagio2000 <xxx@hotmail.com>\r\n");

// Replace with the sender address above
  client.write("From: Arduino <xxx@online.nl>\r\n");
  
  client.write("Subject: bericht van uw Arduino\r\n");
  
  client.write("Dit is de tekst die in de email komt te staan.\r\n");
  
  client.write(".\r\n");

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

  respCode = client.peek();

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

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
  client.write("QUIT\r\n");

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

  respCode = client.peek();

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

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

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

void efail()
{
  byte thisByte = 0;

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

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

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

  client.stop();
  
  Serial.println("disconnected");
  
}
}
sendEmail()
{
{
  byte inChar;

  inChar = Serial.read();
 
  if(inChar == 'e')
  {
      if(sendEmail()) Serial.println("Email sent");
      else Serial.println("Email failed");
  }
}

Functions MUST have a return type defined. The number of { and the number of } MUST match. You've tried to violate both of these rules.

The number of { and } I will check. But what do you mean with return type? What is a return type of my "sendEmail' function? Do you mean I have to fill in some parameters?

This is the return type I used.

byte sendEmail()
{
   // email send code here.
}

The return type is a byte. That allows you to return the pass/fail to the loop().

return 0; // fail
return 1; //pass

That is what makes this work:

    if(sendEmail()) Serial.println("Email sent");
    else Serial.println("Email failed");

I see I used

if(sendEmail()) Serial.println("Email sent");
    else Serial.println("Email failed");

two times:

in 'void loop' and in the function 'sendEmail' is this correct? Or should I delete it in the email function and start the emailfunction with:

byte sendEmail()
{
 return 0; // fail
return 1; //pass
  
  if (client.connect()) {
    Serial.println("connected");
  } else {
    Serial.println("connection failed");
    return 0;
  }

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

  respCode = client.peek();
and so on........

I recommend starting again with the email sketch (renamed of course), and slowly add stuff to make it work. Add a motionDetect() function like the example below. The motionDetect routine will return 1, indication there was motion detected. Now when you press 'e' and enter, you should get a "Motion detected" message on the serial monitor before it sends the email.

void loop()
{
  byte inChar;

  inChar = Serial.read();
 
  if(inChar == 'e')
  {
      if(motionDetect())
      {
         Serial.println("Motion detected");

         if(sendEmail()) Serial.println("Email sent");
         else Serial.println("Email failed");
      }
  }
}

byte motionDetect()
{
   // your motion detect code here eventually
   return 1; // motion detected
   // return 0; // motion not detected
}

byte sendEmail()
{
   // the send email code here.
}

Start with that code and slowly modify it in stages, testing it as you go.

Thanx, I`ll try it!

Just so you can see how it works, try this:
comment out the "return 1;" and uncomment the "return 0;" in the motionDetect routine.
Then it will not display the "Motion detected", nor will it send the email, when you press the 'e'.

byte motionDetect()
{
   // your motion detect code here eventually
   // return 1; // motion detected
   return 0; // motion not detected
}

Add: Eventually you will be able to remove the serial input 'e' trigger completely when the code is working as you expect. That will leave only the motionDetect() return value as the email trigger.

I've been copy/pasting everybody's code into the below that sends an email when pin 4 is touched to ground. Might be useful for testing.

/*
12/21/11
SEND AN EMAIL WITH ARDUINO
 for IDE 1.0
 This code was created by modifying the connect example from 
 arduino.cc and with the help of the YABB forums and their very 
 helpful members. This code sends an email to any email address 
 and then disconnects.
 
 Send e in serial monitor to send email
 touch pin 4 to ground to send email
 */

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

// Change these next 4 entries to your network settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  
byte ip[] = { 192, 168, 1, 102 };  
byte subnet[] = { 255, 255, 255, 0 };
byte gateway[] = { 192, 168, 1, 1 };
byte server[] = { abc, abc, abc, abc }; //smtp server ip address
EthernetClient client;

int button1 = 4; //button pin, connect to ground to move servo
int press1 = 0;

void setup()
{
  Serial.begin(9600);
  delay(10);
  //Ethernet.begin(mac, ip); //subnet and gateway may not be needed
  Ethernet.begin(mac, ip, subnet, gateway); 
  delay(1000);
  
  pinMode(button1, INPUT);
  digitalWrite(4, HIGH); //enable pullups to make pin high
  
  Serial.println("Ready");
}

void loop()
{
  byte inChar;
  inChar = Serial.read();
  press1 = digitalRead(button1);
     
  if(inChar == 'e')
  {
    if(sendEmail()) Serial.println("Serial Email sent"); //start sendEmail()
    else Serial.println("Serial Email failed");
  }
 
   if (press1 == LOW)
  {
    delay(2000);
    if(sendEmail()) Serial.println("Button Email sent"); //start sendEmail()
    else Serial.println("Button Email failed");
  }
}

//////////////////////////////// email function
byte sendEmail()  //sendEmail() function that returns 1 or 0
{
  //start and check for email server connection
  if (client.connect(server,25)) { 
    Serial.println("connected");
  } 
  else {
    Serial.println("connection failed");
    return 0; //send 0 (failed) back to sendEmail() function
  }
  
  //wait for server "queing" response
  while(!client.available()) delay(1);

  client.println("HELO itismeletschat"); /*hello (statement after helo is needed but irrelevant)*/

  //wait for server "hello" response
  while(!client.available()) delay(1);

  client.println("MAIL From: me@myisp.net"); // identify sender, this should be the same as the smtp server you are using*/

  //wait for server "sender ok" response
  while(!client.available()) delay(1);

  client.println("RCPT To: you@yourisp.net"); /* identify recipient */

  //wait for server "receipent ok" response
  while(!client.available()) delay(1);

  client.println("DATA"); 

  //wait for server to say "enter your message" response
  while(!client.available()) delay(1);
 
  //send email message to server
  client.println("To: you@yourisp.net"); /* identify recipient */
  client.println("Subject: You Have Arduino Mail!!"); /* insert subject */
  client.println("Please let me know it worked!!!"); /* insert body */
  client.println("."); /* end email */

  //wait for server "message accepted" response
  while(!client.available()) delay(1);

  client.println("QUIT"); /* terminate connection */
  
  //wait for server "goodby" response
  while(!client.available()) delay(1);

  //stop client connection
  client.stop();
  Serial.println("disconnected");
  return 1; //send 1 (success) back to sendEmail() function
}

I think I`m almost there.
I combine al code and this looks like this:

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



// Change these next 4 entries to your network settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, xxx};   
byte gateway[] = { 192, xxx1, 254 };
byte subnet[] = { 255, xxx. 255, 0 };
byte server[] = { 194, xxx, 41, 21 };

Client client(server,25);

void setup()
{
  Serial.begin(9600);
  delay(10);
  Ethernet.begin(mac, ip, gateway, subnet); 
  delay(1000);
  Serial.println("Ready");
}

void loop()
{
   if (motionDetect return 1);
  {
    delay(2000);
    if(sendEmail()) Serial.println("Email sent"); 
    else Serial.println("Email failed");
  }
   
}

byte motionDetect()
{
  const unsigned int PIR_INPUT_PIN = 2;
const unsigned int BAUD_RATE = 9600;

class PassiveInfraredSensor { // <label id="code.ethernet.pir_class"/>
  int _input_pin;

  public:

  PassiveInfraredSensor(const int input_pin) {
    _input_pin = input_pin;
    pinMode(_input_pin, INPUT);
  }
  
  const bool motion_detected() const {
    return digitalRead(_input_pin) == HIGH;
  }
};

PassiveInfraredSensor pir(PIR_INPUT_PIN); 

   return 1; // motion detected
   // return 0; // motion not detected
}


byte sendEmail()
{
  al the emailcode.....................
  
}

The only error I think there is is the trigger motiondetect return 1. Am I right and what is it I`m doing wrong?

You are very close! Just a small error here. The call to motionDetect() was incorrect. This is the correct way to call that function.

void loop()
{
   if (motionDetect());
  {
    delay(2000);
    if(sendEmail()) Serial.println("Email sent"); 
    else Serial.println("Email failed");
  }
  // rest of code
}

There also needs to be two returns in the motionDetect() function. One for pass, the other for fail. Something like this:

byte motionDetect()
{
   byte mytest = 1;

   if(mytest == 1)
   {
      // this will send the email
      return 1;
   }

   // this will not
   return 0;
}

yes, but it keeps sending emails now. The trigger with the 'return 1' form the byte motiondetect isn`t correct I think but what is the problem...............?

Look at zoomkat's example a few posts above. He is using a pin state to send the email. My code will always send it, unless mytest is a pin state or other "volatile" variable.

That`s why I try this:

void loop()
{
   if (motionDetect());
   digitalRead (HIGH);
  {
    delay(2000);
    if(sendEmail()) Serial.println("Email sent"); 
    else Serial.println("Email failed");
  }

}

but it keeps sending......I think I say with this: when in the function motiondetect the readpin is high (motion is detected) send a email.

You need to do that in the motionDetect routine. For a test, select a digital pin. I will use pin 5 as an example.

in the setup(), add

pinMode(5,INPUT);
digitalWrite(5,HIGH);

This will set pin 5 to input with a pullup resistor on that pin. To send email, connect pin 5 to ground.

byte motionDetect()
{
   if(digitalRead(5) == LOW)
   {
      // returns 1 if pin is grounded
      return 1;
   }

   // returns 0 if it isn't
   return 0;
}

You should become a bit more proficient at the C programming language if you wish to continue. These are basic C statements.

   if (motionDetect());

That semi-colon on the end is causing your grief. It IS the body to be executed when the statement is true. Remove is, and the stuff in the curly braces that follows the statement will become the body to be executed (which appears to be what you want).

You need to do that in the motionDetect routine. For a test, select a digital pin. I will use pin 5 as an example.

Be aware that all pins don't seem to be equal when using my code. I tried adding additional button pins (I think I tried pin 5) and got the looping email sending (resulting in an emergency unplug of the USB cable to prevent blowing out my email in box!). I'll have to do more pin testing to see what the deal is.

I just looked at the schematics for the "old version" and the "new version" ethernet shields, and there is a pin difference, and not just 11-13.

The old shield uses digital pins pins 2-6 for something.
http://www.cutedigi.com/pub/Arduino/arduino-ethernet-shield-schematic.pdf

The new shield uses pins 0-4 for something. Pin 4 is the SD SPI Slave Select pin. No idea what the PD pins are (pins 0-3).

I`ve made some changes in my code and leave the idea of 'return'. I think this is for newbies like me easier.
This is the code:

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

// Change these next 4 entries to your network settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, xxx, 1, 200 };   
byte gateway[] = { 192, xxx, 1, xxx};
byte subnet[] = { 255, xxx, 255, 0 };
byte server[] = { 194, xxx, 41, 21 };

Client client(server,25);
const int inputPin = 2;

void setup()
{
  Serial.begin(9600);
  delay(10);
  Ethernet.begin(mac, ip, gateway, subnet); 
  delay(5000);
  Serial.println("Ready");
  pinMode (inputPin, INPUT);
}

void loop (){
  int val = digitalRead(inputPin);
  if (val == HIGH)
  {
    delay(2000);
    if(sendEmail()) Serial.println("Email sent"); 
    else Serial.println("Email failed");
  }
}
  
 byte sendEmail()
{
  byte thisByte = 0;
  byte respCode;
  
  if (client.connect()) {
    Serial.println("connected");
  } else {
    Serial.println("connection failed");
    return 0;
  }

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

  respCode = client.peek();
  
  while(client.available())
  {  
    thisByte = client.read();    
    Serial.print(thisByte);
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
// replace with your public ip
  client.write("helo 83.xxx.xxx.134\r\n");
  
  while(!client.available()) delay(1);

  respCode = client.peek();

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

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
// replace with a valid from address
  client.write("MAIL From: <xxx@online.nl>\r\n");
  
  while(!client.available()) delay(1);

  respCode = client.peek();

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

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
// Replace with the recipient address
// This must be a gmail.com domain to work if you are using Gmail
  client.write("RCPT To: <xxx@hotmail.com>\r\n");

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

  respCode = client.peek();
  
  thisByte = 0;
  
  while(client.available())
  {  
    thisByte = client.read();    
    Serial.print(thisByte);
  }

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
  client.write("DATA\r\n");

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

  respCode = client.peek();

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

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

// Replace with the recipient address as above  
  client.write("To: xxx<xxx@hotmail.com>\r\n");

// Replace with the sender address above
  client.write("From: Arduino <xxx@online.nl>\r\n");
  
  client.write("Subject: bericht van uw Arduino\r\n");
  
  client.write("Dit is de tekst die in de email komt te staan.\r\n");
  
  client.write(".\r\n");

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

  respCode = client.peek();

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

  if(respCode >= '4')
  {
    efail();
    return 0;  
  }
  
  client.write("QUIT\r\n");

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

  respCode = client.peek();

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

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

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

void efail()
{
  byte thisByte = 0;

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

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

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

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

Are there disaventages doing it this way?