Using a PIR sensor as a switch to control servo

I'm hoping someone can help me with this (probably simple) problem. I've spent several hours browsing forums and trying different options and I just can't seem to crack it.

Project overview:
Use a PIR sensor as switch to control a servo. When PIR sensor is first activated the servo moves from 0 to 180 and should stop, until the PIR sensor is activated again, which moves the servo from 180 back to 0.

Issue:
I've modified an existing sketch designed to sweep a servo when the PIR is activated, and everything seems to be working correctly for the first activation, but if the sensor is activated again within about 70 seconds of the first activation (with the PIR timer set to it's lowest setting), the servo will move quickly from 180 to (not quite 0), and then slowly shift back up to 180.

Activating the sensor after about 70 seconds sends the servo from 180 back to 0 with no problem (the same quick movement, and regression happens if the sensor is activated within 70 seconds from the 0 position too).

I know these PIR sensors have a hardware knob to control sensitivity and time, and turning this timer to it's maximum setting will hold the servo in the 180 position after the first activation, flick back to nearly 0 after 5 seconds, and then sweep back to 180. This continued for more than 6 minutes before I switched the hardware knob back to the minimum setting.

I'm not sure whether there is a problem with the sketch, or whether the hardware timer on the PIR sensor is stuffing things up. I think what would be ideal is for the delay time following the servo movement to be just longer than the PIR sensor reset time but I don't really know if this is the only issue.

Thanks for any insight.

#include <Servo.h>

Servo myservo;                        //creates a servo object called myservo

int pos = 0;                          //variable to store servo position

int calibrationTime = 30;             //amount of time we give the sensor to calibrate(10-60 secs according to the datasheet)

long unsigned int lowIn;              //the time when the sensor outputs a low impulse

long unsigned int pause = 5000;       //the amount of milliseconds the sensor has to be low before we assume all motion has stopped

boolean lockLow = true;               //Boolean variables hold 2 values, in this case true or false
boolean takeLowTime;

int PIRpin = 12;                      //digital pin connected to the PIR's output
int PIRpos = 13;                      //connects to the PIR's 5V pin

void setup() {                        //Identifies where the PIR sensor and Servo are attached to the arduino
  myservo.attach(4);                  //attaches servo to pin 4
  Serial.begin(9600);                 //begins serial communication
  pinMode(PIRpin, INPUT);             //pinmode configures pin 12 to act as the input signal from the PIR sensor
  pinMode(PIRpos, OUTPUT);            //pinmode configures pin 13 to act as input (in this case power) to the PIR sensor
  digitalWrite(PIRpos, HIGH);
  myservo.write(0);                   // sets servo position to 0 at startup

  Serial.println("Calibrating light sensor ");             //give the sensor time to calibrate
  for (int i = 0; i < calibrationTime; i++) {        //this code takes the declared integer calibration time of 30, decreasing by 1 each time with a delay of 1 second.
    Serial.print(calibrationTime - i);
    Serial.print("-");                               //a hyphen is printed between each number
    delay(1000);
  }
  Serial.println();
  Serial.println("Calibration complete");

  while (digitalRead(PIRpin) == HIGH) {
    delay(500);
    Serial.print(".");
  }
  Serial.print("sensor is active");            // This code ensures that the sensor is in low mode (unstimulated) before declaring the sensor is active.
}


/*
 This section determines what the servo will do when the sensor is triggered
 */


