HTTP GET based on Motion Detection

Hi.
I have an UNO and have the ethernet shield attached to it too.

I want to trigger once based on a trigger from my passive IR.

Problem I have is that it keeps sending the http get request whilst the IR is in HIGH state.

I have a work around in that I have introduced a 7 second delay from time of detection before it does the GET.

This however is too long for my use case.

Is there a way that I could change the code to trigger only once for a motion event rather than sending in non stop while the circuit is HIGH?

code below:

/*
Simple HTTP trigger sent to Video Management System based on motion detection event to start recording
 
 */

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


// MAc Address of Ethernet Shield
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xD5, 0x0B };
//Static Ip
byte ip[] = {10, 194, 31, 177};
//Subnet Mask
byte subnet[] = {255, 255, 255, 0};
//Gateway
byte gaetway[] = {10, 194, 31, 1};
// Ip address of Web Server
IPAddress server(10,194,31,190);  



//set as client mode
EthernetClient client;
const byte motionPin = 2;   // motion detector input pin 
byte senseMotion = 0;       // variable to hold current state of motion detector

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  {   
       // start the Ethernet connection using mac, ip, subnet, gw:
    Ethernet.begin(mac, ip);
    delay(1000);
  }
  {
  // Set pin as input      
  pinMode(motionPin, INPUT);
}
}

void loop()
{
    // Now watch for Motion
    senseMotion = digitalRead(motionPin);
    if (senseMotion == HIGH) {
 delay(7000);
      Serial.println("connecting...");
  client.connect(server, 80); {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /joumatest.html");
    client.println("Host: Test-server");
    client.println("Connection: close");
    client.println();
  } }
 else {
    client.stop();
  }
    }

Thanks for any help on this one

Is there a way that I could change the code to trigger only once for a motion event rather than sending in non stop while the circuit is HIGH?

More than one way
to skin that
cat. Depends
on what, exactly
youaretryingtoaccomplish.

slug2zero:
Is there a way that I could change the code to trigger only once for a motion event rather than sending in non stop while the circuit is HIGH?

This is very similar to the problem of detecting switch transitions and the same solution would work here: define a variable to record whether a motion event is in progress; if the motion detection indicates motion and there was no motion event already in progress then this is the start of the event, so do your one-off processing. You will find plenty of examples of similar logic to detect changes in switch input states. This is sometimes referred to as edge detection so that is a good term to search for.

Thanks for the responses.

Once I get it solved I will re-post with all the info

Once I get it solved I will re-post with all the info

Make sure you use Tools + Auto Format first, and post the code correctly next time.

Make sure you use Tools + Auto Format first, and post the code correctly next time.

Yup sorry missed the # and only spotted it later. Fixed now...

Ok
Thanks for pointing me in the right direction.

Edge Detection did the trick!!

As promised code below... In correct format :slight_smile:

/*
Simple HTTP trigger sent to a Video Management System based on motion detection event to start recording
 
 */

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


// MAc Address of Ethernet Shield
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xD5, 0x0B };
//Static Ip
byte ip[] = {10, 194, 31, 177};
//Subnet Mask
byte subnet[] = {255, 255, 255, 0};
//Gateway
byte gaetway[] = {10, 194, 31, 1};
// Ip address of Web Server
IPAddress server(10,194,31,190);  



//set as client mode
EthernetClient client;
const int motionPin = 2;   // motion detector input pin 
       
int motioncount = 0;
int MotionState = 0;
int lastmotionstate = 0;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  {   
       // start the Ethernet connection using mac, ip, subnet, gw:
    Ethernet.begin(mac, ip);
    delay(1000);
  }
  {
  // Set pin as input      
  pinMode(motionPin, INPUT);
}
}

