Go Down

Topic: HTTP GET based on Motion Detection (Read 436 times) previous topic - next topic

slug2zero

Apr 21, 2013, 03:27 am Last Edit: Apr 21, 2013, 04:15 am by slug2zero Reason: 1
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:

Code: [Select]
/*
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

PaulS

Quote
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.

PeterH


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.
I only provide help via the forum - please do not contact me for private consultancy.

slug2zero

Thanks for the responses.

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


PaulS

Quote
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.

slug2zero


Quote

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...

slug2zero

Ok
Thanks for pointing me in the right direction.

Edge Detection did the trick!!

As promised code below... In correct format :-)

Code: [Select]
/*
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();
 }
   }

PaulS

Code: [Select]
  {   
       // start the Ethernet connection using mac, ip, subnet, gw:
    Ethernet.begin(mac, ip);
    delay(1000);
  }

These braces are for?

Code: [Select]
  {
  // Set pin as input     
  pinMode(motionPin, INPUT);
}

And these misaligned ones?

Code: [Select]
      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.

Quote
In correct format :-)

No.

PeterH

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.
I only provide help via the forum - please do not contact me for private consultancy.

slug2zero

#9
Apr 22, 2013, 05:57 pm Last Edit: Apr 22, 2013, 06:11 pm by slug2zero Reason: 1
Right thanks Understood. :smiley-red:

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?

Code: [Select]
/*
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();
  }
}


PaulS

Quote
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.

Code: [Select]
      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?

Code: [Select]
  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.

slug2zero

Quote
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.



Go Up