PIR servo

The servo starts but won’t stop. This same code has been working flawlessly twice but then later, the servo will not stop but runs continuously. Would seem the problem has to be programming, not hardware. What am I doing wrong?

//PIR runs 2 servos randomly for 5 seconds
#include <Servo.h>

#define PIN_SERVO1 9

int pos = 0;

Servo servo1;



int ledPin = 13; // led connected to control pin 13
int PIRSensor = 2; // the PIR sensor will be plugged at digital pin 2
int state = 0; // variable to store the value read from the sensor pin
int statePin = LOW; // variable used to store the last LED status, to toggle the light

void setup() {
  servo1.attach(PIN_SERVO1);
 
  
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
pinMode(PIRSensor, INPUT); // declare the PIRSensor as as OUTPUT
Serial.begin(9600); // use the serial po
}

void loop() {
static unsigned long StartTime=0;
state = digitalRead(PIRSensor); // read the sensor and store it in "state"

if (state != 0)
  {
  digitalWrite(ledPin, HIGH);
  Serial.println("Motion Detected!"); // send the string "Motion Detected!" back // to the computer
  StartTime=millis();
  while(millis()-StartTime < 8000)
    {
   
  for(pos = 0; pos <100; pos += 1)  // goes from 0 degrees to 100 degrees 
  {                                  // in steps of 1 degree 
    servo1.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(10);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 100; pos>=1; pos-=1)     // goes from 100 degrees to 0 degrees 
  {                                
    servo1.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(10);                       // waits 10ms for the servo to reach the position 
  }
    
  }
  }
else
  digitalWrite (9,LOW); // [color=red]turns light off if motion is not detected[/color]
delay(100); // we have to make a delay to avoid overloading the serial port
}

The servo starts but won't stop

Perhaps the HIGH state persists. You could try looking for transitions on the PIR input.

What are you seeing on the serial monitor?

I'm guessing that you want to wave the servo around for 8 seconds when there is a CHANGE in the value returned by reading the PIRSensor pin.

Yes, there seems to be a problem with the PIR. The serial monitor continues to read "motion detected", even when there is none. I don't know how to deal with this condition. Please advise. Thank you.

The arm should wave for eight seconds after detecting motion, then stop and wait for the next motion.

So, only trigger on transitions on the PIR input.

You need to save the previous state (at the end of loop). At the start of loop, after reading the current state, compare that to the previous state. Only if they are different, and the state is currently "motion detected" should you move the servo.

Is this a "state machine" example? If so, I assume there are examples that can be adapted from web sources as this is beyond my ability.

Is this a "state machine" example? I

No.

Create a new global variable called "lastState". In "setup" set "lastState" to the current state of the PIR input. In "loop", when you read the current state of the PIR input, comapre this to "lastState". If they are different, and the new state indicates the start of a detection event, start your animation. Save the value you read as the current state into "lastState".

this is beyond my ability.

I don’t think so.

int oldState = 0; // Save previous state

OK. Now you have a place to save the previous state.

else
digitalWrite (9,LOW); // turns light off if motion is not detected
delay(100); // we have to make a delay to avoid overloading the serial port
oldState = state; // Save the previous state
}

if (oldState != state && state != 0)

Now, you do something only when the state this time is not the same as last time.

3 changes to the code…

Thank you so much for the immediate help. My wife has to display this asap. I am going to hack this out with your notes and get back to you when it is up and running.

I continue to get the “expected unqualified-id before 'else” error. Usually, I play around with the braces to correct this but I am lost on this one. Can’t compile to see if your suggestions were plugged in as they should be.

//PIR runs 2 servos randomly for 5 seconds
#include <Servo.h>

#define PIN_SERVO1 9

int pos = 0;
[color=red]int lastState;[/color]
Servo servo1;



int ledPin = 13; // led connected to control pin 13
int PIRSensor = 2; // the PIR sensor will be plugged at digital pin 2
int state = 0; // variable to store the value read from the sensor pin
int statePin = LOW; // variable used to store the last LED status, to toggle the light