void loop()
{
    // Now watch for burglers
    MotionState = digitalRead(motionPin);
    if (MotionState != lastmotionstate) {
      if (MotionState == HIGH){
        motioncount++;       
      Serial.println("connecting...");
  client.connect(server, 80); {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /joumatest.html");
    client.println("Host: Test-server");
    client.println("Connection: close");
    client.println();
  }
    
  }
  lastmotionstate = MotionState;
  }
  
  
 else {
    client.stop();
  }
    }
  {   
       // start the Ethernet connection using mac, ip, subnet, gw:
    Ethernet.begin(mac, ip);
    delay(1000);
  }

These braces are for?

  {
  // Set pin as input      
  pinMode(motionPin, INPUT);
}

And these misaligned ones?

      if (MotionState == HIGH){
        motioncount++;       
      Serial.println("connecting...");
  client.connect(server, 80); {

I can't believe that Tools + Auto Format did this. And, there's another useless brace.

In correct format :slight_smile:

No.

You've got the code tags right, but as PaulS points out your code layout leaves a lot to be desired and makes the code harder to read.

Braces (curly brackets { and }) are need around function bodies, and should also be used around any conditional piece of code (the body of a FOR loop, IF/ELSE statements and so on). They are not needed, and should not be used, in the middle of plain old sequential code. You do this in several places, and you should get rid of those spurious braces.

I recommend that you put each { and } on a separate line with patching pairs indented by the same amount, and lines between them indented one extra level. This makes it easy to identify matching pairs visually when scanning the code so the control structure can be seen easily. If you put the braces on separate lines and then use the Tools/Auto Format feature of the IDE, it will sort the indentation out for you.

Right thanks Understood. :blush:

I have now done auto-format and removed what I hope I needed to.

this is the code I have now.
Is this better? Anything else I can remove to make this cleaner? Is there a cleaner way of doing this?

/*
Simple HTTP trigger sent Video Management System based on moition detection event to start recording
 
 */

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


// MAc Address of Ethernet Shield
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0xD5, 0x0B
};
//Static Ip
byte ip[] = {
  10, 194, 31, 11
};
//Subnet Mask
byte subnet[] = {
  255, 255, 255, 0
};
//Gateway
byte gateway[] = {
  10, 194, 31, 1
};
// Ip address of Web Server
IPAddress server(10, 194, 31, 226);  
//set as client mode
EthernetClient client;
const int motionPin = 2;   // motion detector input pin 
//Motion Variables
int motioncount = 0;
int MotionState = 0;
int lastmotionstate = 0;

void setup(){
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // start the Ethernet connection using mac, ip, subnet, gw:
  Ethernet.begin(mac, ip);
  delay(1000);
  // Set pin as input      
  pinMode(motionPin, INPUT);
}

void loop(){
  // Now watch for burglers
  MotionState = digitalRead(motionPin);
  if (MotionState != lastmotionstate){
    if (MotionState == HIGH){
      motioncount++;       
      Serial.println("connecting...");
      client.connect(server, 80); 
      Serial.println("connected");
      // Make a HTTP request:
      delay(1000);
      client.println("GET /Event/SoftTrigger/primary/8cd5ccde-6efd-48d0-b065-35f1681e73feQXJkdWlubyBNb3Rpb24gZGV0ZWN0ZWQ%3D HTTP/1.0");
      client.println();
    }

    lastmotionstate = MotionState;
  }


  else {
    client.stop();
  }
}

Is this better? Anything else I can remove to make this cleaner?

Put each { on a new line.

Use consistent naming styles. MotionState and lastmotionstate just don't go together. currMotionState and prevMotionState do.

      Serial.println("connected");
      // Make a HTTP request:
      delay(1000);
      client.println("GET

Why is there a delay? Doesn't the GET request take long enough already?

  if (MotionState != lastmotionstate)
  {
     // Deal with intrusion

    lastmotionstate = MotionState;
  }
  else
  {
    client.stop();
  }

How does the true case relate to the false case?

lastmotionstate should be set EVERY pass through loop.

Why is there a delay? Doesn't the GET request take long enough already?

I added this in to make sure I could see a gap in my log files as I was debugging on the linux web box and the network and running Wireshark. Just didn't want to remove it until I had this perfectly tweaked to be as small as possible.

Thanks for the help.
Appreciated.