void loop() {

                                                   

  if (digitalRead(PIRpin) == HIGH) {                //if the PIR output is HIGH (motion is detected), then the servo is triggered.

    for (pos = 0; pos < 180; pos += 1)              //if servo goes from 0 to 180 degrees in steps of one degree

    {
      myservo.write(pos);                          //tells servo to go to position indicated by the above equation (incrementally adding one step)
      delay(20);                                   //waits 20ms at each step
    }

    {
      delay(5000);                                 //Waits for 1 second at the end of the move

    }

    if (lockLow) {                                 //waits until sensor setting LOW before further action is
      lockLow = false;
      Serial.println("---");
      Serial.print("sensor detects motion at ");
      Serial.print(millis() / 1000);
      Serial.println(" sec");
      delay(5000);  // this was at 50
    }
    takeLowTime = true;

  }

  if (digitalRead(PIRpin) == LOW) {

    if (takeLowTime) {
      lowIn = millis();                            //save the time of the transition from HIGH to LOW
      takeLowTime = false;                         //make sure this is only done at the start of a LOW phase
    }

                                                   //if the sensor is low for more than the given pause, we can assume the motion has stopped
                                                   
    if (!lockLow && millis() - lowIn > pause) {
                                                   //makes sure this block of code is only executed again after a new motion sequence has been detected
      lockLow = true;
      Serial.print("motion ended at "); //output
      Serial.print((millis() - pause) / 1000);
      Serial.println(" sec");
      delay(5000);    //this was at 50
    }

/*
 * The following code activates if the servo is in the ON position.
 */


    if (digitalRead(PIRpin) == HIGH) {            //if the PIR output is HIGH (motion is detected), then the servo is triggered.

      for (pos = 180; pos >= 0; pos -= 1)         //goes from 180 to 0 degrees in steps of one degree

      {
        myservo.write(pos);                       //tells servo to go to position indicated by the above equation (incrementally adding one step)
        delay(20);                                //waits 20ms at each step
      }

      {
        delay(5000);                              //waits for 5 seconds

      }

      if (lockLow) {                              //makes sure we wait for a transition to LOW before further output is made
        lockLow = false;
        Serial.println("---");
        Serial.print("motion detected at ");
        Serial.print(millis() / 1000);
        Serial.println(" sec");
        delay(5000);    //this was at 50
      }
      takeLowTime = true;

    }

    if (digitalRead(PIRpin) == LOW) {

      if (takeLowTime) {
        lowIn = millis();                             //save the time of the transition from HIGH to LOW
        takeLowTime = false;                          //make sure this is only done at the start of a LOW phase
      }

                                                      //if the sensor is low for more than the given pause, we can assume the motion has stopped
      if (!lockLow && millis() - lowIn > pause) {
                                                      //makes sure this block of code is only executed again after a new motion sequence has been detected
        lockLow = true;
        Serial.print("motion ended at "); //output
        Serial.print((millis() - pause) / 1000);
        Serial.println(" sec");
        delay(5000);    //this was at 50
      }
    }
  }
}
    {
      delay(5000);                                 //Waits for 1 second at the end of the move

    }

What are those curly braces for? Why does the useless comment not match the code?

   if (lockLow) {                                 //waits until sensor setting LOW before further action is
      lockLow = false;

I cringe every time I see this crappy code reused. The state change detection example shows how to determine that a switch has become pressed, or has become released. The same code can be used to determine if a PIR sensor has sensed motion, or is no longer sensing motion, without the need for this stupid variable/construct.

What are those curly braces for? Why does the useless comment not match the code?

I'm still learning and trying my best. My apologies, I was fiddling with the delay timing and didn't update the comment. I suppose the use of the unnecessary curly brackets can be put down to my inexperience.

I cringe every time I see this crappy code reused. The state change detection example shows how to determine that a switch has become pressed, or has become released. The same code can be used to determine if a PIR sensor has sensed motion, or is no longer sensing motion, without the need for this stupid variable/construct.

Honestly I didn't understand the value or necessity of this code, it was part of the sketch I started with -- thanks for pointing out that it's superfluous.

Anyone?

sroho:
Anyone?

Yeah, you. I suggested that you look at the state change detection example, and base your code on that. That the state change is based on a PIR sensor rather than a switch is irrelevant. There is motion when there was not, or there is no motion when there was motion. Those are the two changes that are relevant.