void setup() {
  servo1.attach(PIN_SERVO1);
 
 
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
pinMode(PIRSensor, INPUT); // declare the PIRSensor as as OUTPUT
Serial.begin(9600); // use the serial po
l[color=red][font=Verdana][font=Verdana]astState = digitalRead(PIRSensor);[/font][/font][/color]
}

void loop() {
static unsigned long StartTime=0;
state = digitalRead(PIRSensor); // read the sensor and store it in "state"

[color=red]if (state != lastState);[/color]
  {
    
  digitalWrite(ledPin, HIGH);
  Serial.println("Motion Detected!"); // send the string "Motion Detected!" back // to the computer
  StartTime=millis();
  while(millis()-StartTime <4000)
    {
   
  for(pos = 0; pos <100; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    servo1.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(10);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 100; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    servo1.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(10);                       // waits 15ms for the servo to reach the position 
    [color=red]lastState = digitalRead(PIRSensor);[/color]
 
   
  }
  }
}
}

else
  servo1.write( LOW);
  //digitalWrite (9,LOW);
  // turns light off if motion is not detected
delay(100); // we have to make a delay to avoid overloading the serial port
}

I suggest that you use the Tools + Auto Format menu item to properly align the { and } in your code, and the indent everything in between them. You will then see that the numbers of { and } in your code do not match.

the "[ color=red ]" stuff isnt going to help. That was to display some code in color on the web page, it is not code. Get rid of that.

Secondly it is just a matter of counting "{" and "}" - they have to match. You have too many "}"

Around line 31 you have a ";" immediatly after the "if". That ends the if statment and the following "{" is for a statement block that will always be executed. And therefor there is "lese without a "if" around line 54.

Thus, remove a "}" or two and the semicolon. Of course the logic (what executed under which conditions) is highly dependent on which "}" you remove, so think about it. Dont just wildly delete (as I did, because I only wanted to find syntax errors, not logic errors)

Oops! The last post was incomplete.

//PIR runs 2 servos randomly for 5 seconds
#include <Servo.h>

#define PIN_SERVO1 9

int pos = 0;
int lastState;
Servo servo1;
int oldState = 0;



int ledPin = 13; // led connected to control pin 13
int PIRSensor = 2; // the PIR sensor will be plugged at digital pin 2
int state = 0; // variable to store the value read from the sensor pin
int statePin = LOW; // variable used to store the last LED status, to toggle the light

void setup() {
  servo1.attach(PIN_SERVO1);
 //digitalWrite(servo1, LOW); /////////////////////////
 
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
pinMode(PIRSensor, INPUT); // declare the PIRSensor as as OUTPUT
Serial.begin(9600); // use the serial po
oldStat = digitalRead(PIRSensor);
}

void loop() {
static unsigned long StartTime=0;
state = digitalRead(PIRSensor); // read the sensor and store it in "state"

if (state != oldState)
  {
    
  digitalWrite(ledPin, HIGH);
  Serial.println("Motion Detected!"); // send the string "Motion Detected!" back // to the computer
  StartTime=millis();
  while(millis()-StartTime <4000)
    {
   
  for(pos = 0; pos <100; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    servo1.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(10);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 100; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    servo1.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(10);
 
    
  }
   
  }
  }
}

else
{
  servo1.write(9, LOW);
  //digitalWrite (9,LOW);
  // turns light off if motion is not detected
delay(100); // we have to make a delay to avoid overloading the serial port
oldState = state;
}

At first glance, missing at least one closing }

Auto format might help, but if you don't take more care, it'll struggle like we do.

I think you should take a little more time, care and thinking. The last post included a stupid, yet simple mistake

oldStat = digitalRead(PIRSensor);

error: 'oldStat' was not declared in this scopeBecuse of a simple typo - you declared oldState(with an "e") and used it correctly everywhere else.

Hey, we all make mistakes, that is allowed. But your posts look a bit like "hey I tried a few random keypresses, it doesnt compile/work, lets toss it on the forum and see what happens."

You are right! I have been at this since 4:30 this morning and late last night. Has to be done for display in two days so I am becoming a little desperate. I apologize for the obvious abuse. A week ago I thought this was up and running perfectly but something was amiss. Hard to be thoughtful when drowning! Sorry.